Reputation: 1924
TLDR: Is there some tool/linker-option to ensure that all object files that will be linked are actually built for the same architecture? Ideally something that can be set as alias for ld.
Long: I just learned that ld
has no issues or concerns about linking an armv4
object into an armv6-m
binary despite this beeing very obvious nonsense. Especially since objdump
can figure out what architecture something was built for, this seems worth at least a warning.
I can't find anything in the manpages, the linker doesn't even accept the architecture as argument. The best I could think of is adding something like the follwing to my compilation targets, but that wouldn't protect me from this on the command line where the error is more likely to happen.
[ $(objdump -f $@ | grep -oE 'architecture:\s[^,]+,') == "architecture:${arch}," ]
So is there some way to ensure that any call to ld
when given objects for mismatching architectures aborts with error?
Update:
armv6k
(presumably the smallest architecture supporting both).arm-none-eabi-readelf -a | tail
shows the following, except for cpu name and arch where it's v6-m
or v6k
depending on the file.
Attribute Section: aeabi
File Attributes
Tag_CPU_name: "4T"
Tag_CPU_arch: v4T
Tag_ARM_ISA_use: Yes
Tag_THUMB_ISA_use: Thumb-1
Tag_ABI_PCS_wchar_t: 4
Tag_ABI_FP_denormal: Needed
Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754
Tag_ABI_align_needed: 8-byte
Tag_ABI_align_preserved: 8-byte, except leaf SP
Tag_ABI_enum_size: small
Tag_ABI_optimization_goals: Aggressive Speed
Upvotes: 1
Views: 864
Reputation:
To answer you first question, without a given linker option, ld
detects the input architecture from the ELF objects and refuse the linking of the objects with an error if there is a mismatch.
The output should be similar to this:
arm-none-eabi-ld: error: main.o: conflicting CPU architectures 13/1
arm-none-eabi-ld: failed to merge target specific data of file main.o
Why ld
links an armv4
object into an armv6-m
binary without warning/error?
This is just a guess, but it could be possible that the machine code (instructions) from armv4
is compatible with armv6-m
. But without my knowledge from the GNU ld
code I can't give a clear answer. So I don't know how ld
handles this.
Why ld
doesn't accept the target architecture from command line?
I have tried this and I can confirm this behaviour. It could be possible, that this is a bug or configuration issue from GNU ld
. Will ask this on the official ARM developer community and provide a cross link here. A workaround is to specify the target architecture in a linker script with OUTPUT_ARCH
. If the architecture is specified, ld
also refuse the linking with an error.
UPDATE:
I have to admit, that I had gone out that this works (setting the output architecture via linker script) also on ARM GNU ld, like on other architectures like AVR from Microchip. But it leads in many EABI version mismatches. I also asked this in the official ARM developer community.
The link to the question on ARM developer community.
UPDATE 1:
The workaround with setting the output architecture (OUTPUT_ARCH
) with the linker script, works with the GNU gold
linker. Confirmed by a ARM developer community member. You can read this in the above link. The behaviour with the EABI version mismatches indicates a bug in GNU ld
.
I have tried this on my current projects with a Cortex-M7 (Armv7E-M).
Compiled the source code with the GCC options:
CCFLAGS += -march=armv7e-m
CCFLAGS += -mcpu=cortex-m7
Selected the output target architecture in the linker script:
OUTPUT_ARCH(armv7e-m)
The linking with GNU ld
fails here with many of these EABI mismatches:
arm-none-eabi-ld: error: source object main.o has EABI version 5, but target main_cm7.elf has EABI version 0
arm-none-eabi-ld: failed to merge target specific data of file main.o
When using GNU gold
instead of GNU ld
the linking works, without the EABI mismatches, confirmed by a ARM developer community member.
NOTE
This issue from GNU ld
affects at least the official GNU toolchain binaries with the GNU ld
version from the ARM site:
$ arm-none-eabi-ld --version
GNU ld (GNU Arm Embedded Toolchain 10.3-2021.07) 2.36.1.20210621
Copyright (C) 2021 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.
Currently don't tried newer or older versions.
UPDATE 2:
I have written an bug report for GNU-ld. Can be found here.
Upvotes: 3