15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ELFDynamic.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//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFFileFormat.h"
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h"
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/ELFDynamic.h"
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNULDBackend.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h"
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines
155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ErrorHandling.h>
1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <llvm/Support/Host.h>
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
1937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace elf_dynamic {
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// elf_dynamic::EntryIF
23d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===//
2437b74a387bb3993387029859c2d9d051c41c724eStephen HinesEntryIF::EntryIF() {
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2737b74a387bb3993387029859c2d9d051c41c724eStephen HinesEntryIF::~EntryIF() {
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace elf_dynamic
3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines
325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ELFDynamic
34d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===//
3537b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFDynamic::ELFDynamic(const GNULDBackend& pParent, const LinkerConfig& pConfig)
3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    : m_pEntryFactory(NULL), m_Backend(pParent), m_Config(pConfig), m_Idx(0) {
376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  // FIXME: support big-endian machine.
386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (m_Config.targets().is32Bits()) {
396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (m_Config.targets().isLittleEndian())
4037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pEntryFactory = new elf_dynamic::Entry<32, true>();
416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  } else if (m_Config.targets().is64Bits()) {
426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    if (m_Config.targets().isLittleEndian())
4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_pEntryFactory = new elf_dynamic::Entry<64, true>();
446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  } else {
456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    fatal(diag::unsupported_bitclass) << m_Config.targets().triple().str()
466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines                                      << m_Config.targets().bitclass();
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5037b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFDynamic::~ELFDynamic() {
5137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (m_pEntryFactory != NULL)
525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    delete m_pEntryFactory;
535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  EntryListType::iterator entry, entryEnd = m_EntryList.end();
555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (entry = m_EntryList.begin(); entry != entryEnd; ++entry) {
5637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    if (*entry != NULL)
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      delete (*entry);
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entryEnd = m_NeedList.end();
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (entry = m_NeedList.begin(); entry != entryEnd; ++entry) {
6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    if (*entry != NULL)
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao      delete (*entry);
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
6737b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t ELFDynamic::size() const {
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return (m_NeedList.size() + m_EntryList.size());
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7137b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t ELFDynamic::numOfBytes() const {
7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  return size() * entrySize();
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7537b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t ELFDynamic::entrySize() const {
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pEntryFactory->size();
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
7937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ELFDynamic::reserveOne(uint64_t pTag) {
8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  assert(m_pEntryFactory != NULL);
816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  m_EntryList.push_back(m_pEntryFactory->clone());
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ELFDynamic::applyOne(uint64_t pTag, uint64_t pValue) {
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  assert(m_Idx < m_EntryList.size());
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_EntryList[m_Idx]->setValue(pTag, pValue);
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ++m_Idx;
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// reserveEntries - reserve entries
9137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ELFDynamic::reserveEntries(const ELFFileFormat& pFormat) {
92d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (LinkerConfig::DynObj == m_Config.codeGenType()) {
9337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_SONAME);
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
95d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (m_Config.options().Bsymbolic())
9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines      reserveOne(llvm::ELF::DT_SYMBOLIC);
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasInit())
10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_INIT);
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasFini())
10337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_FINI);
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
105551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  if (pFormat.hasPreInitArray()) {
10637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_PREINIT_ARRAY);
10737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_PREINIT_ARRAYSZ);
108551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  }
109551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasInitArray()) {
11137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_INIT_ARRAY);
11237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_INIT_ARRAYSZ);
1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasFiniArray()) {
11637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_FINI_ARRAY);
11737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_FINI_ARRAYSZ);
1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasHashTab())
12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_HASH);
1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pFormat.hasGNUHashTab())
12437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_GNU_HASH);
1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasDynSymTab()) {
12737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_SYMTAB);
12837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_SYMENT);
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasDynStrTab()) {
13237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_STRTAB);
13337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_STRSZ);
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  reserveTargetEntries(pFormat);
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
13887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines  if (pFormat.hasRelPlt() || pFormat.hasRelaPlt()) {
13937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_PLTREL);
14037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_JMPREL);
14137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_PLTRELSZ);
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasRelDyn()) {
14537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_REL);
14637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_RELSZ);
14737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_RELENT);
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasRelaDyn()) {
15137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_RELA);
15237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_RELASZ);
15337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_RELAENT);
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
155affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
1566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  uint64_t dt_flags = 0x0;
1576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (m_Config.options().hasOrigin())
1586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    dt_flags |= llvm::ELF::DF_ORIGIN;
1596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (m_Config.options().Bsymbolic())
1606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    dt_flags |= llvm::ELF::DF_SYMBOLIC;
1616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (m_Config.options().hasNow())
1626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    dt_flags |= llvm::ELF::DF_BIND_NOW;
1636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (m_Backend.hasTextRel())
1646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    dt_flags |= llvm::ELF::DF_TEXTREL;
1656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (m_Backend.hasStaticTLS() &&
1666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines      (LinkerConfig::DynObj == m_Config.codeGenType()))
1676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines    dt_flags |= llvm::ELF::DF_STATIC_TLS;
1686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
16937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if ((m_Config.options().hasNewDTags() && dt_flags != 0x0) ||
17037b74a387bb3993387029859c2d9d051c41c724eStephen Hines      (dt_flags & llvm::ELF::DF_STATIC_TLS) != 0x0)
17137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_FLAGS);
172affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
17322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_Backend.hasTextRel())
17437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_TEXTREL);
17537b74a387bb3993387029859c2d9d051c41c724eStephen Hines
17637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (m_Config.options().hasNow() || m_Config.options().hasLoadFltr() ||
17737b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_Config.options().hasOrigin() || m_Config.options().hasInterPose() ||
17837b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_Config.options().hasNoDefaultLib() || m_Config.options().hasNoDump() ||
17937b74a387bb3993387029859c2d9d051c41c724eStephen Hines      m_Config.options().Bgroup() ||
180d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      ((LinkerConfig::DynObj == m_Config.codeGenType()) &&
18137b74a387bb3993387029859c2d9d051c41c724eStephen Hines       (m_Config.options().hasNoDelete() || m_Config.options().hasInitFirst() ||
182d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        m_Config.options().hasNoDLOpen()))) {
18337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    reserveOne(llvm::ELF::DT_FLAGS_1);
184affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
185affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
18604c59f3b00def22b7c75f5a490c323cec58a7c71Stephen Hines  unsigned num_spare_dtags = m_Config.options().getNumSpareDTags();
18704c59f3b00def22b7c75f5a490c323cec58a7c71Stephen Hines  for (unsigned i = 0; i < num_spare_dtags; ++i) {
18804c59f3b00def22b7c75f5a490c323cec58a7c71Stephen Hines    reserveOne(llvm::ELF::DT_NULL);
18904c59f3b00def22b7c75f5a490c323cec58a7c71Stephen Hines  }
1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// applyEntries - apply entries
19337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ELFDynamic::applyEntries(const ELFFileFormat& pFormat) {
194d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (LinkerConfig::DynObj == m_Config.codeGenType() &&
195d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      m_Config.options().Bsymbolic()) {
19637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_SYMBOLIC, 0x0);
1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasInit())
20037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_INIT, pFormat.getInit().addr());
2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasFini())
20337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_FINI, pFormat.getFini().addr());
2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
205551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  if (pFormat.hasPreInitArray()) {
206551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    applyOne(llvm::ELF::DT_PREINIT_ARRAY, pFormat.getPreInitArray().addr());
207551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines    applyOne(llvm::ELF::DT_PREINIT_ARRAYSZ, pFormat.getPreInitArray().size());
208551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines  }
209551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines
2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasInitArray()) {
2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    applyOne(llvm::ELF::DT_INIT_ARRAY, pFormat.getInitArray().addr());
2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    applyOne(llvm::ELF::DT_INIT_ARRAYSZ, pFormat.getInitArray().size());
2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasFiniArray()) {
2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    applyOne(llvm::ELF::DT_FINI_ARRAY, pFormat.getFiniArray().addr());
2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    applyOne(llvm::ELF::DT_FINI_ARRAYSZ, pFormat.getFiniArray().size());
2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasHashTab())
22137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_HASH, pFormat.getHashTab().addr());
2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  if (pFormat.hasGNUHashTab())
22437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_GNU_HASH, pFormat.getGNUHashTab().addr());
2256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasDynSymTab()) {
22737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_SYMTAB, pFormat.getDynSymTab().addr());
22837b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_SYMENT, symbolSize());
2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasDynStrTab()) {
23237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_STRTAB, pFormat.getDynStrTab().addr());
23337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_STRSZ, pFormat.getDynStrTab().size());
2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
23637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  applyTargetEntries(pFormat);
2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasRelPlt()) {
23937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_PLTREL, llvm::ELF::DT_REL);
24037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_JMPREL, pFormat.getRelPlt().addr());
24137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_PLTRELSZ, pFormat.getRelPlt().size());
24237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  } else if (pFormat.hasRelaPlt()) {
24337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_PLTREL, llvm::ELF::DT_RELA);
24437b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_JMPREL, pFormat.getRelaPlt().addr());
24537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_PLTRELSZ, pFormat.getRelaPlt().size());
2466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines  }
2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasRelDyn()) {
24937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_REL, pFormat.getRelDyn().addr());
25037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_RELSZ, pFormat.getRelDyn().size());
25137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_RELENT, m_pEntryFactory->relSize());
2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pFormat.hasRelaDyn()) {
25537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_RELA, pFormat.getRelaDyn().addr());
25637b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_RELASZ, pFormat.getRelaDyn().size());
25737b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_RELAENT, m_pEntryFactory->relaSize());
2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
26022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_Backend.hasTextRel()) {
26137b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_TEXTREL, 0x0);
26222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
263d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (m_Config.options().warnSharedTextrel() &&
264d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao        LinkerConfig::DynObj == m_Config.codeGenType())
26522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao      mcld::warning(mcld::diag::warn_shared_textrel);
26622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  }
26722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t dt_flags = 0x0;
269d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (m_Config.options().hasOrigin())
270affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dt_flags |= llvm::ELF::DF_ORIGIN;
271d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (m_Config.options().Bsymbolic())
272affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dt_flags |= llvm::ELF::DF_SYMBOLIC;
273d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (m_Config.options().hasNow())
274affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dt_flags |= llvm::ELF::DF_BIND_NOW;
27522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_Backend.hasTextRel())
27622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    dt_flags |= llvm::ELF::DF_TEXTREL;
27722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  if (m_Backend.hasStaticTLS() &&
278d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao      (LinkerConfig::DynObj == m_Config.codeGenType()))
27922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    dt_flags |= llvm::ELF::DF_STATIC_TLS;
2806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines
28137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if ((m_Config.options().hasNewDTags() && dt_flags != 0x0) ||
28237b74a387bb3993387029859c2d9d051c41c724eStephen Hines      (dt_flags & llvm::ELF::DF_STATIC_TLS) != 0)
28337b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_FLAGS, dt_flags);
284affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  uint64_t dt_flags_1 = 0x0;
286d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (m_Config.options().hasNow())
287affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dt_flags_1 |= llvm::ELF::DF_1_NOW;
288d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (m_Config.options().hasLoadFltr())
289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dt_flags_1 |= llvm::ELF::DF_1_LOADFLTR;
290d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (m_Config.options().hasOrigin())
291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dt_flags_1 |= llvm::ELF::DF_1_ORIGIN;
292d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (m_Config.options().hasInterPose())
293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dt_flags_1 |= llvm::ELF::DF_1_INTERPOSE;
294d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (m_Config.options().hasNoDefaultLib())
295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dt_flags_1 |= llvm::ELF::DF_1_NODEFLIB;
296d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (m_Config.options().hasNoDump())
297affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dt_flags_1 |= llvm::ELF::DF_1_NODUMP;
298d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (m_Config.options().Bgroup())
299affc150dc44fab1911775a49636d0ce85333b634Zonr Chang    dt_flags_1 |= llvm::ELF::DF_1_GROUP;
300d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao  if (LinkerConfig::DynObj == m_Config.codeGenType()) {
301d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (m_Config.options().hasNoDelete())
302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      dt_flags_1 |= llvm::ELF::DF_1_NODELETE;
303d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (m_Config.options().hasInitFirst())
304affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      dt_flags_1 |= llvm::ELF::DF_1_INITFIRST;
305d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao    if (m_Config.options().hasNoDLOpen())
306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang      dt_flags_1 |= llvm::ELF::DF_1_NOOPEN;
307affc150dc44fab1911775a49636d0ce85333b634Zonr Chang  }
30837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  if (dt_flags_1 != 0x0)
30937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    applyOne(llvm::ELF::DT_FLAGS_1, dt_flags_1);
310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang
31104c59f3b00def22b7c75f5a490c323cec58a7c71Stephen Hines  unsigned num_spare_dtags = m_Config.options().getNumSpareDTags();
31204c59f3b00def22b7c75f5a490c323cec58a7c71Stephen Hines  for (unsigned i = 0; i < num_spare_dtags; ++i) {
31304c59f3b00def22b7c75f5a490c323cec58a7c71Stephen Hines    applyOne(llvm::ELF::DT_NULL, 0x0);
31404c59f3b00def22b7c75f5a490c323cec58a7c71Stephen Hines  }
3155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// symbolSize
31837b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t ELFDynamic::symbolSize() const {
3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  return m_pEntryFactory->symbolSize();
3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// reserveNeedEntry - reserve on DT_NEED entry.
32337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ELFDynamic::reserveNeedEntry() {
3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  m_NeedList.push_back(m_pEntryFactory->clone());
3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emit
32837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ELFDynamic::emit(const LDSection& pSection, MemoryRegion& pRegion) const {
3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  if (pRegion.size() < pSection.size()) {
3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    llvm::report_fatal_error(llvm::Twine("the given memory is smaller") +
3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                             llvm::Twine(" than the section's demaind.\n"));
3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  }
3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
33437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  uint8_t* address = reinterpret_cast<uint8_t*>(pRegion.begin());
3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  EntryListType::const_iterator entry, entryEnd = m_NeedList.end();
3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (entry = m_NeedList.begin(); entry != entryEnd; ++entry)
3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    address += (*entry)->emit(address);
3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  entryEnd = m_EntryList.end();
3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  for (entry = m_EntryList.begin(); entry != entryEnd; ++entry)
3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao    address += (*entry)->emit(address);
3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
34437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ELFDynamic::applySoname(uint64_t pStrTabIdx) {
34537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  applyOne(llvm::ELF::DT_SONAME, pStrTabIdx);
3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}
3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
34837b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
349