• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
27 namespace mcld {
28 
29 //===----------------------------------------------------------------------===//
30 // AArch64CA53Erratum843419Stub
31 //===----------------------------------------------------------------------===//
AArch64CA53Erratum843419Stub()32 AArch64CA53Erratum843419Stub::AArch64CA53Erratum843419Stub() {
33 }
34 
35 /// for doClone
AArch64CA53Erratum843419Stub(const uint32_t * pData,size_t pSize,const char * pName,const_fixup_iterator pBegin,const_fixup_iterator pEnd)36 AArch64CA53Erratum843419Stub::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 
~AArch64CA53Erratum843419Stub()45 AArch64CA53Erratum843419Stub::~AArch64CA53Erratum843419Stub() {
46 }
47 
isErratum843419Sequence(unsigned insn1,unsigned insn2,unsigned insn3)48 bool 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 
isMyDuty(const FragmentRef & pFragRef) const61 bool 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 
doClone()85 Stub* 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