1 //===- AVR.cpp ------------------------------------------------------------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // AVR is a Harvard-architecture 8-bit micrcontroller designed for small 11 // baremetal programs. All AVR-family processors have 32 8-bit registers. 12 // The tiniest AVR has 32 byte RAM and 1 KiB program memory, and the largest 13 // one supports up to 2^24 data address space and 2^22 code address space. 14 // 15 // Since it is a baremetal programming, there's usually no loader to load 16 // ELF files on AVRs. You are expected to link your program against address 17 // 0 and pull out a .text section from the result using objcopy, so that you 18 // can write the linked code to on-chip flush memory. You can do that with 19 // the following commands: 20 // 21 // ld.lld -Ttext=0 -o foo foo.o 22 // objcopy -O binary --only-section=.text foo output.bin 23 // 24 // Note that the current AVR support is very preliminary so you can't 25 // link any useful program yet, though. 26 // 27 //===----------------------------------------------------------------------===// 28 29 #include "InputFiles.h" 30 #include "Symbols.h" 31 #include "Target.h" 32 #include "lld/Common/ErrorHandler.h" 33 #include "llvm/Object/ELF.h" 34 #include "llvm/Support/Endian.h" 35 36 using namespace llvm; 37 using namespace llvm::object; 38 using namespace llvm::support::endian; 39 using namespace llvm::ELF; 40 using namespace lld; 41 using namespace lld::elf; 42 43 namespace { 44 class AVR final : public TargetInfo { 45 public: 46 RelExpr getRelExpr(RelType Type, const Symbol &S, 47 const uint8_t *Loc) const override; 48 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; 49 }; 50 } // namespace 51 52 RelExpr AVR::getRelExpr(RelType Type, const Symbol &S, 53 const uint8_t *Loc) const { 54 return R_ABS; 55 } 56 57 void AVR::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { 58 switch (Type) { 59 case R_AVR_CALL: { 60 uint16_t Hi = Val >> 17; 61 uint16_t Lo = Val >> 1; 62 write16le(Loc, read16le(Loc) | ((Hi >> 1) << 4) | (Hi & 1)); 63 write16le(Loc + 2, Lo); 64 break; 65 } 66 default: 67 error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type)); 68 } 69 } 70 71 TargetInfo *elf::getAVRTargetInfo() { 72 static AVR Target; 73 return &Target; 74 } 75