Issue 146837
Summary [clang][PowerPC] Clang links against host `/usr/lib32` when targeting `powerpc-linux-gnu` (but not `powerpc64-linux-gnu`)
Labels clang
Assignees
Reporter venkyqz
    ## Environment

| Category | Detail |
| --- | --- |
| **OS** | Ubuntu 22.04 |
| **Architecture** | x86_64 host |
| **Clang Versions** | 11 – 20 (tested: 11, 13, 15, 17, 19, 20.1.6) |
| **Target triple** | `powerpc-linux-gnu` |
| **Clang build** | Release |

## Summary

- Clang incorrectly links host's `/usr/lib32/Scrt1.o` when compiling for `--target=powerpc-linux-gnu` on `x86_64` Ubuntu systems, despite the correct cross toolchain being installed under `/usr/powerpc-linux-gnu`.
This causes linker errors due to a mismatched ELF format. This issue does **not** occur for `--target=powerpc64-linux-gnu` under identical environments (with dependencies `gcc-powerpc64-linux-gnu`, `g++-powerpc64-linux-gnu`, `binutils-powerpc64-linux-gnu` and `libc6-dev-ppc64-cross` installed with `apt` as well).

## Reproduce

- **File: `hello.c`**

```c
#include <stdio.h>
int main() {
    printf("Hello PowerPC!\\n");
    return 0;
}
```

- **Install dependency**

```bash
root@f806c162d501:/test# apt-get install gcc-powerpc-linux-gnu g++-powerpc-linux-gnu binutils-powerpc-linux-gnu libc6-dev-powerpc-cross
```

- **Broken command**

```bash
root@f806c162d501:/test# clang-20 --target=powerpc-linux-gnu -o hello-ppc hello.c
```

- **Output: Failed**

```bash
/usr/bin/powerpc-linux-gnu-ld: /usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../lib32/Scrt1.o: relocations in generic ELF (EM: 3)
/usr/bin/powerpc-linux-gnu-ld: /usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../lib32/Scrt1.o: relocations in generic ELF (EM: 3)
/usr/bin/powerpc-linux-gnu-ld: /usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../lib32/Scrt1.o: error adding symbols: file in wrong format
```

- **Verbose Output**

```bash
root@f806c162d501:/test# clang-20 -v --target=powerpc-linux-gnu -o hello-ppc hello.c 
clang version 20.1.7
Target: powerpc-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin
Found candidate GCC installation: /usr/lib/gcc-cross/powerpc-linux-gnu/11
Found candidate GCC installation: /usr/lib/gcc-cross/powerpc64-linux-gnu/11
Selected GCC installation: /usr/lib/gcc-cross/powerpc-linux-gnu/11
Candidate multilib: .;@m32
Selected multilib: .;@m32
 "/usr/local/bin/clang-20" -cc1 -triple powerpc-unknown-linux-gnu -emit-obj -dumpdir hello-ppc- -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name hello.c -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu ppc -mfloat-abi hard -debugger-tuning=gdb -fdebug-compilation-dir=/test -v -fcoverage-compilation-dir=/test -resource-dir /usr/local/lib/clang/20 -internal-isystem /usr/local/lib/clang/20/include/ppc_wrappers -internal-isystem /usr/local/lib/clang/20/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../powerpc-linux-gnu/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fno-signed-char -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcolor-diagnostics -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/hello-ac8ddb.o -x c hello.c
clang -cc1 version 20.1.7 based upon LLVM 20.1.7 default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/lib/clang/20/include/ppc_wrappers
 /usr/local/lib/clang/20/include
 /usr/local/include
 /usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../powerpc-linux-gnu/include
 /usr/include
End of search list.
 "/usr/bin/powerpc-linux-gnu-ld" -z relro --hash-style=gnu --eh-frame-hdr -m elf32ppclinux -pie -dynamic-linker /lib/ld.so.1 -o hello-ppc /usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../lib32/Scrt1.o /usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../lib32/crti.o /usr/lib/gcc-cross/powerpc-linux-gnu/11/crtbeginS.o -L/usr/lib/gcc-cross/powerpc-linux-gnu/11 -L/usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../lib32 -L/lib/powerpc-linux-gnu -L/lib/../lib32 -L/usr/lib/powerpc-linux-gnu -L/usr/lib/../lib32 -L/usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../powerpc-linux-gnu/lib -L/lib -L/usr/lib /tmp/hello-ac8ddb.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc-cross/powerpc-linux-gnu/11/crtendS.o /usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../lib32/crtn.o
/usr/bin/powerpc-linux-gnu-ld: /usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../**lib32/Scrt1.o**: relocations in generic ELF (EM: 3)
/usr/bin/powerpc-linux-gnu-ld: /usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../**lib32/Scrt1.o**: relocations in generic ELF (EM: 3)
/usr/bin/powerpc-linux-gnu-ld: /usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../**lib32/Scrt1.o**: error adding symbols: file in wrong format
clang-20: error: linker command failed with exit code 1 (use -v to see invocation)
```

