Pages

Thursday, January 1, 2026

Tao's Fragments: RiscV Linux lib ELF Generation

Today is Jan 1st, 2026. And I will be back with what is meaningful. Years ago, I decide to start a new journey. After working on Rust, Linux OS, ELF file format, RiscV chip/ABI, and assembler and linker, and started C language compiler. Let's see how compiler tech and latest AI can change how technology can make programmer's life easier. 

I feel I can start blog again and share some fragments of my work and ready for open source. 

I've done the ELF executable with dynamic link support, it means that I can use my assembler+linker to generate ELF binary to invoke printf in libc. I've to say the RISCV's PLT/GOT RELA is really a headache, which can be topic for another fragemnt of mine. 😉

Today I finished the .so file generation and it can generate a library can be linked with gcc. Now I know why F# choose to support library after executable is done. And I know why F# library has its own printf. But anyway. 

The .so ELF generation is simple, my test .s file is listed below. Please note that i added my own pseudo instruction for RiscV assembly language. 

.data
.extern printf

tt_fmt: .string "%d\n"

const_float_or_string_value_104:
.string "Array index access test, expected value 42 and actual value: %d\n"

.text 
    .globl  add2               
    .type   add2, @function
add2:
    add     a0, a0, a1
    ret
    .size   add2, .-add2

    exit 42

The .extern will trigger dynamic symbol structure generation. The key here is the add2 function related instruction which is in bold font. 

  • globl add2 is to add "add2" to the dynamic symbol (.dynsym) table.
  • add2 shows the starting point of add2 function and it will be used to compute the size of the add2 function. 
  • .size show the add2's size is equal to current (the small dot) minus add2. 
After these info being added to dynamic symbol table, the readelf -a shows the following:



the riscv64 gcc link can link this shared library with c code and command is listed below:

#include <stdio.h>

int add2(int a, int b);

int main() {
    printf("%d\n", add2(20, 22));
    return 0;



and the exeuction result shows 42 which is 20 + 22 from add2(20, 22). 



Thanks to ChatGPT's which helps me to generate Linux command. Being a long time windows guy, I am still struggle to use correct Linux language, but let's see if this can change when I add more feature.