15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- ELFWriter.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//===----------------------------------------------------------------------===// 9cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 10cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cstdlib> 11cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <cstring> 12cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ELF.h> 14cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <llvm/Support/Casting.h> 15cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/ADT/SizeTraits.h> 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLDInfo.h> 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/MC/MCLinker.h> 19cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/AlignFragment.h> 20cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/FillFragment.h> 21cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/LD/RegionFragment.h> 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/ELFWriter.h> 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDSymbol.h> 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/LDSection.h> 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/LD/Layout.h> 26affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/ELFSegment.h> 27affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/LD/ELFSegmentFactory.h> 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Target/GNULDBackend.h> 29cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao#include <mcld/Support/MemoryRegion.h> 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace llvm::ELF; 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaousing namespace mcld; 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// writeELF32Header - write ELF header 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFWriter::writeELF32Header(const MCLDInfo& pLDInfo, 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Layout& pLayout, 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const GNULDBackend& pBackend, 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Output& pOutput) const 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pOutput.hasMemArea()); 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // ELF header must start from 0x0 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion *region = pOutput.memArea()->request(0, 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sizeof(Elf32_Ehdr)); 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Elf32_Ehdr* header = (Elf32_Ehdr*)region->start(); 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao memcpy(header->e_ident, ElfMagic, EI_MAG3+1); 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_ident[EI_CLASS] = ELFCLASS32; 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_ident[EI_DATA] = pBackend.isLittleEndian()? 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFDATA2LSB : ELFDATA2MSB; 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_ident[EI_VERSION] = pBackend.ELFVersion(); 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_ident[EI_OSABI] = pBackend.OSABI(); 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_ident[EI_ABIVERSION] = pBackend.ABIVersion(); 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: add processor-specific and core file types. 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(pOutput.type()) { 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Output::Object: 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_type = ET_REL; 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Output::DynObj: 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_type = ET_DYN; 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Output::Exec: 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_type = ET_EXEC; 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::errs() << "unspported output file type: " << pOutput.type() << ".\n"; 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_type = ET_NONE; 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_machine = pBackend.machine(); 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_version = header->e_ident[EI_VERSION]; 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_entry = getEntryPoint(pLDInfo, pLayout, pBackend, pOutput); 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_phoff = sizeof(Elf32_Ehdr); 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_shoff = getELF32LastStartOffset(pOutput); 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_flags = pBackend.flags(); 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_ehsize = sizeof(Elf32_Ehdr); 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_phentsize = sizeof(Elf32_Phdr); 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_phnum = pBackend.numOfSegments(); 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_shentsize = sizeof(Elf32_Shdr); 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_shnum = pOutput.context()->numOfSections(); 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_shstrndx = pOutput.context()->getSectionIdx(".shstrtab"); 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// writeELF64Header - write ELF header 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFWriter::writeELF64Header(const MCLDInfo& pLDInfo, 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Layout& pLayout, 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const GNULDBackend& pBackend, 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Output& pOutput) const 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(pOutput.hasMemArea()); 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // ELF header must start from 0x0 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion *region = pOutput.memArea()->request(0, 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao sizeof(Elf64_Ehdr)); 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Elf64_Ehdr* header = (Elf64_Ehdr*)region->start(); 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao memcpy(header->e_ident, ElfMagic, EI_MAG3+1); 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_ident[EI_CLASS] = ELFCLASS64; 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_ident[EI_DATA] = pBackend.isLittleEndian()? 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ELFDATA2LSB : ELFDATA2MSB; 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_ident[EI_VERSION] = pBackend.ELFVersion(); 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_ident[EI_OSABI] = pBackend.OSABI(); 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_ident[EI_ABIVERSION] = pBackend.ABIVersion(); 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: add processor-specific and core file types. 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(pOutput.type()) { 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Output::Object: 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_type = ET_REL; 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Output::DynObj: 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_type = ET_DYN; 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case Output::Exec: 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_type = ET_EXEC; 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::errs() << "unspported output file type: " << pOutput.type() << ".\n"; 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_type = ET_NONE; 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_machine = pBackend.machine(); 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_version = header->e_ident[EI_VERSION]; 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_entry = getEntryPoint(pLDInfo, pLayout, pBackend, pOutput); 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_phoff = sizeof(Elf64_Ehdr); 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_shoff = getELF64LastStartOffset(pOutput); 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_flags = pBackend.flags(); 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_ehsize = sizeof(Elf64_Ehdr); 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_phentsize = sizeof(Elf64_Phdr); 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_phnum = pBackend.numOfSegments(); 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_shentsize = sizeof(Elf64_Shdr); 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_shnum = pOutput.context()->numOfSections(); 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header->e_shstrndx = pOutput.context()->getSectionIdx(".shstrtab"); 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getEntryPoint 1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ELFWriter::getEntryPoint(const MCLDInfo& pLDInfo, 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Layout& pLayout, 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const GNULDBackend& pBackend, 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput) const 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::StringRef entry_name; 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pLDInfo.options().hasEntry()) 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry_name = pLDInfo.options().entry(); 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry_name = pBackend.entry(); 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t result = 0x0; 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool issue_warning = (pLDInfo.options().hasEntry() 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao && (pOutput.type() != Output::Object) 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao && (pOutput.type() != Output::DynObj)); 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 155affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const LDSymbol* entry_symbol = pLDInfo.getNamePool().findSymbol(entry_name); 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // found the symbol 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL != entry_symbol) { 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (entry_symbol->desc() != ResolveInfo::Define && issue_warning) { 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::errs() << "WARNING: entry symbol '" 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao << entry_symbol->name() 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao << "' exists but is not defined.\n"; 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = entry_symbol->value(); 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // not in the symbol pool 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // We should parse entry as a number. 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // @ref GNU ld manual, Options -e. e.g., -e 0x1000. 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao char* endptr; 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = strtoull(entry_name.data(), &endptr, 0); 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (*endptr != '\0') { 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (issue_warning) { 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::errs() << "cannot find entry symbol '" 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao << entry_name.data() 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao << "'.\n"; 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao result = 0x0; 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return result; 1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitELF32SectionHeader - emit Elf32_Shdr 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid 1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFWriter::emitELF32SectionHeader(Output& pOutput, MCLinker& pLinker) const 1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit section header 1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int sectNum = pOutput.context()->numOfSections(); 1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int header_size = sizeof(Elf32_Shdr) * sectNum; 1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* region = pOutput.memArea()->request( 1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao getELF32LastStartOffset(pOutput), 1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header_size); 1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Elf32_Shdr* shdr = (Elf32_Shdr*)region->start(); 1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Iterate the SectionTable in LDContext 1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int sectIdx = 0; 1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int shstridx = 0; // NULL section has empty name 1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (; sectIdx < sectNum; ++sectIdx) { 2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSection *ld_sect = pOutput.context()->getSection(sectIdx); 2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_name = shstridx; 2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_type = ld_sect->type(); 2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_flags = ld_sect->flag(); 2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_addr = ld_sect->addr(); 2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_offset = ld_sect->offset(); 2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_size = ld_sect->size(); 2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_addralign = ld_sect->align(); 2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_entsize = getELF32SectEntrySize(*ld_sect); 2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_link = getSectLink(*ld_sect, pOutput); 2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_info = getSectInfo(*ld_sect, pOutput); 2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // adjust strshidx 2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstridx += ld_sect->name().size() + 1; 2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitELF64SectionHeader - emit Elf64_Shdr 2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid 2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFWriter::emitELF64SectionHeader(Output& pOutput, MCLinker& pLinker) const 2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // emit section header 2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int sectNum = pOutput.context()->numOfSections(); 2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int header_size = sizeof(Elf64_Shdr) * sectNum; 2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* region = pOutput.memArea()->request( 2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao getELF64LastStartOffset(pOutput), 2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao header_size); 2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Elf64_Shdr* shdr = (Elf64_Shdr*)region->start(); 2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Iterate the SectionTable in LDContext 2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int sectIdx = 0; 2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int shstridx = 0; // NULL section has empty name 2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (; sectIdx < sectNum; ++sectIdx) { 2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSection *ld_sect = pOutput.context()->getSection(sectIdx); 2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_name = shstridx; 2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_type = ld_sect->type(); 2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_flags = ld_sect->flag(); 2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_addr = ld_sect->addr(); 2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_offset = ld_sect->offset(); 2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_size = ld_sect->size(); 2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_addralign = (ld_sect->hasSectionData())? 2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ld_sect->getSectionData()->getAlignment(): 2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0; 2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_entsize = getELF64SectEntrySize(*ld_sect); 2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_link = getSectLink(*ld_sect, pOutput); 2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shdr[sectIdx].sh_info = getSectInfo(*ld_sect, pOutput); 2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // adjust strshidx 2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstridx += ld_sect->name().size() + 1; 2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 253affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 254affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// emitELF32ProgramHeader - emit Elf32_Phdr 255affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid ELFWriter::emitELF32ProgramHeader(Output& pOutput, 256affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const GNULDBackend& pBackend) const 257affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 258affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(pOutput.hasMemArea()); 259affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 260affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint64_t start_offset, phdr_size; 261affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 262affc150dc44fab1911775a49636d0ce85333b634Zonr Chang start_offset = sizeof(Elf32_Ehdr); 263affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr_size = sizeof(Elf32_Phdr); 264affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Program header must start directly after ELF header 265affc150dc44fab1911775a49636d0ce85333b634Zonr Chang MemoryRegion *region = pOutput.memArea()->request(start_offset, 266affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pBackend.numOfSegments() * phdr_size); 267affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 268affc150dc44fab1911775a49636d0ce85333b634Zonr Chang Elf32_Phdr* phdr = (Elf32_Phdr*)region->start(); 269affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 270affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Iterate the elf segment table in GNULDBackend 271affc150dc44fab1911775a49636d0ce85333b634Zonr Chang size_t index = 0; 272affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFSegmentFactory::const_iterator seg = pBackend.elfSegmentTable().begin(), 273affc150dc44fab1911775a49636d0ce85333b634Zonr Chang segEnd = pBackend.elfSegmentTable().end(); 274affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (; seg != segEnd; ++seg, ++index) { 275affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_type = (*seg).type(); 276affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_flags = (*seg).flag(); 277affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_offset = (*seg).offset(); 278affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_vaddr = (*seg).vaddr(); 279affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_paddr = (*seg).paddr(); 280affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_filesz = (*seg).filesz(); 281affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_memsz = (*seg).memsz(); 282affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_align = (*seg).align(); 283affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 284affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 286affc150dc44fab1911775a49636d0ce85333b634Zonr Chang/// emitELF64ProgramHeader - emit ElfR64Phdr 287affc150dc44fab1911775a49636d0ce85333b634Zonr Changvoid ELFWriter::emitELF64ProgramHeader(Output& pOutput, 288affc150dc44fab1911775a49636d0ce85333b634Zonr Chang const GNULDBackend& pBackend) const 289affc150dc44fab1911775a49636d0ce85333b634Zonr Chang{ 290affc150dc44fab1911775a49636d0ce85333b634Zonr Chang assert(pOutput.hasMemArea()); 291affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 292affc150dc44fab1911775a49636d0ce85333b634Zonr Chang uint64_t start_offset, phdr_size; 293affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 294affc150dc44fab1911775a49636d0ce85333b634Zonr Chang start_offset = sizeof(Elf64_Ehdr); 295affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr_size = sizeof(Elf64_Phdr); 296affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Program header must start directly after ELF header 297affc150dc44fab1911775a49636d0ce85333b634Zonr Chang MemoryRegion *region = pOutput.memArea()->request(start_offset, 298affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pBackend.numOfSegments() * phdr_size); 299affc150dc44fab1911775a49636d0ce85333b634Zonr Chang Elf64_Phdr* phdr = (Elf64_Phdr*)region->start(); 300affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 301affc150dc44fab1911775a49636d0ce85333b634Zonr Chang // Iterate the elf segment table in GNULDBackend 302affc150dc44fab1911775a49636d0ce85333b634Zonr Chang size_t index = 0; 303affc150dc44fab1911775a49636d0ce85333b634Zonr Chang ELFSegmentFactory::const_iterator seg = pBackend.elfSegmentTable().begin(), 304affc150dc44fab1911775a49636d0ce85333b634Zonr Chang segEnd = pBackend.elfSegmentTable().end(); 305affc150dc44fab1911775a49636d0ce85333b634Zonr Chang for (; seg != segEnd; ++seg, ++index) { 306affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_type = (*seg).type(); 307affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_flags = (*seg).flag(); 308affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_offset = (*seg).offset(); 309affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_vaddr = (*seg).vaddr(); 310affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_paddr = (*seg).paddr(); 311affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_filesz = (*seg).filesz(); 312affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_memsz = (*seg).memsz(); 313affc150dc44fab1911775a49636d0ce85333b634Zonr Chang phdr[index].p_align = (*seg).align(); 314affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 315affc150dc44fab1911775a49636d0ce85333b634Zonr Chang} 316affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 3175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitELF32ShStrTab - emit section string table 3185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFWriter::emitELF32ShStrTab(Output& pOutput, MCLinker& pLinker) const 3195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t shstroffset = getELF32LastStartOffset(pOutput); 3215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get shstrtab 3235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& shstrtab = pLinker.getOrCreateOutputSectHdr(".shstrtab", 3245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDFileFormat::NamePool, 3255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao SHT_STRTAB, 3265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0); 3275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (0 != shstrtab.size()) 3285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(".shstrtab has been set.\n"); 3295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // compute size 3315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int shstrsize = 0; 3325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDContext::const_sect_iterator section, sectEnd = pOutput.context()->sectEnd(); 3335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) { 3345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrsize += (*section)->name().size() + 1; 3355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrtab.setSize(shstrsize); 3385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrtab.setOffset(shstroffset); 3395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // write out data 3415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* region = pOutput.memArea()->request(shstrtab.offset(), 3425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrtab.size()); 3435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned char* data = region->start(); 3445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrsize = 0; 3455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) { 3465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strcpy((char*)(data + shstrsize), (*section)->name().c_str()); 3475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrsize += (*section)->name().size() + 1; 3485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrtab.setKind(LDFileFormat::NamePool); 3515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrtab.setType(llvm::ELF::SHT_STRTAB); 3525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrtab.setFlag(0x0); 3535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrtab.setAddr(0x0); 3545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitELF64ShStrTab - emit section string table 3585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFWriter::emitELF64ShStrTab(Output& pOutput, MCLinker& pLinker) const 3595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 3605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t shstroffset = getELF64LastStartOffset(pOutput); 3615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // get shstrtab 3635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection& shstrtab = pLinker.getOrCreateOutputSectHdr(".shstrtab", 3645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDFileFormat::NamePool, 3655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao SHT_STRTAB, 3665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0x0); 3675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (0 != shstrtab.size()) 3685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(".shstrtab has been set.\n"); 3695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // compute offset 3715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // compute size 3735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned int shstrsize = 0; 3745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDContext::const_sect_iterator section, sectEnd = pOutput.context()->sectEnd(); 3755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) { 3765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrsize += (*section)->name().size() + 1; 3775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrtab.setSize(shstrsize); 3805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrtab.setOffset(shstroffset); 3815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // write out data 3835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion* region = pOutput.memArea()->request(shstrtab.offset(), 3845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrtab.size()); 3855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao unsigned char* data = region->start(); 3865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrsize = 0; 3875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) { 3885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao strcpy((char*)(data + shstrsize), (*section)->name().c_str()); 3895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrsize += (*section)->name().size() + 1; 3905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 3915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrtab.setKind(LDFileFormat::NamePool); 3935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrtab.setType(llvm::ELF::SHT_STRTAB); 3945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrtab.setFlag(0x0); 3955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao shstrtab.setAddr(0x0); 3965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 3975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitSectionData 3995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid 4005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei LiaoELFWriter::emitSectionData(const Layout& pLayout, 4015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSection& pSection, 4025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const 4035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 404cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao const SectionData* data = pSection.getSectionData(); 405cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao SectionData::const_iterator fragIter, fragEnd = data->end(); 4065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t cur_offset = 0; 4075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (fragIter = data->begin(); fragIter != fragEnd; ++fragIter) { 4085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t size = computeFragmentSize(pLayout, *fragIter); 4095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(fragIter->getKind()) { 410cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Region: { 411cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao const RegionFragment& region_frag = llvm::cast<RegionFragment>(*fragIter); 4125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const uint8_t* from = region_frag.getRegion().start(); 4135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao memcpy(pRegion.getBuffer(cur_offset), from, size); 4145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 4155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 416cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Alignment: { 4175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // TODO: emit values with different sizes (> 1 byte), and emit nops 418cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao AlignFragment& align_frag = llvm::cast<AlignFragment>(*fragIter); 4195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t count = size / align_frag.getValueSize(); 4205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (align_frag.getValueSize()) { 4215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case 1u: 4225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao std::memset(pRegion.getBuffer(cur_offset), 4235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao align_frag.getValue(), 4245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao count); 4255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 4265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 4275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error("unsupported value size for align fragment emission yet.\n"); 4285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 4295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 4315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 432cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Fillment: { 433cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FillFragment& fill_frag = llvm::cast<FillFragment>(*fragIter); 4345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (0 == size || 4355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0 == fill_frag.getValueSize() || 4365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 0 == fill_frag.getSize()) { 4375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // ignore virtual fillment 4385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 4395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao uint64_t num_tiles = fill_frag.getSize() / fill_frag.getValueSize(); 4425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao for (uint64_t i = 0; i != num_tiles; ++i) { 4435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao std::memset(pRegion.getBuffer(cur_offset), 4445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao fill_frag.getValue(), 4455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao fill_frag.getValueSize()); 4465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 4485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 449cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Relocation: 4505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error("relocation fragment should not be in a regular section.\n"); 4515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 452cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao case Fragment::Target: 4535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error("Target fragment should not be in a regular section.\n"); 4545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 4555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 4565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error("invalid fragment should not be in a regular section.\n"); 4575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 4585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao cur_offset += size; 4605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 4615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitRelocation 4645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFWriter::emitRelocation(const Layout& pLayout, 4655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput, 4665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSection& pSection, 4675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const 4685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 469cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao const SectionData* sect_data = pSection.getSectionData(); 470cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao assert(NULL != sect_data && "SectionData is NULL in emitRelocation!"); 4715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pSection.type() == SHT_REL) 473cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao emitRel(pLayout, pOutput, *sect_data, pRegion); 4745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if (pSection.type() == SHT_RELA) 475cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao emitRela(pLayout, pOutput, *sect_data, pRegion); 4765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 4775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error("unsupported relocation section type!"); 4785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 4795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitRel 4825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFWriter::emitRel(const Layout& pLayout, 4835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput, 484cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao const SectionData& pSectionData, 4855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const 4865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 4875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Elf32_Rel* rel = reinterpret_cast<Elf32_Rel*>(pRegion.start()); 4885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Relocation* relocation = 0; 490cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* frag_ref = 0; 4915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 492cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao for (SectionData::const_iterator it = pSectionData.begin(), 4935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ie = pSectionData.end(); it != ie; ++it, ++rel) { 4945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao relocation = &(llvm::cast<Relocation>(*it)); 496cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao frag_ref = &(relocation->targetRef()); 4975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 4985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) { 4995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel->r_offset = static_cast<Elf32_Addr>( 500cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao frag_ref->frag()->getParent()->getSection().addr() + 501cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pLayout.getOutputOffset(*frag_ref)); 5025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 5045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel->r_offset = static_cast<Elf32_Addr>( 505cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao frag_ref->frag()->getParent()->getSection().offset() + 506cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pLayout.getOutputOffset(*frag_ref)); 5075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Elf32_Word Index; 5105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if( relocation->symInfo() == NULL ) 5115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Index = 0; 5125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 5135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Index = static_cast<Elf32_Word>( 5145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao f_Backend.getSymbolIdx(relocation->symInfo()->outSymbol())); 5155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel->setSymbolAndType(Index, relocation->type()); 5175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// emitRela 5215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid ELFWriter::emitRela(const Layout& pLayout, 5225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const Output& pOutput, 523cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao const SectionData& pSectionData, 5245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao MemoryRegion& pRegion) const 5255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Elf32_Rela* rel = reinterpret_cast<Elf32_Rela*>(pRegion.start()); 5275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Relocation* relocation = 0; 529cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao FragmentRef* frag_ref = 0; 5305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 531cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao for (SectionData::const_iterator it = pSectionData.begin(), 5325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ie = pSectionData.end(); it != ie; ++it, ++rel) { 5335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao relocation = &(llvm::cast<Relocation>(*it)); 535cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao frag_ref = &(relocation->targetRef()); 5365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) { 5385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel->r_offset = static_cast<Elf32_Addr>( 539cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao frag_ref->frag()->getParent()->getSection().addr() + 540cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pLayout.getOutputOffset(*frag_ref)); 5415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 5435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel->r_offset = static_cast<Elf32_Addr>( 544cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao frag_ref->frag()->getParent()->getSection().offset() + 545cedee4b38f4786845183be7f5916dd520a170ae0Shih-wei Liao pLayout.getOutputOffset(*frag_ref)); 5465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Elf32_Word Index; 5495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if( relocation->symInfo() == NULL ) 5505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Index = 0; 5515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 5525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao Index = static_cast<Elf32_Word>( 5535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao f_Backend.getSymbolIdx(relocation->symInfo()->outSymbol())); 5545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel->setSymbolAndType(Index, relocation->type()); 5565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao rel->r_addend = relocation->addend(); 5575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 5585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getELF32SectEntrySize - compute Elf32_Shdr::sh_entsize 5615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ELFWriter::getELF32SectEntrySize(const LDSection& pSection) const 5625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::SHT_DYNSYM == pSection.type() || 5645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHT_SYMTAB == pSection.type()) 5655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return sizeof(llvm::ELF::Elf32_Sym); 5665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::SHT_REL == pSection.type()) 5675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return sizeof(llvm::ELF::Elf32_Rel); 5685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::SHT_RELA == pSection.type()) 5695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return sizeof(llvm::ELF::Elf32_Rela); 5705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::SHT_HASH == pSection.type()) 5715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return sizeof(llvm::ELF::Elf32_Word); 5725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::SHT_DYNAMIC == pSection.type()) 5735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return sizeof(llvm::ELF::Elf32_Dyn); 5745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0x0; 5755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getELF64SectEntrySize - compute Elf64_Shdr::sh_entsize 5785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ELFWriter::getELF64SectEntrySize(const LDSection& pSection) const 5795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::SHT_DYNSYM == pSection.type() || 5815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHT_SYMTAB == pSection.type()) 5825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return sizeof(llvm::ELF::Elf64_Sym); 5835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::SHT_REL == pSection.type()) 5845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return sizeof(llvm::ELF::Elf64_Rel); 5855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::SHT_RELA == pSection.type()) 5865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return sizeof(llvm::ELF::Elf64_Rela); 5875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::SHT_HASH == pSection.type()) 5885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return sizeof(llvm::ELF::Elf64_Word); 5895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::SHT_DYNAMIC == pSection.type()) 5905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return sizeof(llvm::ELF::Elf64_Dyn); 5915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0x0; 5925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 5935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSectLink - compute ElfXX_Shdr::sh_link 5955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ELFWriter::getSectLink(const LDSection& pSection, const Output& pOutput) const 5965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 5975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDContext* context = pOutput.context(); 5985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::SHT_SYMTAB == pSection.type()) 5995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return context->getSectionIdx(".strtab"); 6005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::SHT_DYNSYM == pSection.type()) 6015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return context->getSectionIdx(".dynstr"); 6025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::SHT_DYNAMIC == pSection.type()) 6035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return context->getSectionIdx(".dynstr"); 6045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::SHT_HASH == pSection.type()) 6055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return context->getSectionIdx(".dynsym"); 6065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (llvm::ELF::SHT_REL == pSection.type() || 6075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::ELF::SHT_RELA == pSection.type()) { 6085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pOutput.type() == Output::Object) 6095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return context->getSectionIdx(".symtab"); 6105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 6115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return context->getSectionIdx(".dynsym"); 6125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 6135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return llvm::ELF::SHN_UNDEF; 6145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getSectInfo - compute ElfXX_Shdr::sh_info 6175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ELFWriter::getSectInfo(const LDSection& pSection, const Output& pOutput) const 6185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao const LDSection* info_link = pSection.getLink(); 6205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == info_link) 6215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0x0; 6225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return info_link->index(); 6235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getELF32LastStartOffset 6265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ELFWriter::getELF32LastStartOffset(const Output& pOutput) const 6275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection* lastSect = pOutput.context()->getSectionTable().back(); 6295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(lastSect != NULL); 6305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return Align<32>(lastSect->offset() + lastSect->size()); 6315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 6335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// getELF64LastStartOffset 6345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaouint64_t ELFWriter::getELF64LastStartOffset(const Output& pOutput) const 6355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 6365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao LDSection* lastSect = pOutput.context()->getSectionTable().back(); 6375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao assert(lastSect != NULL); 6385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return Align<64>(lastSect->offset() + lastSect->size()); 6395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 6405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 641