1551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===- AArch64RelocationHelpers.h -----------------------------------------===//
2551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//
3551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//                     The MCLinker Project
4551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//
5551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// This file is distributed under the University of Illinois Open Source
6551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// License. See LICENSE.TXT for details.
7551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//
8551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===----------------------------------------------------------------------===//
9551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#ifndef TARGET_AARCH64_AARCH64RELOCATIONHELPERS_H
10551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#define TARGET_AARCH64_AARCH64RELOCATIONHELPERS_H
11551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
12551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#include "AArch64Relocator.h"
13551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#include <llvm/Support/Host.h>
14551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
15551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesnamespace mcld {
16551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===----------------------------------------------------------------------===//
17551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// Relocation helper functions
18551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===----------------------------------------------------------------------===//
19551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// Return true if overflow
20551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline bool
21551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hineshelper_check_signed_overflow(Relocator::DWord pValue, unsigned bits)
22551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
23551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  if (bits >= sizeof(int64_t) * 8)
24551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    return false;
25551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  int64_t signed_val = static_cast<int64_t>(pValue);
26551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  int64_t max = (1 << (bits - 1)) - 1;
27551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  int64_t min = -(1 << (bits - 1));
28551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  if (signed_val > max || signed_val < min)
29551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    return true;
30551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return false;
31551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
32551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
33551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline Relocator::Address
34551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hineshelper_get_page_address(Relocator::Address pValue)
35551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
36551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return (pValue & ~ (Relocator::Address) 0xFFF);
37551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
38551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
39551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline Relocator::Address
40551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hineshelper_get_page_offset(Relocator::Address pValue)
41551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
42551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return (pValue & (Relocator::Address) 0xFFF);
43551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
44551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
45551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline uint32_t get_mask(uint32_t pValue)
46551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
47551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return ((1u << (pValue)) - 1);
48551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
49551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
50551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline uint32_t
51551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hineshelper_reencode_adr_imm(uint32_t pInst, uint32_t pImm)
52551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
53551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return (pInst & ~((get_mask(2) << 29) | (get_mask(19) << 5)))
54551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines      | ((pImm & get_mask(2)) << 29) | ((pImm & (get_mask(19) << 2)) << 3);
55551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
56551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
57551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// Reencode the imm field of add immediate.
58551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline uint32_t helper_reencode_add_imm(uint32_t pInst, uint32_t pImm)
59551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
60551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return (pInst & ~(get_mask(12) << 10)) | ((pImm & get_mask(12)) << 10);
61551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
62551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
63551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// Encode the 26-bit offset of unconditional branch.
64551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline uint32_t
65551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hineshelper_reencode_branch_offset_26(uint32_t pInst, uint32_t pOff)
66551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
67551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return (pInst & ~get_mask(26)) | (pOff & get_mask(26));
68551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
69551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
70551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// Encode the 19-bit offset of conditional branch and compare & branch.
71551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline uint32_t
72551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hineshelper_reencode_cond_branch_ofs_19(uint32_t pInst, uint32_t pOff)
73551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
74551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return (pInst & ~(get_mask(19) << 5)) | ((pOff & get_mask(19)) << 5);
75551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
76551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
77551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines// Reencode the imm field of ld/st pos immediate.
78551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline uint32_t
79551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hineshelper_reencode_ldst_pos_imm (uint32_t pInst, uint32_t pImm)
80551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
81551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return (pInst & ~(get_mask(12) << 10)) | ((pImm & get_mask(12)) << 10);
82551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
83551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
84551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline uint32_t helper_get_upper32(Relocator::DWord pData)
85551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
86551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  if (llvm::sys::IsLittleEndianHost)
87551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    return pData >> 32;
88551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return pData & 0xFFFFFFFF;
89551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
90551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
91551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline void helper_put_upper32(uint32_t pData, Relocator::DWord& pDes)
92551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
93551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  *(reinterpret_cast<uint32_t*>(&pDes)) = pData;
94551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
95551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
96551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline Relocator::Address
97551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hineshelper_get_PLT_address(ResolveInfo& pSym, AArch64Relocator& pParent)
98551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
99551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  PLTEntryBase* plt_entry = pParent.getSymPLTMap().lookUp(pSym);
100551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  assert(NULL != plt_entry);
101551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return pParent.getTarget().getPLT().addr() + plt_entry->getOffset();
102551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
103551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
104551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline AArch64PLT1&
105551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hineshelper_PLT_init(Relocation& pReloc, AArch64Relocator& pParent)
106551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
107551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  // rsym - The relocation target symbol
108551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  ResolveInfo* rsym = pReloc.symInfo();
109551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  AArch64GNULDBackend& ld_backend = pParent.getTarget();
110551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  assert(NULL == pParent.getSymPLTMap().lookUp(*rsym));
111551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
112551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  AArch64PLT1* plt_entry = ld_backend.getPLT().create();
113551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  pParent.getSymPLTMap().record(*rsym, *plt_entry);
114551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
115551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  // initialize plt and the corresponding gotplt and dyn rel entry.
116551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  assert(NULL == pParent.getSymGOTPLTMap().lookUp(*rsym) &&
117551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines         "PLT entry not exist, but DynRel entry exist!");
118551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  AArch64GOTEntry* gotplt_entry = ld_backend.getGOTPLT().createGOTPLT();
119551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  pParent.getSymGOTPLTMap().record(*rsym, *gotplt_entry);
120551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
121551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  // init the corresponding rel entry in .rela.plt
122551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  Relocation& rel_entry = *ld_backend.getRelaPLT().create();
123551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  rel_entry.setType(R_AARCH64_JUMP_SLOT);
124551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  rel_entry.targetRef().assign(*gotplt_entry);
125551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  rel_entry.setSymInfo(rsym);
126551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return *plt_entry;
127551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
128551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
129551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines/// helper_DynRel - Get an relocation entry in .rela.dyn
130551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline Relocation&
131551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hineshelper_DynRela_init(ResolveInfo* pSym,
132551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                    Fragment& pFrag,
133551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                    uint64_t pOffset,
134551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                    Relocator::Type pType,
135551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                    AArch64Relocator& pParent)
136551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
137551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  AArch64GNULDBackend& ld_backend = pParent.getTarget();
138551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  Relocation& rel_entry = *ld_backend.getRelaDyn().create();
139551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  rel_entry.setType(pType);
140551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  rel_entry.targetRef().assign(pFrag, pOffset);
141551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  if (pType == R_AARCH64_RELATIVE || NULL == pSym)
142551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    rel_entry.setSymInfo(NULL);
143551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  else
144551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    rel_entry.setSymInfo(pSym);
145551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
146551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return rel_entry;
147551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
148551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
149551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines/// helper_use_relative_reloc - Check if symbol can use relocation
150551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines/// R_AARCH64_RELATIVE
151551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline bool
152551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hineshelper_use_relative_reloc(const ResolveInfo& pSym,
153551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                          const AArch64Relocator& pParent)
154551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
155551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
156551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  // if symbol is dynamic or undefine or preemptible
157551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  if (pSym.isDyn() ||
158551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines      pSym.isUndef() ||
159551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines      pParent.getTarget().isSymbolPreemptible(pSym))
160551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    return false;
161551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return true;
162551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
163551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
164551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline Relocator::Address
165551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hineshelper_get_GOT_address(ResolveInfo& pSym, AArch64Relocator& pParent)
166551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
167551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  AArch64GOTEntry* got_entry = pParent.getSymGOTMap().lookUp(pSym);
168551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  assert(NULL != got_entry);
169551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return pParent.getTarget().getGOT().addr() + got_entry->getOffset();
170551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
171551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
172551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline Relocator::Address
173551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hineshelper_GOT_ORG(AArch64Relocator& pParent)
174551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
175551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return pParent.getTarget().getGOT().addr();
176551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
177551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
178551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hinesstatic inline AArch64GOTEntry&
179551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hineshelper_GOT_init(Relocation& pReloc, bool pHasRel, AArch64Relocator& pParent)
180551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines{
181551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  // rsym - The relocation target symbol
182551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  ResolveInfo* rsym = pReloc.symInfo();
183551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  AArch64GNULDBackend& ld_backend = pParent.getTarget();
184551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  assert(NULL == pParent.getSymGOTMap().lookUp(*rsym));
185551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
186551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  AArch64GOTEntry* got_entry = ld_backend.getGOT().createGOT();
187551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  pParent.getSymGOTMap().record(*rsym, *got_entry);
188551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
189551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  // If we first get this GOT entry, we should initialize it.
190551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  if (!pHasRel) {
191551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    // No corresponding dynamic relocation, initialize to the symbol value.
192551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    got_entry->setValue(AArch64Relocator::SymVal);
193551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  }
194551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  else {
195551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    // Initialize got_entry content and the corresponding dynamic relocation.
196551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    if (helper_use_relative_reloc(*rsym, pParent)) {
197551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines      got_entry->setValue(AArch64Relocator::SymVal);
198551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines      Relocation& rel_entry = helper_DynRela_init(rsym, *got_entry, 0x0,
199551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines                                                  R_AARCH64_RELATIVE, pParent);
200551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines      rel_entry.setAddend(AArch64Relocator::SymVal);
201551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines      pParent.getRelRelMap().record(pReloc, rel_entry);
202551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    }
203551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    else {
204551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines      helper_DynRela_init(rsym, *got_entry, 0x0, R_AARCH64_GLOB_DAT, pParent);
205551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines      got_entry->setValue(0);
206551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    }
207551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  }
208551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  return *got_entry;
209551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
210551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
211551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines}
212551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines#endif
213