<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ayush</title>
    <description>The latest articles on Forem by Ayush (@ayush1325).</description>
    <link>https://forem.com/ayush1325</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F472328%2Faee500a1-1a47-445f-a6c1-1e67c7e1ef40.png</url>
      <title>Forem: Ayush</title>
      <link>https://forem.com/ayush1325</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ayush1325"/>
    <language>en</language>
    <item>
      <title>Handling ExitBootServices Event in Rust std</title>
      <dc:creator>Ayush</dc:creator>
      <pubDate>Fri, 07 Apr 2023 10:37:12 +0000</pubDate>
      <link>https://forem.com/ayush1325/handling-exitbootservices-event-in-rust-std-gma</link>
      <guid>https://forem.com/ayush1325/handling-exitbootservices-event-in-rust-std-gma</guid>
      <description>&lt;p&gt;Hello everyone. Recently, there was a discussion about the exact scope/boundary of Rust std for UEFI. In this post, I am going to go over the different stages of UEFI and define what std for UEFI aims to target. Additionally, I will go over how the current implementation handles &lt;code&gt;ExitBootServices()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;Unlike Operating Systems, UEFI is a collection of stages in the boot sequence, each with its own set of available resources/functionality. As such, it is vital to remember where in the UEFI boot stages a binary is supposed to be run. Here is a simple diagram of the different Boot Stages in UEFI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MVyAmTE_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://assets.programmershideaway.xyz/images/post20/uefi_stages.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MVyAmTE_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://assets.programmershideaway.xyz/images/post20/uefi_stages.webp" alt="UEFI Boot Sequence" width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I will go over each stage and their relation to Rust std.&lt;/p&gt;

&lt;h3&gt;
  
  
  SEC – Security Phase
&lt;/h3&gt;

&lt;p&gt;The Security (SEC) phase is the first phase in the PI Architecture and is responsible for the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Handling all platform restart events&lt;/li&gt;
&lt;li&gt;Creating a temporary memory store&lt;/li&gt;
&lt;li&gt;Serving as the root of trust in the system&lt;/li&gt;
&lt;li&gt;Passing handoff information to the PEI Foundation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rust std implementation should not be used here. In fact, even the &lt;code&gt;{arch}-unknown-uefi&lt;/code&gt; target is not meant to be used in this phase.&lt;/p&gt;

&lt;h3&gt;
  
  
  PEI – Pre-EFI Initialization
&lt;/h3&gt;

&lt;p&gt;The PEI phase initially operates with the platform in a nascent state, leveraging only on-processor resources, such as the processor cache as a call stack, to dispatch Pre-EFI Initialization Modules (PEIMs). These PEIMs are responsible for the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initializing some permanent memory complement&lt;/li&gt;
&lt;li&gt;Describing the memory in Handoff Blocks (HOBs)&lt;/li&gt;
&lt;li&gt;Describing the firmware volume locations in HOBs&lt;/li&gt;
&lt;li&gt;Passing control into the Driver Execution Environment (DXE) phase.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rust std implementation should not be used here. In fact, even the &lt;code&gt;{arch}-unknown-uefi&lt;/code&gt; target is not meant to be used in this phase.&lt;/p&gt;

&lt;h3&gt;
  
  
  DXE – Driver Execution Environment
&lt;/h3&gt;

&lt;p&gt;There are several components in the DXE phase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DXE Foundation&lt;/li&gt;
&lt;li&gt;DXE Dispatcher&lt;/li&gt;
&lt;li&gt;A set of DXE Drivers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rust std implementation can be used here.&lt;/p&gt;

&lt;h3&gt;
  
  
  BDS – Boot Device Select
&lt;/h3&gt;

&lt;p&gt;The BDS phase is responsible for the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initializing console devices&lt;/li&gt;
&lt;li&gt;Loading device drivers&lt;/li&gt;
&lt;li&gt;Attempting to load and execute boot selections&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rust std implementation can be used here.&lt;/p&gt;

&lt;h3&gt;
  
  
  TSL – Transient System Load
&lt;/h3&gt;

&lt;p&gt;This is the stage between boot device selection and handoff to the OS. At this point, one may enter the UEFI shell or execute a UEFI application such as the OS boot loader.&lt;/p&gt;

&lt;p&gt;Rust std implementation can be used here.&lt;/p&gt;

&lt;h3&gt;
  
  
  RT – Runtime
&lt;/h3&gt;

&lt;p&gt;The UEFI hands off to the operating system (OS) after &lt;code&gt;ExitBootServices()&lt;/code&gt; is executed. A UEFI-compatible OS is now responsible for exiting boot services triggering the firmware to unload all no longer needed code and data, leaving only runtime services code/data, e.g., SMM and ACPI.[86] A typical modern OS will prefer to use its own programs (such as kernel drivers) to control hardware devices.&lt;/p&gt;

&lt;p&gt;Since any UEFI stuff still running needs to be started in one of the earlier stages, it is possible to use Rust std. However, it is up to the developer to deal with dangling/invalid pointers once &lt;code&gt;ExitBootServices&lt;/code&gt; is called.&lt;/p&gt;

&lt;p&gt;Also, the allocator, console, and a lot of other stuff are unavailable at this point. While the std will try to ensure the invalid pointers are not accessed, it cannot provide functionality that no longer exists.&lt;/p&gt;

&lt;p&gt;I will not recommend using Rust std for writing Runtime Drivers unless you are absolutely sure of what you are doing.&lt;/p&gt;

&lt;h3&gt;
  
  
  AL - After Life
&lt;/h3&gt;

&lt;p&gt;The After Life (AL) phase consists of persistent UEFI drivers used for storing the state of the system during the OS orderly shutdown, sleep, hibernate or restart processes.&lt;/p&gt;

&lt;p&gt;Similar to RT, I would not recommend using Rust std in this phase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling ExitBootServices()
&lt;/h2&gt;

&lt;p&gt;The Rust std now registers a callback when &lt;code&gt;EVT_SIGNAL_EXIT_BOOT_SERVICES&lt;/code&gt; is signaled. This callback makes BootServices unavailable. The most significant consequence of this is that the provided &lt;a href="https://doc.rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html"&gt;Allocator&lt;/a&gt; no longer works.&lt;/p&gt;

&lt;p&gt;Since, all the memory in Rust std is allocated with the memory type &lt;code&gt;EfiLoaderData&lt;/code&gt;, it is not really valid at after this point. Feel free to comment at the &lt;a href="https://github.com/rust-lang/rust/pull/100316"&gt;PR&lt;/a&gt; if you would like to see this configurable.&lt;/p&gt;

&lt;p&gt;An additional function, &lt;code&gt;boot_services&lt;/code&gt; has been added under &lt;code&gt;std::os::uefi::env&lt;/code&gt;. This function ensures that BootServices are still valid before returning the pointer. However, it is still possible to circumvent this by just directly using the &lt;code&gt;system_table&lt;/code&gt; function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Hopefully, this post will clarify when and where Rust std for UEFI should be used.&lt;/p&gt;

&lt;p&gt;Consider &lt;a href="https://programmershideaway.xyz/supportme/"&gt;supporting me&lt;/a&gt; if you like my work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Helpful Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://edk2-docs.gitbook.io/edk-ii-build-specification/2_design_discussion/23_boot_sequence"&gt;Boot Sequence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/rust-lang/rust/pull/100316"&gt;Minimal Rust std PR&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>uefi</category>
    </item>
    <item>
      <title>Compiler generate custom entry for any target</title>
      <dc:creator>Ayush</dc:creator>
      <pubDate>Sat, 18 Mar 2023 10:38:12 +0000</pubDate>
      <link>https://forem.com/ayush1325/compiler-generate-custom-entry-for-any-target-31me</link>
      <guid>https://forem.com/ayush1325/compiler-generate-custom-entry-for-any-target-31me</guid>
      <description>&lt;p&gt;Hello everyone. While implementing Rust std for UEFI, I came across an interesting problem. The signature of the entry function in Rust did not match the UEFI entry signature. Initially, I just used a hacky way to get things to work. However, later I made some changes to upstream Rust to make generating entry functions with custom signatures much easier. In this post, I will show how to implement generating such an entry function in upstream Rust through the example of UEFI.&lt;/p&gt;

&lt;p&gt;Read my &lt;a href="https://programmershideaway.xyz/post7/"&gt;prior post&lt;/a&gt; for an in-depth explanation of everything that goes on before Rust main.&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;UEFI expects the entry function to have the following signature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;r_efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"efiapi"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_handle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;system_table&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Currently, the Rust compiler generates a custom LLVM function that calls the Rust entry. In earlier versions of Rust, generating a custom entry function would have needed modification to many different modules in upstream Rust. However, since &lt;a href="https://github.com/rust-lang/rust/pull/104045"&gt;#104045&lt;/a&gt; and &lt;a href="https://github.com/rust-lang/rust/pull/104001"&gt;#104001&lt;/a&gt; have been merged, only a few files need to be modified.&lt;/p&gt;

&lt;p&gt;It is important to note that the Rust &lt;code&gt;lang_start&lt;/code&gt; has the following signature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;lang_start&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;crate&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;process&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Termination&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;'static&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;isize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;isize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thus even a custom entry function has to finally call this &lt;code&gt;lang_start&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;Now I will go through the two main steps needed for custom entry function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modifying Target spec
&lt;/h3&gt;

&lt;p&gt;The target spec now contains the entry function's &lt;strong&gt;name&lt;/strong&gt; and &lt;strong&gt;ABI&lt;/strong&gt;. This means it is also possible to modify the name and ABI by using a target specification Json instead of modifying the compiler.&lt;/p&gt;

&lt;p&gt;For the UEFI entry name, we need to modify &lt;code&gt;compiler/rustc_target/src/spec/uefi_msvc_base.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;compiler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rustc_target&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;uefi_msvc_base&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;compiler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rustc_target&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;uefi_msvc_base&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="mi"&gt;8968&lt;/span&gt;&lt;span class="n"&gt;d3c8fc1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;a50a55ad7e0&lt;/span&gt; &lt;span class="mi"&gt;100644&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;compiler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rustc_target&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;uefi_msvc_base&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
&lt;span class="o"&gt;+++&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;compiler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rustc_target&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;uefi_msvc_base&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
&lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;TargetOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="n"&gt;stack_probes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;StackProbeType&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Call&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="n"&gt;singlethread&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="n"&gt;linker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"rust-lld"&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;entry_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"efi_main"&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
         &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the entry ABI, we need to modify &lt;code&gt;compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;compiler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rustc_target&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x86_64_unknown_uefi&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;compiler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rustc_target&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x86_64_unknown_uefi&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="n"&gt;a7ae17839da&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="n"&gt;bc74ad2999&lt;/span&gt; &lt;span class="mi"&gt;100644&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;compiler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rustc_target&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x86_64_unknown_uefi&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
&lt;span class="o"&gt;+++&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;compiler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rustc_target&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;x86_64_unknown_uefi&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
&lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt;
 &lt;span class="c1"&gt;// The win64 ABI is used. It differs from the sysv64 ABI, so we must use a windows target with&lt;/span&gt;
 &lt;span class="c1"&gt;// LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features.&lt;/span&gt;

&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;crate&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;crate&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;call&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Conv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

 &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;target&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;uefi_msvc_base&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
     &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="py"&gt;.cpu&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"x86-64"&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
     &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="py"&gt;.max_atomic_width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="py"&gt;.entry_abi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Conv&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;X86_64Win64&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

     &lt;span class="c1"&gt;// We disable MMX and SSE for now, even though UEFI allows using them. Problem is, you have to&lt;/span&gt;
     &lt;span class="c1"&gt;// enable these CPU features explicitly before their first use, otherwise their instructions&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implement LLVM entry generation
&lt;/h3&gt;

