Skip to content

ifunc references to shared library functions are not resolved correctly #1237

Open
@monkuous

Description

@monkuous

When an ifunc in a shared library is referenced, mlibc's dynamic linker currently resolves it to the resolver function instead of the target function. This is because such references are linked with the R_<arch>_JUMP_SLOT and R_<arch>_GLOB_DAT relocations instead of the R_<arch>_IRELATIVE one. The dynamic linker is supposed to handle this by detecting that the resolved symbol is STT_GNU_IFUNC and dereferencing it, but mlibc doesn't do this.

Test case

test1.c:

static int foo_impl(void) {
    return 1;
}

static int (*foo_resolver(void))(void) {
    return foo_impl;
}

int foo(void) __attribute__((ifunc("foo_resolver")));

test2.c:

#include <stdio.h>

int foo(void);

int main(void) {
    printf("%d\n", foo());
}
$ gcc test1.c -o libtest.so -shared
$ gcc test2.c -o test -L. -ltest -Wl,-rpath=.
$ ./test
# expected output (glibc): 1
# actual output (mlibc): address of foo_impl, truncated to 32 bits and interpreted as signed

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions