1 //===- AArch64CA53Erratum843419Stub2.cpp ----------------------------------===// 2 // 3 // The MCLinker Project 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "AArch64CA53Erratum843419Stub.h" 11 #include "AArch64CA53Erratum843419Stub2.h" 12 #include "AArch64InsnHelpers.h" 13 14 #include "mcld/Fragment/FragmentRef.h" 15 #include "mcld/Fragment/Relocation.h" 16 #include "mcld/IRBuilder.h" 17 #include "mcld/LD/BranchIsland.h" 18 #include "mcld/LD/LDSection.h" 19 #include "mcld/LD/LDSymbol.h" 20 #include "mcld/LD/ResolveInfo.h" 21 #include "mcld/LD/SectionData.h" 22 23 #include <llvm/ADT/StringExtras.h> 24 #include <llvm/Support/ELF.h> 25 26 #include <cassert> 27 28 namespace mcld { 29 30 //===----------------------------------------------------------------------===// 31 // AArch64CA53Erratum843419Stub2 32 //===----------------------------------------------------------------------===// 33 AArch64CA53Erratum843419Stub2::AArch64CA53Erratum843419Stub2() { 34 } 35 36 /// for doClone 37 AArch64CA53Erratum843419Stub2::AArch64CA53Erratum843419Stub2( 38 const uint32_t* pData, 39 size_t pSize, 40 const char* pName, 41 const_fixup_iterator pBegin, 42 const_fixup_iterator pEnd) 43 : AArch64CA53ErratumStub(pData, pSize, pName, pBegin, pEnd) { 44 } 45 46 AArch64CA53Erratum843419Stub2::~AArch64CA53Erratum843419Stub2() { 47 } 48 49 bool AArch64CA53Erratum843419Stub2::isMyDuty( 50 const FragmentRef& pFragRef) const { 51 if ((pFragRef.offset() + AArch64InsnHelpers::InsnSize * 4) > 52 pFragRef.frag()->size()) { 53 return false; 54 } 55 56 // The first instruction must be ending at 0xFF8 or 0xFFC. 57 const uint64_t vma = pFragRef.frag()->getParent()->getSection().addr() + 58 pFragRef.getOutputOffset(); 59 const unsigned page_offset = (vma & 0xFFF); 60 if ((page_offset != 0xFF8) && (page_offset != 0xFFC)) { 61 return false; 62 } 63 64 ErratumSequence code; 65 pFragRef.memcpy(&code, AArch64InsnHelpers::InsnSize * 4, 0); 66 67 if (AArch64CA53Erratum843419Stub::isErratum843419Sequence(code.insns[0], 68 code.insns[1], 69 code.insns[3])) { 70 return true; 71 } 72 73 return false; 74 } 75 76 Stub* AArch64CA53Erratum843419Stub2::doClone() { 77 return new AArch64CA53Erratum843419Stub2(getData(), 78 size(), 79 "erratum_843419_veneer", 80 fixup_begin(), 81 fixup_end()); 82 } 83 84 } // namespace mcld 85