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//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFObjectWriter.h" 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerConfig.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LinkerScript.h" 1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Module.h" 1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/ADT/SizeTraits.h" 1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/AlignFragment.h" 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/FillFragment.h" 1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/NullFragment.h" 1837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/RegionFragment.h" 1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/Stub.h" 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/DebugString.h" 2137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/EhFrame.h" 2237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFFileFormat.h" 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFSegment.h" 2437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/ELFSegmentFactory.h" 2537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSection.h" 2637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/LDSymbol.h" 2737b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/RelocData.h" 2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/LD/SectionData.h" 2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/MsgHandling.h" 3037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNUInfo.h" 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Target/GNULDBackend.h" 3222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <llvm/Support/Casting.h> 3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <llvm/Support/ELF.h> 350dea6bc96bb52346737966839ac68644f7939f58Stephen Hines#include <llvm/Support/Errc.h> 366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines#include <llvm/Support/ErrorHandling.h> 37d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 3837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace 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) 4537b74a387bb3993387029859c2d9d051c41c724eStephen Hines : ObjectWriter(), m_Backend(pBackend), m_Config(pConfig) { 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4837b74a387bb3993387029859c2d9d051c41c724eStephen HinesELFObjectWriter::~ELFObjectWriter() { 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid ELFObjectWriter::writeSection(Module& pModule, 5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines FileOutputBuffer& pOutput, 5337b74a387bb3993387029859c2d9d051c41c724eStephen Hines LDSection* section) { 5487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MemoryRegion region; 556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Request output region 566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch (section->kind()) { 5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Note: 5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (section->getSectionData() == NULL) 5937b74a387bb3993387029859c2d9d051c41c724eStephen Hines return; 606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Fall through 6137b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::TEXT: 6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::DATA: 6337b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Relocation: 6437b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Target: 6537b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Debug: 6637b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::DebugString: 6737b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::GCCExceptTable: 6837b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::EhFrame: { 6937b74a387bb3993387029859c2d9d051c41c724eStephen Hines region = pOutput.request(section->offset(), section->size()); 7037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (region.size() == 0) { 7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines return; 7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7537b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Null: 7637b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::NamePool: 7737b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::BSS: 7837b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::MetaData: 7937b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Version: 8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::EhFrameHdr: 8137b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::StackNote: 8237b74a387bb3993387029859c2d9d051c41c724eStephen Hines // Ignore these sections 8337b74a387bb3993387029859c2d9d051c41c724eStephen Hines return; 8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines default: 8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::errs() << "WARNING: unsupported section kind: " << section->kind() 8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines << " of section " << section->name() << ".\n"; 8737b74a387bb3993387029859c2d9d051c41c724eStephen Hines return; 886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out sections with data 9137b74a387bb3993387029859c2d9d051c41c724eStephen Hines switch (section->kind()) { 9237b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::GCCExceptTable: 9337b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::TEXT: 9437b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::DATA: 9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Debug: 9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Note: 9737b74a387bb3993387029859c2d9d051c41c724eStephen Hines emitSectionData(*section, region); 9837b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::EhFrame: 10037b74a387bb3993387029859c2d9d051c41c724eStephen Hines emitEhFrame(pModule, *section->getEhFrame(), region); 10137b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 10237b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Relocation: 10337b74a387bb3993387029859c2d9d051c41c724eStephen Hines // sort relocation for the benefit of the dynamic linker. 10437b74a387bb3993387029859c2d9d051c41c724eStephen Hines target().sortRelocation(*section); 10537b74a387bb3993387029859c2d9d051c41c724eStephen Hines 10637b74a387bb3993387029859c2d9d051c41c724eStephen Hines emitRelocation(m_Config, *section, region); 10737b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 10837b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::Target: 10937b74a387bb3993387029859c2d9d051c41c724eStephen Hines target().emitSectionData(*section, region); 11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 11137b74a387bb3993387029859c2d9d051c41c724eStephen Hines case LDFileFormat::DebugString: 11237b74a387bb3993387029859c2d9d051c41c724eStephen Hines section->getDebugString()->emit(region); 11337b74a387bb3993387029859c2d9d051c41c724eStephen Hines break; 11437b74a387bb3993387029859c2d9d051c41c724eStephen Hines default: 11537b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm_unreachable("invalid section kind"); 1166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1190dea6bc96bb52346737966839ac68644f7939f58Stephen Hinesstd::error_code ELFObjectWriter::writeObject(Module& pModule, 12037b74a387bb3993387029859c2d9d051c41c724eStephen Hines FileOutputBuffer& pOutput) { 1216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool is_dynobj = m_Config.codeGenType() == LinkerConfig::DynObj; 1226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool is_exec = m_Config.codeGenType() == LinkerConfig::Exec; 1236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool is_binary = m_Config.codeGenType() == LinkerConfig::Binary; 1246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines bool is_object = m_Config.codeGenType() == LinkerConfig::Object; 1256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(is_dynobj || is_exec || is_binary || is_object); 1276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (is_dynobj || is_exec) { 129f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines // Allow backend to sort symbols before emitting 130f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines target().orderSymbolTable(pModule); 131f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines 1326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out the interpreter section: .interp 1336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines target().emitInterp(pOutput); 1346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out name pool sections: .dynsym, .dynstr, .hash 1366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines target().emitDynNamePools(pModule, pOutput); 1376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (is_object || is_dynobj || is_exec) { 1406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out name pool sections: .symtab, .strtab 1416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines target().emitRegNamePools(pModule, pOutput); 1426f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (is_binary) { 1456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Iterate over the loadable segments and write the corresponding sections 1466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFSegmentFactory::iterator seg, segEnd = target().elfSegmentTable().end(); 1476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (seg = target().elfSegmentTable().begin(); seg != segEnd; ++seg) { 14987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (llvm::ELF::PT_LOAD == (*seg)->type()) { 15087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ELFSegment::iterator sect, sectEnd = (*seg)->end(); 15187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (sect = (*seg)->begin(); sect != sectEnd; ++sect) 15287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines writeSection(pModule, pOutput, *sect); 15322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 15422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 1556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else { 1566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out regular ELF sections 1576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::iterator sect, sectEnd = pModule.end(); 1586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (sect = pModule.begin(); sect != sectEnd; ++sect) 15987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines writeSection(pModule, pOutput, *sect); 16022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 1616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitShStrTab(target().getOutputFormat()->getShStrTab(), pModule, pOutput); 1626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (m_Config.targets().is32Bits()) { 1646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out ELF header 1656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out section header table 1666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines writeELFHeader<32>(m_Config, pModule, pOutput); 1676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (is_dynobj || is_exec) 1686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitProgramHeader<32>(pOutput); 1696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSectionHeader<32>(pModule, m_Config, pOutput); 17137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (m_Config.targets().is64Bits()) { 1726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out ELF header 1736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Write out section header table 1746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines writeELFHeader<64>(m_Config, pModule, pOutput); 1756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (is_dynobj || is_exec) 1766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitProgramHeader<64>(pOutput); 1776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSectionHeader<64>(pModule, m_Config, pOutput); 17937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 1800dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return llvm::make_error_code(llvm::errc::function_not_supported); 18137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } 1826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 1836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 1840dea6bc96bb52346737966839ac68644f7939f58Stephen Hines return std::error_code(); 1856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 1866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 18787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines// getOutputSize - count the final output size 18837b74a387bb3993387029859c2d9d051c41c724eStephen Hinessize_t ELFObjectWriter::getOutputSize(const Module& pModule) const { 18987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (m_Config.targets().is32Bits()) { 19087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return getLastStartOffset<32>(pModule) + 19187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sizeof(ELFSizeTraits<32>::Shdr) * pModule.size(); 19287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else if (m_Config.targets().is64Bits()) { 19387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return getLastStartOffset<64>(pModule) + 19487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines sizeof(ELFSizeTraits<64>::Shdr) * pModule.size(); 19587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } else { 19687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines assert(0 && "Invalid ELF Class"); 19787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return 0; 19887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 19987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 20087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 2016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// writeELFHeader - emit ElfXX_Ehdr 20237b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <size_t SIZE> 2036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::writeELFHeader(const LinkerConfig& pConfig, 2046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const Module& pModule, 20537b74a387bb3993387029859c2d9d051c41c724eStephen Hines FileOutputBuffer& pOutput) const { 2066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Ehdr ElfXX_Ehdr; 2076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Shdr ElfXX_Shdr; 2086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Phdr ElfXX_Phdr; 2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // ELF header must start from 0x0 21187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MemoryRegion region = pOutput.request(0, sizeof(ElfXX_Ehdr)); 21237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ElfXX_Ehdr* header = reinterpret_cast<ElfXX_Ehdr*>(region.begin()); 2136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 21437b74a387bb3993387029859c2d9d051c41c724eStephen Hines memcpy(header->e_ident, llvm::ELF::ElfMagic, llvm::ELF::EI_MAG3 + 1); 2156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 21637b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_ident[llvm::ELF::EI_CLASS] = 21737b74a387bb3993387029859c2d9d051c41c724eStephen Hines (SIZE == 32) ? llvm::ELF::ELFCLASS32 : llvm::ELF::ELFCLASS64; 21837b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_ident[llvm::ELF::EI_DATA] = 21937b74a387bb3993387029859c2d9d051c41c724eStephen Hines pConfig.targets().isLittleEndian() 22037b74a387bb3993387029859c2d9d051c41c724eStephen Hines ? llvm::ELF::ELFDATA2LSB : llvm::ELF::ELFDATA2MSB; 22137b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_ident[llvm::ELF::EI_VERSION] = target().getInfo().ELFVersion(); 22237b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_ident[llvm::ELF::EI_OSABI] = target().getInfo().OSABI(); 22337b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_ident[llvm::ELF::EI_ABIVERSION] = target().getInfo().ABIVersion(); 2246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // FIXME: add processor-specific and core file types. 22637b74a387bb3993387029859c2d9d051c41c724eStephen Hines switch (pConfig.codeGenType()) { 2276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LinkerConfig::Object: 22837b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_type = llvm::ELF::ET_REL; 2296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 2306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LinkerConfig::DynObj: 23137b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_type = llvm::ELF::ET_DYN; 2326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 2336f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LinkerConfig::Exec: 23437b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_type = llvm::ELF::ET_EXEC; 2356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 2366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 23737b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::errs() << "unspported output file type: " << pConfig.codeGenType() 23837b74a387bb3993387029859c2d9d051c41c724eStephen Hines << ".\n"; 23937b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_type = llvm::ELF::ET_NONE; 2406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 24137b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_machine = target().getInfo().machine(); 24237b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_version = header->e_ident[llvm::ELF::EI_VERSION]; 24337b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_entry = getEntryPoint(pConfig, pModule); 2446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object != pConfig.codeGenType()) 24637b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_phoff = sizeof(ElfXX_Ehdr); 2476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 24837b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_phoff = 0x0; 2496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 25037b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_shoff = getLastStartOffset<SIZE>(pModule); 25137b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_flags = target().getInfo().flags(); 25237b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_ehsize = sizeof(ElfXX_Ehdr); 2536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_phentsize = sizeof(ElfXX_Phdr); 25437b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_phnum = target().elfSegmentTable().size(); 2556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines header->e_shentsize = sizeof(ElfXX_Shdr); 25637b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_shnum = pModule.size(); 25737b74a387bb3993387029859c2d9d051c41c724eStephen Hines header->e_shstrndx = pModule.getSection(".shstrtab")->index(); 2586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 2596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getEntryPoint 2616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getEntryPoint(const LinkerConfig& pConfig, 26237b74a387bb3993387029859c2d9d051c41c724eStephen Hines const Module& pModule) const { 26387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines llvm::StringRef entry_name = target().getEntry(pModule); 2646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t result = 0x0; 2656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 26687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines bool issue_warning = (pModule.getScript().hasEntry() && 2676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkerConfig::Object != pConfig.codeGenType() && 2686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines LinkerConfig::DynObj != pConfig.codeGenType()); 2696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSymbol* entry_symbol = pModule.getNamePool().findSymbol(entry_name); 2716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 2726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // found the symbol 27337b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (entry_symbol != NULL) { 2746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (entry_symbol->desc() != ResolveInfo::Define && issue_warning) { 27537b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::errs() << "WARNING: entry symbol '" << entry_symbol->name() 2766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << "' exists but is not defined.\n"; 2776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result = entry_symbol->value(); 27937b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 28037b74a387bb3993387029859c2d9d051c41c724eStephen Hines // not in the symbol pool 2816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // We should parse entry as a number. 2826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // @ref GNU ld manual, Options -e. e.g., -e 0x1000. 2836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines char* endptr; 2846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result = strtoull(entry_name.data(), &endptr, 0); 2856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (*endptr != '\0') { 2866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (issue_warning) { 28737b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::errs() << "cannot find entry symbol '" << entry_name.data() 2886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << "'.\n"; 28922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines result = 0x0; 29122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 2926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 2936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return result; 2946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 29522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 2966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// emitSectionHeader - emit ElfXX_Shdr 29737b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <size_t SIZE> 2986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitSectionHeader(const Module& pModule, 2996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LinkerConfig& pConfig, 30037b74a387bb3993387029859c2d9d051c41c724eStephen Hines FileOutputBuffer& pOutput) const { 3016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Shdr ElfXX_Shdr; 30222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // emit section header 3046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int sectNum = pModule.size(); 3056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int header_size = sizeof(ElfXX_Shdr) * sectNum; 30637b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion region = 30737b74a387bb3993387029859c2d9d051c41c724eStephen Hines pOutput.request(getLastStartOffset<SIZE>(pModule), header_size); 30837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ElfXX_Shdr* shdr = reinterpret_cast<ElfXX_Shdr*>(region.begin()); 30922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Iterate the SectionTable in LDContext 3116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines unsigned int sectIdx = 0; 31237b74a387bb3993387029859c2d9d051c41c724eStephen Hines unsigned int shstridx = 0; // NULL section has empty name 3136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (; sectIdx < sectNum; ++sectIdx) { 31437b74a387bb3993387029859c2d9d051c41c724eStephen Hines const LDSection* ld_sect = pModule.getSectionTable().at(sectIdx); 31537b74a387bb3993387029859c2d9d051c41c724eStephen Hines shdr[sectIdx].sh_name = shstridx; 31637b74a387bb3993387029859c2d9d051c41c724eStephen Hines shdr[sectIdx].sh_type = ld_sect->type(); 31737b74a387bb3993387029859c2d9d051c41c724eStephen Hines shdr[sectIdx].sh_flags = ld_sect->flag(); 31837b74a387bb3993387029859c2d9d051c41c724eStephen Hines shdr[sectIdx].sh_addr = ld_sect->addr(); 31937b74a387bb3993387029859c2d9d051c41c724eStephen Hines shdr[sectIdx].sh_offset = ld_sect->offset(); 32037b74a387bb3993387029859c2d9d051c41c724eStephen Hines shdr[sectIdx].sh_size = ld_sect->size(); 3216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shdr[sectIdx].sh_addralign = ld_sect->align(); 32237b74a387bb3993387029859c2d9d051c41c724eStephen Hines shdr[sectIdx].sh_entsize = getSectEntrySize<SIZE>(*ld_sect); 32337b74a387bb3993387029859c2d9d051c41c724eStephen Hines shdr[sectIdx].sh_link = getSectLink(*ld_sect, pConfig); 32437b74a387bb3993387029859c2d9d051c41c724eStephen Hines shdr[sectIdx].sh_info = getSectInfo(*ld_sect); 3256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // adjust strshidx 3276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstridx += ld_sect->name().size() + 1; 32822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 3296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// emitProgramHeader - emit ElfXX_Phdr 33237b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <size_t SIZE> 33337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ELFObjectWriter::emitProgramHeader(FileOutputBuffer& pOutput) const { 3346f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Ehdr ElfXX_Ehdr; 3356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Phdr ElfXX_Phdr; 3366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t start_offset, phdr_size; 33822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines start_offset = sizeof(ElfXX_Ehdr); 3406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines phdr_size = sizeof(ElfXX_Phdr); 3416f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Program header must start directly after ELF header 34237b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion region = pOutput.request( 34337b74a387bb3993387029859c2d9d051c41c724eStephen Hines start_offset, target().elfSegmentTable().size() * phdr_size); 3446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 34537b74a387bb3993387029859c2d9d051c41c724eStephen Hines ElfXX_Phdr* phdr = reinterpret_cast<ElfXX_Phdr*>(region.begin()); 3466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // Iterate the elf segment table in GNULDBackend 3486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t index = 0; 3496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines ELFSegmentFactory::const_iterator seg = target().elfSegmentTable().begin(), 35037b74a387bb3993387029859c2d9d051c41c724eStephen Hines segEnd = target().elfSegmentTable().end(); 3516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (; seg != segEnd; ++seg, ++index) { 35237b74a387bb3993387029859c2d9d051c41c724eStephen Hines phdr[index].p_type = (*seg)->type(); 35337b74a387bb3993387029859c2d9d051c41c724eStephen Hines phdr[index].p_flags = (*seg)->flag(); 35487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines phdr[index].p_offset = (*seg)->offset(); 35537b74a387bb3993387029859c2d9d051c41c724eStephen Hines phdr[index].p_vaddr = (*seg)->vaddr(); 35637b74a387bb3993387029859c2d9d051c41c724eStephen Hines phdr[index].p_paddr = (*seg)->paddr(); 35787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines phdr[index].p_filesz = (*seg)->filesz(); 35837b74a387bb3993387029859c2d9d051c41c724eStephen Hines phdr[index].p_memsz = (*seg)->memsz(); 35937b74a387bb3993387029859c2d9d051c41c724eStephen Hines phdr[index].p_align = (*seg)->align(); 36022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao } 3616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 36222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 3636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitShStrTab - emit section string table 36437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ELFObjectWriter::emitShStrTab(const LDSection& pShStrTab, 36537b74a387bb3993387029859c2d9d051c41c724eStephen Hines const Module& pModule, 36637b74a387bb3993387029859c2d9d051c41c724eStephen Hines FileOutputBuffer& pOutput) { 3676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // write out data 36887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines MemoryRegion region = pOutput.request(pShStrTab.offset(), pShStrTab.size()); 36937b74a387bb3993387029859c2d9d051c41c724eStephen Hines char* data = reinterpret_cast<char*>(region.begin()); 3706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t shstrsize = 0; 3716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines Module::const_iterator section, sectEnd = pModule.end(); 3726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (section = pModule.begin(); section != sectEnd; ++section) { 37337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ::memcpy(reinterpret_cast<char*>(data + shstrsize), 37437b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*section)->name().data(), 37537b74a387bb3993387029859c2d9d051c41c724eStephen Hines (*section)->name().size()); 3766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines shstrsize += (*section)->name().size() + 1; 3776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 3806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitSectionData 38137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesvoid ELFObjectWriter::emitSectionData(const LDSection& pSection, 38237b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion& pRegion) const { 3836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const SectionData* sd = NULL; 3846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch (pSection.kind()) { 3856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::Relocation: 3866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(pSection.hasRelocData()); 3876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return; 3886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case LDFileFormat::EhFrame: 3896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(pSection.hasEhFrame()); 390f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines sd = pSection.getEhFrame()->getSectionData(); 3916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 3926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 3936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(pSection.hasSectionData()); 3946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines sd = pSection.getSectionData(); 3956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 3966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 3976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitSectionData(*sd, pRegion); 3986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 3996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 40087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines/// emitEhFrame 40187f34658dec9097d987d254a990ea7f311bfc95fStephen Hinesvoid ELFObjectWriter::emitEhFrame(Module& pModule, 40237b74a387bb3993387029859c2d9d051c41c724eStephen Hines EhFrame& pFrame, 40337b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion& pRegion) const { 40487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines emitSectionData(*pFrame.getSectionData(), pRegion); 40587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 40687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Patch FDE field (offset to CIE) 40787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines for (EhFrame::cie_iterator i = pFrame.cie_begin(), e = pFrame.cie_end(); 40837b74a387bb3993387029859c2d9d051c41c724eStephen Hines i != e; 40937b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++i) { 41087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::CIE& cie = **i; 41137b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (EhFrame::fde_iterator fi = cie.begin(), fe = cie.end(); fi != fe; 41237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++fi) { 41387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::FDE& fde = **fi; 41487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (fde.getRecordType() == EhFrame::RECORD_GENERATED) { 41587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Patch PLT offset 41687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines LDSection* plt_sect = pModule.getSection(".plt"); 41737b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(plt_sect && "We have no plt but have corresponding eh_frame?"); 41887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t plt_offset = plt_sect->offset(); 41987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // FDE entry for PLT is always 32-bit 42087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t fde_offset = pFrame.getSection().offset() + fde.getOffset() + 42187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::getDataStartOffset<32>(); 42287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int32_t offset = fde_offset - plt_offset; 42387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (plt_offset < fde_offset) 42487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset = -offset; 42587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines memcpy(pRegion.begin() + fde.getOffset() + 42637b74a387bb3993387029859c2d9d051c41c724eStephen Hines EhFrame::getDataStartOffset<32>(), 42737b74a387bb3993387029859c2d9d051c41c724eStephen Hines &offset, 42837b74a387bb3993387029859c2d9d051c41c724eStephen Hines 4); 42987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint32_t size = plt_sect->size(); 43087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines memcpy(pRegion.begin() + fde.getOffset() + 43137b74a387bb3993387029859c2d9d051c41c724eStephen Hines EhFrame::getDataStartOffset<32>() + 4, 43237b74a387bb3993387029859c2d9d051c41c724eStephen Hines &size, 43337b74a387bb3993387029859c2d9d051c41c724eStephen Hines 4); 43487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines } 43587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t fde_cie_ptr_offset = fde.getOffset() + 43687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines EhFrame::getDataStartOffset<32>() - 43737b74a387bb3993387029859c2d9d051c41c724eStephen Hines /*ID*/ 4; 43887f34658dec9097d987d254a990ea7f311bfc95fStephen Hines uint64_t cie_start_offset = cie.getOffset(); 43987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines int32_t offset = fde_cie_ptr_offset - cie_start_offset; 44087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (fde_cie_ptr_offset < cie_start_offset) 44187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines offset = -offset; 44287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines memcpy(pRegion.begin() + fde_cie_ptr_offset, &offset, 4); 44337b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for loop fde_iterator 44437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } // for loop cie_iterator 44587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines} 44687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 4476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitRelocation 4486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitRelocation(const LinkerConfig& pConfig, 4496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection& pSection, 45037b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion& pRegion) const { 4516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const RelocData* sect_data = pSection.getRelocData(); 45237b74a387bb3993387029859c2d9d051c41c724eStephen Hines assert(sect_data != NULL && "SectionData is NULL in emitRelocation!"); 4536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 45437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (pSection.type() == llvm::ELF::SHT_REL) { 4556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pConfig.targets().is32Bits()) 4566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitRel<32>(pConfig, *sect_data, pRegion); 4576f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (pConfig.targets().is64Bits()) 4586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitRel<64>(pConfig, *sect_data, pRegion); 4596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 4606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str() 4616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << pConfig.targets().bitclass(); 4626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 46337b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (pSection.type() == llvm::ELF::SHT_RELA) { 4646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (pConfig.targets().is32Bits()) 4656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitRela<32>(pConfig, *sect_data, pRegion); 4666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else if (pConfig.targets().is64Bits()) 4676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines emitRela<64>(pConfig, *sect_data, pRegion); 4686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else { 4696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str() 4706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines << pConfig.targets().bitclass(); 4716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 4726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } else 4736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::report_fatal_error("unsupported relocation section type!"); 4746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 4756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// emitRel - emit ElfXX_Rel 47737b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <size_t SIZE> 4786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitRel(const LinkerConfig& pConfig, 4796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const RelocData& pRelocData, 48037b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion& pRegion) const { 48137b74a387bb3993387029859c2d9d051c41c724eStephen Hines typedef typename ELFSizeTraits<SIZE>::Rel ElfXX_Rel; 4826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Addr ElfXX_Addr; 4836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word; 4846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 48587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ElfXX_Rel* rel = reinterpret_cast<ElfXX_Rel*>(pRegion.begin()); 4866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const Relocation* relocation = 0; 4886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const FragmentRef* frag_ref = 0; 4896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 49037b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (RelocData::const_iterator it = pRelocData.begin(), ie = pRelocData.end(); 49137b74a387bb3993387029859c2d9d051c41c724eStephen Hines it != ie; 49237b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it, ++rel) { 49387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ElfXX_Addr r_offset = 0; 49487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ElfXX_Word r_sym = 0; 4956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 4966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines relocation = &(llvm::cast<Relocation>(*it)); 4976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines frag_ref = &(relocation->targetRef()); 4986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 49937b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (LinkerConfig::DynObj == pConfig.codeGenType() || 50037b74a387bb3993387029859c2d9d051c41c724eStephen Hines LinkerConfig::Exec == pConfig.codeGenType()) { 50187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_offset = static_cast<ElfXX_Addr>( 50237b74a387bb3993387029859c2d9d051c41c724eStephen Hines frag_ref->frag()->getParent()->getSection().addr() + 50337b74a387bb3993387029859c2d9d051c41c724eStephen Hines frag_ref->getOutputOffset()); 50437b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 50587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_offset = static_cast<ElfXX_Addr>(frag_ref->getOutputOffset()); 5066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 50787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines 50837b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (relocation->symInfo() == NULL) 50987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_sym = 0; 5106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 51187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_sym = static_cast<ElfXX_Word>( 51237b74a387bb3993387029859c2d9d051c41c724eStephen Hines target().getSymbolIdx(relocation->symInfo()->outSymbol())); 5136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 51487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines target().emitRelocation(*rel, relocation->type(), r_sym, r_offset); 5156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 5166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5176f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines// emitRela - emit ElfXX_Rela 51937b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <size_t SIZE> 5206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitRela(const LinkerConfig& pConfig, 5216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const RelocData& pRelocData, 52237b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion& pRegion) const { 5236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Rela ElfXX_Rela; 5246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Addr ElfXX_Addr; 5256f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word; 5266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 52787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ElfXX_Rela* rel = reinterpret_cast<ElfXX_Rela*>(pRegion.begin()); 5286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const Relocation* relocation = 0; 5306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const FragmentRef* frag_ref = 0; 5316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 53237b74a387bb3993387029859c2d9d051c41c724eStephen Hines for (RelocData::const_iterator it = pRelocData.begin(), ie = pRelocData.end(); 53337b74a387bb3993387029859c2d9d051c41c724eStephen Hines it != ie; 53437b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it, ++rel) { 53587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ElfXX_Addr r_offset = 0; 53687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines ElfXX_Word r_sym = 0; 5376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines relocation = &(llvm::cast<Relocation>(*it)); 5396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines frag_ref = &(relocation->targetRef()); 5406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 54137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (LinkerConfig::DynObj == pConfig.codeGenType() || 54237b74a387bb3993387029859c2d9d051c41c724eStephen Hines LinkerConfig::Exec == pConfig.codeGenType()) { 54387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_offset = static_cast<ElfXX_Addr>( 54437b74a387bb3993387029859c2d9d051c41c724eStephen Hines frag_ref->frag()->getParent()->getSection().addr() + 54537b74a387bb3993387029859c2d9d051c41c724eStephen Hines frag_ref->getOutputOffset()); 54637b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 54787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_offset = static_cast<ElfXX_Addr>(frag_ref->getOutputOffset()); 5486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 5496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 55037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (relocation->symInfo() == NULL) 55187f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_sym = 0; 5526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 55387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines r_sym = static_cast<ElfXX_Word>( 55437b74a387bb3993387029859c2d9d051c41c724eStephen Hines target().getSymbolIdx(relocation->symInfo()->outSymbol())); 5556f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 55637b74a387bb3993387029859c2d9d051c41c724eStephen Hines target().emitRelocation( 55737b74a387bb3993387029859c2d9d051c41c724eStephen Hines *rel, relocation->type(), r_sym, r_offset, relocation->addend()); 5586f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 5596f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5606f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSectEntrySize - compute ElfXX_Shdr::sh_entsize 56237b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <size_t SIZE> 56337b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t ELFObjectWriter::getSectEntrySize(const LDSection& pSection) const { 5646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word; 56537b74a387bb3993387029859c2d9d051c41c724eStephen Hines typedef typename ELFSizeTraits<SIZE>::Sym ElfXX_Sym; 56637b74a387bb3993387029859c2d9d051c41c724eStephen Hines typedef typename ELFSizeTraits<SIZE>::Rel ElfXX_Rel; 5676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines typedef typename ELFSizeTraits<SIZE>::Rela ElfXX_Rela; 56837b74a387bb3993387029859c2d9d051c41c724eStephen Hines typedef typename ELFSizeTraits<SIZE>::Dyn ElfXX_Dyn; 5696f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5706f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_DYNSYM == pSection.type() || 5716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHT_SYMTAB == pSection.type()) 5726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return sizeof(ElfXX_Sym); 5736f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_REL == pSection.type()) 5746f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return sizeof(ElfXX_Rel); 5756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_RELA == pSection.type()) 5766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return sizeof(ElfXX_Rela); 57737b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (llvm::ELF::SHT_HASH == pSection.type() || 5786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHT_GNU_HASH == pSection.type()) 5796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return sizeof(ElfXX_Word); 5806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_DYNAMIC == pSection.type()) 5816f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return sizeof(ElfXX_Dyn); 58287f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // FIXME: We should get the entsize from input since the size of each 58387f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // character is specified in the section header's sh_entsize field. 58487f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // For example, traditional string is 0x1, UCS-2 is 0x2, ... and so on. 58587f34658dec9097d987d254a990ea7f311bfc95fStephen Hines // Ref: http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html 58687f34658dec9097d987d254a990ea7f311bfc95fStephen Hines if (pSection.flag() & llvm::ELF::SHF_STRINGS) 58787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines return 0x1; 5886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return 0x0; 5896f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 5906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 5916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSectLink - compute ElfXX_Shdr::sh_link 5926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesuint64_t ELFObjectWriter::getSectLink(const LDSection& pSection, 59337b74a387bb3993387029859c2d9d051c41c724eStephen Hines const LinkerConfig& pConfig) const { 5946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_SYMTAB == pSection.type()) 5956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getOutputFormat()->getStrTab().index(); 5966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_DYNSYM == pSection.type()) 5976f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getOutputFormat()->getDynStrTab().index(); 5986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_DYNAMIC == pSection.type()) 5996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getOutputFormat()->getDynStrTab().index(); 60037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (llvm::ELF::SHT_HASH == pSection.type() || 6016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHT_GNU_HASH == pSection.type()) 6026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getOutputFormat()->getDynSymTab().index(); 6036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_REL == pSection.type() || 6046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHT_RELA == pSection.type()) { 6056f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (LinkerConfig::Object == pConfig.codeGenType()) 6066f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getOutputFormat()->getSymTab().index(); 6076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines else 6086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getOutputFormat()->getDynSymTab().index(); 6096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6106f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // FIXME: currently we link ARM_EXIDX section to output text section here 6116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_ARM_EXIDX == pSection.type()) 6126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return target().getOutputFormat()->getText().index(); 6136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return llvm::ELF::SHN_UNDEF; 6146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 6156f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6166f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getSectInfo - compute ElfXX_Shdr::sh_info 61737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t ELFObjectWriter::getSectInfo(const LDSection& pSection) const { 6186f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_SYMTAB == pSection.type() || 6196f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHT_DYNSYM == pSection.type()) 6206f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return pSection.getInfo(); 6216f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6226f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines if (llvm::ELF::SHT_REL == pSection.type() || 6236f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines llvm::ELF::SHT_RELA == pSection.type()) { 6246f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection* info_link = pSection.getLink(); 62537b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (info_link != NULL) 6266f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return info_link->index(); 6276f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6286f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6296f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return 0x0; 6306f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 6316f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6326f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getLastStartOffset 63337b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <> 63437b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t ELFObjectWriter::getLastStartOffset<32>(const Module& pModule) const { 6356f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection* lastSect = pModule.back(); 6366f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(lastSect != NULL); 6376f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Align<32>(lastSect->offset() + lastSect->size()); 6386f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 6396f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6406f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// getLastStartOffset 64137b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <> 64237b74a387bb3993387029859c2d9d051c41c724eStephen Hinesuint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const { 6436f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const LDSection* lastSect = pModule.back(); 6446f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(lastSect != NULL); 6456f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines return Align<64>(lastSect->offset() + lastSect->size()); 6466f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines} 6476f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6486f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines/// emitSectionData 6496f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hinesvoid ELFObjectWriter::emitSectionData(const SectionData& pSD, 65037b74a387bb3993387029859c2d9d051c41c724eStephen Hines MemoryRegion& pRegion) const { 6516f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines SectionData::const_iterator fragIter, fragEnd = pSD.end(); 6526f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t cur_offset = 0; 6536f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (fragIter = pSD.begin(); fragIter != fragEnd; ++fragIter) { 6546f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines size_t size = fragIter->size(); 65537b74a387bb3993387029859c2d9d051c41c724eStephen Hines switch (fragIter->getKind()) { 6566f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case Fragment::Region: { 65737b74a387bb3993387029859c2d9d051c41c724eStephen Hines const RegionFragment& region_frag = 65837b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::cast<RegionFragment>(*fragIter); 65987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines const char* from = region_frag.getRegion().begin(); 66087f34658dec9097d987d254a990ea7f311bfc95fStephen Hines memcpy(pRegion.begin() + cur_offset, from, size); 6616f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6626f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6636f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case Fragment::Alignment: { 6646f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // TODO: emit values with different sizes (> 1 byte), and emit nops 6656f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const AlignFragment& align_frag = llvm::cast<AlignFragment>(*fragIter); 6666f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t count = size / align_frag.getValueSize(); 6676f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines switch (align_frag.getValueSize()) { 6686f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case 1u: 66937b74a387bb3993387029859c2d9d051c41c724eStephen Hines std::memset( 67037b74a387bb3993387029859c2d9d051c41c724eStephen Hines pRegion.begin() + cur_offset, align_frag.getValue(), count); 6716f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6726f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 67337b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::report_fatal_error( 67437b74a387bb3993387029859c2d9d051c41c724eStephen Hines "unsupported value size for align fragment emission yet.\n"); 6756f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6766f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6776f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6786f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6796f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case Fragment::Fillment: { 6806f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const FillFragment& fill_frag = llvm::cast<FillFragment>(*fragIter); 68137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (0 == size || 0 == fill_frag.getValueSize() || 6826f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 0 == fill_frag.size()) { 6836f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines // ignore virtual fillment 6846f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6856f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6866f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines 6876f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines uint64_t num_tiles = fill_frag.size() / fill_frag.getValueSize(); 6886f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines for (uint64_t i = 0; i != num_tiles; ++i) { 68987f34658dec9097d987d254a990ea7f311bfc95fStephen Hines std::memset(pRegion.begin() + cur_offset, 6906f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fill_frag.getValue(), 6916f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines fill_frag.getValueSize()); 6926f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6936f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6946f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 6956f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case Fragment::Stub: { 6966f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines const Stub& stub_frag = llvm::cast<Stub>(*fragIter); 69787f34658dec9097d987d254a990ea7f311bfc95fStephen Hines memcpy(pRegion.begin() + cur_offset, stub_frag.getContent(), size); 6986f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 6996f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7006f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case Fragment::Null: { 7016f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines assert(0x0 == size); 7026f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 7036f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7046f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines case Fragment::Target: 70537b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::report_fatal_error( 70637b74a387bb3993387029859c2d9d051c41c724eStephen Hines "Target fragment should not be in a regular section.\n"); 7076f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 7086f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines default: 70937b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::report_fatal_error( 71037b74a387bb3993387029859c2d9d051c41c724eStephen Hines "invalid fragment should not be in a regular section.\n"); 7116f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines break; 7126f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 7136f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines cur_offset += size; 7146f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines } 71522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao} 7165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 71737b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 718