&lt;p&gt;Now we need to implement the actual LLVM code to generate for our target. For UEFI, we will pass the SystemTable and ImageHandle in &lt;code&gt;argv&lt;/code&gt; and set the value of &lt;code&gt;argc&lt;/code&gt; to 2. For this, we need to make the following changes to &lt;code&gt;compiler/rustc_codegen_ssa/src/base.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;compiler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rustc_codegen_ssa&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;compiler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rustc_codegen_ssa&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="n"&gt;abc510e360d&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;be75552efd&lt;/span&gt; &lt;span class="mi"&gt;100644&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;compiler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rustc_codegen_ssa&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
&lt;span class="o"&gt;+++&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;compiler&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rustc_codegen_ssa&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
&lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;430&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;430&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;create_entry_fn&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;'tcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BuilderMethods&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;'tcx&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
         &lt;span class="n"&gt;rust_main_def_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DefId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="n"&gt;entry_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EntryFnType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Bx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Function&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="c1"&gt;// The entry function is either `int main(void)` or `int main(int argc, char **argv)`,&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="c1"&gt;// depending on whether the target needs `argc` and `argv` to be passed in.&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;llfty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.sess&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.target.main_needs_argc_argv&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="c1"&gt;// The entry function is either `int main(void)` or `int main(int argc, char **argv)`, or&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="c1"&gt;// `Status efi_main(Handle hd, SystemTable *st)` depending on the target.&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;llfty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.sess&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.target.os&lt;/span&gt;&lt;span class="nf"&gt;.contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"uefi"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_i8p&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_i8p&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_isize&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.sess&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.target.main_needs_argc_argv&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_int&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_ptr_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_i8p&lt;/span&gt;&lt;span class="p"&gt;())],&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_int&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_int&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;496&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;498&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;create_entry_fn&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;'tcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BuilderMethods&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;'tcx&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
         &lt;span class="p"&gt;};&lt;/span&gt;

         &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start_ty&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;start_fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;cast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.intcast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_int&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.ret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.sess&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.target.os&lt;/span&gt;&lt;span class="nf"&gt;.contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"uefi"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.ret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;cast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.intcast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_int&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.ret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

         &lt;span class="n"&gt;llfn&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;508&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;514&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;get_argc_argv&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;'tcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BuilderMethods&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;'tcx&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="nn"&gt;Bx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CodegenCx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Bx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Bx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Bx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.sess&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.target.main_needs_argc_argv&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.sess&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.target.os&lt;/span&gt;&lt;span class="nf"&gt;.contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"uefi"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="c1"&gt;// Params for UEFI&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;param_handle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.get_param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;param_system_table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.get_param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;arg_argc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.const_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_isize&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;arg_argv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.alloca&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_i8p&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nn"&gt;Align&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ONE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param_handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg_argv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Align&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ONE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;arg_argv_el1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.gep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_ptr_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_i8&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt; &lt;span class="n"&gt;arg_argv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.const_int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_int&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)]);&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param_system_table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg_argv_el1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Align&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ONE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg_argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg_argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.sess&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.target.main_needs_argc_argv&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="c1"&gt;// Params from native `main()` used as args for rust start function&lt;/span&gt;
         &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;param_argc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.get_param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
         &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;param_argv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bx&lt;/span&gt;&lt;span class="nf"&gt;.get_param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; While the generation code seems to use &lt;code&gt;i8&lt;/code&gt; pointers, the generated LLVM IR actually uses &lt;a href="https://llvm.org/docs/OpaquePointers.html"&gt;Opque Pointers&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As outlined in this post, it should now be much easier to implement generating custom entry functions for Rust targets. This can be especially useful for embedded or some custom OS use cases.&lt;/p&gt;

&lt;p&gt;Consider &lt;a href="https://programmershideaway.xyz/supportme/"&gt;supporting me&lt;/a&gt; if you like my work.&lt;/p&gt;

</description>
      <category>rust</category>
    </item>
    <item>
      <title>Validating Json Request in axum</title>
      <dc:creator>Ayush</dc:creator>
      <pubDate>Tue, 17 Jan 2023 13:31:12 +0000</pubDate>
      <link>https://forem.com/ayush1325/validating-json-request-in-axum-2n34</link>
      <guid>https://forem.com/ayush1325/validating-json-request-in-axum-2n34</guid>
      <description>&lt;p&gt;I have been playing around with &lt;a href="https://docs.rs/axum/latest/axum/index.html"&gt;axum&lt;/a&gt;, and it has been quite a fun web framework. While using it, I came across what is a relatively common use case of validating the request JSON. However, I could not find any &lt;a href="https://docs.rs/axum/latest/axum/index.html#extractors"&gt;extractor&lt;/a&gt; for this. Thus I decided to write my own and share it with everyone. While I haven't put it in a crate, feel free to use the code as you wish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Axum Extractors
&lt;/h2&gt;

&lt;p&gt;An extractor allows us to pick apart the incoming request to get the parts our HTTP handler needs. More about extractors can be found &lt;a href="https://docs.rs/axum/latest/axum/extract/index.html"&gt;here&lt;/a&gt;. There are two important traits when talking about extractors:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://docs.rs/axum/latest/axum/extract/trait.FromRequestParts.html"&gt;FromRequestParts&lt;/a&gt;: This is used if the extractor does not need access to the request body.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.rs/axum/latest/axum/extract/trait.FromRequest.html"&gt;FromRequest&lt;/a&gt;: This is used if the extractor does need access to the request body. (we will be using this)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;I will use &lt;a href="https://crates.io/crates/validator"&gt;validator&lt;/a&gt; crate for the actual validation.&lt;/p&gt;

&lt;p&gt;Here is the code for our validated JSON extractor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;axum&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;async_trait&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;FromRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RequestExt&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;hyper&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Validate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;ValidatedJson&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;J&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;J&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nd"&gt;#[async_trait]&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;J&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;FromRequest&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;ValidatedJson&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;J&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt;
    &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;'static&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Send&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Sync&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;J&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Validate&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;'static&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;J&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FromRequest&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Rejection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;from_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Rejection&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;
            &lt;span class="py"&gt;.extract&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Json&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;J&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;.await&lt;/span&gt;
            &lt;span class="nf"&gt;.map_err&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BAD_REQUEST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Invalid JSON body"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nf"&gt;.validate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.map_err&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BAD_REQUEST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Invalid JSON body"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am using &lt;code&gt;(StatusCode, &amp;amp;'static str)&lt;/code&gt; for error response since all the responses in my server are of this type. Feel free to use whatever you prefer.&lt;/p&gt;

&lt;p&gt;It is important to note that extractors can use other extractors themselves. So we do not need to replicate the &lt;a href="https://docs.rs/axum/latest/axum/struct.Json.html"&gt;Json&lt;/a&gt; extractor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As you can see, writing a custom extractor is relatively straightforward, especially when compared to writing a &lt;a href="https://crates.io/crates/tower"&gt;tower&lt;/a&gt; middleware.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Using Rust main from custom entry point (Part 3)</title>
      <dc:creator>Ayush</dc:creator>
      <pubDate>Thu, 27 Oct 2022 16:52:12 +0000</pubDate>
      <link>https://forem.com/ayush1325/using-rust-main-from-custom-entry-point-part-3-ch1</link>
      <guid>https://forem.com/ayush1325/using-rust-main-from-custom-entry-point-part-3-ch1</guid>
      <description>&lt;p&gt;Even though GSoC 2022 has ended, I am still working on getting &lt;a href="https://github.com/rust-lang/rust/pull/100316"&gt;Rust std PR&lt;/a&gt; merged into the master. In the initial PR, I still used the entry function described in the &lt;a href="https://programmershideaway.xyz/post7/"&gt;prior post&lt;/a&gt;. However, this had many limitations, and thus I have finally transitioned to using a compiler-generated entry function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations of the older method
&lt;/h2&gt;

&lt;p&gt;In the initial PR, I used an extern &lt;code&gt;efi_main&lt;/code&gt; function called the compiler-generated &lt;code&gt;main&lt;/code&gt; function. This had the following limitations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;efi_main&lt;/code&gt; function is generated in all projects using std. This means it will be present when using the &lt;code&gt;no_main&lt;/code&gt; attribute or library crate, thus diminishing the usefulness of std in libraries and drivers. It also rules out anything that does not want to use Heap allocation since Rust does some Heap allocations during the runtime setup.&lt;/li&gt;
&lt;li&gt;Trying to pass pointers to &lt;code&gt;SystemTable&lt;/code&gt; and &lt;code&gt;ImageHandle&lt;/code&gt; as argv caused errors when building in release mode. This meant I was doing initialization from a function with no runtime setup and could thus cause all kinds of UB in case of panics.&lt;/li&gt;
&lt;li&gt;Added a layer of redirection.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The new implementation
&lt;/h2&gt;

&lt;p&gt;If you are unaware of everything that goes on before Rust &lt;code&gt;main&lt;/code&gt;, then you should read my &lt;a href="https://programmershideaway.xyz/post7/"&gt;previous post&lt;/a&gt; about this. I am replacing the compiler-generated C &lt;code&gt;main&lt;/code&gt; in the new implementation with the Win64 &lt;code&gt;efi_main&lt;/code&gt; function. Inspecting the LLVM-IR of a simple application, we can see the generated &lt;code&gt;efi_main&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight llvm"&gt;&lt;code&gt;&lt;span class="c1"&gt;; Function Attrs: noredzone nounwind&lt;/span&gt;
&lt;span class="k"&gt;define&lt;/span&gt; &lt;span class="k"&gt;win64cc&lt;/span&gt; &lt;span class="kt"&gt;i64&lt;/span&gt; &lt;span class="vg"&gt;@efi_main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ptr&lt;/span&gt; &lt;span class="nv"&gt;%0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;ptr&lt;/span&gt; &lt;span class="nv"&gt;%1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;unnamed_addr&lt;/span&gt; &lt;span class="vg"&gt;#4&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nl"&gt;top:&lt;/span&gt;
  &lt;span class="nv"&gt;%_9.i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;alloca&lt;/span&gt; &lt;span class="kt"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;align&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;
  &lt;span class="nv"&gt;%2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;alloca&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="p"&gt;x&lt;/span&gt; &lt;span class="kt"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="k"&gt;align&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;
  &lt;span class="k"&gt;store&lt;/span&gt; &lt;span class="kt"&gt;ptr&lt;/span&gt; &lt;span class="nv"&gt;%0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;ptr&lt;/span&gt; &lt;span class="nv"&gt;%2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;align&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;
  &lt;span class="nv"&gt;%3&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;getelementptr&lt;/span&gt; &lt;span class="k"&gt;inbounds&lt;/span&gt; &lt;span class="kt"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;ptr&lt;/span&gt; &lt;span class="nv"&gt;%2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;i64&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;store&lt;/span&gt; &lt;span class="kt"&gt;ptr&lt;/span&gt; &lt;span class="nv"&gt;%1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;ptr&lt;/span&gt; &lt;span class="nv"&gt;%3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;align&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;
  &lt;span class="k"&gt;call&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="vg"&gt;@llvm.lifetime.start.p0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;i64&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;ptr&lt;/span&gt; &lt;span class="k"&gt;nonnull&lt;/span&gt; &lt;span class="nv"&gt;%_9.i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;store&lt;/span&gt; &lt;span class="kt"&gt;ptr&lt;/span&gt; &lt;span class="vg"&gt;@_ZN11hello_world4main17h57c4996130ab67deE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;ptr&lt;/span&gt; &lt;span class="nv"&gt;%_9.i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;align&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;
