class AVR final : public TargetInfo {
public:
AVR();
+ uint32_t calcEFlags() const override;
RelExpr getRelExpr(RelType type, const Symbol &s,
const uint8_t *loc) const override;
void relocate(uint8_t *loc, const Relocation &rel,
static AVR target;
return ⌖
}
+
+static uint32_t getEFlags(InputFile *file) {
+ return cast<ObjFile<ELF32LE>>(file)->getObj().getHeader().e_flags;
+}
+
+uint32_t AVR::calcEFlags() const {
+ assert(!objectFiles.empty());
+
+ uint32_t flags = getEFlags(objectFiles[0]);
+ bool hasLinkRelaxFlag = flags & EF_AVR_LINKRELAX_PREPARED;
+
+ for (InputFile *f : makeArrayRef(objectFiles).slice(1)) {
+ uint32_t objFlags = getEFlags(f);
+ if ((objFlags & EF_AVR_ARCH_MASK) != (flags & EF_AVR_ARCH_MASK))
+ error(toString(f) +
+ ": cannot link object files with incompatible target ISA");
+ if (!(objFlags & EF_AVR_LINKRELAX_PREPARED))
+ hasLinkRelaxFlag = false;
+ }
+
+ if (!hasLinkRelaxFlag)
+ flags &= ~EF_AVR_LINKRELAX_PREPARED;
+
+ return flags;
+}
--- /dev/null
+; RUN: llvm-mc -filetype=obj -triple=avr -mcpu=avr5 %s -o %t-v5
+; RUN: llvm-mc -filetype=obj -triple=avr -mcpu=avrxmega3 %s -o %t-xmega3
+; RUN: ld.lld %t-v5 -o %t-v5.out
+; RUN: ld.lld %t-xmega3 -o %t-xmega3.out
+; RUN: llvm-readobj -h %t-v5.out | FileCheck --check-prefix V5 %s
+; RUN: llvm-readobj -h %t-xmega3.out | FileCheck --check-prefix XMEGA3 %s
+
+;; Ensure LLD won't silently mix object files targeting different ISAs.
+; RUN: not ld.lld %t-v5 %t-xmega3 -o /dev/null 2>&1 | FileCheck --check-prefix ERR %s
+; ERR: error: {{.*}}: cannot link object files with incompatible target ISA
+
+; V5: Flags [ (0x5)
+; V5: EF_AVR_ARCH_AVR5 (0x5)
+; XMEGA3: Flags [ (0x67)
+; XMEGA3: EF_AVR_ARCH_XMEGA3 (0x67)