Skip to content

Miscompilation when targeting mipsel with -static-pie #124681

Open
@Gelbpunkt

Description

@Gelbpunkt

I'm not 100% sure what is going on exactly, so here's what I'm doing for a minimal reproducer:

I have a very simple program, say test.c:

#include <stdio.h>

int main() {
    printf("Hello world!\n");
    return 0;
}

I then compile it with clang for mipsel:

mipsel-unknown-linux-musl-clang --sysroot ./sysroot/usr/mipsel-unknown-linux-musl/ -fuse-ld=lld -static test.c -o test -mips32r2

...and run it with binfmt-misc using qemu-static-mipsel:

$ ./test
Hello world!

So far, so good. Now I try -static-pie instead of -static:

$ mipsel-unknown-linux-musl-clang --sysroot ./sysroot/usr/mipsel-unknown-linux-musl/ -fuse-ld=lld -static-pie test.c -o test -mips32r2
$ ./test
Hello world!
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
fish: Job 1, './test' terminated by signal SIGSEGV (Address boundary error)

Something is fishy - so I put it in gdb:

Image

Notice the bal 0x55550000. That address is in the middle of nowhere and not at instruction boundary. The jump triggers the fault. Removing the block for __cxa_finalize "fixes" the issue.

$ llvm-readelf -Ws test | grep cxa_finalize
   143: 00000000     0 NOTYPE  WEAK   DEFAULT   UND __cxa_finalize

I wonder why this resolves to the weak symbol - maybe that is part of the issue? On x86_64 it does as well, but doesn't crash. It definitely is an issue with weak symbols I believe - I had to revert c228289 to make it stop calling __register_frame_info (an unresolved weak symbol because it is not enabled by default in libunwind), calling which triggered basically the same issue that I'm describing here now.

This is all on LLVM 19.1.7 built with Chimera Linux' packaging infrastructure (i.e. a full LLVM toolchain).

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions