diff --git a/content/this-month/2026-06/index.md b/content/this-month/2026-06/index.md index e2ecd09..c12d6a7 100644 --- a/content/this-month/2026-06/index.md +++ b/content/this-month/2026-06/index.md @@ -87,9 +87,53 @@ In this section, we describe updates to Rust OS projects that are not directly r ...<>... --> -No projects updates were submitted this month. +### [`mkroening/elf-symbols`](https://github.com/mkroening/elf-symbols) +(Section written by [@mkroening](https://github.com/mkroening)) + +When developing an OS, you often need some information about the loaded kernel image: + +- Where has the loader loaded the kernel to? +- How large is the loaded kernel? +- Where do the text segment and the data segment end? +- How do I get the kernel TLS image? + +These questions can be answered by building non-relocatable images, by writing custom linker scripts, or by having a custom loader that provides this information somehow. + +But there is another way! +In fact, the main ELF linkers that I am aware of ([BFD], [gold], [LLD], [mold], and [Wild]) all have built-in ELF symbols that answer these questions when not using custom linker scripts. +Unfortunately, many are poorly documented, so I created the [elf-symbols] crate that exposes and documents them. +All symbols are tested on the aforementioned linkers. +The documentation shows when each linker gained support for the respective symbol. + +The following symbols are straightforward: + +- `__executable_start` (`executable_start()`) is the start of the executable. +- `_etext` (`text_end()`) is the end of the text segment. +- `_edata` (`data_end()`) is the end of the data segment. +- `_end` (`executable_end()`) is the end of the executable. + +`__ehdr_start` (`elf_header()`) is especially interesting. +It allows programs to examine themselves by reading their ELF headers (file headers and program headers). +This can be used to get TLS image information, for example. + +Note that these symbols are ELF specific, though, so they cannot be used when linking to something else, such as a PE32+ UEFI executable. + +#### Examples +```rust +println!("Executable start: {:p}", elf_symbols::executable_start()); +println!("ELF header: {:p}", elf_symbols::elf_header()); +println!("Text segment end: {:p}", elf_symbols::text_end()); +println!("Data segment end: {:p}", elf_symbols::data_end()); +println!("Executable end: {:p}", elf_symbols::executable_end()); +``` +[BFD]: https://sourceware.org/git/?p=binutils-gdb.git;a=tree;f=ld;h=b1662159cdd15bb857e04e42bd26361c0d406099;hb=5e56594815854de5eca35c7c04b11705d0f19c02 +[gold]: https://sourceware.org/git/?p=binutils-gdb.git;a=tree;f=gold;h=ac6272c7bb3ad02524b2ca86a2cf9b68e9ca30ca;hb=5e56594815854de5eca35c7c04b11705d0f19c02 +[LLD]: https://github.com/llvm/llvm-project/tree/llvmorg-22.1.8/lld +[mold]: https://github.com/rui314/mold/tree/v2.41.0 +[Wild]: https://github.com/wild-linker/wild/tree/0.9.0 +[elf-symbols]: https://crates.io/crates/elf-symbols ## Join Us?