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 //===----------------------------------------------------------------------===//
AArch64CA53Erratum843419Stub2()33 AArch64CA53Erratum843419Stub2::AArch64CA53Erratum843419Stub2() {
34 }
35
36 /// for doClone
AArch64CA53Erratum843419Stub2(const uint32_t * pData,size_t pSize,const char * pName,const_fixup_iterator pBegin,const_fixup_iterator pEnd)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
~AArch64CA53Erratum843419Stub2()46 AArch64CA53Erratum843419Stub2::~AArch64CA53Erratum843419Stub2() {
47 }
48
isMyDuty(const FragmentRef & pFragRef) const49 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
doClone()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