Articles tagged #no_std

Running glibc applications

In the last article, we implemented thread-local storage.

Well, some of it. We didn't actually bother supporting any kind of threading, so, if we try to load and execute a multithreaded program

Shell session
$ cargo b -q && gdb --args ./target/debug/elk run /bin/ls
(gdb) break jmp
Breakpoint 1 at 0x47e02: file src/process.rs, line 819.
(gdb) r
Starting program: /home/amos/ftl/elk/target/debug/elk run /bin/ls
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib/libthread_db.so.1".
Loading "/usr/bin/ls"
Loading "/usr/lib/libcap.so.2.33"
Loading "/usr/lib/libc-2.31.so"
Loading "/usr/lib/ld-2.31.so"

Breakpoint 1, elk::process::jmp (
    entry_point=0x7ffff7faab20 "\363\017\036\372\061\355I\211\321^H\211\342H\203\344\360PTL\215\005f\030\001\000",
    stack_contents=0x5555557150a0, qword_count=94) at src/process.rs:819
819         asm!(
(gdb) autosym
add symbol table from file "/home/amos/ftl/elk/target/debug/elk" at
        .text_addr = 0x555555565160
add symbol table from file "/usr/lib/ld-2.31.so" at
        .text_addr = 0x7ffff7a94100
add symbol table from file "/usr/lib/libc-2.31.so" at
        .text_addr = 0x7ffff7ba6630
add symbol table from file "/usr/lib/libgcc_s.so.1" at
        .text_addr = 0x7ffff7d8d020
add symbol table from file "/usr/lib/libpthread-2.31.so" at
        .text_addr = 0x7ffff7dabad0
add symbol table from file "/usr/lib/libdl-2.31.so" at
        .text_addr = 0x7ffff7dc7210
add symbol table from file "/usr/lib/libc-2.31.so" at
        .text_addr = 0x7ffff7df0630
add symbol table from file "/usr/lib/libcap.so.2.33" at
        .text_addr = 0x7ffff7f9e020
add symbol table from file "/usr/bin/ls" at
        .text_addr = 0x7ffff7fa9040
add symbol table from file "/usr/lib/ld-2.31.so" at
        .text_addr = 0x7ffff7fd3100
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
Thread-local storage

Welcome back and thanks for joining us for the reads notes... the thirteenth installment of our series on ELF files, what they are, what they can do, what does the dynamic linker do to them, and how can we do it ourselves.

I've been pretty successfully avoiding talking about TLS so far (no, not that one) but I guess we've reached a point where it cannot be delayed any further, so.

A no_std Rust binary

In Part 11, we spent some time clarifying mechanisms we had previously glossed over: how variables and functions from other ELF objects were accessed at runtime.

We saw that doing so "proper" required the cooperation of the compiler, the assembler, the linker, and the dynamic loader. We also learned that the mechanism for functions was actually quite complicated! And sorta clever!

Go back to the homepage.