diff options
Diffstat (limited to 'lld')
| -rw-r--r-- | lld/ELF/InputFiles.cpp | 2 | ||||
| -rw-r--r-- | lld/ELF/Target.cpp | 35 | ||||
| -rw-r--r-- | lld/test/ELF/basic-avr.s | 14 | ||||
| -rw-r--r-- | lld/test/lit.cfg | 2 |
4 files changed, 53 insertions, 0 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 902593b63a7..3d11239bf88 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -821,6 +821,8 @@ static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) { case Triple::arm: case Triple::thumb: return EM_ARM; + case Triple::avr: + return EM_AVR; case Triple::mips: case Triple::mipsel: case Triple::mips64: diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index ee5a7690fc6..ac21ef91066 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -230,6 +230,13 @@ public: void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; }; +class AVRTargetInfo final : public TargetInfo { +public: + RelExpr getRelExpr(uint32_t Type, const SymbolBody &S, + const uint8_t *Loc) const override; + void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; +}; + template <class ELFT> class MipsTargetInfo final : public TargetInfo { public: MipsTargetInfo(); @@ -260,6 +267,8 @@ TargetInfo *createTarget() { return make<AMDGPUTargetInfo>(); case EM_ARM: return make<ARMTargetInfo>(); + case EM_AVR: + return make<AVRTargetInfo>(); case EM_MIPS: switch (Config->EKind) { case ELF32LEKind: @@ -2046,6 +2055,32 @@ int64_t ARMTargetInfo::getImplicitAddend(const uint8_t *Buf, } } +RelExpr AVRTargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S, + const uint8_t *Loc) const { + switch (Type) { + case R_AVR_CALL: + return R_ABS; + default: + error(toString(S.File) + ": unknown relocation type: " + toString(Type)); + return R_HINT; + } +} + +void AVRTargetInfo::relocateOne(uint8_t *Loc, uint32_t Type, + uint64_t Val) const { + switch (Type) { + case R_AVR_CALL: { + uint16_t Hi = Val >> 17; + uint16_t Lo = Val >> 1; + write16le(Loc, read16le(Loc) | ((Hi >> 1) << 4) | (Hi & 1)); + write16le(Loc + 2, Lo); + break; + } + default: + error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type)); + } +} + template <class ELFT> MipsTargetInfo<ELFT>::MipsTargetInfo() { GotPltHeaderEntriesNum = 2; DefaultMaxPageSize = 65536; diff --git a/lld/test/ELF/basic-avr.s b/lld/test/ELF/basic-avr.s new file mode 100644 index 00000000000..c8a3af9536f --- /dev/null +++ b/lld/test/ELF/basic-avr.s @@ -0,0 +1,14 @@ +# REQUIRES: avr +# RUN: llvm-mc -filetype=obj -triple=avr-unknown-linux -mcpu=atmega328p %s -o %t.o +# RUN: ld.lld %t.o -o %t.exe -Ttext=0 +# RUN: llvm-objdump -d %t.exe | FileCheck %s + +main: + call foo +foo: + jmp foo + +# CHECK: main: +# CHECK-NEXT: 0: 0e 94 02 00 <unknown> +# CHECK: foo: +# CHECK-NEXT: 4: 0c 94 02 00 <unknown> diff --git a/lld/test/lit.cfg b/lld/test/lit.cfg index 0f9e03aa386..c8471e1280a 100644 --- a/lld/test/lit.cfg +++ b/lld/test/lit.cfg @@ -247,6 +247,8 @@ if re.search(r'AArch64', archs): config.available_features.add('aarch64') if re.search(r'ARM', archs): config.available_features.add('arm') +if re.search(r'AVR', archs): + config.available_features.add('avr') if re.search(r'Mips', archs): config.available_features.add('mips') if re.search(r'X86', archs): |