&lt;span class="c1"&gt;; call std::rt::lang_start_internal&lt;/span&gt;
  &lt;span class="nv"&gt;%4&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;call&lt;/span&gt; &lt;span class="kt"&gt;i64&lt;/span&gt; &lt;span class="vg"&gt;@_ZN3std2rt19lang_start_internal17hd4c288149f777b4aE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ptr&lt;/span&gt; &lt;span class="k"&gt;noundef&lt;/span&gt; &lt;span class="k"&gt;nonnull&lt;/span&gt; &lt;span class="k"&gt;align&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="nv"&gt;%_9.i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;ptr&lt;/span&gt; &lt;span class="k"&gt;noalias&lt;/span&gt; &lt;span class="k"&gt;noundef&lt;/span&gt; &lt;span class="k"&gt;nonnull&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="k"&gt;align&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt; &lt;span class="k"&gt;dereferenceable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;24&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="vg"&gt;@vtable.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;i64&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;ptr&lt;/span&gt; &lt;span class="k"&gt;nonnull&lt;/span&gt; &lt;span class="nv"&gt;%2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;i8&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="vg"&gt;#6&lt;/span&gt;
  &lt;span class="k"&gt;call&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="vg"&gt;@llvm.lifetime.end.p0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;i64&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;ptr&lt;/span&gt; &lt;span class="k"&gt;nonnull&lt;/span&gt; &lt;span class="nv"&gt;%_9.i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;ret&lt;/span&gt; &lt;span class="kt"&gt;i64&lt;/span&gt; &lt;span class="nv"&gt;%4&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this function does is pass an array &lt;code&gt;[ImageHandle, *mut SystemTable]&lt;/code&gt; as &lt;code&gt;argv&lt;/code&gt; and &lt;code&gt;2&lt;/code&gt; as &lt;code&gt;argc&lt;/code&gt; to Rust &lt;code&gt;lang_start&lt;/code&gt;. We then initialize the global variables from Rust &lt;code&gt;sys::init()&lt;/code&gt; function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of new implementation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;no_main&lt;/code&gt; attribute works as intended now since &lt;code&gt;std::os::uefi::init()&lt;/code&gt; is part of public API, this allows using Rust std in cases where we want to initialize something before the Heap is available (in some driver) but would still like to use &lt;code&gt;std&lt;/code&gt; after initialization.&lt;/li&gt;
&lt;li&gt;Allows UEFI to work like all other Rust platforms since &lt;code&gt;efi_main&lt;/code&gt; is only generated in places where C &lt;code&gt;main&lt;/code&gt; would typically be generated.&lt;/li&gt;
&lt;li&gt;It seems to improve startup speed.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With this implementation, one of the major blockers for the PR has been resolved. While implementing this, I also modified the Rust target specification to allow specifying the Entry Function name and ABI, which might enable making compiler-generated entry functions easier for other targets. Feel free to comment on the PR and follow it if interested.&lt;/p&gt;

&lt;h2&gt;
  
  
  Helpful Links
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://github.com/rust-lang/rust/pull/100316"&gt;Rust std PR&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://programmershideaway.xyz/post7/"&gt;Using Rust main from a custom entry point&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>GSoC22: Final Blog Post</title>
      <dc:creator>Ayush</dc:creator>
      <pubDate>Mon, 05 Sep 2022 16:52:12 +0000</pubDate>
      <link>https://forem.com/ayush1325/gsoc22-final-blog-post-3j5l</link>
      <guid>https://forem.com/ayush1325/gsoc22-final-blog-post-3j5l</guid>
      <description>&lt;p&gt;Hello everyone. This is probably the final blog post I write before Google Summer of Code 2022 ends (hopefully not the final uefi one). In this post, I will summarize my GSoC22 work to make it more accessible to everyone.&lt;/p&gt;

&lt;h2&gt;
  
  
  PRs
&lt;/h2&gt;

&lt;p&gt;Just a list of all PRs I opened as a part of GSoC22. While other people created some additional PRs to fix problems I found during my work; I do not include them since I wasn’t the one who found the solution for those.&lt;/p&gt;

&lt;h3&gt;
  
  
  r-efi
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://github.com/r-efi/r-efi/pull/33"&gt;Getting r-efi ready for use in Rust std&lt;/a&gt;: 4 commits&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r-efi/r-efi/pull/34"&gt;Add TCP6 Protocol&lt;/a&gt;: 1 commit&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r-efi/r-efi/pull/36"&gt;Add EFI_RNG_PROTOCOL&lt;/a&gt;: 1 commit&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r-efi/r-efi/pull/37"&gt;Add EFI_TIMESTAMP_PROTOCOL&lt;/a&gt;: 1 commit&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r-efi/r-efi/pull/38"&gt;Derive Default for Time&lt;/a&gt;: 1 commit&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r-efi/r-efi/pull/39"&gt;Add TCP4 and IP4 protocols&lt;/a&gt;: 1 commit&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r-efi/r-efi/pull/40"&gt;Fix MODE_CREATE value&lt;/a&gt;: 1 commit&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r-efi/r-efi/pull/42"&gt;Make NotifyFunction Optional&lt;/a&gt;: 1 commit&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r-efi/r-efi/pull/44"&gt;Add ICMP Error Definitions&lt;/a&gt;: 1 commit&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r-efi/r-efi/pull/45"&gt;Add &lt;code&gt;EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL&lt;/code&gt; and &lt;code&gt;EFI_DEVICE_PATH_TO_TEXT_PROTOCOL&lt;/code&gt;&lt;/a&gt;: 2 commits&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r-efi/r-efi/pull/48"&gt;Make RNG protocol members public&lt;/a&gt;: 1 commit&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r-efi/r-efi/pull/49"&gt;Fix timestamp properties&lt;/a&gt;: 1 commit&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r-efi/r-efi/pull/50"&gt;Implement Default for tcp4::ConfigData&lt;/a&gt;: 1 commit&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r-efi/r-efi/pull/51"&gt;Add EFI_SHELL_PROTOCOL&lt;/a&gt;: 1 commit. Still Open.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/r-efi/r-efi/pull/52"&gt;Add UDP Protocols&lt;/a&gt;: 2 commit. Still Open.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  compiler-builtins
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://github.com/rust-lang/compiler-builtins/pull/473"&gt;Enable mem for UEFI&lt;/a&gt;: 1 commit&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/rust-lang/compiler-builtins/pull/480"&gt;Use all of src/math for UEFI&lt;/a&gt;: 1 commit&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  rust
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/rust-lang/rust/pull/100316"&gt;Add Rust std support for x86_64-unknown-uefi&lt;/a&gt;: 76 commits. Still Open.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Blog Posts
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://programmershideaway.xyz/post5/"&gt;Google Summer of Code 2022&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://programmershideaway.xyz/post6/"&gt;Use Restricted std in UEFI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://programmershideaway.xyz/post7/"&gt;Using Rust main from a custom entry point&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://programmershideaway.xyz/post8/"&gt;Writing an Allocator for UEFI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://programmershideaway.xyz/post9/"&gt;Using Rust main from a custom entry point (Part 2)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://programmershideaway.xyz/post10/"&gt;GSoC 2022: Progress Report 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://programmershideaway.xyz/post11/"&gt;Implementing Stdio for UEFI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://programmershideaway.xyz/post12/"&gt;GSoC 2022: Progress Report 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://programmershideaway.xyz/post13/"&gt;UEFI Rust std has a new home&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://programmershideaway.xyz/post14/"&gt;Writing UEFI Protocol in Rust&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I will continue working on getting Rust std &lt;a href="https://github.com/rust-lang/rust/pull/100316"&gt;PR&lt;/a&gt; merged since it is still unmerged. I also have some more UEFI Rust Projects lined up, and I think I will keep working on them for the foreseeable future. Feel free to check out and experiment with using Rust for UEFI (with or without std).&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Writing UEFI Protocol in Rust</title>
      <dc:creator>Ayush</dc:creator>
      <pubDate>Sat, 27 Aug 2022 16:52:12 +0000</pubDate>
      <link>https://forem.com/ayush1325/writing-uefi-protocol-in-rust-2bd4</link>
      <guid>https://forem.com/ayush1325/writing-uefi-protocol-in-rust-2bd4</guid>
      <description>&lt;p&gt;Hello everyone. As a part of Porting Rust std for UEFI, I had to write a hacky implementation of pipes (using UEFI Variables) for piping output from launched programs. However, this implementation had some problems and failed to run tests using the feature &lt;code&gt;panic_abort_tests&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Since I had some time this week, I decided to write a Protocol to fix the pipes. Along the way, I also found many ways to shoot myself on foot. So I decided to write this post documenting all the gotchas I discovered while writing a new protocol in Rust. This post will only contain 1 of the two protocols I decided to create, internally named &lt;code&gt;UEFI_COMMAND_PROTOCOL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This Protocol is not public API and thus should not be relied upon/used outside of Rust std, at least for the foreseeable future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Protocol Definition
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;UEFI_COMMAND_PROTOCOL&lt;/code&gt; has a straightforward use: to share the Handles of pipes (stdout, stderr, stdin) with the image to be started. It might contain more stuff in the future, but for right now, that is all it does. It is installed on all UEFI executables launched using the Rust &lt;code&gt;std::process::Command&lt;/code&gt; API and needs Pipes (In case they don’t need any kinds of Pipes, this Protocol will not be installed).&lt;/p&gt;

&lt;h3&gt;
  
  
  Structure
&lt;/h3&gt;