## Expected Behavior

- Clang should use the correct startup objects from:

```bash
/usr/powerpc-linux-gnu/lib/Scrt1.o
```

- and **not** pick up unrelated host files from:

```bash
/usr/lib32/Scrt1.o
```

## Observation

- Despite `-target=powerpc-linux-gnu`, Clang chooses `/usr/lib32/Scrt1.o` from the host.
- Resulting in a linker error due to incompatible ELF class.
- This behavior is **not** observed when targeting:
    - `powerpc64-linux-gnu`
    - `aarch64-linux-gnu`
    - `arm-linux-gnueabi`
    - etc.

## Workarounds

- **Specify targer specific `Scrt1.o` file**

```bash
root@f806c162d501:/test# clang-20 -v --target=powerpc-linux-gnu -nostdlib /usr/powerpc-linux-gnu/lib/crt1.o -L/usr/powerpc-linux-gnu/lib -lc /usr/powerpc-linux-gnu/lib/crtn.o -o hello-ppc hello.c
```

- **Output (Verbose): Success**

```bash
root@f806c162d501:/test# clang-20 -v --target=powerpc-linux-gnu -nostdlib /usr/powerpc-linux-gnu/lib/crt1.o -L/usr/powerpc-linux-gnu/lib -lc /usr/powerpc-linux-gnu/lib/crtn.o -o hello-ppc hello.c
clang version 20.1.7
Target: powerpc-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin
Found candidate GCC installation: /usr/lib/gcc-cross/powerpc-linux-gnu/11
Found candidate GCC installation: /usr/lib/gcc-cross/powerpc64-linux-gnu/11
Selected GCC installation: /usr/lib/gcc-cross/powerpc-linux-gnu/11
Candidate multilib: .;@m32
Selected multilib: .;@m32
 "/usr/local/bin/clang-20" -cc1 -triple powerpc-unknown-linux-gnu -emit-obj -dumpdir hello-ppc- -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name hello.c -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu ppc -mfloat-abi hard -debugger-tuning=gdb -fdebug-compilation-dir=/test -v -fcoverage-compilation-dir=/test -resource-dir /usr/local/lib/clang/20 -internal-isystem /usr/local/lib/clang/20/include/ppc_wrappers -internal-isystem /usr/local/lib/clang/20/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../powerpc-linux-gnu/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fno-signed-char -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcolor-diagnostics -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/hello-d0a071.o -x c hello.c
clang -cc1 version 20.1.7 based upon LLVM 20.1.7 default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/lib/clang/20/include/ppc_wrappers
 /usr/local/lib/clang/20/include
 /usr/local/include
 /usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../powerpc-linux-gnu/include
 /usr/include
End of search list.
 "/usr/bin/powerpc-linux-gnu-ld" -z relro --hash-style=gnu --eh-frame-hdr -m elf32ppclinux -pie -dynamic-linker /lib/ld.so.1 -o hello-ppc -L/usr/powerpc-linux-gnu/lib -L/usr/lib/gcc-cross/powerpc-linux-gnu/11 -L/usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../lib32 -L/lib/powerpc-linux-gnu -L/lib/../lib32 -L/usr/lib/powerpc-linux-gnu -L/usr/lib/../lib32 -L/usr/lib/gcc-cross/powerpc-linux-gnu/11/../../../../powerpc-linux-gnu/lib -L/lib -L/usr/lib /usr/powerpc-linux-gnu/lib/crt1.o -lc /usr/powerpc-linux-gnu/lib/crtn.o /tmp/hello-d0a071.o
```

## Fix Advice

Clang should:

- Prefer `$sysroot/$triple/lib` and similar over host `/usr/lib32` if `-target` is specified.
- Match the behavior of GCC and avoid falling back to host paths unless explicitly instructed.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to