1 //===- X86GOTPLT.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 #include "X86GOTPLT.h"
10 #include "X86PLT.h"
11 
12 #include "mcld/LD/LDSection.h"
13 #include "mcld/LD/LDFileFormat.h"
14 #include "mcld/Support/MsgHandling.h"
15 
16 #include <llvm/Support/Casting.h>
17 
18 namespace mcld {
19 
20 //===----------------------------------------------------------------------===//
21 // X86_32GOTPLT
22 //===----------------------------------------------------------------------===//
X86_32GOTPLT(LDSection & pSection)23 X86_32GOTPLT::X86_32GOTPLT(LDSection& pSection) : X86_32GOT(pSection) {
24   // create GOT0 entries
25   for (size_t i = 0; i < X86GOTPLT0Num; ++i)
26     create();
27 }
28 
~X86_32GOTPLT()29 X86_32GOTPLT::~X86_32GOTPLT() {
30 }
31 
hasGOT1() const32 bool X86_32GOTPLT::hasGOT1() const {
33   return (m_SectionData->size() > X86GOTPLT0Num);
34 }
35 
applyGOT0(uint64_t pAddress)36 void X86_32GOTPLT::applyGOT0(uint64_t pAddress) {
37   llvm::cast<X86_32GOTEntry>(*(m_SectionData->getFragmentList().begin()))
38       .setValue(pAddress);
39 }
40 
applyAllGOTPLT(const X86PLT & pPLT)41 void X86_32GOTPLT::applyAllGOTPLT(const X86PLT& pPLT) {
42   iterator it = begin();
43   // skip GOT0
44   for (size_t i = 0; i < X86GOTPLT0Num; ++i)
45     ++it;
46   // address of corresponding plt entry
47   uint64_t plt_addr = pPLT.addr() + pPLT.getPLT0Size();
48   for (; it != end(); ++it) {
49     llvm::cast<X86_32GOTEntry>(*it).setValue(plt_addr + 6);
50     plt_addr += pPLT.getPLT1Size();
51   }
52 }
53 
54 //===----------------------------------------------------------------------===//
55 // X86_64GOTPLT
56 //===----------------------------------------------------------------------===//
X86_64GOTPLT(LDSection & pSection)57 X86_64GOTPLT::X86_64GOTPLT(LDSection& pSection) : X86_64GOT(pSection) {
58   for (size_t i = 0; i < X86GOTPLT0Num; ++i)
59     create();
60 }
61 
~X86_64GOTPLT()62 X86_64GOTPLT::~X86_64GOTPLT() {
63 }
64 
hasGOT1() const65 bool X86_64GOTPLT::hasGOT1() const {
66   return (m_SectionData->size() > X86GOTPLT0Num);
67 }
68 
applyGOT0(uint64_t pAddress)69 void X86_64GOTPLT::applyGOT0(uint64_t pAddress) {
70   llvm::cast<X86_64GOTEntry>(*(m_SectionData->getFragmentList().begin()))
71       .setValue(pAddress);
72 }
73 
applyAllGOTPLT(const X86PLT & pPLT)74 void X86_64GOTPLT::applyAllGOTPLT(const X86PLT& pPLT) {
75   iterator it = begin();
76   // skip GOT0
77   for (size_t i = 0; i < X86GOTPLT0Num; ++i)
78     ++it;
79   // address of corresponding plt entry
80   uint64_t plt_addr = pPLT.addr() + pPLT.getPLT0Size();
81   for (; it != end(); ++it) {
82     llvm::cast<X86_64GOTEntry>(*it).setValue(plt_addr + 6);
83     plt_addr += pPLT.getPLT1Size();
84   }
85 }
86 
87 }  // namespace mcld
88