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//===----------------------------------------------------------------------===// 95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/Host.h> 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ErrorHandling.h> 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/ELFDynamic.h> 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/GNULDBackend.h> 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFFileFormat.h> 1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LinkerConfig.h> 1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MsgHandling.h> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace elf_dynamic; 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// elf_dynamic::EntryIF 22d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===// 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoEntryIF::EntryIF() 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoEntryIF::~EntryIF() 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ELFDynamic 33d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao//===----------------------------------------------------------------------===// 34d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei LiaoELFDynamic::ELFDynamic(const GNULDBackend& pParent, 35d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao const LinkerConfig& pConfig) 36d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao : 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()) 406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pEntryFactory = new Entry<32, true>(); 416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else if (m_Config.targets().is64Bits()) { 426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (m_Config.targets().isLittleEndian()) 436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_pEntryFactory = new 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 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFDynamic::~ELFDynamic() 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != m_pEntryFactory) 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete m_pEntryFactory; 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao EntryListType::iterator entry, entryEnd = m_EntryList.end(); 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (entry = m_EntryList.begin(); entry != entryEnd; ++entry) { 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != *entry) 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete (*entry); 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entryEnd = m_NeedList.end(); 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (entry = m_NeedList.begin(); entry != entryEnd; ++entry) { 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != *entry) 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao delete (*entry); 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t ELFDynamic::size() const 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return (m_NeedList.size() + m_EntryList.size()); 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t ELFDynamic::numOfBytes() const 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return size()*entrySize(); 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t ELFDynamic::entrySize() const 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_pEntryFactory->size(); 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFDynamic::reserveOne(uint64_t pTag) 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(NULL != m_pEntryFactory); 876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines m_EntryList.push_back(m_pEntryFactory->clone()); 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFDynamic::applyOne(uint64_t pTag, uint64_t pValue) 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(m_Idx < m_EntryList.size()); 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_EntryList[m_Idx]->setValue(pTag, pValue); 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++m_Idx; 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// reserveEntries - reserve entries 98d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaovoid ELFDynamic::reserveEntries(const ELFFileFormat& pFormat) 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 100d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (LinkerConfig::DynObj == m_Config.codeGenType()) { 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_SONAME); // DT_SONAME 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 103d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().Bsymbolic()) 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_SYMBOLIC); // DT_SYMBOLIC 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasInit()) 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_INIT); // DT_INIT 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasFini()) 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_FINI); // DT_FINI 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 113551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (pFormat.hasPreInitArray()) { 114551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines reserveOne(llvm::ELF::DT_PREINIT_ARRAY); // DT_PREINIT_ARRAY 115551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines reserveOne(llvm::ELF::DT_PREINIT_ARRAYSZ); // DT_PREINIT_ARRAYSZ 116551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 117551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasInitArray()) { 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_INIT_ARRAY); // DT_INIT_ARRAY 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_INIT_ARRAYSZ); // DT_INIT_ARRAYSZ 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasFiniArray()) { 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_FINI_ARRAY); // DT_FINI_ARRAY 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_FINI_ARRAYSZ); // DT_FINI_ARRAYSZ 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasHashTab()) 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_HASH); // DT_HASH 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // FIXME: use llvm enum constant 1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pFormat.hasGNUHashTab()) 1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines reserveOne(0x6ffffef5); // DT_GNU_HASH 1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasDynSymTab()) { 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_SYMTAB); // DT_SYMTAB 1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_SYMENT); // DT_SYMENT 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasDynStrTab()) { 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_STRTAB); // DT_STRTAB 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_STRSZ); // DT_STRSZ 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveTargetEntries(pFormat); // DT_PLTGOT 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pFormat.hasRelPlt() || pFormat.hasRelaPlt()) { 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_PLTREL); // DT_PLTREL 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_JMPREL); // DT_JMPREL 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_PLTRELSZ); // DT_PLTRELSZ 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasRelDyn()) { 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_REL); // DT_REL 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_RELSZ); // DT_RELSZ 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_RELENT); // DT_RELENT 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasRelaDyn()) { 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_RELA); // DT_RELA 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_RELASZ); // DT_RELASZ 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_RELAENT); // DT_RELAENT 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 164affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t dt_flags = 0x0; 1666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (m_Config.options().hasOrigin()) 1676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dt_flags |= llvm::ELF::DF_ORIGIN; 1686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (m_Config.options().Bsymbolic()) 1696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dt_flags |= llvm::ELF::DF_SYMBOLIC; 1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (m_Config.options().hasNow()) 1716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dt_flags |= llvm::ELF::DF_BIND_NOW; 1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (m_Backend.hasTextRel()) 1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dt_flags |= llvm::ELF::DF_TEXTREL; 1746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (m_Backend.hasStaticTLS() && 1756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines (LinkerConfig::DynObj == m_Config.codeGenType())) 1766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines dt_flags |= llvm::ELF::DF_STATIC_TLS; 1776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if ((m_Config.options().hasNewDTags() && 0x0 != dt_flags) || 1796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0 != (dt_flags & llvm::ELF::DF_STATIC_TLS)) 180affc150dc44fab1911775a49636d0ce85333b634Zonr Chang reserveOne(llvm::ELF::DT_FLAGS); // DT_FLAGS 181affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 18222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_Backend.hasTextRel()) 18322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao reserveOne(llvm::ELF::DT_TEXTREL); // DT_TEXTREL 18422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 185d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().hasNow() || 186d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_Config.options().hasLoadFltr() || 187d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_Config.options().hasOrigin() || 188d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_Config.options().hasInterPose() || 189d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_Config.options().hasNoDefaultLib() || 190d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_Config.options().hasNoDump() || 191d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_Config.options().Bgroup() || 192d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao ((LinkerConfig::DynObj == m_Config.codeGenType()) && 193d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (m_Config.options().hasNoDelete() || 194d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_Config.options().hasInitFirst() || 195d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_Config.options().hasNoDLOpen()))) { 196affc150dc44fab1911775a49636d0ce85333b634Zonr Chang reserveOne(llvm::ELF::DT_FLAGS_1); // DT_FLAGS_1 197affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 198affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao reserveOne(llvm::ELF::DT_NULL); // for DT_NULL 2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// applyEntries - apply entries 203d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liaovoid ELFDynamic::applyEntries(const ELFFileFormat& pFormat) 2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 205d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (LinkerConfig::DynObj == m_Config.codeGenType() && 206d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao m_Config.options().Bsymbolic()) { 2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_SYMBOLIC, 0x0); // DT_SYMBOLIC 2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasInit()) 2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_INIT, pFormat.getInit().addr()); // DT_INIT 2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasFini()) 2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_FINI, pFormat.getFini().addr()); // DT_FINI 2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 216551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines if (pFormat.hasPreInitArray()) { 217551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // DT_PREINIT_ARRAY 218551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines applyOne(llvm::ELF::DT_PREINIT_ARRAY, pFormat.getPreInitArray().addr()); 219551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines // DT_PREINIT_ARRAYSZ 220551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines applyOne(llvm::ELF::DT_PREINIT_ARRAYSZ, pFormat.getPreInitArray().size()); 221551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines } 222551ae4ebd3e9d137ea668fb83ae4a55b8cfba451Stephen Hines 2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasInitArray()) { 2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // DT_INIT_ARRAY 2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_INIT_ARRAY, pFormat.getInitArray().addr()); 2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // DT_INIT_ARRAYSZ 2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_INIT_ARRAYSZ, pFormat.getInitArray().size()); 2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasFiniArray()) { 2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // DT_FINI_ARRAY 2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_FINI_ARRAY, pFormat.getFiniArray().addr()); 2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // DT_FINI_ARRAYSZ 2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_FINI_ARRAYSZ, pFormat.getFiniArray().size()); 2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasHashTab()) 2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_HASH, pFormat.getHashTab().addr()); // DT_HASH 2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // FIXME: use llvm enum constant 2436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pFormat.hasGNUHashTab()) 2446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines applyOne(0x6ffffef5, pFormat.getGNUHashTab().addr()); // DT_GNU_HASH 2456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasDynSymTab()) { 2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_SYMTAB, pFormat.getDynSymTab().addr()); // DT_SYMTAB 2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_SYMENT, symbolSize()); // DT_SYMENT 2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasDynStrTab()) { 2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_STRTAB, pFormat.getDynStrTab().addr()); // DT_STRTAB 2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_STRSZ, pFormat.getDynStrTab().size()); // DT_STRSZ 2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyTargetEntries(pFormat); // DT_PLTGOT 2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasRelPlt()) { 2596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines applyOne(llvm::ELF::DT_PLTREL, llvm::ELF::DT_REL); // DT_PLTREL 2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_JMPREL, pFormat.getRelPlt().addr()); // DT_JMPREL 2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_PLTRELSZ, pFormat.getRelPlt().size()); // DT_PLTRELSZ 2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (pFormat.hasRelaPlt()) { 2646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines applyOne(llvm::ELF::DT_PLTREL, llvm::ELF::DT_RELA); // DT_PLTREL 2656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines applyOne(llvm::ELF::DT_JMPREL, pFormat.getRelaPlt().addr()); // DT_JMPREL 2666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines applyOne(llvm::ELF::DT_PLTRELSZ, pFormat.getRelaPlt().size()); // DT_PLTRELSZ 2676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasRelDyn()) { 2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_REL, pFormat.getRelDyn().addr()); // DT_REL 2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_RELSZ, pFormat.getRelDyn().size()); // DT_RELSZ 2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_RELENT, m_pEntryFactory->relSize()); // DT_RELENT 2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pFormat.hasRelaDyn()) { 2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_RELA, pFormat.getRelaDyn().addr()); // DT_RELA 2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_RELASZ, pFormat.getRelaDyn().size()); // DT_RELASZ 2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_RELAENT, m_pEntryFactory->relaSize()); // DT_RELAENT 2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 28122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_Backend.hasTextRel()) { 28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao applyOne(llvm::ELF::DT_TEXTREL, 0x0); // DT_TEXTREL 28322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 284d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().warnSharedTextrel() && 285d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao LinkerConfig::DynObj == m_Config.codeGenType()) 28622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao mcld::warning(mcld::diag::warn_shared_textrel); 28722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint64_t dt_flags = 0x0; 290d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().hasOrigin()) 291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dt_flags |= llvm::ELF::DF_ORIGIN; 292d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().Bsymbolic()) 293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dt_flags |= llvm::ELF::DF_SYMBOLIC; 294d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().hasNow()) 295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dt_flags |= llvm::ELF::DF_BIND_NOW; 29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_Backend.hasTextRel()) 29722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dt_flags |= llvm::ELF::DF_TEXTREL; 29822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (m_Backend.hasStaticTLS() && 299d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao (LinkerConfig::DynObj == m_Config.codeGenType())) 30022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao dt_flags |= llvm::ELF::DF_STATIC_TLS; 3016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if ((m_Config.options().hasNewDTags() && 0x0 != dt_flags) || 3036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0 != (dt_flags & llvm::ELF::DF_STATIC_TLS)) 304affc150dc44fab1911775a49636d0ce85333b634Zonr Chang applyOne(llvm::ELF::DT_FLAGS, dt_flags); // DT_FLAGS 305affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint64_t dt_flags_1 = 0x0; 307d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().hasNow()) 308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dt_flags_1 |= llvm::ELF::DF_1_NOW; 309d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().hasLoadFltr()) 310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dt_flags_1 |= llvm::ELF::DF_1_LOADFLTR; 311d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().hasOrigin()) 312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dt_flags_1 |= llvm::ELF::DF_1_ORIGIN; 313d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().hasInterPose()) 314affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dt_flags_1 |= llvm::ELF::DF_1_INTERPOSE; 315d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().hasNoDefaultLib()) 316affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dt_flags_1 |= llvm::ELF::DF_1_NODEFLIB; 317d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().hasNoDump()) 318affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dt_flags_1 |= llvm::ELF::DF_1_NODUMP; 319d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().Bgroup()) 320affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dt_flags_1 |= llvm::ELF::DF_1_GROUP; 321d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (LinkerConfig::DynObj == m_Config.codeGenType()) { 322d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().hasNoDelete()) 323affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dt_flags_1 |= llvm::ELF::DF_1_NODELETE; 324d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().hasInitFirst()) 325affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dt_flags_1 |= llvm::ELF::DF_1_INITFIRST; 326d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao if (m_Config.options().hasNoDLOpen()) 327affc150dc44fab1911775a49636d0ce85333b634Zonr Chang dt_flags_1 |= llvm::ELF::DF_1_NOOPEN; 328affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 329affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (0x0 != dt_flags_1) 330affc150dc44fab1911775a49636d0ce85333b634Zonr Chang applyOne(llvm::ELF::DT_FLAGS_1, dt_flags_1); // DT_FLAGS_1 331affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_NULL, 0x0); // for DT_NULL 3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// symbolSize 3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t ELFDynamic::symbolSize() const 3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return m_pEntryFactory->symbolSize(); 3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// reserveNeedEntry - reserve on DT_NEED entry. 3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFDynamic::reserveNeedEntry() 3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao m_NeedList.push_back(m_pEntryFactory->clone()); 3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emit 3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFDynamic::emit(const LDSection& pSection, MemoryRegion& pRegion) const 3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pRegion.size() < pSection.size()) { 3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(llvm::Twine("the given memory is smaller") + 3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::Twine(" than the section's demaind.\n")); 3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 35587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint8_t* address = (uint8_t*)pRegion.begin(); 3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao EntryListType::const_iterator entry, entryEnd = m_NeedList.end(); 3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (entry = m_NeedList.begin(); entry != entryEnd; ++entry) 3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao address += (*entry)->emit(address); 3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entryEnd = m_EntryList.end(); 3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (entry = m_EntryList.begin(); entry != entryEnd; ++entry) 3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao address += (*entry)->emit(address); 3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFDynamic::applySoname(uint64_t pStrTabIdx) 3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao applyOne(llvm::ELF::DT_SONAME, pStrTabIdx); // DT_SONAME 3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 370