Using lld in ELLCC for different targets

With all the talk about using lld on the list, I thought it would be interesting to try using it in my clang based ELLCC cross compilation tool chain. http://ellcc.org

The change was simple, since I use configuration files to tell clang how to compile, where to find libraries, etc. I described the config files here: http://ellcc.org/blog/?p=13246

All I had to do was change the linker executable definition for each target:

linker:

   #exe: $E/ecc-ld$X

   exe: $E/ld.lld$x

(where $E is the executable directory where the compiler was found and $X is the executable extension, "" under Linux)

Here are the results of linking a program for Linux:

ARM32 v6: Good

ARM32 v7: Good

ARM32 big endian: Not supported by lld, no armelfb_linux_eabi emulation mode.

Aarch64: Good

MIPS 32 little and big endian: Good

MIPS64 big endian: Good

PPC32: lld failed with a bad relocation type.

PPC64 little endian: Not supported by lld, no elf64lppc emulation mode.

X86 32 and 64: Good

As a test I built clang to run native on ARMv6, ARMv7, Aarch64, MIPS32, MIPS64, and x86_84 Linux: Good

Very cool!

I use ld for mingw-w64 targets. Is there a mode for the COFF lld that makes it also act like ld?

Now I have to look into how lld supports Linker scripts for my non-Linux targets.

-Rich

With all the talk about using lld on the list, I thought it would be
interesting to try using it in my clang based ELLCC cross compilation tool
chain. http://ellcc.org

The change was simple, since I use configuration files to tell clang how
to compile, where to find libraries, etc. I described the config files
here: http://ellcc.org/blog/?p=13246

All I had to do was change the linker executable definition for each
target:

linker:

  #exe: $E/ecc-ld$X

  exe: $E/ld.lld$x

(where $E is the executable directory where the compiler was found and $X
is the executable extension, "" under Linux)

Here are the results of linking a program for Linux:

ARM32 v6: Good

ARM32 v7: Good

ARM32 big endian: Not supported by lld, no armelfb_linux_eabi emulation
mode.

Aarch64: Good

MIPS 32 little and big endian: Good

MIPS64 big endian: Good

PPC32: lld failed with a bad relocation type.

PPC64 little endian: Not supported by lld, no elf64lppc emulation mode.

X86 32 and 64: Good

As a test I built clang to run native on ARMv6, ARMv7, Aarch64, MIPS32,
MIPS64, and x86_84 Linux: Good

Very cool!

Awesome results!

I wonder if ARM32 BE is a real thing. I know that the processor is
bi-endian, but is there any system that uses ARM32 in big-endian mode?

I use ld for mingw-w64 targets. Is there a mode for the COFF lld that
makes it also act like ld?

Unfortunately, no. You can use the GNU compatible driver on Windows, but it
always produces ELF.

Now I have to look into how lld supports Linker scripts for my non-Linux

Awesome results!

I'm surprised! LLD is barely working on ARM at the moment. :slight_smile:

I wonder if ARM32 BE is a real thing. I know that the processor is
bi-endian, but is there any system that uses ARM32 in big-endian mode?

Yes... it is "a thing". :slight_smile:

ARM has two modes: BE32 and BE8 (mixed) and they can be enabled via
CP15 registers.

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0290g/ch06s05s01.html

cheers,
--renato

> Awesome results!

I'm surprised! LLD is barely working on ARM at the moment. :slight_smile:

> I wonder if ARM32 BE is a real thing. I know that the processor is
> bi-endian, but is there any system that uses ARM32 in big-endian mode?

Yes... it is "a thing". :slight_smile:

Apologies for my ignorance. :slight_smile:

ARM has two modes: BE32 and BE8 (mixed) and they can be enabled via
CP15 registers.

Supporting both BE and LE should be easy. We have very small amount of code
to support both for MIPS.

[snip]
My mistake. ARM worked for small programs, but lld failed for clang with a bunch of these errors:
/home/rich/ellcc-release/bin/ld.lld: error: relocation R_ARM_CALL out of range

Sorry about the misinformation.

-Rich

Well, at least it works on some programs across all arches. That was some great testing you’ve done for us. :slight_smile:

Thanks!
Renato

Thank you very much for the testing of LLD Rich.

The current status of the ARM port of LLD is that I've been working on
the obvious known missing features first, but I haven't aggressively
tested LLD on ARM against real applications to find the long tail of
bugs that will need fixing. I think we're close to that point, but not
yet.

Unimplemented features:
- Target awareness, LLD assumes ARMv7 (Cortex A and R) and makes use
of Thumb2 branch encodings and instructions, it will be possible to
link ARMv6 programs but don't try and run them on a ARMv6 machine. The
most widely known v6 platform used by developers is the original
Raspberry Pi.
- Long branch thunks, that is one of the reasons you'll see many
R_ARM_CALL instructions out of range on larger programs.
- big endian, a little more complicated than other targets due to
instructions being little endian in ARM BE8. It is true that big
endian linux systems are much rarer than little endian, but there have
been a few instances. It is more common in microcontrollers.

Known problems:
- ifunc not working
- TLS for static linking not working
- ARM (and AArch64) undefined weak reference handling

I know what the problems are and have some prototype fixes. I'll be
working to get these fixes in soon.

Peter