LoginSignup
4
3

More than 5 years have passed since last update.

LD_PRELOADで動的ライブラリへの依存を追加できるかの検証

Posted at

TL;DR

LD_PRELOADでprintfを後から差し替える - Qiita

上記の記事で LD_PRELOAD で先行ロードしたライブラリに新しい依存があったときに、ちゃんとリンクしてくれるのか疑問に思ったので検証した。
結論、新しい依存性も解決してくれることが確認できた。

検証

以下に検証をまとめる。printfの差し替えしたときの実装liblua.so への依存を追加した。

print.c
#include <stdio.h>

int main(int argc, char const* argv[])
{
    printf("printf no args\n");
    printf("printf %d\n", 1);

    fprintf(stdout, "fprintf no args\n");
    fprintf(stdout, "fprintf %d\n", 1);

    return 0;
}
override.c(luaの依存を追加)
#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
    const char *c = "override fwrite\n";
    write(1, c, strlen(c)); // stdout
    return 0;
}

int fprintf (FILE *__restrict __stream, const char *__restrict __format, ...) {
    const char *c = "override fprintf\n";
    write(1, c, strlen(c)); // stdout
    return 0;
}

int puts(const char *s) {
    const char *c = "override puts\n";
    write(1, c, strlen(c)); // stdout

    return 0;
}

int printf (const char *__restrict __format, ...) {
    const char *c = "override printf\n";
    write(1, c, strlen(c)); // stdout

    {
        const char *fn = "hello.lua";
        // Lua の言語エンジンを初期化
        lua_State *lua = luaL_newstate();

        // Lua のライブラリを使えるようにする
        luaL_openlibs(lua);

        // Lua のスクリプトを読み込む
        luaL_dofile(lua, fn);
    }

    return 0;
}
hello.lua
print("hello lua")

ビルドと実行結果は以下のようになる。

ビルドと実行結果
$ gcc print.c 
$ ./a.out 
printf no args
printf 1
fprintf no args
fprintf 1

$ gcc -shared -fPIC override.c -llua5.1 -o liboverride.so
$ LD_PRELOAD=./liboverride.so ./a.out
override puts
override printf
hello lua
override fwrite
override fprintf

LD_PRELOADで追加したライブラリの依存性も問題なく解決されていることがわかる。

ライブラリの依存性の確認
$ ldd ./a.out
        linux-vdso.so.1 =>  (0x00007ffea74ca000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8569757000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f8569b3a000)

$ LD_PRELOAD=./liboverride.so ldd ./a.out
        linux-vdso.so.1 =>  (0x00007ffd939fb000)
        ./liboverride.so (0x00007f9c7c35c000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9c7bf7b000)
        liblua5.1.so.0 => /usr/lib/x86_64-linux-gnu/liblua5.1.so.0 (0x00007f9c7bd4d000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f9c7c560000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9c7ba47000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9c7b843000)

参考

第 5 回: Lua を組み込み用の言語として利用する方法 (関数編) — WTOPIA v1.0 documentation

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3