1551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines//===- ARMGOT.cpp ---------------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include "ARMGOT.h"
10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSection.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDFileFormat.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h"
14cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao
1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <llvm/Support/Casting.h>
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace {
1837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst unsigned int ARMGOT0Num = 3;
1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // end of anonymous namespace
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ARMGOT
2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoARMGOT::ARMGOT(LDSection& pSection)
2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : GOT(pSection), m_pGOTPLTFront(NULL), m_pGOTFront(NULL) {
2787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // create GOT0, and put them into m_SectionData immediately
2887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (unsigned int i = 0; i < ARMGOT0Num; ++i)
2987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    new ARMGOTEntry(0, m_SectionData);
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3237b74a387bb3993387029859c2d9d051c41c724eStephen HinesARMGOT::~ARMGOT() {
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesbool ARMGOT::hasGOT1() const {
3687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return ((!m_GOT.empty()) || (!m_GOTPLT.empty()));
37d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
38d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
3937b74a387bb3993387029859c2d9d051c41c724eStephen HinesARMGOTEntry* ARMGOT::createGOT() {
4087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ARMGOTEntry* entry = new ARMGOTEntry(0, NULL);
4187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_GOT.push_back(entry);
4287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return entry;
43d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao}
44d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao
4537b74a387bb3993387029859c2d9d051c41c724eStephen HinesARMGOTEntry* ARMGOT::createGOTPLT() {
4687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  ARMGOTEntry* entry = new ARMGOTEntry(0, NULL);
4787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_GOTPLT.push_back(entry);
4887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  return entry;
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ARMGOT::finalizeSectionSize() {
5287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint32_t offset = 0;
5387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionData::FragmentListType& frag_list = m_SectionData->getFragmentList();
5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // setup GOT0 offset
5587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionData::iterator frag, fragEnd = m_SectionData->end();
5687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  for (frag = m_SectionData->begin(); frag != fragEnd; ++frag) {
5787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    frag->setOffset(offset);
5887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    offset += frag->size();
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // push GOTPLT into the SectionData and setup the offset
6287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (!m_GOTPLT.empty()) {
6387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    m_pGOTPLTFront = m_GOTPLT.front();
6487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    entry_iterator it, end = m_GOTPLT.end();
6587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (it = m_GOTPLT.begin(); it != end; ++it) {
6687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      ARMGOTEntry* entry = *it;
6787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      frag_list.push_back(entry);
6887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      entry->setParent(m_SectionData);
6987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      entry->setOffset(offset);
7087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      offset += entry->size();
7187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
7222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
7387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_GOTPLT.clear();
7487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines
7587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // push GOT into the SectionData and setup the offset
7687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (!m_GOT.empty()) {
7787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    m_pGOTFront = m_GOT.front();
7887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    entry_iterator it, end = m_GOT.end();
7987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    for (it = m_GOT.begin(); it != end; ++it) {
8087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      ARMGOTEntry* entry = *it;
8187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      frag_list.push_back(entry);
8287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      entry->setParent(m_SectionData);
8387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      entry->setOffset(offset);
8487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines      offset += entry->size();
8587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    }
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
8787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_GOT.clear();
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  // set section size
9087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  m_Section.setSize(offset);
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ARMGOT::applyGOT0(uint64_t pAddress) {
9437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  llvm::cast<ARMGOTEntry>(*(m_SectionData->getFragmentList().begin()))
9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines      .setValue(pAddress);
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
9837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ARMGOT::applyGOTPLT(uint64_t pPLTBase) {
9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (m_pGOTPLTFront == NULL)
10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    return;
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  SectionData::iterator entry(m_pGOTPLTFront);
10322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  SectionData::iterator e_end;
10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (m_pGOTFront == NULL)
10522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    e_end = m_SectionData->end();
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  else
10787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines    e_end = SectionData::iterator(m_pGOTFront);
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
10922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  while (entry != e_end) {
110d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    llvm::cast<ARMGOTEntry>(entry)->setValue(pPLTBase);
11122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    ++entry;
11222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
11537b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t ARMGOT::emit(MemoryRegion& pRegion) {
11687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  uint32_t* buffer = reinterpret_cast<uint32_t*>(pRegion.begin());
1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
118d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  ARMGOTEntry* got = NULL;
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  uint64_t result = 0x0;
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  for (iterator it = begin(), ie = end(); it != ie; ++it, ++buffer) {
12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    got = &(llvm::cast<ARMGOTEntry>((*it)));
12237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    *buffer = static_cast<uint32_t>(got->getValue());
12337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    result += ARMGOTEntry::EntrySize;
1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return result;
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
127affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
12837b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
129