bool ARMGNULDBackend::readSection(Input& pInput, MCLinker& pLinker, LDSection& pInputSectHdr) { LDSection& out_sect = pLinker.getOrCreateOutputSectHdr(pInputSectHdr.name(), pInputSectHdr.kind(), pInputSectHdr.type(), pInputSectHdr.flag()); // FIXME: (Luba) // Handle ARM attributes in the right way. // In current milestone, MCLinker goes through the shortcut. // It reads input's ARM attributes and copies the first ARM attributes // into the output file. The correct way is merge these sections, not // just copy. if ((0 == out_sect.name().compare(".ARM.attributes")) && (0 != out_sect.size())) return true; MemoryRegion* region = pInput.memArea()->request(pInputSectHdr.offset(), pInputSectHdr.size()); llvm::MCSectionData& sect_data = pLinker.getOrCreateSectData(pInputSectHdr); new MCRegionFragment(*region, §_data); out_sect.setSize(out_sect.size() + pInputSectHdr.size()); return true; }
bool SectionSymbolSet::finalize(LDSection& pOutSect, SymbolTable& pSymTab, bool relocatable) { if (!relocatable && pOutSect.size() == 0) return true; LDSymbol* sym = get(pOutSect); assert(NULL != sym); SectionData* data = NULL; switch (pOutSect.kind()) { case LDFileFormat::Relocation: // Relocation section should not have section symbol. return true; case LDFileFormat::EhFrame: if (EhFrame *ehframe = pOutSect.getEhFrame()) data = ehframe->getSectionData(); break; default: data = pOutSect.getSectionData(); break; } FragmentRef* frag_ref; if (data && !data->empty()) frag_ref = FragmentRef::Create(data->front(), 0x0); else frag_ref = FragmentRef::Null(); sym->setFragmentRef(frag_ref); // push symbol into output symbol table pSymTab.add(*sym); return true; }
/// emitShStrTab - emit section string table void ELFObjectWriter::emitShStrTab(const LDSection& pShStrTab, const Module& pModule, MemoryArea& pOutput) { // write out data MemoryRegion* region = pOutput.request(pShStrTab.offset(), pShStrTab.size()); unsigned char* data = region->start(); size_t shstrsize = 0; Module::const_iterator section, sectEnd = pModule.end(); for (section = pModule.begin(); section != sectEnd; ++section) { strcpy((char*)(data + shstrsize), (*section)->name().data()); shstrsize += (*section)->name().size() + 1; } }
/// emit void ELFDynamic::emit(const LDSection& pSection, MemoryRegion& pRegion) const { if (pRegion.size() < pSection.size()) { llvm::report_fatal_error(llvm::Twine("the given memory is smaller") + llvm::Twine(" than the section's demaind.\n")); } uint8_t* address = (uint8_t*)pRegion.begin(); EntryListType::const_iterator entry, entryEnd = m_NeedList.end(); for (entry = m_NeedList.begin(); entry != entryEnd; ++entry) address += (*entry)->emit(address); entryEnd = m_EntryList.end(); for (entry = m_EntryList.begin(); entry != entryEnd; ++entry) address += (*entry)->emit(address); }
//========================== // DebugString void DebugString::merge(LDSection& pSection) { // get the fragment contents llvm::StringRef strings; SectionData::iterator it, end = pSection.getSectionData()->end(); for (it = pSection.getSectionData()->begin(); it != end; ++it) { if ((*it).getKind() == Fragment::Region) { RegionFragment* frag = llvm::cast<RegionFragment>(&(*it)); strings = frag->getRegion().data(); } } // get the debug strings and add them into merged string table const char* str = strings.data(); const char* str_end = str + pSection.size(); while (str < str_end) { size_t len = string_length(str); m_StringTable.insertString(llvm::StringRef(str, len)); str = str + len + 1; } }
bool MipsAbiFlags::fillBySection(const Input& pInput, const LDSection& pSection, MipsAbiFlags& mipsAbi) { assert(pSection.type() == llvm::ELF::SHT_MIPS_ABIFLAGS && "Unexpected section type"); if (pSection.size() != size()) { error(diag::error_Mips_abiflags_invalid_size) << pInput.name(); return false; } const SectionData* secData = pSection.getSectionData(); if (secData->size() != 2 || !llvm::isa<RegionFragment>(secData->front())) { error(diag::error_Mips_abiflags_invalid_size) << pInput.name(); return false; } const auto& frag = llvm::cast<RegionFragment>(secData->front()); auto* data = reinterpret_cast<const ElfMipsAbiFlags*>(frag.getRegion().data()); if (data->version != 0) { error(diag::error_Mips_abiflags_invalid_version) << int(data->version) << pInput.name(); return false; } mipsAbi.m_IsaLevel = data->isa_level; mipsAbi.m_IsaRev = data->isa_rev; mipsAbi.m_GprSize = data->gpr_size; mipsAbi.m_Cpr1Size = data->cpr1_size; mipsAbi.m_Cpr2Size = data->cpr2_size; mipsAbi.m_FpAbi = data->fp_abi; mipsAbi.m_IsaExt = data->isa_ext; mipsAbi.m_Ases = data->ases; mipsAbi.m_Flags1 = data->flags1; return true; }
bool ELFAttribute::merge(const Input &pInput, LDSection &pInputAttrSectHdr) { // Skip corrupt subsection if (pInputAttrSectHdr.size() < MinimalELFAttributeSectionSize) return true; // Obtain the region containing the attribute data. Expect exactly one // RegionFragment in the section data. const SectionData* sect_data = pInputAttrSectHdr.getSectionData(); // FIXME: Why is 2? if ((sect_data->size() != 2) || (!llvm::isa<RegionFragment>(sect_data->front()))) { return true; } const RegionFragment& region_frag = llvm::cast<RegionFragment>(sect_data->front()); llvm::StringRef region = region_frag.getRegion(); // Parse the ELF attribute section header. ARM [ABI-addenda], 2.2.3. // // <format-version: ‘A’> // [ <uint32: subsection-length> NTBS: vendor-name // <bytes: vendor-data> // ]* const char *attribute_data = region.begin(); // format-version if (attribute_data[0] != FormatVersion) { warning(diag::warn_unsupported_attribute_section_format) << pInput.name() << attribute_data[0]; return true; } size_t subsection_offset = FormatVersionFieldSize; // Iterate all subsections containing in this attribute section. do { const char *subsection_data = region.begin() + subsection_offset; // subsection-length uint32_t subsection_length = *reinterpret_cast<const uint32_t*>(subsection_data); if(llvm::sys::IsLittleEndianHost != m_Config.targets().isLittleEndian()) bswap32(subsection_length); // vendor-name const char* vendor_name = subsection_data + SubsectionLengthFieldSize; const size_t vendor_name_length = ::strlen(vendor_name) + 1 /* '\0' */; // Check the length. if ((vendor_name_length <= 1) || (subsection_length <= (SubsectionLengthFieldSize + vendor_name_length))) return true; // Select the attribute subsection. Subsection *subsection = getSubsection(vendor_name); // Only process the subsections whose vendor can be recognized. if (subsection == NULL) { warning(diag::warn_unrecognized_vendor_subsection) << vendor_name << pInput.name(); } else { // vendor-data size_t vendor_data_offset = subsection_offset + SubsectionLengthFieldSize + vendor_name_length; size_t vendor_data_size = subsection_length - SubsectionLengthFieldSize - vendor_name_length; ConstAddress vendor_data = reinterpret_cast<ConstAddress>(region.begin()) + vendor_data_offset; // Merge the vendor data in the subsection. if (!subsection->merge(pInput, vendor_data, vendor_data_size)) return false; } subsection_offset += subsection_length; } while ((subsection_offset + SubsectionLengthFieldSize) < pInputAttrSectHdr.size()); return true; }