size_t MipsELFDynamic::getSymTabNum(const ELFFileFormat& pFormat) const { if (!pFormat.hasDynSymTab()) return 0; const LDSection& dynsym = pFormat.getDynSymTab(); return dynsym.size() / symbolSize(); }
/// reserveEntries - reserve entries void ELFDynamic::reserveEntries(const ELFFileFormat& pFormat) { if (LinkerConfig::DynObj == m_Config.codeGenType()) { reserveOne(llvm::ELF::DT_SONAME); // DT_SONAME if (m_Config.options().Bsymbolic()) reserveOne(llvm::ELF::DT_SYMBOLIC); // DT_SYMBOLIC } if (pFormat.hasInit()) reserveOne(llvm::ELF::DT_INIT); // DT_INIT if (pFormat.hasFini()) reserveOne(llvm::ELF::DT_FINI); // DT_FINI if (pFormat.hasPreInitArray()) { reserveOne(llvm::ELF::DT_PREINIT_ARRAY); // DT_PREINIT_ARRAY reserveOne(llvm::ELF::DT_PREINIT_ARRAYSZ); // DT_PREINIT_ARRAYSZ } if (pFormat.hasInitArray()) { reserveOne(llvm::ELF::DT_INIT_ARRAY); // DT_INIT_ARRAY reserveOne(llvm::ELF::DT_INIT_ARRAYSZ); // DT_INIT_ARRAYSZ } if (pFormat.hasFiniArray()) { reserveOne(llvm::ELF::DT_FINI_ARRAY); // DT_FINI_ARRAY reserveOne(llvm::ELF::DT_FINI_ARRAYSZ); // DT_FINI_ARRAYSZ } if (pFormat.hasHashTab()) reserveOne(llvm::ELF::DT_HASH); // DT_HASH // FIXME: use llvm enum constant if (pFormat.hasGNUHashTab()) reserveOne(0x6ffffef5); // DT_GNU_HASH if (pFormat.hasDynSymTab()) { reserveOne(llvm::ELF::DT_SYMTAB); // DT_SYMTAB reserveOne(llvm::ELF::DT_SYMENT); // DT_SYMENT } if (pFormat.hasDynStrTab()) { reserveOne(llvm::ELF::DT_STRTAB); // DT_STRTAB reserveOne(llvm::ELF::DT_STRSZ); // DT_STRSZ } reserveTargetEntries(pFormat); // DT_PLTGOT if (pFormat.hasRelPlt() || pFormat.hasRelaPlt()) { reserveOne(llvm::ELF::DT_PLTREL); // DT_PLTREL reserveOne(llvm::ELF::DT_JMPREL); // DT_JMPREL reserveOne(llvm::ELF::DT_PLTRELSZ); // DT_PLTRELSZ } if (pFormat.hasRelDyn()) { reserveOne(llvm::ELF::DT_REL); // DT_REL reserveOne(llvm::ELF::DT_RELSZ); // DT_RELSZ reserveOne(llvm::ELF::DT_RELENT); // DT_RELENT } if (pFormat.hasRelaDyn()) { reserveOne(llvm::ELF::DT_RELA); // DT_RELA reserveOne(llvm::ELF::DT_RELASZ); // DT_RELASZ reserveOne(llvm::ELF::DT_RELAENT); // DT_RELAENT } uint64_t dt_flags = 0x0; if (m_Config.options().hasOrigin()) dt_flags |= llvm::ELF::DF_ORIGIN; if (m_Config.options().Bsymbolic()) dt_flags |= llvm::ELF::DF_SYMBOLIC; if (m_Config.options().hasNow()) dt_flags |= llvm::ELF::DF_BIND_NOW; if (m_Backend.hasTextRel()) dt_flags |= llvm::ELF::DF_TEXTREL; if (m_Backend.hasStaticTLS() && (LinkerConfig::DynObj == m_Config.codeGenType())) dt_flags |= llvm::ELF::DF_STATIC_TLS; if ((m_Config.options().hasNewDTags() && 0x0 != dt_flags) || 0 != (dt_flags & llvm::ELF::DF_STATIC_TLS)) reserveOne(llvm::ELF::DT_FLAGS); // DT_FLAGS if (m_Backend.hasTextRel()) reserveOne(llvm::ELF::DT_TEXTREL); // DT_TEXTREL if (m_Config.options().hasNow() || m_Config.options().hasLoadFltr() || m_Config.options().hasOrigin() || m_Config.options().hasInterPose() || m_Config.options().hasNoDefaultLib() || m_Config.options().hasNoDump() || m_Config.options().Bgroup() || ((LinkerConfig::DynObj == m_Config.codeGenType()) && (m_Config.options().hasNoDelete() || m_Config.options().hasInitFirst() || m_Config.options().hasNoDLOpen()))) { reserveOne(llvm::ELF::DT_FLAGS_1); // DT_FLAGS_1 } reserveOne(llvm::ELF::DT_NULL); // for DT_NULL }
/// applyEntries - apply entries void ELFDynamic::applyEntries(const ELFFileFormat& pFormat) { if (LinkerConfig::DynObj == m_Config.codeGenType() && m_Config.options().Bsymbolic()) { applyOne(llvm::ELF::DT_SYMBOLIC, 0x0); // DT_SYMBOLIC } if (pFormat.hasInit()) applyOne(llvm::ELF::DT_INIT, pFormat.getInit().addr()); // DT_INIT if (pFormat.hasFini()) applyOne(llvm::ELF::DT_FINI, pFormat.getFini().addr()); // DT_FINI if (pFormat.hasPreInitArray()) { // DT_PREINIT_ARRAY applyOne(llvm::ELF::DT_PREINIT_ARRAY, pFormat.getPreInitArray().addr()); // DT_PREINIT_ARRAYSZ applyOne(llvm::ELF::DT_PREINIT_ARRAYSZ, pFormat.getPreInitArray().size()); } if (pFormat.hasInitArray()) { // DT_INIT_ARRAY applyOne(llvm::ELF::DT_INIT_ARRAY, pFormat.getInitArray().addr()); // DT_INIT_ARRAYSZ applyOne(llvm::ELF::DT_INIT_ARRAYSZ, pFormat.getInitArray().size()); } if (pFormat.hasFiniArray()) { // DT_FINI_ARRAY applyOne(llvm::ELF::DT_FINI_ARRAY, pFormat.getFiniArray().addr()); // DT_FINI_ARRAYSZ applyOne(llvm::ELF::DT_FINI_ARRAYSZ, pFormat.getFiniArray().size()); } if (pFormat.hasHashTab()) applyOne(llvm::ELF::DT_HASH, pFormat.getHashTab().addr()); // DT_HASH // FIXME: use llvm enum constant if (pFormat.hasGNUHashTab()) applyOne(0x6ffffef5, pFormat.getGNUHashTab().addr()); // DT_GNU_HASH if (pFormat.hasDynSymTab()) { applyOne(llvm::ELF::DT_SYMTAB, pFormat.getDynSymTab().addr()); // DT_SYMTAB applyOne(llvm::ELF::DT_SYMENT, symbolSize()); // DT_SYMENT } if (pFormat.hasDynStrTab()) { applyOne(llvm::ELF::DT_STRTAB, pFormat.getDynStrTab().addr()); // DT_STRTAB applyOne(llvm::ELF::DT_STRSZ, pFormat.getDynStrTab().size()); // DT_STRSZ } applyTargetEntries(pFormat); // DT_PLTGOT if (pFormat.hasRelPlt()) { applyOne(llvm::ELF::DT_PLTREL, llvm::ELF::DT_REL); // DT_PLTREL applyOne(llvm::ELF::DT_JMPREL, pFormat.getRelPlt().addr()); // DT_JMPREL applyOne(llvm::ELF::DT_PLTRELSZ, pFormat.getRelPlt().size()); // DT_PLTRELSZ } else if (pFormat.hasRelaPlt()) { applyOne(llvm::ELF::DT_PLTREL, llvm::ELF::DT_RELA); // DT_PLTREL applyOne(llvm::ELF::DT_JMPREL, pFormat.getRelaPlt().addr()); // DT_JMPREL applyOne(llvm::ELF::DT_PLTRELSZ, pFormat.getRelaPlt().size()); // DT_PLTRELSZ } if (pFormat.hasRelDyn()) { applyOne(llvm::ELF::DT_REL, pFormat.getRelDyn().addr()); // DT_REL applyOne(llvm::ELF::DT_RELSZ, pFormat.getRelDyn().size()); // DT_RELSZ applyOne(llvm::ELF::DT_RELENT, m_pEntryFactory->relSize()); // DT_RELENT } if (pFormat.hasRelaDyn()) { applyOne(llvm::ELF::DT_RELA, pFormat.getRelaDyn().addr()); // DT_RELA applyOne(llvm::ELF::DT_RELASZ, pFormat.getRelaDyn().size()); // DT_RELASZ applyOne(llvm::ELF::DT_RELAENT, m_pEntryFactory->relaSize()); // DT_RELAENT } if (m_Backend.hasTextRel()) { applyOne(llvm::ELF::DT_TEXTREL, 0x0); // DT_TEXTREL if (m_Config.options().warnSharedTextrel() && LinkerConfig::DynObj == m_Config.codeGenType()) mcld::warning(mcld::diag::warn_shared_textrel); } uint64_t dt_flags = 0x0; if (m_Config.options().hasOrigin()) dt_flags |= llvm::ELF::DF_ORIGIN; if (m_Config.options().Bsymbolic()) dt_flags |= llvm::ELF::DF_SYMBOLIC; if (m_Config.options().hasNow()) dt_flags |= llvm::ELF::DF_BIND_NOW; if (m_Backend.hasTextRel()) dt_flags |= llvm::ELF::DF_TEXTREL; if (m_Backend.hasStaticTLS() && (LinkerConfig::DynObj == m_Config.codeGenType())) dt_flags |= llvm::ELF::DF_STATIC_TLS; if ((m_Config.options().hasNewDTags() && 0x0 != dt_flags) || 0 != (dt_flags & llvm::ELF::DF_STATIC_TLS)) applyOne(llvm::ELF::DT_FLAGS, dt_flags); // DT_FLAGS uint64_t dt_flags_1 = 0x0; if (m_Config.options().hasNow()) dt_flags_1 |= llvm::ELF::DF_1_NOW; if (m_Config.options().hasLoadFltr()) dt_flags_1 |= llvm::ELF::DF_1_LOADFLTR; if (m_Config.options().hasOrigin()) dt_flags_1 |= llvm::ELF::DF_1_ORIGIN; if (m_Config.options().hasInterPose()) dt_flags_1 |= llvm::ELF::DF_1_INTERPOSE; if (m_Config.options().hasNoDefaultLib()) dt_flags_1 |= llvm::ELF::DF_1_NODEFLIB; if (m_Config.options().hasNoDump()) dt_flags_1 |= llvm::ELF::DF_1_NODUMP; if (m_Config.options().Bgroup()) dt_flags_1 |= llvm::ELF::DF_1_GROUP; if (LinkerConfig::DynObj == m_Config.codeGenType()) { if (m_Config.options().hasNoDelete()) dt_flags_1 |= llvm::ELF::DF_1_NODELETE; if (m_Config.options().hasInitFirst()) dt_flags_1 |= llvm::ELF::DF_1_INITFIRST; if (m_Config.options().hasNoDLOpen()) dt_flags_1 |= llvm::ELF::DF_1_NOOPEN; } if (0x0 != dt_flags_1) applyOne(llvm::ELF::DT_FLAGS_1, dt_flags_1); // DT_FLAGS_1 applyOne(llvm::ELF::DT_NULL, 0x0); // for DT_NULL }