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 AVR(); 47 RelExpr getRelExpr(RelType Type, const Symbol &S, 48 const uint8_t *Loc) const override; 49 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; 50 }; 51 } // namespace 52 53 AVR::AVR() { NoneRel = R_AVR_NONE; } 54 55 RelExpr AVR::getRelExpr(RelType Type, const Symbol &S, 56 const uint8_t *Loc) const { 57 return R_ABS; 58 } 59 60 void AVR::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { 61 switch (Type) { 62 case R_AVR_CALL: { 63 uint16_t Hi = Val >> 17; 64 uint16_t Lo = Val >> 1; 65 write16le(Loc, read16le(Loc) | ((Hi >> 1) << 4) | (Hi & 1)); 66 write16le(Loc + 2, Lo); 67 break; 68 } 69 default: 70 error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type)); 71 } 72 } 73 74 TargetInfo *elf::getAVRTargetInfo() { 75 static AVR Target; 76 return &Target; 77 } 78