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