ELFObjectWriter.cpp revision f7ac0f19a1c8d0ad14bcf6456ce368b830fea886
15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ELFObjectWriter.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//===----------------------------------------------------------------------===// 922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/LD/ELFObjectWriter.h> 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Module.h> 12d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao#include <mcld/LinkerConfig.h> 1322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Target/GNULDBackend.h> 1422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <mcld/Support/MemoryArea.h> 156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Support/MemoryRegion.h> 166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Support/MsgHandling.h> 176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/ADT/SizeTraits.h> 186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Fragment/FragmentLinker.h> 196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Fragment/AlignFragment.h> 206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Fragment/FillFragment.h> 216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Fragment/RegionFragment.h> 226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Fragment/Stub.h> 236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/Fragment/NullFragment.h> 246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LD/LDSection.h> 256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LD/SectionData.h> 266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LD/ELFSegment.h> 276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LD/ELFSegmentFactory.h> 286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LD/RelocData.h> 296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <mcld/LD/EhFrame.h> 3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/ErrorHandling.h> 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/system_error.h> 336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/ELF.h> 346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/Casting.h> 35d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaousing namespace llvm; 376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesusing namespace llvm::ELF; 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// ELFObjectWriter 4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===// 4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei LiaoELFObjectWriter::ELFObjectWriter(GNULDBackend& pBackend, 44d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao const LinkerConfig& pConfig) 456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines : ObjectWriter(), m_Backend(pBackend), m_Config(pConfig) 466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFObjectWriter::~ELFObjectWriter() 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::writeSection(MemoryArea& pOutput, LDSection *section) 546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* region; 566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Request output region 576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch (section->kind()) { 586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Note: 596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (section->getSectionData() == NULL) 606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return; 616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Fall through 626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Regular: 636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Relocation: 646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Target: 656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Debug: 666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::GCCExceptTable: 676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::EhFrame: { 686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines region = pOutput.request(section->offset(), section->size()); 696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL == region) { 706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::report_fatal_error(llvm::Twine("cannot get enough memory region for output section `") + 716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::Twine(section->name()) + 726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::Twine("'.\n")); 736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Null: 776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::NamePool: 786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::BSS: 796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::MetaData: 806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Version: 816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::EhFrameHdr: 826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::StackNote: 836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Ignore these sections 846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return; 856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::errs() << "WARNING: unsupported section kind: " 876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << section->kind() 886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << " of section " 896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << section->name() 906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << ".\n"; 916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return; 926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out sections with data 956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch(section->kind()) { 966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::GCCExceptTable: 976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::EhFrame: 986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Regular: 996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Debug: 1006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Note: 1016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // FIXME: if optimization of exception handling sections is enabled, 1026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // then we should emit these sections by the other way. 1036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSectionData(*section, *region); 1046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 1056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Relocation: 1066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitRelocation(m_Config, *section, *region); 1076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 1086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Target: 1096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines target().emitSectionData(*section, *region); 1106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 1116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 1126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm_unreachable("invalid section kind"); 1136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaollvm::error_code ELFObjectWriter::writeObject(Module& pModule, 11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao MemoryArea& pOutput) 11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao{ 1196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool is_dynobj = m_Config.codeGenType() == LinkerConfig::DynObj; 1206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool is_exec = m_Config.codeGenType() == LinkerConfig::Exec; 1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool is_binary = m_Config.codeGenType() == LinkerConfig::Binary; 1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool is_object = m_Config.codeGenType() == LinkerConfig::Object; 1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(is_dynobj || is_exec || is_binary || is_object); 1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (is_dynobj || is_exec) { 127f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Allow backend to sort symbols before emitting 128f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines target().orderSymbolTable(pModule); 129f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out the interpreter section: .interp 1316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines target().emitInterp(pOutput); 1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out name pool sections: .dynsym, .dynstr, .hash 1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines target().emitDynNamePools(pModule, pOutput); 1356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (is_object || is_dynobj || is_exec) { 1386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out name pool sections: .symtab, .strtab 1396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines target().emitRegNamePools(pModule, pOutput); 1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (is_binary) { 1436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Iterate over the loadable segments and write the corresponding sections 1446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFSegmentFactory::iterator seg, segEnd = target().elfSegmentTable().end(); 1456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (seg = target().elfSegmentTable().begin(); seg != segEnd; ++seg) { 1476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::PT_LOAD == (*seg).type()) { 1486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFSegment::sect_iterator sect, sectEnd = (*seg).end(); 1496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (sect = (*seg).begin(); sect != sectEnd; ++sect) 1506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines writeSection(pOutput, *sect); 15122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 15222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 1546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out regular ELF sections 1556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::iterator sect, sectEnd = pModule.end(); 1566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (sect = pModule.begin(); sect != sectEnd; ++sect) 1576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines writeSection(pOutput, *sect); 15822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitShStrTab(target().getOutputFormat()->getShStrTab(), pModule, pOutput); 1606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (m_Config.targets().is32Bits()) { 1626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out ELF header 1636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out section header table 1646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines writeELFHeader<32>(m_Config, pModule, pOutput); 1656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (is_dynobj || is_exec) 1666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitProgramHeader<32>(pOutput); 1676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSectionHeader<32>(pModule, m_Config, pOutput); 1696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (m_Config.targets().is64Bits()) { 1716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out ELF header 1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out section header table 1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines writeELFHeader<64>(m_Config, pModule, pOutput); 1746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (is_dynobj || is_exec) 1756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitProgramHeader<64>(pOutput); 1766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSectionHeader<64>(pModule, m_Config, pOutput); 1786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 1806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return make_error_code(errc::not_supported); 1816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines pOutput.clear(); 1846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return llvm::make_error_code(llvm::errc::success); 1856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// writeELFHeader - emit ElfXX_Ehdr 1886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<size_t SIZE> 1896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::writeELFHeader(const LinkerConfig& pConfig, 1906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const Module& pModule, 1916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryArea& pOutput) const 1926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 1936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Ehdr ElfXX_Ehdr; 1946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Shdr ElfXX_Shdr; 1956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Phdr ElfXX_Phdr; 1966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // ELF header must start from 0x0 1986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion *region = pOutput.request(0, sizeof(ElfXX_Ehdr)); 1996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ElfXX_Ehdr* header = (ElfXX_Ehdr*)region->start(); 2006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines memcpy(header->e_ident, ElfMagic, EI_MAG3+1); 2026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_ident[EI_CLASS] = (SIZE == 32) ? ELFCLASS32 : ELFCLASS64; 2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_ident[EI_DATA] = pConfig.targets().isLittleEndian()? 2056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFDATA2LSB : ELFDATA2MSB; 2066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_ident[EI_VERSION] = target().getInfo().ELFVersion(); 2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_ident[EI_OSABI] = target().getInfo().OSABI(); 2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_ident[EI_ABIVERSION] = target().getInfo().ABIVersion(); 2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // FIXME: add processor-specific and core file types. 2116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch(pConfig.codeGenType()) { 2126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LinkerConfig::Object: 2136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_type = ET_REL; 2146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 2156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LinkerConfig::DynObj: 2166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_type = ET_DYN; 2176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 2186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LinkerConfig::Exec: 2196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_type = ET_EXEC; 2206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 2216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 2226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::errs() << "unspported output file type: " << pConfig.codeGenType() << ".\n"; 2236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_type = ET_NONE; 2246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_machine = target().getInfo().machine(); 2266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_version = header->e_ident[EI_VERSION]; 2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_entry = getEntryPoint(pConfig, pModule); 2286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != pConfig.codeGenType()) 2306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_phoff = sizeof(ElfXX_Ehdr); 2316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 2326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_phoff = 0x0; 2336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_shoff = getLastStartOffset<SIZE>(pModule); 2356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_flags = target().getInfo().flags(); 2366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_ehsize = sizeof(ElfXX_Ehdr); 2376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_phentsize = sizeof(ElfXX_Phdr); 2386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_phnum = target().numOfSegments(); 2396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_shentsize = sizeof(ElfXX_Shdr); 2406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_shnum = pModule.size(); 2416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_shstrndx = pModule.getSection(".shstrtab")->index(); 2426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getEntryPoint 2456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getEntryPoint(const LinkerConfig& pConfig, 2466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const Module& pModule) const 2476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::StringRef entry_name; 2496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pConfig.options().hasEntry()) 2506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines entry_name = pConfig.options().entry(); 2516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 2526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines entry_name = target().getInfo().entry(); 2536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t result = 0x0; 2556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool issue_warning = (pConfig.options().hasEntry() && 2576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkerConfig::Object != pConfig.codeGenType() && 2586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkerConfig::DynObj != pConfig.codeGenType()); 2596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSymbol* entry_symbol = pModule.getNamePool().findSymbol(entry_name); 2616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // found the symbol 2636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL != entry_symbol) { 2646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (entry_symbol->desc() != ResolveInfo::Define && issue_warning) { 2656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::errs() << "WARNING: entry symbol '" 2666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << entry_symbol->name() 2676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << "' exists but is not defined.\n"; 2686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result = entry_symbol->value(); 2706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // not in the symbol pool 2726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 2736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // We should parse entry as a number. 2746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // @ref GNU ld manual, Options -e. e.g., -e 0x1000. 2756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines char* endptr; 2766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result = strtoull(entry_name.data(), &endptr, 0); 2776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (*endptr != '\0') { 2786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (issue_warning) { 2796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::errs() << "cannot find entry symbol '" 2806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << entry_name.data() 2816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << "'.\n"; 28222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result = 0x0; 28422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return result; 2876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 28822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// emitSectionHeader - emit ElfXX_Shdr 2906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<size_t SIZE> 2916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitSectionHeader(const Module& pModule, 2926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LinkerConfig& pConfig, 2936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryArea& pOutput) const 2946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 2956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Shdr ElfXX_Shdr; 29622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit section header 2986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int sectNum = pModule.size(); 2996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int header_size = sizeof(ElfXX_Shdr) * sectNum; 3006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* region = pOutput.request(getLastStartOffset<SIZE>(pModule), 3016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header_size); 3026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ElfXX_Shdr* shdr = (ElfXX_Shdr*)region->start(); 30322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Iterate the SectionTable in LDContext 3056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int sectIdx = 0; 3066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int shstridx = 0; // NULL section has empty name 3076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (; sectIdx < sectNum; ++sectIdx) { 3086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection *ld_sect = pModule.getSectionTable().at(sectIdx); 3096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr[sectIdx].sh_name = shstridx; 3106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr[sectIdx].sh_type = ld_sect->type(); 3116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr[sectIdx].sh_flags = ld_sect->flag(); 3126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr[sectIdx].sh_addr = ld_sect->addr(); 3136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr[sectIdx].sh_offset = ld_sect->offset(); 3146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr[sectIdx].sh_size = ld_sect->size(); 3156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr[sectIdx].sh_addralign = ld_sect->align(); 3166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr[sectIdx].sh_entsize = getSectEntrySize<SIZE>(*ld_sect); 3176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr[sectIdx].sh_link = getSectLink(*ld_sect, pConfig); 3186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr[sectIdx].sh_info = getSectInfo(*ld_sect); 3196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // adjust strshidx 3216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstridx += ld_sect->name().size() + 1; 32222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 3236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// emitProgramHeader - emit ElfXX_Phdr 3266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<size_t SIZE> 3276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitProgramHeader(MemoryArea& pOutput) const 3286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 3296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Ehdr ElfXX_Ehdr; 3306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Phdr ElfXX_Phdr; 3316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t start_offset, phdr_size; 33322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines start_offset = sizeof(ElfXX_Ehdr); 3356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines phdr_size = sizeof(ElfXX_Phdr); 3366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Program header must start directly after ELF header 3376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion *region = pOutput.request(start_offset, 3386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines target().numOfSegments() * phdr_size); 3396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ElfXX_Phdr* phdr = (ElfXX_Phdr*)region->start(); 3416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Iterate the elf segment table in GNULDBackend 3436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t index = 0; 3446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFSegmentFactory::const_iterator seg = target().elfSegmentTable().begin(), 3456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines segEnd = target().elfSegmentTable().end(); 3466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (; seg != segEnd; ++seg, ++index) { 3476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines phdr[index].p_type = (*seg).type(); 3486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines phdr[index].p_flags = (*seg).flag(); 3496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines phdr[index].p_offset = (*seg).offset(); 3506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines phdr[index].p_vaddr = (*seg).vaddr(); 3516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines phdr[index].p_paddr = (*seg).paddr(); 3526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines phdr[index].p_filesz = (*seg).filesz(); 3536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines phdr[index].p_memsz = (*seg).memsz(); 3546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines phdr[index].p_align = (*seg).align(); 35522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 3566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 35722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitShStrTab - emit section string table 3596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid 3606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFObjectWriter::emitShStrTab(const LDSection& pShStrTab, 3616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const Module& pModule, 3626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryArea& pOutput) 3636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 3646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // write out data 3656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion* region = pOutput.request(pShStrTab.offset(), pShStrTab.size()); 3666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned char* data = region->start(); 3676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t shstrsize = 0; 3686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_iterator section, sectEnd = pModule.end(); 3696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (section = pModule.begin(); section != sectEnd; ++section) { 3706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines strcpy((char*)(data + shstrsize), (*section)->name().data()); 3716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrsize += (*section)->name().size() + 1; 3726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitSectionData 3766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid 3776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen HinesELFObjectWriter::emitSectionData(const LDSection& pSection, 3786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion& pRegion) const 3796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 3806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const SectionData* sd = NULL; 3816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch (pSection.kind()) { 3826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Relocation: 3836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(pSection.hasRelocData()); 3846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return; 3856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::EhFrame: 3866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(pSection.hasEhFrame()); 387f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sd = pSection.getEhFrame()->getSectionData(); 3886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 3896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 3906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(pSection.hasSectionData()); 3916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sd = pSection.getSectionData(); 3926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 3936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSectionData(*sd, pRegion); 3956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitRelocation 3986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitRelocation(const LinkerConfig& pConfig, 3996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection& pSection, 4006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion& pRegion) const 4016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const RelocData* sect_data = pSection.getRelocData(); 4036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(NULL != sect_data && "SectionData is NULL in emitRelocation!"); 4046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pSection.type() == SHT_REL) { 4066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pConfig.targets().is32Bits()) 4076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitRel<32>(pConfig, *sect_data, pRegion); 4086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (pConfig.targets().is64Bits()) 4096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitRel<64>(pConfig, *sect_data, pRegion); 4106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 4116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str() 4126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << pConfig.targets().bitclass(); 4136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 4146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else if (pSection.type() == SHT_RELA) { 4156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pConfig.targets().is32Bits()) 4166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitRela<32>(pConfig, *sect_data, pRegion); 4176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (pConfig.targets().is64Bits()) 4186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitRela<64>(pConfig, *sect_data, pRegion); 4196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 4206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str() 4216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << pConfig.targets().bitclass(); 4226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 4236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else 4246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::report_fatal_error("unsupported relocation section type!"); 4256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// emitRel - emit ElfXX_Rel 4296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<size_t SIZE> 4306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitRel(const LinkerConfig& pConfig, 4316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const RelocData& pRelocData, 4326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion& pRegion) const 4336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Rel ElfXX_Rel; 4356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Addr ElfXX_Addr; 4366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word; 4376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ElfXX_Rel* rel = reinterpret_cast<ElfXX_Rel*>(pRegion.start()); 4396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const Relocation* relocation = 0; 4416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const FragmentRef* frag_ref = 0; 4426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (RelocData::const_iterator it = pRelocData.begin(), 4446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ie = pRelocData.end(); it != ie; ++it, ++rel) { 4456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines relocation = &(llvm::cast<Relocation>(*it)); 4476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines frag_ref = &(relocation->targetRef()); 4486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if(LinkerConfig::DynObj == pConfig.codeGenType() || 4506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkerConfig::Exec == pConfig.codeGenType()) { 4516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines rel->r_offset = static_cast<ElfXX_Addr>( 4526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines frag_ref->frag()->getParent()->getSection().addr() + 4536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines frag_ref->getOutputOffset()); 4546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 4556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 4566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines rel->r_offset = static_cast<ElfXX_Addr>(frag_ref->getOutputOffset()); 4576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 4586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ElfXX_Word Index; 4596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if( relocation->symInfo() == NULL ) 4606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Index = 0; 4616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 4626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Index = static_cast<ElfXX_Word>( 4636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines target().getSymbolIdx(relocation->symInfo()->outSymbol())); 4646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines rel->setSymbolAndType(Index, relocation->type()); 4666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 4676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// emitRela - emit ElfXX_Rela 4706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<size_t SIZE> 4716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitRela(const LinkerConfig& pConfig, 4726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const RelocData& pRelocData, 4736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion& pRegion) const 4746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 4756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Rela ElfXX_Rela; 4766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Addr ElfXX_Addr; 4776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word; 4786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ElfXX_Rela* rel = reinterpret_cast<ElfXX_Rela*>(pRegion.start()); 4806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const Relocation* relocation = 0; 4826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const FragmentRef* frag_ref = 0; 4836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (RelocData::const_iterator it = pRelocData.begin(), 4856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ie = pRelocData.end(); it != ie; ++it, ++rel) { 4866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines relocation = &(llvm::cast<Relocation>(*it)); 4886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines frag_ref = &(relocation->targetRef()); 4896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if(LinkerConfig::DynObj == pConfig.codeGenType() || 4916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkerConfig::Exec == pConfig.codeGenType()) { 4926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines rel->r_offset = static_cast<ElfXX_Addr>( 4936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines frag_ref->frag()->getParent()->getSection().addr() + 4946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines frag_ref->getOutputOffset()); 4956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 4966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 4976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines rel->r_offset = static_cast<ElfXX_Addr>(frag_ref->getOutputOffset()); 4986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 4996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ElfXX_Word Index; 5016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if( relocation->symInfo() == NULL ) 5026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Index = 0; 5036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 5046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Index = static_cast<ElfXX_Word>( 5056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines target().getSymbolIdx(relocation->symInfo()->outSymbol())); 5066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines rel->setSymbolAndType(Index, relocation->type()); 5086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines rel->r_addend = relocation->addend(); 5096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 5106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSectEntrySize - compute ElfXX_Shdr::sh_entsize 5146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<size_t SIZE> 5156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getSectEntrySize(const LDSection& pSection) const 5166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word; 5186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Sym ElfXX_Sym; 5196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Rel ElfXX_Rel; 5206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Rela ElfXX_Rela; 5216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Dyn ElfXX_Dyn; 5226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_DYNSYM == pSection.type() || 5246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHT_SYMTAB == pSection.type()) 5256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return sizeof(ElfXX_Sym); 5266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_REL == pSection.type()) 5276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return sizeof(ElfXX_Rel); 5286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_RELA == pSection.type()) 5296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return sizeof(ElfXX_Rela); 5306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_HASH == pSection.type() || 5316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHT_GNU_HASH == pSection.type()) 5326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return sizeof(ElfXX_Word); 5336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_DYNAMIC == pSection.type()) 5346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return sizeof(ElfXX_Dyn); 5356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return 0x0; 5366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSectLink - compute ElfXX_Shdr::sh_link 5396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getSectLink(const LDSection& pSection, 5406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LinkerConfig& pConfig) const 5416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_SYMTAB == pSection.type()) 5436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getOutputFormat()->getStrTab().index(); 5446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_DYNSYM == pSection.type()) 5456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getOutputFormat()->getDynStrTab().index(); 5466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_DYNAMIC == pSection.type()) 5476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getOutputFormat()->getDynStrTab().index(); 5486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_HASH == pSection.type() || 5496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHT_GNU_HASH == pSection.type()) 5506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getOutputFormat()->getDynSymTab().index(); 5516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_REL == pSection.type() || 5526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHT_RELA == pSection.type()) { 5536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object == pConfig.codeGenType()) 5546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getOutputFormat()->getSymTab().index(); 5556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 5566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getOutputFormat()->getDynSymTab().index(); 5576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 5586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // FIXME: currently we link ARM_EXIDX section to output text section here 5596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_ARM_EXIDX == pSection.type()) 5606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getOutputFormat()->getText().index(); 5616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return llvm::ELF::SHN_UNDEF; 5626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSectInfo - compute ElfXX_Shdr::sh_info 5656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getSectInfo(const LDSection& pSection) const 5666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_SYMTAB == pSection.type() || 5686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHT_DYNSYM == pSection.type()) 5696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return pSection.getInfo(); 5706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_REL == pSection.type() || 5726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHT_RELA == pSection.type()) { 5736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection* info_link = pSection.getLink(); 5746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (NULL != info_link) 5756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return info_link->index(); 5766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 5776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return 0x0; 5796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getLastStartOffset 5826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<> 5836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getLastStartOffset<32>(const Module& pModule) const 5846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection* lastSect = pModule.back(); 5866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(lastSect != NULL); 5876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Align<32>(lastSect->offset() + lastSect->size()); 5886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getLastStartOffset 5916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinestemplate<> 5926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const 5936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 5946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection* lastSect = pModule.back(); 5956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(lastSect != NULL); 5966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Align<64>(lastSect->offset() + lastSect->size()); 5976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitSectionData 6006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitSectionData(const SectionData& pSD, 6016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines MemoryRegion& pRegion) const 6026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines{ 6036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines SectionData::const_iterator fragIter, fragEnd = pSD.end(); 6046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t cur_offset = 0; 6056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (fragIter = pSD.begin(); fragIter != fragEnd; ++fragIter) { 6066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t size = fragIter->size(); 6076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch(fragIter->getKind()) { 6086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case Fragment::Region: { 6096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const RegionFragment& region_frag = llvm::cast<RegionFragment>(*fragIter); 6106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const uint8_t* from = region_frag.getRegion().start(); 6116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines memcpy(pRegion.getBuffer(cur_offset), from, size); 6126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case Fragment::Alignment: { 6156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // TODO: emit values with different sizes (> 1 byte), and emit nops 6166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const AlignFragment& align_frag = llvm::cast<AlignFragment>(*fragIter); 6176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t count = size / align_frag.getValueSize(); 6186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch (align_frag.getValueSize()) { 6196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case 1u: 6206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::memset(pRegion.getBuffer(cur_offset), 6216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines align_frag.getValue(), 6226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines count); 6236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 6256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::report_fatal_error("unsupported value size for align fragment emission yet.\n"); 6266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case Fragment::Fillment: { 6316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const FillFragment& fill_frag = llvm::cast<FillFragment>(*fragIter); 6326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (0 == size || 6336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0 == fill_frag.getValueSize() || 6346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0 == fill_frag.size()) { 6356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // ignore virtual fillment 6366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t num_tiles = fill_frag.size() / fill_frag.getValueSize(); 6406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (uint64_t i = 0; i != num_tiles; ++i) { 6416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines std::memset(pRegion.getBuffer(cur_offset), 6426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fill_frag.getValue(), 6436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fill_frag.getValueSize()); 6446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case Fragment::Stub: { 6486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const Stub& stub_frag = llvm::cast<Stub>(*fragIter); 6496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines memcpy(pRegion.getBuffer(cur_offset), stub_frag.getContent(), size); 6506f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case Fragment::Null: { 6536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(0x0 == size); 6546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case Fragment::Target: 6576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::report_fatal_error("Target fragment should not be in a regular section.\n"); 6586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 6606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::report_fatal_error("invalid fragment should not be in a regular section.\n"); 6616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines cur_offset += size; 6646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 66522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 6665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 667