LCOV - code coverage report
Current view: top level - flamenco/runtime/tests - fd_svm_elfgen.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 73 73 100.0 %
Date: 2026-04-15 06:25:28 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #include "fd_svm_elfgen.h"
       2             : #include "../../../ballet/elf/fd_elf64.h"
       3             : 
       4             : static char const shstrtab[] = "\0.text\0.rodata\0.shstrtab\0";
       5           6 : #define SHSTRTAB_OFF_TEXT    1  /* byte offset of ".text"     in shstrtab */
       6           6 : #define SHSTRTAB_OFF_RODATA  7  /* byte offset of ".rodata"   in shstrtab */
       7           6 : #define SHSTRTAB_OFF_SHSTR  15  /* byte offset of ".shstrtab" in shstrtab */
       8             : 
       9             : ulong
      10             : fd_svm_elfgen_sz( ulong text_sz,
      11           6 :                   ulong rodata_sz ) {
      12           6 :   ulong phdr_file_off     = sizeof(fd_elf64_ehdr);
      13           6 :   ulong text_file_off     = fd_ulong_align_up( phdr_file_off + sizeof(fd_elf64_phdr), 8UL );
      14           6 :   ulong rodata_file_off   = text_file_off + text_sz;
      15           6 :   ulong shstrtab_file_off = rodata_file_off + rodata_sz;
      16           6 :   ulong shdr_file_off     = fd_ulong_align_up( shstrtab_file_off + sizeof(shstrtab), 8UL );
      17           6 :   ulong total_sz          = shdr_file_off + 4UL * sizeof(fd_elf64_shdr);
      18           6 :   return total_sz;
      19           6 : }
      20             : 
      21             : void
      22             : fd_svm_elfgen( uchar *       buf,
      23             :                ulong         buf_sz,
      24             :                uchar const * text_data,
      25             :                ulong         text_sz,
      26             :                uchar const * rodata,
      27           6 :                ulong         rodata_sz ) {
      28           6 :   ulong phdr_file_off     = sizeof(fd_elf64_ehdr);
      29           6 :   ulong text_file_off     = fd_ulong_align_up( phdr_file_off + sizeof(fd_elf64_phdr), 8UL );
      30           6 :   ulong rodata_file_off   = text_file_off + text_sz;
      31           6 :   ulong segment_sz        = text_sz + rodata_sz;
      32           6 :   ulong shstrtab_file_off = rodata_file_off + rodata_sz;
      33           6 :   ulong shdr_file_off     = fd_ulong_align_up( shstrtab_file_off + sizeof(shstrtab), 8UL );
      34           6 :   ulong total_sz          = shdr_file_off + 4UL * sizeof(fd_elf64_shdr);
      35             : 
      36           6 :   FD_TEST( total_sz <= buf_sz );
      37           6 :   memset( buf, 0, total_sz );
      38             : 
      39           6 :   FD_STORE( fd_elf64_ehdr, buf, ((fd_elf64_ehdr) {
      40           6 :     .e_ident = { 0x7f,'E','L','F', FD_ELF_CLASS_64, FD_ELF_DATA_LE, 1, FD_ELF_OSABI_NONE },
      41           6 :     .e_type  = FD_ELF_ET_DYN,
      42           6 :     .e_machine   = FD_ELF_EM_BPF,
      43           6 :     .e_version   = 1,
      44           6 :     .e_entry     = text_file_off,
      45           6 :     .e_phoff     = phdr_file_off,
      46           6 :     .e_shoff     = shdr_file_off,
      47           6 :     .e_flags     = 0,
      48           6 :     .e_ehsize    = sizeof(fd_elf64_ehdr),
      49           6 :     .e_phentsize = sizeof(fd_elf64_phdr),
      50           6 :     .e_phnum     = 1,
      51           6 :     .e_shentsize = sizeof(fd_elf64_shdr),
      52           6 :     .e_shnum     = 4,
      53           6 :     .e_shstrndx  = 3
      54           6 :   }) );
      55             : 
      56             :   /* Single PT_LOAD segment covering .text and .rodata */
      57           6 :   fd_elf64_phdr * phdr = (fd_elf64_phdr *)(buf + phdr_file_off);
      58           6 :   phdr->p_type   = FD_ELF_PT_LOAD;
      59           6 :   phdr->p_flags  = 5;
      60           6 :   phdr->p_offset = text_file_off;
      61           6 :   phdr->p_vaddr  = text_file_off;
      62           6 :   phdr->p_paddr  = text_file_off;
      63           6 :   phdr->p_filesz = segment_sz;
      64           6 :   phdr->p_memsz  = segment_sz;
      65           6 :   phdr->p_align  = 8;
      66             : 
      67             :   /* Section 1: .text (sh_addr must equal sh_offset for the loader) */
      68           6 :   fd_elf64_shdr * shdr_text = (fd_elf64_shdr *)(buf + shdr_file_off + sizeof(fd_elf64_shdr));
      69           6 :   shdr_text->sh_name      = SHSTRTAB_OFF_TEXT;
      70           6 :   shdr_text->sh_type      = FD_ELF_SHT_PROGBITS;
      71           6 :   shdr_text->sh_flags     = 0x6;
      72           6 :   shdr_text->sh_addr      = text_file_off;
      73           6 :   shdr_text->sh_offset    = text_file_off;
      74           6 :   shdr_text->sh_size      = text_sz;
      75           6 :   shdr_text->sh_addralign = 8;
      76             : 
      77             :   /* Section 2: .rodata */
      78           6 :   fd_elf64_shdr * shdr_ro = (fd_elf64_shdr *)(buf + shdr_file_off + 2UL * sizeof(fd_elf64_shdr));
      79           6 :   shdr_ro->sh_name      = SHSTRTAB_OFF_RODATA;
      80           6 :   shdr_ro->sh_type      = FD_ELF_SHT_PROGBITS;
      81           6 :   shdr_ro->sh_flags     = 0x2;
      82           6 :   shdr_ro->sh_addr      = rodata_file_off;
      83           6 :   shdr_ro->sh_offset    = rodata_file_off;
      84           6 :   shdr_ro->sh_size      = rodata_sz;
      85           6 :   shdr_ro->sh_addralign = 1;
      86             : 
      87             :   /* Section 3: .shstrtab */
      88           6 :   fd_elf64_shdr * shdr_strtab = (fd_elf64_shdr *)(buf + shdr_file_off + 3UL * sizeof(fd_elf64_shdr));
      89           6 :   shdr_strtab->sh_name      = SHSTRTAB_OFF_SHSTR;
      90           6 :   shdr_strtab->sh_type      = FD_ELF_SHT_STRTAB;
      91           6 :   shdr_strtab->sh_offset    = shstrtab_file_off;
      92           6 :   shdr_strtab->sh_size      = sizeof(shstrtab);
      93           6 :   shdr_strtab->sh_addralign = 1;
      94             : 
      95           6 :   memcpy( buf + text_file_off, text_data, text_sz );
      96           6 :   if( rodata_sz ) memcpy( buf + rodata_file_off, rodata, rodata_sz );
      97           6 :   memcpy( buf + shstrtab_file_off, shstrtab, sizeof(shstrtab) );
      98           6 : }

Generated by: LCOV version 1.14