[llvm-dev] [cfe-dev] Feedback on feature (and status of lld linker script support?)

Christopher Friedt via llvm-dev llvm-dev at lists.llvm.org
Tue Nov 30 08:00:55 PST 2021


On Tue, Nov 30, 2021 at 4:55 AM Peter Smith <Peter.Smith at arm.com> wrote:
> The code to parse linker scripts could be borrowed from the ELF ld.lld but that would only be one small piece of the puzzle. AFAIK the GNU linker doesn't support Mach-O

I think you're right - even though GNU binutils bfd, gas, etc supports
Mach-O, IIRC, it calls out to Apple's ld to actually do the linking.

> so there would have to be a mapping worked out from GNU linker scripts to Mach-O. This is possible but a lot of work and experimentation will be needed to work out what makes sense. For example something like PHDRS is unlikely to cross over from ELF. Then there's the complexity of what linker scripts can do to the linker code. A lot of corner case code has to be written to account for what can be written in a linker script.

Agreed... there are many corner cases with GNU linker scripts, in part
because they are fairly powerful.

> Given the lack of precedent in Mach-O for linker scripts it may be better to look at what specific needs there are and try to look at alternative ways of supporting them rather than adopting GNU linker scripts.

I did look at the "--order-file" option briefly, but I'm not entirely
sure if it's exactly the same concept or if it has any of the same
features of GNU linker scripts. Any idea?

> For example are scripts needed for linker defined symbols? section/atom ordering within a section?

As long as the section name is a valid C identifier, linker scripts
are not needed for linker-defined symbols with GCC (presumably also
Clang + ld.lld). A corresponding __start_SECTION and __stop_SECTION
symbol would automatically be generated (discarded if unused).

That's not the case with ld64.lld, which requires a
__asm("section$start$SEGMENT$SECTION") or
__asm("section$end$SEGMENT$SECTION"). I'm not sure if that has always
been the case with macOS or if it's more of a recent thing since the
switch to Clang.

However, there are other cases where it is either not desired or
impossible to use default linker generated start and stop symbols.
E.g.

 devices :
 {
  __device_start = .;
  __device_PRE_KERNEL_1_start = .;
  KEEP(*(SORT(.z_device_PRE_KERNEL_1[0-9]_*)));
  KEEP(*(SORT(.z_device_PRE_KERNEL_1[1-9][0-9]_*)));
  __device_PRE_KERNEL_2_start = .;
  KEEP(*(SORT(.z_device_PRE_KERNEL_2[0-9]_*)));
  KEEP(*(SORT(.z_device_PRE_KERNEL_2[1-9][0-9]_*)));
  __device_POST_KERNEL_start = .;
  KEEP(*(SORT(.z_device_POST_KERNEL[0-9]_*)));
  KEEP(*(SORT(.z_device_POST_KERNEL[1-9][0-9]_*)));
  __device_APPLICATION_start = .;
  KEEP(*(SORT(.z_device_APPLICATION[0-9]_*)));
  KEEP(*(SORT(.z_device_APPLICATION[1-9][0-9]_*)));
  __device_SMP_start = .;
  KEEP(*(SORT(.z_device_SMP[0-9]_*)));
  KEEP(*(SORT(.z_device_SMP[1-9][0-9]_*)));
  __device_end = .;
 }

It sounds as though adding linker script support would almost mean
writing an entirely new linker. Could be an interesting experiment,
but I have to be careful to not go too far down this rabbit hole.


More information about the llvm-dev mailing list