&lt;p&gt;Here is the Rust Structure to define the Protocol:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[repr(C)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Protocol&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;r_efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;r_efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;r_efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, there is not much to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Guid
&lt;/h3&gt;

&lt;p&gt;Here is the protocol GUID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;PROTOCOL_GUID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;r_efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;r_efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_fields&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mi"&gt;0xc3cc5ede&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;0xb029&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;0x4daa&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;0xa5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;0x5f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0x93&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xf8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x82&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x5b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x29&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0xe7&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Protocol Usage
&lt;/h2&gt;

&lt;p&gt;When constructing and installing a Protocol from Rust, some things must be kept in mind. Here are some of the lessons I learned the hard way:&lt;/p&gt;

&lt;h3&gt;
  
  
  The Protocol should be non-movable
&lt;/h3&gt;

&lt;p&gt;By default, all Rust variables are movable in memory. Once a UEFI Protocol is registered, it has to be valid until it is uninstalled. Installing a Protocol whose interface is on the stack can lead to all sorts of UB. In my particular case, I decided to use Heap allocated Protocol in &lt;code&gt;std::box::Box&lt;/code&gt;. From what I understand, there are ways to move the contents of &lt;code&gt;Box&lt;/code&gt; in memory. However, for my simple needs, it was sufficient since I was not performing any operations on Box once the Protocol was installed.&lt;/p&gt;

&lt;p&gt;In practice, the code looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;protocol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;uefi_command_protocol&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nf"&gt;install_interface&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;protocol&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Do something with Command&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For internal usage, I have wrappers that handle uninstalling the protocol on Drop to play nice with Rust memory management. It might be possible to have a better solution using rust &lt;code&gt;std::pin::Pin&lt;/code&gt; wrapper, but I haven’t used it personally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use EFI_BOOT_SERVICES.InstallProtocolInterface() and EFI_BOOT_SERVICES.UninstallProtocolInterface()
&lt;/h3&gt;

&lt;p&gt;Most modern UEFI drivers use the &lt;code&gt;EFI_BOOT_SERVICES.InstallMultipleProtocolInterfaces()&lt;/code&gt; and &lt;code&gt;EFI_BOOT_SERVICES.UninstallMultipleProtocolInterfaces()&lt;/code&gt; for installing and uninstalling protocols on a handle. However, &lt;code&gt;rustc&lt;/code&gt; currently doesn’t support variable arguments for UEFI. For more information about this, you can look at this &lt;a href="https://github.com/r-efi/r-efi/issues/12"&gt;issue&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Taking care of lifetimes
&lt;/h3&gt;

&lt;p&gt;You need to make sure to strictly define the lifetimes of protocols with their lifetimes as expected by UEFI. I wrote some structures in Rust std to make the internal working easier. However, having a difference in lifetimes can lead to everything ranging from CPU exceptions to an infinite loop.&lt;/p&gt;

&lt;p&gt;Also take care of any data the protocol points to.&lt;/p&gt;

&lt;h3&gt;
  
  
  Taking care of Rust Drop Order
&lt;/h3&gt;

&lt;p&gt;There will be cases when you want the strictly define the drop order of members of Protocol wrapper structures. I found this great &lt;a href="https://stackoverflow.com/questions/41053542/forcing-the-order-in-which-struct-fields-are-dropped"&gt;answer&lt;/a&gt; for this. However, the rule of thumb is that Rust, by default, drops members in the same order they were declared. So make sure to keep this in mind.&lt;/p&gt;

&lt;h3&gt;
  
  
  Avoid storing Rust-specific types in Protocol
&lt;/h3&gt;

&lt;p&gt;Storing dynamic data in UEFI Protocol is generally not a great idea. However, Rust-specific types (Vec, Box, etc) can lead to all kinds of UB since all Rust types are movable by default. I worked around this by storing pointers to a struct that wraps over the Rust-specific type. A simple example is the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;PipeData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;VecDequeue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[repr(C)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Protocol&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;PipeData&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Since there are not many examples of Rust usage in UEFI drivers, there are not many standard practices established yet. With this post, I hope to help anyone trying to use Rust for UEFI driver development. Finally, with the new &lt;code&gt;UEFI_COMMAND_PROTOCOL&lt;/code&gt; and &lt;code&gt;UEFI_PIPE_PROTOCOL&lt;/code&gt;, Rust std port can now use complete &lt;code&gt;libtest&lt;/code&gt; (even &lt;code&gt;should_panic&lt;/code&gt;, which was previously broken). This is useful since even if you go the &lt;code&gt;no_std&lt;/code&gt; route, you can still use std to test your &lt;code&gt;no_std&lt;/code&gt; code. Finally, feel free to check out &lt;a href="https://github.com/rust-lang/rust/pull/100316"&gt;Rust std for UEFI&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>UEFI Rust std has a new home</title>
      <dc:creator>Ayush</dc:creator>
      <pubDate>Fri, 05 Aug 2022 15:14:12 +0000</pubDate>
      <link>https://forem.com/ayush1325/uefi-rust-std-has-a-new-home-4h08</link>
      <guid>https://forem.com/ayush1325/uefi-rust-std-has-a-new-home-4h08</guid>
      <description>&lt;p&gt;Hello everyone. All my work on UEFI Rust std has been moved to &lt;a href="https://github.com/tianocore/rust"&gt;tianocore/rust&lt;/a&gt;. This should help with allowing more contribution from both Tianocore and Rust’s sides. This post is just a sort of introduction to the new repository and how to get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation
&lt;/h2&gt;

&lt;p&gt;The documentation of the std implementation for UEFI can be found at &lt;code&gt;src/doc/rustc/src/platform-support/unknown-uefi.md&lt;/code&gt;. This can be built by using &lt;code&gt;x.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./x.py doc src/doc/rustc/ &lt;span class="nt"&gt;--open&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It outlines the requirements and the limitations of the current std for UEFI. It also contains a few examples to get users started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development Workflow
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/tianocore/rust"&gt;tianocore/rust&lt;/a&gt; repository accepts PRs. I will also accept patches in the edk2 mailing list (my email: &lt;a href="//ayushdevel1325@gmail.com"&gt;ayushdevel1325@gmail.com&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Running Tests locally
&lt;/h2&gt;

&lt;p&gt;Running Tests for UEFI is done using &lt;code&gt;remote-test-server&lt;/code&gt; and &lt;code&gt;remote-test-client&lt;/code&gt; as outlined in my &lt;a href="https://programmershideaway.xyz/post12/"&gt;previous post&lt;/a&gt;. The only thing I would like to change from that guide is the command to run tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;RUST_TEST_THREADS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;TEST_DEVICE_ADDR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"localhost:12345"&lt;/span&gt; ./x.py &lt;span class="nb"&gt;test &lt;/span&gt;src/test/ui/&lt;span class="o"&gt;{&lt;/span&gt;FILE or Directory&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;--target&lt;/span&gt; x86_64-unknown-uefi &lt;span class="nt"&gt;--stage&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running tests in single-threaded, even on the host side, fixes a lot of tests that fail due to timeout.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This post was just to spread the word about this work so more people can experiment and provide their feedback about it.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>uefi</category>
    </item>
    <item>
      <title>Writing an Allocator for UEFI</title>
      <dc:creator>Ayush</dc:creator>
      <pubDate>Thu, 23 Jun 2022 11:15:12 +0000</pubDate>
      <link>https://forem.com/ayush1325/writing-an-allocator-for-uefi-1lij</link>
      <guid>https://forem.com/ayush1325/writing-an-allocator-for-uefi-1lij</guid>
      <description>&lt;p&gt;Hello everyone, we will discuss how to write the Allocator for UEFI in this post. More specifically, the Allocator is for the DEX phase in UEFI. We will be using &lt;a href="https://github.com/Ayush1325/uefi-spec-rs"&gt;uefi-spec-rs&lt;/a&gt;, which is my wrapper around &lt;a href="https://github.com/Ayush1325/r-efi"&gt;r-efi&lt;/a&gt; for use in the std.&lt;/p&gt;

&lt;h2&gt;
  
  
  UEFI Memory Memory Management Services
&lt;/h2&gt;

&lt;p&gt;First, let us look at the Memory Management Services we will be using in UEFI.&lt;/p&gt;

&lt;h3&gt;
  
  
  AllocatePool
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Prototype
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt;
&lt;span class="nf"&gt;EFI_STATUS&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;EFI_ALLOCATE_POOL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;EFI_MEMORY_TYPE&lt;/span&gt; &lt;span class="n"&gt;PoolType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;UINTN&lt;/span&gt; &lt;span class="n"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;OUT&lt;/span&gt; &lt;span class="n"&gt;VOID&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Description
&lt;/h4&gt;

&lt;p&gt;This function allocates a memory region of &lt;code&gt;Size&lt;/code&gt; bytes from the memory of type &lt;code&gt;PoolType&lt;/code&gt; and returns the address of the allocated memory in the location referenced by Buffer. This function allocates pages from EfiConventionalMemory as needed to grow the requested pool type.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; All allocations are eight-byte aligned.&lt;/p&gt;

&lt;h4&gt;
  
  
  Status Codes Returned
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;EFI_SUCCESS&lt;/strong&gt; : The requested number of bytes was allocated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EFI_OUT_OF_RESOURCES&lt;/strong&gt; : The pool requested could not be allocated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EFI_INVALID_PARAMETER&lt;/strong&gt; : PoolType is in the range EfiMaxMemoryType..0x6FFFFFFF.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EFI_INVALID_PARAMETER&lt;/strong&gt; : PoolType is EfiPersistentMemory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EFI_INVALID_PARAMETER&lt;/strong&gt; : Buffer is NULL.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  FreePool
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Prototype
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt;
&lt;span class="nf"&gt;EFI_STATUS&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EFIAPI&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;EFI_FREE_POOL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;IN&lt;/span&gt; &lt;span class="n"&gt;VOID&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Description
&lt;/h4&gt;

&lt;p&gt;This function returns the memory specified by Buffer to the system. In return, the memory’s type is EfiConventionalMemory. The freed Buffer must have been allocated by &lt;code&gt;AllocatePool()&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Status Code Returned
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;EFI_SUCCESS :&lt;/strong&gt; The memory was returned to the system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EFI_INVALID_PARAMETER :&lt;/strong&gt; Buffer was invalid.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Writing a basic allocator
&lt;/h2&gt;

&lt;p&gt;First, we will write an allocator which works for alignment &amp;lt;= 8 bytes. To make a global allocator, we need to implement the’ GlobalAlloc’ trait. In the case of std, we would implement this trait on the &lt;code&gt;System&lt;/code&gt; allocator. However, since I would like to test things out, I will be implementing the allocator as an example in the uefi-spec-rs crate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;GLOBAL_SYSTEM_TABLE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GlobalData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;GlobalData&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nd"&gt;#[global_allocator]&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;GLOBAL_ALLOCATOR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Allocator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Allocator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Allocator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;GlobalAlloc&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Allocator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nd"&gt;todo!&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;dealloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nd"&gt;todo!&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we create an empty struct (&lt;code&gt;Allocator&lt;/code&gt;) as a placeholder for &lt;code&gt;System&lt;/code&gt; and implement GlobalAlloc on it. The &lt;code&gt;GLOBAL_SYSTEM_TABLE&lt;/code&gt; stores an &lt;code&gt;AtomicPtr&lt;/code&gt; to the &lt;code&gt;SystemTable&lt;/code&gt;. I will also be adding a way to access the SystemTable in &lt;code&gt;std::os::uefi&lt;/code&gt;. However, I will not be exposing the static mutable variable there.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement alloc
&lt;/h3&gt;

&lt;p&gt;Firstly, we need to be aware of a few things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;layout.size()&lt;/code&gt; supplied in &lt;code&gt;GlobalAlloc&lt;/code&gt; can be 0. It is up to the implementation to check for that case. &lt;/li&gt;
&lt;li&gt;According to docs, we should return the &lt;code&gt;NULL&lt;/code&gt; pointer in case of errors. &lt;/li&gt;
&lt;li&gt;The &lt;code&gt;alloc&lt;/code&gt; function should not unwind.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Keeping all that in mind, here is the basic implementation of alloc:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;GLOBAL_SYSTEM_TABLE&lt;/span&gt;&lt;span class="nf"&gt;.get_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;null_mut&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;


    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ffi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;c_void&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;null_mut&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="nf"&gt;.align&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="nf"&gt;.size&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;null_mut&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;memory_allocation_services&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;allocate_pool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LOADER_DATA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.is_err&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="nf"&gt;.is_null&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;null_mut&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="nf"&gt;.cast&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is pretty simple. We fail for alignment &amp;gt; 0. we also fail if the &lt;code&gt;ptr&lt;/code&gt; is null after allocation or if the error status is returned.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement dealloc
&lt;/h3&gt;

&lt;p&gt;We need to check that size is non-zero. The only error that &lt;code&gt;FreePool()&lt;/code&gt; returns is in the case of invalid &lt;code&gt;ptr&lt;/code&gt;, so ideally, this should not happen in &lt;code&gt;System&lt;/code&gt; allocator. However, I am adding the assert for now to improve debugging. That assert will probably be removed in production.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;dealloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;GLOBAL_SYSTEM_TABLE&lt;/span&gt;&lt;span class="nf"&gt;.get_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;null_mut&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="nf"&gt;.size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;memory_allocation_services&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;free_pool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="nf"&gt;.cast&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.is_ok&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Testing the new allocator
&lt;/h3&gt;

&lt;p&gt;We just add a &lt;code&gt;efi_main&lt;/code&gt; function that initializes the &lt;code&gt;GLOBAL_SYSTEM_TABLE&lt;/code&gt; and we should be good to use the &lt;code&gt;alloc&lt;/code&gt; types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;efi_run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;GLOBAL_SYSTEM_TABLE&lt;/span&gt;&lt;span class="nf"&gt;.get_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ABORTED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Create string and convert to UTF-16. We need a terminating NUL, since UEFI uses C-String&lt;/span&gt;
    &lt;span class="c1"&gt;// style wide-strings.&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World!&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.encode_utf16&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Print the string on console-out.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;simple_text_output&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;output_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="nf"&gt;.as_mut_slice&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.is_err&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ABORTED&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SUCCESS&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[export_name&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"efi_main"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;GLOBAL_SYSTEM_TABLE&lt;/span&gt;&lt;span class="nf"&gt;.init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.is_err&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ABORTED&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;efi_run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example works as expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting allocations &amp;gt; 8-byte align to work
&lt;/h2&gt;

&lt;p&gt;While the previous allocator works for many cases, there is a clever way to work around the 8-byte alignment limit. This is used in the &lt;a href="https://github.com/rust-lang/rust/blob/10f4ce324baf7cfb7ce2b2096662b82b79204944/library/std/src/sys/windows/alloc.rs"&gt;windows allocator&lt;/a&gt; as well as &lt;a href="https://github.com/Ayush1325/r-efi-alloc/blob/d47b50c75b6f16a44364f21f40db7a0f3d4dd296/src/alloc.rs"&gt;r-efi-alloc&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement alloc
&lt;/h3&gt;

&lt;p&gt;The new &lt;code&gt;alloc&lt;/code&gt; function looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;GLOBAL_SYSTEM_TABLE&lt;/span&gt;&lt;span class="nf"&gt;.get_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;null_mut&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="nf"&gt;.align&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="nf"&gt;.size&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;null_mut&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ffi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;c_void&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;null_mut&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;aligned_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;align_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="nn"&gt;memory_allocation_services&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;allocate_pool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;LOADER_DATA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;aligned_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.is_err&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="nf"&gt;.is_null&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;null_mut&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;align_ptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="nf"&gt;.cast&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The magic happens in the &lt;code&gt;align_size&lt;/code&gt; and the &lt;code&gt;align_ptr&lt;/code&gt; functions.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;align_size&lt;/code&gt; function, we just allocate extra padding in case &lt;code&gt;align&lt;/code&gt; is greater than 8. This padding will later be used in the &lt;code&gt;align_ptr&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;align_size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;POOL_ALIGNMENT&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Allocate extra padding in order to be able to satisfy the alignment.&lt;/span&gt;
        &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;size&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;align_ptr&lt;/code&gt; function we store the original address as &lt;code&gt;Header&lt;/code&gt; in front of the aligned_ptr.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[repr(C)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;align_ptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;POOL_ALIGNMENT&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="nf"&gt;.addr&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;align&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="c1"&gt;// SAFETY: `MIN_ALIGN` &amp;lt;= `offset` &amp;lt;= `layout.align()` and the size of the allocated&lt;/span&gt;
        &lt;span class="c1"&gt;// block is `layout.align() + layout.size()`. `aligned` will thus be a correctly aligned&lt;/span&gt;
        &lt;span class="c1"&gt;// pointer inside the allocated block with at least `layout.size()` bytes after it and at&lt;/span&gt;
        &lt;span class="c1"&gt;// least `MIN_ALIGN` bytes of padding before it.&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;aligned&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;// SAFETY: Because the size and alignment of a header is &amp;lt;= `MIN_ALIGN` and `aligned`&lt;/span&gt;
        &lt;span class="c1"&gt;// is aligned to at least `MIN_ALIGN` and has at least `MIN_ALIGN` bytes of padding before&lt;/span&gt;
        &lt;span class="c1"&gt;// it, it is safe to write a header directly before it.&lt;/span&gt;
        &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;aligned&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.offset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;aligned&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ptr&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; the &lt;code&gt;align_ptr&lt;/code&gt; function assumes that the allocation size has been increased beforehand by &lt;code&gt;align_size&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement dealloc
&lt;/h3&gt;

&lt;p&gt;The new &lt;code&gt;dealloc&lt;/code&gt; looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;dealloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;GLOBAL_SYSTEM_TABLE&lt;/span&gt;&lt;span class="nf"&gt;.get_mut&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="nf"&gt;.size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;unalign_ptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="nf"&gt;.align&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;memory_allocation_services&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;free_pool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="nf"&gt;.cast&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.is_ok&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;unalign_ptr&lt;/code&gt; function basically undoes what the &lt;code&gt;align_ptr&lt;/code&gt; function did and gives back the original pointer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[inline]&lt;/span&gt;
&lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;unalign_ptr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;align&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;POOL_ALIGNMENT&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// SAFETY: Because of the contract of `System`, `ptr` is guaranteed to be non-null&lt;/span&gt;
        &lt;span class="c1"&gt;// and have a header readable directly before it.&lt;/span&gt;
        &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.offset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ptr&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same example as before should work even now without any change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With this, we now have a global allocator. I will soon be integrating it into the Rust std. In the next post, we will discuss implementing &lt;code&gt;stdin&lt;/code&gt; for UEFI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Helpful Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Ayush1325/uefi-spec-rs"&gt;uefi-spec-rs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>uefi</category>
    </item>
    <item>
      <title>Using Rust main from a custom entry point</title>
      <dc:creator>Ayush</dc:creator>
      <pubDate>Mon, 20 Jun 2022 18:42:12 +0000</pubDate>
      <link>https://forem.com/ayush1325/using-rust-main-from-a-custom-entry-point-4ba0</link>
      <guid>https://forem.com/ayush1325/using-rust-main-from-a-custom-entry-point-4ba0</guid>
      <description>&lt;p&gt;Hello everyone. In this post, we will deep dive into the crux of the &lt;code&gt;main()&lt;/code&gt; function and look behind the scenes. By the end, we will have some understanding of Rust runtime. Primarily, I will describe my current implementation of &lt;code&gt;efi_main&lt;/code&gt; to hook into Rust runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  C Runtime
&lt;/h2&gt;

&lt;p&gt;First, we need to get some things out of the way. In “C”, the first function is not &lt;code&gt;int main(int argc, char *argv[])&lt;/code&gt;. While this might surprise some of you, C does have a runtime, and it is called &lt;a href="https://en.wikipedia.org/wiki/Crt0"&gt;Crt0&lt;/a&gt;. It is mostly written in assembly and linked to almost every C Program. This example is for Linux x86-64 with AT&amp;amp;T syntax, without an actual C runtime.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.text

.globl _start

_start: # _start is the entry point known to the linker
    xor %ebp, %ebp # effectively RBP := 0, mark the end of stack frames
    mov (%rsp), %edi # get argc from the stack (implicitly zero-extended to 64-bit)
    lea 8(%rsp), %rsi # take the address of argv from the stack
    lea 16(%rsp,%rdi,8), %rdx # take the address of envp from the stack
    xor %eax, %eax # per ABI and compatibility with icc
    call main # %edi, %rsi, %rdx are the three args (of which first two are C standard) to main

    mov %eax, %edi # transfer the return of main to the first argument of _exit
    xor %eax, %eax # per ABI and compatibility with icc
    call _exit # terminate the program
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;_start&lt;/code&gt; function then calls the all too familiar &lt;code&gt;main&lt;/code&gt; function in C. With this out of the way; we are now going to talk about Rust Runtime and all the things behind the scenes that make a simple “Hello World” program work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rust Runtime
&lt;/h2&gt;

&lt;p&gt;Everyone can already guess that the Rust runtime is much more complicated than the C Runtime. Also, almost every OS is very well integrated with C, while Rust must do most of the heavy lifting of integrating with the OS itself. If you want a detailed explanation, you should look at &lt;a href="https://blog.mgattozzi.dev/rusts-runtime/"&gt;Michael Gattozzi’s blog post&lt;/a&gt; which goes into great detail about it.&lt;/p&gt;

&lt;p&gt;I will give you a quick tldr: “C” &lt;code&gt;main()&lt;/code&gt; -&amp;gt; “Rust” &lt;code&gt;lang_start&lt;/code&gt; -&amp;gt; “Rust” &lt;code&gt;lang_start_internal&lt;/code&gt; -&amp;gt; “Rust” &lt;code&gt;init()&lt;/code&gt; -&amp;gt; “Rust” &lt;code&gt;sys::init()&lt;/code&gt; -&amp;gt; “Rust” &lt;code&gt;main()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Is everyone still with me? Good. Now I will briefly explain all the functions I just mentioned.&lt;/p&gt;

&lt;h3&gt;
  
  
  C main()
&lt;/h3&gt;

&lt;p&gt;This is generated by rustc. Taking a look at code at &lt;code&gt;compiler/rustc_codegen_ssa/src/base.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;create_entry_fn&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;'tcx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;BuilderMethods&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;'tcx&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="nn"&gt;Bx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CodegenCx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;rust_main&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;Bx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;rust_main_def_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DefId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;use_start_lang_item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;Bx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Function&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// The entry function is either `int main(void)` or `int main(int argc, char **argv)`,&lt;/span&gt;
        &lt;span class="c1"&gt;// depending on whether the target needs `argc` and `argv` to be passed in.&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;llfty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.sess&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="py"&gt;.target.main_needs_argc_argv&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_int&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_ptr_to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_i8p&lt;/span&gt;&lt;span class="p"&gt;())],&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_int&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="n"&gt;cx&lt;/span&gt;&lt;span class="nf"&gt;.type_int&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="n"&gt;As&lt;/span&gt; &lt;span class="n"&gt;we&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;see&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;two&lt;/span&gt; &lt;span class="n"&gt;signatures&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;used&lt;/span&gt;&lt;span class="py"&gt;. Incidentally&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;see&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;neither&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;these&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="n"&gt;functions&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;UEFI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;but&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;too&lt;/span&gt; &lt;span class="n"&gt;important&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="py"&gt;.

This&lt;/span&gt; &lt;span class="n"&gt;generated&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="n"&gt;basically&lt;/span&gt; &lt;span class="n"&gt;calls&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;following&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="py"&gt;.e&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;lang_start&lt;/span&gt;&lt;span class="err"&gt;`.&lt;/span&gt;

&lt;span class="err"&gt;###&lt;/span&gt; &lt;span class="n"&gt;Rust&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nf"&gt;_start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;pretty&lt;/span&gt; &lt;span class="n"&gt;simple&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;just&lt;/span&gt; &lt;span class="n"&gt;calls&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="n"&gt;lang_start_internal&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="py"&gt;. Incidently&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;also&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;defined&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;us&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;we&lt;/span&gt; &lt;span class="n"&gt;want&lt;/span&gt;&lt;span class="py"&gt;. The&lt;/span&gt; &lt;span class="n"&gt;issue&lt;/span&gt; &lt;span class="n"&gt;tracking&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;here&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//github.com/rust-lang/rust/issues/29633). This function signature is as follows:&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
rust&lt;br&gt;
fn lang_start(&lt;br&gt;
    main: fn() -&amp;gt; T,&lt;br&gt;
    argc: isize,&lt;br&gt;
    argv: *const *const u8,&lt;br&gt;
) -&amp;gt; isize;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
### Rust lang\_start\_internal()

It basically calls the `init` and then the `main` function. It also prevents unwinding in the `init` and `main` functions, which is a requirement. The function signature is as follows:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
rust&lt;br&gt;
fn lang_start_internal(&lt;br&gt;
    main: &amp;amp;(dyn Fn() -&amp;gt; i32 + Sync + crate::panic::RefUnwindSafe),&lt;br&gt;
    argc: isize,&lt;br&gt;
    argv: *const *const u8,&lt;br&gt;
) -&amp;gt; Result {&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
### Rust init()

This function sets up stack\_guard for the current thread. It also calls the `sys::init()` function. The signature for it is the following:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
rust&lt;br&gt;
unsafe fn init(argc: isize, argv: *const *const u8);&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
This is also the function where heap memory starts coming to play.

### Rust sys::init()

This function sets up platform-specific stuff. This is just an empty function on some platforms, while it does a lot of stuff on others. It is generally defined under `std/sys/&amp;lt;platform&amp;gt;/mod.rs` The function signature is as follows:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
rust&lt;br&gt;
pub fn init(argc: isize, argv: *const *const u8) {&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
### Rust main()

This is the function where most normal programs start execution. By this point, it is assumed that all the `std` stuff that needs initialization must be done and available for the user.

## But wait, who calls the C main()?

This is precisely the question I had after reading about all these functions. The answer, though, is a bit less clear. It depends on the platform. The OS `crt0` on most platforms calls the C `main`. On others, well, people just seem to use a custom entry point like `efi_main` and not use `main()`. Since I wanted to use `main` but had a custom entry point with a custom signature, I had to do a hacky implementation to make things work.



## Using efi\_main() with Rust runtime

Since we have established that Rust generates a C `main` function for every Rust program, all we need to do is call `main` and be done with it. However, the problem is how to pass SystemTable and SystemHandle to Rust. Without those pointers, we cannot do much in UEFI. Thus they need to be stored globally somewhere.

After some thought, I have concluded that I will do it in the `sys::init()` function rather than the `efi_main`. The reasons for this are as follows:

1. The `efi_main` currently calls to “C” `main`, so we are jumping language boundaries here.
2. At some point, I would like to replace the `efi_main` with an autogenerated function or even a function written in assembly. For now, I am writing it in Rust, but that might not be the case in the future. Thus it should be as less complicated as possible.
3. `sys::init` seems kinda the natural place for it.

Now, the question is how to get it to reach `sys::init()`. The answer is pretty simple. We can use pointers.

My current implementation looks like the following:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
rust&lt;/p&gt;
&lt;h1&gt;
  
  
  [no_mangle]
&lt;/h1&gt;

&lt;p&gt;pub unsafe extern "efiapi" fn efi_main(&lt;br&gt;
    handle: efi::Handle,&lt;br&gt;
    st: *mut efi::SystemTable,&lt;br&gt;
) -&amp;gt; efi::Status {&lt;br&gt;
    const argc: isize = 2;&lt;br&gt;
    let handle_ptr: *const u8 = handle.cast();&lt;br&gt;
    let st_ptr: *const u8 = st.cast();&lt;br&gt;
    let argv: *const *const u8 = [handle_ptr, st_ptr, core::ptr::null()].as_ptr();&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;match main(argc, argv) {
    0 =&amp;gt; {
        print_pass(st);
        efi::Status::SUCCESS
    }
    _ =&amp;gt; {
        print_fail(st);
        efi::Status::ABORTED
    } // Or some other status code
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
I just cast both SystemTable and SystemHandle pointers as `*const u8` in the `efi_main`. Then in the `sys::init()`, I cast them back to their original selves. The null at the end is something someone in zulipchat suggested.

And well, it kind of works. This simple hack allows us to get the SystemTable and SystemHandle all the way to `sys::init()`. They can be accessed in the following way:

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
rust&lt;br&gt;
pub unsafe fn init(argc: isize, argv: *const *const u8) {&lt;br&gt;
    let args: &amp;amp;[*const u8] = unsafe { crate::slice::from_raw_parts(argv, argc as usize) };&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let handle: r_efi::efi::Handle = args[0] as r_efi::efi::Handle;
let st: *mut r_efi::efi::SystemTable = args[1] as *mut r_efi::efi::SystemTable;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;}&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
Now comes the catch, if we look at the function calling this, the line where the new Thread is created needs an allocator, or else it panics.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
rust&lt;br&gt;
// One-time runtime initialization.&lt;br&gt;
// Runs before &lt;code&gt;main&lt;/code&gt;.&lt;br&gt;
// SAFETY: must be called only once during runtime initialization.&lt;br&gt;
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.&lt;/p&gt;

&lt;h1&gt;
  
  
  [cfg_attr(test, allow(dead_code))]
&lt;/h1&gt;

&lt;p&gt;unsafe fn init(argc: isize, argv: *const *const u8) {&lt;br&gt;
    unsafe {&lt;br&gt;
        sys::init(argc, argv);&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    let main_guard = sys::thread::guard::init();
    // Next, set up the current Thread with the guard information we just
    // created. Note that this isn't necessary in general for new threads,
    // but we just do this to name the main thread and to give it correct
    // info about the stack bounds.
    let thread = Thread::new(Some(rtunwrap!(Ok, CString::new("main"))));
    thread_info::set(main_guard, thread);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


We can add a `return` before the thread creation and get to `main` perfectly. However, that is a bit of cheating, so this is where I will leave it for now.



## Conclusion

Initially, I set out to print “Hello World” from `main` in this post. However, after getting burned multiple times, I have finally decided to save it for later. The following post will look at creating and initializing the System Allocator. Spoiler, the `thread_info::set` will start panicking after that, so we will not be able to print “Hello World” even in the next post. Still, we are one step closer to a usable std for UEFI.



## Helpful Links

1. [Rust’s Runtime Post by Michael Gattozzi](https://blog.mgattozzi.dev/rusts-runtime/)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>rust</category>
      <category>uefi</category>
    </item>
    <item>
      <title>Use Restricted std in UEFI</title>
      <dc:creator>Ayush</dc:creator>
      <pubDate>Thu, 16 Jun 2022 00:00:00 +0000</pubDate>
      <link>https://forem.com/ayush1325/use-restricted-std-in-uefi-2epg</link>
      <guid>https://forem.com/ayush1325/use-restricted-std-in-uefi-2epg</guid>
      <description>&lt;p&gt;Hello Everyone; in my last &lt;a href="https://programmershideaway.xyz/post5/"&gt;post&lt;/a&gt;, I set up the development environment for working on adding Rust support for UEFI. In this post, I will get a restricted version of std (basically a glorified core + alloc) to work for the x86_64 UEFI target. We will be starting with the &lt;code&gt;no_std&lt;/code&gt; hello_world program from the last post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add env module for UEFI in std
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Add uefi Module
&lt;/h3&gt;

&lt;p&gt;First, I will add &lt;code&gt;uefi&lt;/code&gt; module under &lt;code&gt;library/std/src/sys&lt;/code&gt;. To do this, we will create a new file &lt;code&gt;library/std/src/sys/uefi/mod.rs&lt;/code&gt;. We will point everything other than the &lt;code&gt;env&lt;/code&gt; module to the unsupported module. The contents of &lt;code&gt;library/std/src/sys/uefi/mod.rs&lt;/code&gt; are given below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="cd"&gt;//! Platform-specific extensions to `std` for UEFI platforms.&lt;/span&gt;
&lt;span class="cd"&gt;//!&lt;/span&gt;
&lt;span class="cd"&gt;//! Provides access to platform-level information on UEFI platforms, and&lt;/span&gt;
&lt;span class="cd"&gt;//! exposes Unix-specific functions that would otherwise be inappropriate as&lt;/span&gt;
&lt;span class="cd"&gt;//! part of the core `std` library.&lt;/span&gt;
&lt;span class="cd"&gt;//!&lt;/span&gt;
&lt;span class="cd"&gt;//! It exposes more ways to deal with platform-specific strings ([`OsStr`],&lt;/span&gt;
&lt;span class="cd"&gt;//! [`OsString`]), allows to set permissions more granularly, extract low-level&lt;/span&gt;
&lt;span class="cd"&gt;//! file descriptors from files and sockets, and has platform-specific helpers&lt;/span&gt;
&lt;span class="cd"&gt;//! for spawning processes.&lt;/span&gt;
&lt;span class="cd"&gt;//!&lt;/span&gt;
&lt;span class="cd"&gt;//! [`OsStr`]: crate::ffi::OsStr&lt;/span&gt;
&lt;span class="cd"&gt;//! [`OsString`]: crate::ffi::OsString&lt;/span&gt;

&lt;span class="nd"&gt;#![deny(unsafe_op_in_unsafe_fn)]&lt;/span&gt;

&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unsupported/alloc.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unsupported/args.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unix/cmath.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;cmath&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unsupported/fs.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unsupported/io.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unsupported/locks/mod.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;locks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unsupported/net.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unsupported/os.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../windows/os_str.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;os_str&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unix/path.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unsupported/pipe.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unsupported/process.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unsupported/stdio.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;stdio&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unsupported/thread.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unsupported/thread_local_key.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;thread_local_key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unsupported/time.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[path&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"../unsupported/common.rs"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="nd"&gt;#[deny(unsafe_op_in_unsafe_fn)]&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;common&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, &lt;code&gt;cmath&lt;/code&gt;, &lt;code&gt;os_str&lt;/code&gt;, and &lt;code&gt;path&lt;/code&gt; point to the &lt;code&gt;unix&lt;/code&gt; or &lt;code&gt;windows&lt;/code&gt; module instead of &lt;code&gt;unsupported&lt;/code&gt;. This is because &lt;code&gt;unsupported&lt;/code&gt; does not provide any definition for those. The &lt;code&gt;cmath&lt;/code&gt; unix module API can be provided by &lt;code&gt;compiler-builtins&lt;/code&gt;, so that should work. However, &lt;code&gt;os_str&lt;/code&gt; and &lt;code&gt;path&lt;/code&gt; are simply placeholders for now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implement env module
&lt;/h3&gt;

&lt;p&gt;The env module is very basic and we just need to define a few constants for it. Here are the contents of &lt;code&gt;library/std/src/sys/uefi/env.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;FAMILY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;OS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;DLL_PREFIX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;DLL_SUFFIX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;DLL_EXTENSION&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;EXE_SUFFIX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;".efi"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;EXE_EXTENSION&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"efi"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Export UEFI module contents
&lt;/h3&gt;

&lt;p&gt;This can be done by adding the following lines to &lt;code&gt;library/std/sys/mod.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;     &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nd"&gt;#[cfg(target_family&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"wasm"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;wasm&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
         &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;wasm&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nd"&gt;#[cfg(target_os&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"uefi"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;uefi&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;uefi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nd"&gt;#[cfg(all(target_vendor&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"fortanix"&lt;/span&gt;&lt;span class="nd"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;target_env&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"sgx"&lt;/span&gt;&lt;span class="nd"&gt;))]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;sgx&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
         &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;sgx&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we now have the &lt;code&gt;env&lt;/code&gt; module implemented. These constants are exposed under &lt;code&gt;std::env::consts&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build the new toolchain
&lt;/h3&gt;

&lt;p&gt;We will now need to build the toolchain again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./x.py build &lt;span class="nt"&gt;--stage&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;stage1 should now be pointing to this new toolchain.&lt;/p&gt;

&lt;p&gt;Now, we will try to print these constants to UEFI in a very primitive manner (since io, strings, etc have not been implemented yet).&lt;/p&gt;

&lt;h2&gt;
  
  
  Compile hello_world with std
&lt;/h2&gt;

&lt;p&gt;Firstly, we will remove the &lt;code&gt;no_std&lt;/code&gt; attribute and &lt;code&gt;panic_handler&lt;/code&gt; from &lt;code&gt;src/main.rs&lt;/code&gt;. Then we will update &lt;code&gt;.cargo/config.toml&lt;/code&gt; with the following contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[unstable]&lt;/span&gt;
&lt;span class="py"&gt;build-std&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"std"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"compiler_builtins"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;build-std-features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"compiler-builtins-mem"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On trying to compile the project now, we get the following error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;error[E0463]: can&lt;span class="s1"&gt;'t find crate for `panic_abort`

error[E0658]: use of unstable library feature '&lt;/span&gt;restricted_std&lt;span class="s1"&gt;'
  |
  = help: add `#![feature(restricted_std)]` to the crate attributes to enable

Some errors have detailed explanations: E0463, E0658.
For more information about an error, try `rustc --explain E0463`.
error: could not compile `hello_world` due to 2 previous errors
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first error is a &lt;a href="https://github.com/rust-lang/rust/issues/83805#issuecomment-812874115"&gt;bug in build-std&lt;/a&gt;. It doesn’t know how to handle panic_abort vs panic_unwind, so it doesn’t use either crate, resulting in the above error. It can be fixed by adding &lt;code&gt;panic_abort&lt;/code&gt; to &lt;code&gt;.cargo/config.toml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The second error can be fixed by adding the &lt;code&gt;restricted_std&lt;/code&gt; feature to the &lt;code&gt;src/main.rs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Trying to build now and ………. It fails. We get the following error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;error: linking with &lt;span class="sb"&gt;`&lt;/span&gt;rust-lld&lt;span class="sb"&gt;`&lt;/span&gt; failed: &lt;span class="nb"&gt;exit &lt;/span&gt;status: 1
  |
  &lt;span class="o"&gt;=&lt;/span&gt; note: &lt;span class="s2"&gt;"rust-lld"&lt;/span&gt; &lt;span class="s2"&gt;"-flavor"&lt;/span&gt; &lt;span class="s2"&gt;"link"&lt;/span&gt; &lt;span class="s2"&gt;"/NOLOGO"&lt;/span&gt; &lt;span class="s2"&gt;"/entry:efi_main"&lt;/span&gt; &lt;span class="s2"&gt;"/subsystem:efi_application"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/hello_world-bf96c91d419b97ff.3aumljakx58twtt1.rcgu.o"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/hello_world-bf96c91d419b97ff.11wx9iybsb4s2x54.rcgu.o"&lt;/span&gt; &lt;span class="s2"&gt;"/LIBPATH:/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps"&lt;/span&gt; &lt;span class="s2"&gt;"/LIBPATH:/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/debug/deps"&lt;/span&gt; &lt;span class="s2"&gt;"/LIBPATH:/var/home/ayush/Documents/Programming/Rust/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/target/lib"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/libr_efi-44f0e2c98ca397ed.rlib"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/libstd-0f82fcd1446bb823.rlib"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/libpanic_abort-6267bb336da2fa77.rlib"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/librustc_demangle-12ba4dfb1ce0974e.rlib"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/libstd_detect-af3466d26b0b584c.rlib"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/libhashbrown-282ed18a03cc159e.rlib"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/librustc_std_workspace_alloc-d47af0fe9b191470.rlib"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/libunwind-8ad628841136827a.rlib"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/libcfg_if-f793ff480fd551b6.rlib"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/liblibc-249d18e9ef84acfd.rlib"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/liballoc-4b1b3794d0343e8a.rlib"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/librustc_std_workspace_core-3a7d1ce70363f171.rlib"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/libcore-73e7a0474be04fb7.rlib"&lt;/span&gt; &lt;span class="s2"&gt;"/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/libcompiler_builtins-4f95060227077e02.rlib"&lt;/span&gt; &lt;span class="s2"&gt;"/NXCOMPAT"&lt;/span&gt; &lt;span class="s2"&gt;"/LIBPATH:/var/home/ayush/Documents/Programming/Rust/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/target/lib"&lt;/span&gt; &lt;span class="s2"&gt;"/OUT:/var/home/ayush/Documents/Programming/Rust/uefi/hello_world/target/target/debug/deps/hello_world-bf96c91d419b97ff.efi"&lt;/span&gt; &lt;span class="s2"&gt;"/OPT:REF,NOICF"&lt;/span&gt; &lt;span class="s2"&gt;"/DEBUG"&lt;/span&gt; &lt;span class="s2"&gt;"/NODEFAULTLIB"&lt;/span&gt;
  &lt;span class="o"&gt;=&lt;/span&gt; note: rust-lld: error: undefined symbol: __CxxFrameHandler3
          &lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; referenced by libstd-0f82fcd1446bb823.rlib&lt;span class="o"&gt;(&lt;/span&gt;std-0f82fcd1446bb823.std.ea9c30f6-cgu.2.rcgu.o&lt;span class="o"&gt;)&lt;/span&gt;:&lt;span class="o"&gt;(&lt;/span&gt;.xdata&lt;span class="o"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; referenced by libstd-0f82fcd1446bb823.rlib&lt;span class="o"&gt;(&lt;/span&gt;std-0f82fcd1446bb823.std.ea9c30f6-cgu.2.rcgu.o&lt;span class="o"&gt;)&lt;/span&gt;:&lt;span class="o"&gt;(&lt;/span&gt;.xdata&lt;span class="o"&gt;)&lt;/span&gt;


error: could not compile &lt;span class="sb"&gt;`&lt;/span&gt;hello_world&lt;span class="sb"&gt;`&lt;/span&gt; due to previous error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This error is, well, a bit weird. We can fix the build for now by providing a blank implementation of &lt;code&gt;__CxxFrameHandler3&lt;/code&gt;, but this needs more research. The following lines need to be added to &lt;code&gt;src/main.rs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;__CxxFrameHandler3&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application builds and runs fine now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Print EXE_EXTENSION constant
&lt;/h3&gt;

&lt;p&gt;Now we will print EXE_EXTENSION to the console. Since we do not have io and string implemented yet, we will have to do it in a primitive way using &lt;code&gt;u16&lt;/code&gt; arrays. The final &lt;code&gt;src/main.rs&lt;/code&gt; is given below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_main]&lt;/span&gt;
&lt;span class="nd"&gt;#![feature(restricted_std)]&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;r_efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;consts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[no_mangle]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;__CxxFrameHandler3&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;print_efi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;r_efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;base&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="py"&gt;.con_out&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="py"&gt;.output_string&lt;/span&gt;&lt;span class="p"&gt;)((&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="py"&gt;.con_out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.as_ptr&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Char16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.is_error&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;print_newline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;r_efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;base&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nf"&gt;create_const_uefi_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;print_efi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;create_const_uefi_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;const_str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uefi_array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;const_str&lt;/span&gt;&lt;span class="nf"&gt;.bytes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;uefi_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;uefi_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0x0000u16&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;print_env_constants&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;r_efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;base&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;exe_extension_heading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nf"&gt;create_const_uefi_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"exe_extension: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;exe_extension_heading&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;print_efi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;exe_extension_heading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;exe_extension&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nf"&gt;create_const_uefi_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;consts&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;EXE_EXTENSION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;exe_extension&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;print_efi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;exe_extension&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;print_newline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[export_name&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"efi_main"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;print_env_constants&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SUCCESS&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the program running under qemu:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jTDfyiDQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://programmershideaway.xyz/images/post6/run-qemu-1.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jTDfyiDQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://programmershideaway.xyz/images/post6/run-qemu-1.webp" alt="Program Screenshot" width="800" height="657"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this, we are using our new &lt;code&gt;std&lt;/code&gt; for UEFI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Edit
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;__CxxFrameHandler3&lt;/code&gt; blank implementation is no longer required in the &lt;code&gt;master&lt;/code&gt; branch. I was previously basing my changes on the v1.61.0 tag. However, from now, I am going to work on master directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Technically, we are now using &lt;code&gt;std&lt;/code&gt; (even though none of it has yet been implemented). Now I will slowly start implementing parts of &lt;code&gt;std&lt;/code&gt; starting with allocation. I also wanted to find a way to use the normal Rust &lt;code&gt;main&lt;/code&gt; function instead of the current &lt;code&gt;efi_main&lt;/code&gt;. However, this still does not seem possible (see &lt;a href="https://github.com/rust-lang/rust/issues/29633"&gt;#29633&lt;/a&gt;). So, let’s get allocation working and replace all the arrays with vectors in this code.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>tianocore</category>
      <category>uefi</category>
    </item>
    <item>
      <title>Google Summer of Code 2022</title>
      <dc:creator>Ayush</dc:creator>
      <pubDate>Tue, 14 Jun 2022 00:00:00 +0000</pubDate>
      <link>https://forem.com/ayush1325/google-summer-of-code-2022-jpp</link>
      <guid>https://forem.com/ayush1325/google-summer-of-code-2022-jpp</guid>
      <description>&lt;p&gt;Hello everyone, I am Ayush Singh, a second-year student at the Indian Institute of Technology, Dhanbad, India. As a part of Google Summer of Code 2022, I will be working on Adding Rust Support for building UEFI Applications and Modules under the Tianocore organization. In this post, I will describe this project’s goals and set up my development environment.&lt;/p&gt;

&lt;p&gt;You can follow my GSoC-related blog posts using this &lt;a href="https://www.programmershideaway.xyz/tags/gsoc22/atom.xml"&gt;feed&lt;/a&gt;. I will currently be working under my personal &lt;a href="https://github.com/Ayush1325/rust"&gt;fork&lt;/a&gt;. In the future, it might be moved into the &lt;a href="https://github.com/tianocore/edk2-staging"&gt;edk2-staging&lt;/a&gt; repository. The final goal is to have the support merged upstream. However, that might not be immediately possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Goals
&lt;/h2&gt;

&lt;p&gt;The current project goals, as discussed with the mentors, are given below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get most of Rust-std running under the UEFI target&lt;/li&gt;
&lt;li&gt;Add testing support for UEFI target&lt;/li&gt;
&lt;li&gt;Pass all the general tests of &lt;code&gt;library/std&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Possibly add support for ARM and RISCV UEFI targets (currently, only X86_64, AARCH64, and I686 are present)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Setting up Development Environment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Setup Rust
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Install Rustup
&lt;/h4&gt;

&lt;p&gt;I will be using rustup to install and manage Rust since I will be working with multiple versions of standard libraries and compilers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;-sSf&lt;/span&gt; https://sh.rustup.rs | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will ask for some options, but I just set it to default.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install Rust toolchains
&lt;/h3&gt;

&lt;p&gt;I will be installing stable as well as nightly toolchains. For Stable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rustup toolchain &lt;span class="nb"&gt;install &lt;/span&gt;stable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Nightly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rustup toolchain &lt;span class="nb"&gt;install &lt;/span&gt;nightly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, add &lt;code&gt;~/.cargo/bin&lt;/code&gt; to &lt;code&gt;PATH&lt;/code&gt;. Alternatively, we can just source &lt;code&gt;$HOME/.cargo/env&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup rust project
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Setup Git Repository
&lt;/h4&gt;

&lt;p&gt;I will mostly follow the &lt;a href="https://rustc-dev-guide.rust-lang.org/getting-started.html"&gt;Getting Started&lt;/a&gt; section of the rustc-dev-guide for this. First, we need to clone the &lt;code&gt;rust-lang/rust&lt;/code&gt; repository. I prefer using ssh:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone git@github.com:rust-lang/rust.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, I will add my personal fork as a remote:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote add personal git@github.com:Ayush1325/rust.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Install depenencies
&lt;/h4&gt;

&lt;p&gt;Rust repository contains a script (&lt;code&gt;x.py&lt;/code&gt;) to help us install most of the dependencies we need and configures the bootstrapping process. However, since we need to compile to a different target, we need to build &lt;code&gt;rust-lld&lt;/code&gt;, which requires extra dependencies. Since I am using Fedora, I will list the command I used to install dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install &lt;/span&gt;ccache cmake python ninja-build llvm-devel llvm-libunwind-devel zlib-devel lld clang clang-tools-extra qemu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we will use the script to configure our build.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./x.py setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since I will mostly work on &lt;code&gt;library/std&lt;/code&gt;, I select the library option during configuration. We will need to modify the generated &lt;code&gt;config.toml&lt;/code&gt; since we will need &lt;code&gt;rust-lld&lt;/code&gt; for cross-compilation. Here is my config.toml:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# Includes one of the default files in src/bootstrap/defaults&lt;/span&gt;
&lt;span class="py"&gt;profile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"library"&lt;/span&gt;
&lt;span class="py"&gt;changelog-seen&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="nn"&gt;[llvm]&lt;/span&gt;
&lt;span class="py"&gt;download-ci-llvm&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"if-available"&lt;/span&gt;
&lt;span class="py"&gt;ccache&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="nn"&gt;[rust]&lt;/span&gt;
&lt;span class="py"&gt;lld&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;incremental&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Build toolchain
&lt;/h3&gt;

&lt;p&gt;Now, we will build the local toolchain using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./x.py build &lt;span class="nt"&gt;--stage&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We build the stage1 compiler since we will need to use this compiler to build sample applications for testing (Since we cannot use the testing framework yet).&lt;/p&gt;

&lt;p&gt;Finally, we will add this newly built toolchain using rustup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rustup toolchain &lt;span class="nb"&gt;link &lt;/span&gt;stage1 build/x86_64-unknown-linux-gnu/stage1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can use this toolchain to build any rust project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a UEFI hello_world
&lt;/h2&gt;

&lt;p&gt;Now to check that our new toolchain works, we will build a simple hello world application (no_std).&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a binary application
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo new hello_world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure Cargo
&lt;/h3&gt;

&lt;p&gt;First, we need to add the &lt;code&gt;r-efi&lt;/code&gt; crate to &lt;code&gt;Cargo.toml&lt;/code&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;r-efi&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"4.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we will add a file &lt;code&gt;.cargo/config.toml&lt;/code&gt; to configure building &lt;code&gt;core&lt;/code&gt; and &lt;code&gt;alloc&lt;/code&gt;. This way we do not need to specify &lt;code&gt;build-std&lt;/code&gt; option at the commmand line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[unstable]&lt;/span&gt;
&lt;span class="py"&gt;build-std&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"core"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"compiler_builtins"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;build-std-features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"compiler-builtins-mem"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we will set the current project to use our local toolchain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rustup override &lt;span class="nb"&gt;set &lt;/span&gt;stage1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Main Code
&lt;/h3&gt;

&lt;p&gt;Here is the code for &lt;code&gt;src/main.rs&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_main]&lt;/span&gt;
&lt;span class="nd"&gt;#![no_std]&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;r_efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[panic_handler]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;panic_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;core&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;PanicInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[export_name&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"efi_main"&lt;/span&gt;&lt;span class="nd"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="s"&gt;"C"&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SystemTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="mi"&gt;0x0048u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x0065u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x006cu16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x006cu16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x006fu16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// "Hello"&lt;/span&gt;
        &lt;span class="mi"&gt;0x0020u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// " "&lt;/span&gt;
        &lt;span class="mi"&gt;0x0057u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x006fu16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x0072u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x006cu16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0x0064u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// "World"&lt;/span&gt;
        &lt;span class="mi"&gt;0x0021u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// "!"&lt;/span&gt;
        &lt;span class="mi"&gt;0x000au16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// "\n"&lt;/span&gt;
        &lt;span class="mi"&gt;0x0000u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// NUL&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="c1"&gt;// Print "Hello World!".&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="py"&gt;.con_out&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="py"&gt;.output_string&lt;/span&gt;&lt;span class="p"&gt;)((&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="py"&gt;.con_out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.as_ptr&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Char16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.is_error&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Wait for key input, by waiting on the `wait_for_key` event hook.&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;unsafe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="py"&gt;.boot_services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="py"&gt;.wait_for_event&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="py"&gt;.con_in&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="py"&gt;.wait_for_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="nf"&gt;.is_error&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nn"&gt;efi&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SUCCESS&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Build and Test application
&lt;/h3&gt;

&lt;p&gt;We can build the application using a normal &lt;code&gt;cargo build&lt;/code&gt; now. To test the application, we will use qemu. To test out EFI applications in qemu, I have written a small python &lt;a href="https://github.com/Ayush1325/scripts/blob/main/Tianocore/RunQemu.py"&gt;script&lt;/a&gt;. The &lt;code&gt;hello_world.efi&lt;/code&gt; file that should be inside &lt;code&gt;target/x86_64-unknown-uefi/debug/&lt;/code&gt;. Here is the output screenshot: &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UTn043oG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://programmershideaway.xyz/images/post5/run_qemu.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UTn043oG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://programmershideaway.xyz/images/post5/run_qemu.webp" alt="Run Qemu" width="800" height="657"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With this, we can start implementing parts of std for UEFI and testing them in actual applications. Feel free to ask/make any suggestions on the Tianocore mailing list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Important Links
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.programmershideaway.xyz/tags/gsoc22/atom.xml"&gt;GSoC22 feed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Ayush1325/rust"&gt;Current Work Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>rust</category>
      <category>edk2</category>
      <category>tianocore</category>
    </item>
    <item>
      <title>Using KConfig with Rust</title>
      <dc:creator>Ayush</dc:creator>
      <pubDate>Mon, 14 Mar 2022 16:49:49 +0000</pubDate>
      <link>https://forem.com/ayush1325/using-kconfig-with-rust-37cg</link>
      <guid>https://forem.com/ayush1325/using-kconfig-with-rust-37cg</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;Hello everyone, I am currently working on KConfig bindings for Rust as a part of the Season of KDE 2022. The wrappers for most of the significant aspects of KConfig are complete, so I decided to rewrite the &lt;a href="https://develop.kde.org/docs/use/configuration/introduction/"&gt;Introduction to KConfig Docs&lt;/a&gt; in Rust. The bindings are still not stable and will probably change before the end of the Season of KDE. Still, this post should also help me test out the bindings outside tests. The kconfig bindings can be found &lt;a href="https://invent.kde.org/oreki/kconfig-rs"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The bindings currently use the git version of &lt;a href="https://github.com/woboq/qmetaobject-rs"&gt;qttypes&lt;/a&gt; since I had to merge some upstream changes that are needed for these bindings. So they are not ready for prime time just yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to KConfig
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The KConfig Class
&lt;/h3&gt;

&lt;p&gt;The KConfig object is used to access a given configuration object. The config object can be created in the following ways:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// a plain old read/write config object&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;KConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"myapprc"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// a specific file in the filesystem&lt;/span&gt;
&lt;span class="c1"&gt;// currently must be an INI style file&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;full_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;KConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/etc/kderc"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// not merged with global values&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;global_free&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;KConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"config"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;OpenFlags&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NO_GLOBALS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;QStandardPathLocation&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AppDataLocation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// not merged with globals or the $KDEDIRS hierarchy&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;simple_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;KConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"simple_rc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;OpenFlags&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SIMPLE_CONFIG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;QStandardPathLocation&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AppDataLocation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// outside the standard config resource&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;data_resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;KConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;OpenFlags&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;SIMPLE_CONFIG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;QStandardPathLocation&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AppDataLocation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// with custom backend&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;custom_backend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;KConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with_backend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"config"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"backend"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;QStandardPathLocation&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;AppDataLocation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Special Configuration Objects
&lt;/h3&gt;

&lt;p&gt;Each application has its own configuration object that uses the name provided to KAboutData appended with “rc” as its name. So an app named “myapp” would have the default configuration object of “myapprc” (located in &lt;code&gt;$HOME/.config/&lt;/code&gt;). This configuration file can be retrieved in this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;KSharedConfigPtr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default configuration object for the application is accessed when no name is specified when creating a KConfig object. So we could also do this instead - but it would be slower because it would have to parse the whole file again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;KConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally there is a global configuration object, &lt;code&gt;kdeglobals&lt;/code&gt;, that is shared by every application. It holds such information as the default application shortcuts for various actions. It is “blended” into the configuration object if the &lt;code&gt;kconfig::kconfig::OpenFlags::INCLUDE_GLOBALS&lt;/code&gt; flag is passed to the KConfig constructor, which is the default.&lt;/p&gt;

&lt;h3&gt;
  
  
  Commonly Useful Methods
&lt;/h3&gt;

&lt;p&gt;To save the current state of the configuration object we call the &lt;code&gt;sync()&lt;/code&gt; method. This method is also called when the object is destroyed. If no changes have been made or the resource reports itself as non-writable (such as in the case of the user not having write permissions to the file) then no disk activity occurs. &lt;code&gt;sync()&lt;/code&gt; merges changes performed concurrently by other processes - local changes have priority, though.&lt;/p&gt;

&lt;p&gt;If we want to make sure that we have the latest values from disk we can call &lt;code&gt;reparse_configuration()&lt;/code&gt; which calls &lt;code&gt;sync()&lt;/code&gt; and then reloads the data from disk.&lt;/p&gt;

&lt;p&gt;If we need to prevent the config object from saving already made modifications to disk we need to call &lt;code&gt;mark_as_clean()&lt;/code&gt;. A particular use case for this is rolling back the configuration to the on-disk state by calling &lt;code&gt;mark_as_clean()&lt;/code&gt; followed by &lt;code&gt;reparse_configuration()&lt;/code&gt;. Listing all groups in a configuration object is as simple as calling &lt;code&gt;group_list()&lt;/code&gt; as in this code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;KSharedConfigPtr&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;group_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="nf"&gt;.group_list&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;group_list&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;log&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;debug!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"next group: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  KSharedConfig
&lt;/h2&gt;

&lt;p&gt;The KSharedConfig class is a reference counted pointer to a KConfig . It thus provides a way to reference the same configuration object from multiple places in your application without the extra overhead of separate objects or concerns about synchronizing writes to disk even if the configuration object is updated from multiple code paths. Accessing a KSharedConfig object is as easy as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;KSharedConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open_config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ksomefilerc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;OpenFlags&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;FULL_CONFIG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;QStandardPathLocation&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GenericConfigLocation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;KSharedConfig is generally recommended over using KConfig itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  KConfigGroup
&lt;/h3&gt;

&lt;p&gt;Now that we have a configuration object, the next step is to actually use it. The first thing we must do is to define which group of key/value pairs we wish to access in the object. We do this by creating a KConfigGroup object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;KConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;general_group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="nf"&gt;.group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"General"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;colors_group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="nf"&gt;.group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Colors"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Config groups can be nested as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sub_group2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;general_group&lt;/span&gt;&lt;span class="nf"&gt;.group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Dialogs"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reading Entries
&lt;/h3&gt;

&lt;p&gt;With a KConfigGroup object in hand reading entries is now quite straight forward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;account_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;general_group&lt;/span&gt;&lt;span class="nf"&gt;.read_qstring_entry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Account"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;QColor&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_qvariant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;colors_group&lt;/span&gt;&lt;span class="nf"&gt;.read_qvariant_entry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"background"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;QColor&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Qt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;white&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.to_qvariant&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;QStringList&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_qvariant&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;general_group&lt;/span&gt;&lt;span class="nf"&gt;.read_qvariant_entry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"List"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;QStringList&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.to_qvariant&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;general_group&lt;/span&gt;&lt;span class="nf"&gt;.read_path_entry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SaveTo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"defaultPath"&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, one can mix reads from different KConfigGroup objects created on the same KConfig object. The bindings currently contain three read methods:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;read_qstring_entry()&lt;/code&gt; for reading &lt;code&gt;QString&lt;/code&gt; values&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;read_entry()&lt;/code&gt; for reading &lt;code&gt;QVariant&lt;/code&gt; values that can later be converted to any of the other types&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;read_path_entry()&lt;/code&gt; which returns a file system path.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If no such key currently exists in the configuration object, the default value is returned instead. If there is a localized (e.g. translated into another language) entry for the key that matches the current locale, that is returned.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing Entries
&lt;/h3&gt;

&lt;p&gt;Setting new values is similarly straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;general_group&lt;/span&gt;&lt;span class="nf"&gt;.write_qstring_entry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Account"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"accountName"&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;WriteConfigFlags&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NORMAL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;general_group&lt;/span&gt;&lt;span class="nf"&gt;.write_path_entry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SaveTo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"savePath"&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;WriteConfigFlags&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NORMAL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;color_group&lt;/span&gt;&lt;span class="nf"&gt;.write_qvariant_entry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"background"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;QColor&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"white"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nn"&gt;WriteConfigFlags&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NORMAL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="nf"&gt;.sync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we are done writing entries, &lt;code&gt;sync()&lt;/code&gt; must be called on the config object for it to be saved to disk. We can also simply wait for the object to be destroyed, which triggers an automatic &lt;code&gt;sync()&lt;/code&gt; if necessary.&lt;/p&gt;

&lt;h3&gt;
  
  
  KDesktopFile: A Special Case
&lt;/h3&gt;

&lt;p&gt;When is a configuration file not a configuration file? When it is a desktop file. These files, which are essentially configuration files at their heart, are used to describe entries for application menus, mimetypes, plugins and various services. When accessing a .desktop file, one should instead use the KDesktopFile class which, while a KConfig class offering all the capabilities described above, offers a set of methods designed to make accessing standard attributes of these files consistent and reliable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kiosk: Lockdown and User/Group Profiles
&lt;/h2&gt;

&lt;p&gt;KConfig provides a powerful set of lockdown and configuration definition capabilities, collectively known as “Kiosk”, that many system administrators and system integrators rely on. While most of this framework is provided transparently to the application, there is occasion when an application will want to check on the read/write status of a configuration object. Entries in configuration objects that are locked down using the kiosk facilities are said to be immutable. An application can check for immutability of entire configuration objects, groups or keys as shown in this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;KGlobal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="nf"&gt;.is_immutable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;log&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;debug!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"configuration object is immutable"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="nf"&gt;.group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"General"&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="nf"&gt;.is_immutable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;log&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;debug!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"group General is immutable"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="nf"&gt;.is_entry_immutable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"URL"&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;log&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;debug!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"URL entry in group General is immutable"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be useful in particular situations where an action should be taken when an item is immutable. For instance, the KDE panels will not offer configuration options to the user or allow them to otherwise change the order of applets and icons when the panel’s configuration object is marked as immutable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Since most of the work on base KConfig bindings is done, I will now be working on KConfigXT implementation in Rust. Instead to a wrapper, I will be generating Rust code from the kcfg files. Some work has already been done, however, it does not seem like I will be able to complete it anytime soon. Anyone interested in contributing to Rust/QML development is welcome. Here are some important project links:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://invent.kde.org/oreki/kconfig-rs"&gt;KConfig Rust Bindings&lt;/a&gt;: The bindings I am currently working on.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/woboq/qmetaobject-rs"&gt;qmetaobject&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/KDAB/cxx-qt/"&gt;cxx-qt&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>kde</category>
      <category>rust</category>
      <category>qt</category>
    </item>
  </channel>
</rss>
