<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - clang ignores linker script option -T when cross compiling for freestanding environment"
   href="https://bugs.llvm.org/show_bug.cgi?id=46330">46330</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>clang ignores linker script option -T when cross compiling for freestanding environment
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>10.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>alex.bereza@huawei.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>blitzrakete@gmail.com, dgregor@apple.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Hello,

I'm running into problems during the linking phase, when trying to
cross-compile for an aarch64 bare-metal target on a X86_64 host.

I have tried using the GNU linker and lld, which both fail, but with different
reasons. Clang either ignores the linker script that I pass via command line
option -T or it assumes that I'm trying to link an X86_64 binary, while my
target actually is aarch64.

Here is a minimal example:

main.c:

```
void bare_metal_entry(void){
        return;
}
```

linkerscript.ld:

```
ENTRY(bare_metal_entry)

SECTIONS {
    .text : { *(.text*) }
    .rodata : { *(.rodata*) }
    .data : { *(.data*) }
    .bss : { *(.bss COMMON) }
}
```

Compile command:

```
clang --target=aarch64-none-elf -ffreestanding -nostdlib -o main.c.obj -c
main.c
``` 

When linking with the command

```
/home/alex/opt/lld/bin/clang --target=aarch64-none-elf -ffreestanding -nostdlib
main.c.obj -T linkerscript.ld
```

I get:

```
/usr/bin/ld: unknown architecture of input file `main.c.obj' is incompatible
with i386:x86-64 output
collect2: error: ld returned 1 exit status
clang-11: error: linker (via gcc) command failed with exit code 1 (use -v to
see invocation)
```

When using lld via -fuse-ld=lld the situation is the same, the error message is
just slightly different:

```
ld.lld: error: main.c.obj is incompatible with elf_x86_64
collect2: error: ld returned 1 exit status
clang-11: error: linker (via gcc) command failed with exit code 1 (use -v to
see invocation)
```

I don't have an aarch64-none-elf-ld on my PATH. I realized that the behavior
changes when the target triplet matches the one of a GNU linker which I do have
on my PATH. I'm using Ubuntu 20.04 LTS and have installed aarch64-linux-gnu-ld
on my system from the corresponding package.

When linking with the command

```
/home/alex/opt/lld/bin/clang --target=aarch64-linux-gnu -ffreestanding
-nostdlib main.c.obj -T linkerscript.ld
```

I get:

```
clang-11: warning: argument unused during compilation: '-T linkerscript.ld'
[-Wunused-command-line-argument]
/usr/lib/gcc-cross/aarch64-linux-gnu/9/../../../../aarch64-linux-gnu/bin/ld:
warning: cannot find entry symbol _start; defaulting to 00000000004000b0
```

The linking succeeds, but the linked binary is not what I expect, because as
written above, the linker script is ignored.

When bypassin clang invocation and linking directly via

```
aarch64-linux-gnu-ld main.c.obj -T linkerscript.ld
```

or

```
ld.lld main.c.obj -T linkerscript.ld
```

the linking succeeds and the linker script is respected.


I maybe I am getting something wrong regarding the target triplet. If yes,
could you please point me to the relevant documentation? Independent from that
I think the fact the linker script is ignored with the output 


```
clang-11: warning: argument unused during compilation: '-T linkerscript.ld'
[-Wunused-command-line-argument]
```

might be a bug.

I tried a recent clang version that I built from upstream and clang from an
installed package. The result is the same. Here are the versions I tried:

clang version 11.0.0 (<a href="https://github.com/llvm/llvm-project.git">https://github.com/llvm/llvm-project.git</a>
14c1e987546ef161769aa619bb9de21c943721ec)
clang version 10.0.0-4ubuntu1

Please let me know if this is in fact a bug or if I am doing something wrong.
Thank you.

Best regards,
Alex Bereza</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>