cstatic-linkingmusl

Override file access functions with statically linked musl (to implement a read-only virtual FS)


If dlsym is available in dynamic linking setup, I can get access to the original impl pointers using dlsym with RTLD_NEXT and use them in my overrides, e.g. as follows:

// paste these in main.c

#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <dlfcn.h>

int open(const char *path, int flags)
{
    fprintf(stderr, "log_file_access_preload: open(\"%s\", %d)\n", path, flags);

    typedef int (*orig_open_func_type)(const char *pathname, int flags);
    orig_open_func_type orig_func = (orig_open_func_type)dlsym(RTLD_NEXT, "open");
    return orig_func(path, flags);
}

FILE* fopen(const char *path, const char *mode)
{
    fprintf(stderr, "log_file_access_preload: fopen(\"%s\", \"%s\")\n", path, mode);

    typedef FILE* (*orig_fopen_func_type)(const char *path, const char *mode);
    orig_fopen_func_type orig_func = (orig_fopen_func_type)dlsym(RTLD_NEXT, "fopen");
    return orig_func(path, mode);
}

Is there a way to do static linking in such a way that doesn't hide the original libc/POSIX symbols and so that I can use them in my overrides? Should I create my own copy of musl *.a files with renamed original symbols? Should it work? Is there another way?

Usecase: implement redirection of file read/access functions for a custom LaTeX program (compilation process is controlled by me, statically built with musl) to read files from ISO or TAR archive (that contains a prepared TeX Directory Structure) without extraction to disk


Solution

  • My current solution for this (as discussed in comments with @KamilCuk):

    cp $(cc -print-file-name=libc.a) libcmy.a
    ar x libcmy open.lo close.lo read.lo stat.lo fstat.lo lseek.lo access.lo fopen.lo fileno.lo
    objcopy --redefine-sym open=orig_open       open.lo
    objcopy --redefine-sym close=orig_close    close.lo
    objcopy --redefine-sym read=orig_read       read.lo
    objcopy --redefine-sym stat=orig_stat       stat.lo
    objcopy --redefine-sym fstat=orig_fstat    fstat.lo
    objcopy --redefine-sym lseek=orig_lseek    lseek.lo
    objcopy --redefine-sym access=orig_access access.lo
    objcopy --redefine-sym fopen=orig_fopen    fopen.lo
    objcopy --redefine-sym fileno=orig_fileno fileno.lo
    ar rs libcmy.a open.lo close.lo read.lo stat.lo fstat.lo lseek.lo access.lo fopen.lo fileno.lo
    

    And then linking with libcmy.a instead of plain -lc.

    Then in the code we can add prototypes for these orig functions and define new functions using the orig functions.