AArch64CA53Erratum843419Stub2.cpp revision cfcb22478ca64c308df58f9abe6fa2dedb213c16
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
28namespace mcld {
29
30//===----------------------------------------------------------------------===//
31// AArch64CA53Erratum843419Stub2
32//===----------------------------------------------------------------------===//
33AArch64CA53Erratum843419Stub2::AArch64CA53Erratum843419Stub2() {
34}
35
36/// for doClone
37AArch64CA53Erratum843419Stub2::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
46AArch64CA53Erratum843419Stub2::~AArch64CA53Erratum843419Stub2() {
47}
48
49bool 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
76Stub* 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