AArch64CA53Erratum843419Stub.cpp revision cfcb22478ca64c308df58f9abe6fa2dedb213c16
1//===- AArch64CA53Erratum843419Stub.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 "AArch64InsnHelpers.h" 12 13#include "mcld/Fragment/FragmentRef.h" 14#include "mcld/Fragment/Relocation.h" 15#include "mcld/IRBuilder.h" 16#include "mcld/LD/BranchIsland.h" 17#include "mcld/LD/LDSection.h" 18#include "mcld/LD/LDSymbol.h" 19#include "mcld/LD/ResolveInfo.h" 20#include "mcld/LD/SectionData.h" 21 22#include <llvm/ADT/StringExtras.h> 23#include <llvm/Support/ELF.h> 24 25#include <cassert> 26 27namespace mcld { 28 29//===----------------------------------------------------------------------===// 30// AArch64CA53Erratum843419Stub 31//===----------------------------------------------------------------------===// 32AArch64CA53Erratum843419Stub::AArch64CA53Erratum843419Stub() { 33} 34 35/// for doClone 36AArch64CA53Erratum843419Stub::AArch64CA53Erratum843419Stub( 37 const uint32_t* pData, 38 size_t pSize, 39 const char* pName, 40 const_fixup_iterator pBegin, 41 const_fixup_iterator pEnd) 42 : AArch64CA53ErratumStub(pData, pSize, pName, pBegin, pEnd) { 43} 44 45AArch64CA53Erratum843419Stub::~AArch64CA53Erratum843419Stub() { 46} 47 48bool AArch64CA53Erratum843419Stub::isErratum843419Sequence(unsigned insn1, 49 unsigned insn2, 50 unsigned insn3) { 51 unsigned rt; 52 unsigned rt2; 53 bool is_pair; 54 bool is_load; 55 return AArch64InsnHelpers::isMemOp(insn2, rt, rt2, is_pair, is_load) && 56 (!is_pair || (is_pair && !is_load)) && 57 AArch64InsnHelpers::isLDSTUIMM(insn3) && 58 (AArch64InsnHelpers::getRn(insn3) == AArch64InsnHelpers::getRd(insn1)); 59} 60 61bool AArch64CA53Erratum843419Stub::isMyDuty(const FragmentRef& pFragRef) const { 62 if ((pFragRef.offset() + AArch64InsnHelpers::InsnSize * 3) > 63 pFragRef.frag()->size()) { 64 return false; 65 } 66 67 // The first instruction must be ending at 0xFF8 or 0xFFC. 68 const uint64_t vma = pFragRef.frag()->getParent()->getSection().addr() + 69 pFragRef.getOutputOffset(); 70 const unsigned page_offset = (vma & 0xFFF); 71 if ((page_offset != 0xFF8) && (page_offset != 0xFFC)) { 72 return false; 73 } 74 75 ErratumSequence code; 76 pFragRef.memcpy(&code, AArch64InsnHelpers::InsnSize * 3, 0); 77 78 if (isErratum843419Sequence(code.insns[0], code.insns[1], code.insns[2])) { 79 return true; 80 } 81 82 return false; 83} 84 85Stub* AArch64CA53Erratum843419Stub::doClone() { 86 return new AArch64CA53Erratum843419Stub(getData(), 87 size(), 88 "erratum_843419_veneer", 89 fixup_begin(), 90 fixup_end()); 91} 92 93} // namespace mcld 94