ELFObjectWriter.cpp revision 87f34658dec9097d987d254a990ea7f311bfc95f
1//===- ELFObjectWriter.cpp ------------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9#include <mcld/LD/ELFObjectWriter.h> 10 11#include <mcld/Module.h> 12#include <mcld/LinkerConfig.h> 13#include <mcld/LinkerScript.h> 14#include <mcld/Target/GNULDBackend.h> 15#include <mcld/Support/MsgHandling.h> 16#include <mcld/ADT/SizeTraits.h> 17#include <mcld/Fragment/AlignFragment.h> 18#include <mcld/Fragment/FillFragment.h> 19#include <mcld/Fragment/RegionFragment.h> 20#include <mcld/Fragment/Stub.h> 21#include <mcld/Fragment/NullFragment.h> 22#include <mcld/LD/LDSymbol.h> 23#include <mcld/LD/LDSection.h> 24#include <mcld/LD/SectionData.h> 25#include <mcld/LD/ELFSegment.h> 26#include <mcld/LD/ELFSegmentFactory.h> 27#include <mcld/LD/RelocData.h> 28#include <mcld/LD/EhFrame.h> 29#include <mcld/LD/ELFFileFormat.h> 30#include <mcld/Target/GNUInfo.h> 31 32#include <llvm/Support/ErrorHandling.h> 33#include <llvm/Support/system_error.h> 34#include <llvm/Support/ELF.h> 35#include <llvm/Support/Casting.h> 36 37using namespace llvm; 38using namespace llvm::ELF; 39using namespace mcld; 40 41//===----------------------------------------------------------------------===// 42// ELFObjectWriter 43//===----------------------------------------------------------------------===// 44ELFObjectWriter::ELFObjectWriter(GNULDBackend& pBackend, 45 const LinkerConfig& pConfig) 46 : ObjectWriter(), m_Backend(pBackend), m_Config(pConfig) 47{ 48} 49 50ELFObjectWriter::~ELFObjectWriter() 51{ 52} 53 54void ELFObjectWriter::writeSection(Module& pModule, 55 FileOutputBuffer& pOutput, LDSection *section) 56{ 57 MemoryRegion region; 58 // Request output region 59 switch (section->kind()) { 60 case LDFileFormat::Note: 61 if (section->getSectionData() == NULL) 62 return; 63 // Fall through 64 case LDFileFormat::Regular: 65 case LDFileFormat::Relocation: 66 case LDFileFormat::Target: 67 case LDFileFormat::Debug: 68 case LDFileFormat::GCCExceptTable: 69 case LDFileFormat::EhFrame: { 70 region = pOutput.request(section->offset(), section->size()); 71 if (region.size() == 0) { 72 return; 73 } 74 break; 75 } 76 case LDFileFormat::Null: 77 case LDFileFormat::NamePool: 78 case LDFileFormat::BSS: 79 case LDFileFormat::MetaData: 80 case LDFileFormat::Version: 81 case LDFileFormat::EhFrameHdr: 82 case LDFileFormat::StackNote: 83 // Ignore these sections 84 return; 85 default: 86 llvm::errs() << "WARNING: unsupported section kind: " 87 << section->kind() 88 << " of section " 89 << section->name() 90 << ".\n"; 91 return; 92 } 93 94 // Write out sections with data 95 switch(section->kind()) { 96 case LDFileFormat::GCCExceptTable: 97 case LDFileFormat::Regular: 98 case LDFileFormat::Debug: 99 case LDFileFormat::Note: 100 emitSectionData(*section, region); 101 break; 102 case LDFileFormat::EhFrame: 103 emitEhFrame(pModule, *section->getEhFrame(), region); 104 break; 105 case LDFileFormat::Relocation: 106 // sort relocation for the benefit of the dynamic linker. 107 target().sortRelocation(*section); 108 109 emitRelocation(m_Config, *section, region); 110 break; 111 case LDFileFormat::Target: 112 target().emitSectionData(*section, region); 113 break; 114 default: 115 llvm_unreachable("invalid section kind"); 116 } 117} 118 119llvm::error_code ELFObjectWriter::writeObject(Module& pModule, 120 FileOutputBuffer& pOutput) 121{ 122 bool is_dynobj = m_Config.codeGenType() == LinkerConfig::DynObj; 123 bool is_exec = m_Config.codeGenType() == LinkerConfig::Exec; 124 bool is_binary = m_Config.codeGenType() == LinkerConfig::Binary; 125 bool is_object = m_Config.codeGenType() == LinkerConfig::Object; 126 127 assert(is_dynobj || is_exec || is_binary || is_object); 128 129 if (is_dynobj || is_exec) { 130 // Allow backend to sort symbols before emitting 131 target().orderSymbolTable(pModule); 132 133 // Write out the interpreter section: .interp 134 target().emitInterp(pOutput); 135 136 // Write out name pool sections: .dynsym, .dynstr, .hash 137 target().emitDynNamePools(pModule, pOutput); 138 } 139 140 if (is_object || is_dynobj || is_exec) { 141 // Write out name pool sections: .symtab, .strtab 142 target().emitRegNamePools(pModule, pOutput); 143 } 144 145 if (is_binary) { 146 // Iterate over the loadable segments and write the corresponding sections 147 ELFSegmentFactory::iterator seg, segEnd = target().elfSegmentTable().end(); 148 149 for (seg = target().elfSegmentTable().begin(); seg != segEnd; ++seg) { 150 if (llvm::ELF::PT_LOAD == (*seg)->type()) { 151 ELFSegment::iterator sect, sectEnd = (*seg)->end(); 152 for (sect = (*seg)->begin(); sect != sectEnd; ++sect) 153 writeSection(pModule, pOutput, *sect); 154 } 155 } 156 } else { 157 // Write out regular ELF sections 158 Module::iterator sect, sectEnd = pModule.end(); 159 for (sect = pModule.begin(); sect != sectEnd; ++sect) 160 writeSection(pModule, pOutput, *sect); 161 162 emitShStrTab(target().getOutputFormat()->getShStrTab(), pModule, pOutput); 163 164 if (m_Config.targets().is32Bits()) { 165 // Write out ELF header 166 // Write out section header table 167 writeELFHeader<32>(m_Config, pModule, pOutput); 168 if (is_dynobj || is_exec) 169 emitProgramHeader<32>(pOutput); 170 171 emitSectionHeader<32>(pModule, m_Config, pOutput); 172 } 173 else if (m_Config.targets().is64Bits()) { 174 // Write out ELF header 175 // Write out section header table 176 writeELFHeader<64>(m_Config, pModule, pOutput); 177 if (is_dynobj || is_exec) 178 emitProgramHeader<64>(pOutput); 179 180 emitSectionHeader<64>(pModule, m_Config, pOutput); 181 } 182 else 183 return make_error_code(errc::not_supported); 184 } 185 186 return llvm::make_error_code(llvm::errc::success); 187} 188 189// getOutputSize - count the final output size 190size_t ELFObjectWriter::getOutputSize(const Module& pModule) const 191{ 192 if (m_Config.targets().is32Bits()) { 193 return getLastStartOffset<32>(pModule) + 194 sizeof(ELFSizeTraits<32>::Shdr) * pModule.size(); 195 } else if (m_Config.targets().is64Bits()) { 196 return getLastStartOffset<64>(pModule) + 197 sizeof(ELFSizeTraits<64>::Shdr) * pModule.size(); 198 } else { 199 assert(0 && "Invalid ELF Class"); 200 return 0; 201 } 202} 203 204// writeELFHeader - emit ElfXX_Ehdr 205template<size_t SIZE> 206void ELFObjectWriter::writeELFHeader(const LinkerConfig& pConfig, 207 const Module& pModule, 208 FileOutputBuffer& pOutput) const 209{ 210 typedef typename ELFSizeTraits<SIZE>::Ehdr ElfXX_Ehdr; 211 typedef typename ELFSizeTraits<SIZE>::Shdr ElfXX_Shdr; 212 typedef typename ELFSizeTraits<SIZE>::Phdr ElfXX_Phdr; 213 214 // ELF header must start from 0x0 215 MemoryRegion region = pOutput.request(0, sizeof(ElfXX_Ehdr)); 216 ElfXX_Ehdr* header = (ElfXX_Ehdr*)region.begin(); 217 218 memcpy(header->e_ident, ElfMagic, EI_MAG3+1); 219 220 header->e_ident[EI_CLASS] = (SIZE == 32) ? ELFCLASS32 : ELFCLASS64; 221 header->e_ident[EI_DATA] = pConfig.targets().isLittleEndian()? 222 ELFDATA2LSB : ELFDATA2MSB; 223 header->e_ident[EI_VERSION] = target().getInfo().ELFVersion(); 224 header->e_ident[EI_OSABI] = target().getInfo().OSABI(); 225 header->e_ident[EI_ABIVERSION] = target().getInfo().ABIVersion(); 226 227 // FIXME: add processor-specific and core file types. 228 switch(pConfig.codeGenType()) { 229 case LinkerConfig::Object: 230 header->e_type = ET_REL; 231 break; 232 case LinkerConfig::DynObj: 233 header->e_type = ET_DYN; 234 break; 235 case LinkerConfig::Exec: 236 header->e_type = ET_EXEC; 237 break; 238 default: 239 llvm::errs() << "unspported output file type: " << pConfig.codeGenType() << ".\n"; 240 header->e_type = ET_NONE; 241 } 242 header->e_machine = target().getInfo().machine(); 243 header->e_version = header->e_ident[EI_VERSION]; 244 header->e_entry = getEntryPoint(pConfig, pModule); 245 246 if (LinkerConfig::Object != pConfig.codeGenType()) 247 header->e_phoff = sizeof(ElfXX_Ehdr); 248 else 249 header->e_phoff = 0x0; 250 251 header->e_shoff = getLastStartOffset<SIZE>(pModule); 252 header->e_flags = target().getInfo().flags(); 253 header->e_ehsize = sizeof(ElfXX_Ehdr); 254 header->e_phentsize = sizeof(ElfXX_Phdr); 255 header->e_phnum = target().elfSegmentTable().size(); 256 header->e_shentsize = sizeof(ElfXX_Shdr); 257 header->e_shnum = pModule.size(); 258 header->e_shstrndx = pModule.getSection(".shstrtab")->index(); 259} 260 261/// getEntryPoint 262uint64_t ELFObjectWriter::getEntryPoint(const LinkerConfig& pConfig, 263 const Module& pModule) const 264{ 265 llvm::StringRef entry_name = target().getEntry(pModule); 266 uint64_t result = 0x0; 267 268 bool issue_warning = (pModule.getScript().hasEntry() && 269 LinkerConfig::Object != pConfig.codeGenType() && 270 LinkerConfig::DynObj != pConfig.codeGenType()); 271 272 const LDSymbol* entry_symbol = pModule.getNamePool().findSymbol(entry_name); 273 274 // found the symbol 275 if (NULL != entry_symbol) { 276 if (entry_symbol->desc() != ResolveInfo::Define && issue_warning) { 277 llvm::errs() << "WARNING: entry symbol '" 278 << entry_symbol->name() 279 << "' exists but is not defined.\n"; 280 } 281 result = entry_symbol->value(); 282 } 283 // not in the symbol pool 284 else { 285 // We should parse entry as a number. 286 // @ref GNU ld manual, Options -e. e.g., -e 0x1000. 287 char* endptr; 288 result = strtoull(entry_name.data(), &endptr, 0); 289 if (*endptr != '\0') { 290 if (issue_warning) { 291 llvm::errs() << "cannot find entry symbol '" 292 << entry_name.data() 293 << "'.\n"; 294 } 295 result = 0x0; 296 } 297 } 298 return result; 299} 300 301// emitSectionHeader - emit ElfXX_Shdr 302template<size_t SIZE> 303void ELFObjectWriter::emitSectionHeader(const Module& pModule, 304 const LinkerConfig& pConfig, 305 FileOutputBuffer& pOutput) const 306{ 307 typedef typename ELFSizeTraits<SIZE>::Shdr ElfXX_Shdr; 308 309 // emit section header 310 unsigned int sectNum = pModule.size(); 311 unsigned int header_size = sizeof(ElfXX_Shdr) * sectNum; 312 MemoryRegion region = pOutput.request(getLastStartOffset<SIZE>(pModule), 313 header_size); 314 ElfXX_Shdr* shdr = (ElfXX_Shdr*)region.begin(); 315 316 // Iterate the SectionTable in LDContext 317 unsigned int sectIdx = 0; 318 unsigned int shstridx = 0; // NULL section has empty name 319 for (; sectIdx < sectNum; ++sectIdx) { 320 const LDSection *ld_sect = pModule.getSectionTable().at(sectIdx); 321 shdr[sectIdx].sh_name = shstridx; 322 shdr[sectIdx].sh_type = ld_sect->type(); 323 shdr[sectIdx].sh_flags = ld_sect->flag(); 324 shdr[sectIdx].sh_addr = ld_sect->addr(); 325 shdr[sectIdx].sh_offset = ld_sect->offset(); 326 shdr[sectIdx].sh_size = ld_sect->size(); 327 shdr[sectIdx].sh_addralign = ld_sect->align(); 328 shdr[sectIdx].sh_entsize = getSectEntrySize<SIZE>(*ld_sect); 329 shdr[sectIdx].sh_link = getSectLink(*ld_sect, pConfig); 330 shdr[sectIdx].sh_info = getSectInfo(*ld_sect); 331 332 // adjust strshidx 333 shstridx += ld_sect->name().size() + 1; 334 } 335} 336 337// emitProgramHeader - emit ElfXX_Phdr 338template<size_t SIZE> 339void ELFObjectWriter::emitProgramHeader(FileOutputBuffer& pOutput) const 340{ 341 typedef typename ELFSizeTraits<SIZE>::Ehdr ElfXX_Ehdr; 342 typedef typename ELFSizeTraits<SIZE>::Phdr ElfXX_Phdr; 343 344 uint64_t start_offset, phdr_size; 345 346 start_offset = sizeof(ElfXX_Ehdr); 347 phdr_size = sizeof(ElfXX_Phdr); 348 // Program header must start directly after ELF header 349 MemoryRegion region = pOutput.request(start_offset, 350 target().elfSegmentTable().size() * phdr_size); 351 352 ElfXX_Phdr* phdr = (ElfXX_Phdr*)region.begin(); 353 354 // Iterate the elf segment table in GNULDBackend 355 size_t index = 0; 356 ELFSegmentFactory::const_iterator seg = target().elfSegmentTable().begin(), 357 segEnd = target().elfSegmentTable().end(); 358 for (; seg != segEnd; ++seg, ++index) { 359 phdr[index].p_type = (*seg)->type(); 360 phdr[index].p_flags = (*seg)->flag(); 361 phdr[index].p_offset = (*seg)->offset(); 362 phdr[index].p_vaddr = (*seg)->vaddr(); 363 phdr[index].p_paddr = (*seg)->paddr(); 364 phdr[index].p_filesz = (*seg)->filesz(); 365 phdr[index].p_memsz = (*seg)->memsz(); 366 phdr[index].p_align = (*seg)->align(); 367 } 368} 369 370/// emitShStrTab - emit section string table 371void 372ELFObjectWriter::emitShStrTab(const LDSection& pShStrTab, 373 const Module& pModule, 374 FileOutputBuffer& pOutput) 375{ 376 // write out data 377 MemoryRegion region = pOutput.request(pShStrTab.offset(), pShStrTab.size()); 378 char* data = (char*)region.begin(); 379 size_t shstrsize = 0; 380 Module::const_iterator section, sectEnd = pModule.end(); 381 for (section = pModule.begin(); section != sectEnd; ++section) { 382 strcpy((char*)(data + shstrsize), (*section)->name().data()); 383 shstrsize += (*section)->name().size() + 1; 384 } 385} 386 387/// emitSectionData 388void 389ELFObjectWriter::emitSectionData(const LDSection& pSection, 390 MemoryRegion& pRegion) const 391{ 392 const SectionData* sd = NULL; 393 switch (pSection.kind()) { 394 case LDFileFormat::Relocation: 395 assert(pSection.hasRelocData()); 396 return; 397 case LDFileFormat::EhFrame: 398 assert(pSection.hasEhFrame()); 399 sd = pSection.getEhFrame()->getSectionData(); 400 break; 401 default: 402 assert(pSection.hasSectionData()); 403 sd = pSection.getSectionData(); 404 break; 405 } 406 emitSectionData(*sd, pRegion); 407} 408 409/// emitEhFrame 410void ELFObjectWriter::emitEhFrame(Module& pModule, 411 EhFrame& pFrame, MemoryRegion& pRegion) const 412{ 413 emitSectionData(*pFrame.getSectionData(), pRegion); 414 415 // Patch FDE field (offset to CIE) 416 for (EhFrame::cie_iterator i = pFrame.cie_begin(), e = pFrame.cie_end(); 417 i != e; ++i) { 418 EhFrame::CIE& cie = **i; 419 for (EhFrame::fde_iterator fi = cie.begin(), fe = cie.end(); 420 fi != fe; ++fi) { 421 EhFrame::FDE& fde = **fi; 422 if (fde.getRecordType() == EhFrame::RECORD_GENERATED) { 423 // Patch PLT offset 424 LDSection* plt_sect = pModule.getSection(".plt"); 425 assert (plt_sect && "We have no plt but have corresponding eh_frame?"); 426 uint64_t plt_offset = plt_sect->offset(); 427 // FDE entry for PLT is always 32-bit 428 uint64_t fde_offset = pFrame.getSection().offset() + fde.getOffset() + 429 EhFrame::getDataStartOffset<32>(); 430 int32_t offset = fde_offset - plt_offset; 431 if (plt_offset < fde_offset) 432 offset = -offset; 433 memcpy(pRegion.begin() + fde.getOffset() + 434 EhFrame::getDataStartOffset<32>(), 435 &offset, 4); 436 uint32_t size = plt_sect->size(); 437 memcpy(pRegion.begin() + fde.getOffset() + 438 EhFrame::getDataStartOffset<32>() + 4, 439 &size, 4); 440 } 441 uint64_t fde_cie_ptr_offset = fde.getOffset() + 442 EhFrame::getDataStartOffset<32>() - 443 /*ID*/4; 444 uint64_t cie_start_offset = cie.getOffset(); 445 int32_t offset = fde_cie_ptr_offset - cie_start_offset; 446 if (fde_cie_ptr_offset < cie_start_offset) 447 offset = -offset; 448 memcpy(pRegion.begin() + fde_cie_ptr_offset, &offset, 4); 449 } // for loop fde_iterator 450 } // for loop cie_iterator 451} 452 453/// emitRelocation 454void ELFObjectWriter::emitRelocation(const LinkerConfig& pConfig, 455 const LDSection& pSection, 456 MemoryRegion& pRegion) const 457{ 458 const RelocData* sect_data = pSection.getRelocData(); 459 assert(NULL != sect_data && "SectionData is NULL in emitRelocation!"); 460 461 if (pSection.type() == SHT_REL) { 462 if (pConfig.targets().is32Bits()) 463 emitRel<32>(pConfig, *sect_data, pRegion); 464 else if (pConfig.targets().is64Bits()) 465 emitRel<64>(pConfig, *sect_data, pRegion); 466 else { 467 fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str() 468 << pConfig.targets().bitclass(); 469 } 470 } else if (pSection.type() == SHT_RELA) { 471 if (pConfig.targets().is32Bits()) 472 emitRela<32>(pConfig, *sect_data, pRegion); 473 else if (pConfig.targets().is64Bits()) 474 emitRela<64>(pConfig, *sect_data, pRegion); 475 else { 476 fatal(diag::unsupported_bitclass) << pConfig.targets().triple().str() 477 << pConfig.targets().bitclass(); 478 } 479 } else 480 llvm::report_fatal_error("unsupported relocation section type!"); 481} 482 483 484// emitRel - emit ElfXX_Rel 485template<size_t SIZE> 486void ELFObjectWriter::emitRel(const LinkerConfig& pConfig, 487 const RelocData& pRelocData, 488 MemoryRegion& pRegion) const 489{ 490 typedef typename ELFSizeTraits<SIZE>::Rel ElfXX_Rel; 491 typedef typename ELFSizeTraits<SIZE>::Addr ElfXX_Addr; 492 typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word; 493 494 ElfXX_Rel* rel = reinterpret_cast<ElfXX_Rel*>(pRegion.begin()); 495 496 const Relocation* relocation = 0; 497 const FragmentRef* frag_ref = 0; 498 499 for (RelocData::const_iterator it = pRelocData.begin(), 500 ie = pRelocData.end(); it != ie; ++it, ++rel) { 501 ElfXX_Addr r_offset = 0; 502 ElfXX_Word r_sym = 0; 503 504 relocation = &(llvm::cast<Relocation>(*it)); 505 frag_ref = &(relocation->targetRef()); 506 507 if(LinkerConfig::DynObj == pConfig.codeGenType() || 508 LinkerConfig::Exec == pConfig.codeGenType()) { 509 r_offset = static_cast<ElfXX_Addr>( 510 frag_ref->frag()->getParent()->getSection().addr() + 511 frag_ref->getOutputOffset()); 512 } 513 else { 514 r_offset = static_cast<ElfXX_Addr>(frag_ref->getOutputOffset()); 515 } 516 517 if( relocation->symInfo() == NULL ) 518 r_sym = 0; 519 else 520 r_sym = static_cast<ElfXX_Word>( 521 target().getSymbolIdx(relocation->symInfo()->outSymbol())); 522 523 target().emitRelocation(*rel, relocation->type(), r_sym, r_offset); 524 } 525} 526 527// emitRela - emit ElfXX_Rela 528template<size_t SIZE> 529void ELFObjectWriter::emitRela(const LinkerConfig& pConfig, 530 const RelocData& pRelocData, 531 MemoryRegion& pRegion) const 532{ 533 typedef typename ELFSizeTraits<SIZE>::Rela ElfXX_Rela; 534 typedef typename ELFSizeTraits<SIZE>::Addr ElfXX_Addr; 535 typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word; 536 537 ElfXX_Rela* rel = reinterpret_cast<ElfXX_Rela*>(pRegion.begin()); 538 539 const Relocation* relocation = 0; 540 const FragmentRef* frag_ref = 0; 541 542 for (RelocData::const_iterator it = pRelocData.begin(), 543 ie = pRelocData.end(); it != ie; ++it, ++rel) { 544 ElfXX_Addr r_offset = 0; 545 ElfXX_Word r_sym = 0; 546 547 relocation = &(llvm::cast<Relocation>(*it)); 548 frag_ref = &(relocation->targetRef()); 549 550 if(LinkerConfig::DynObj == pConfig.codeGenType() || 551 LinkerConfig::Exec == pConfig.codeGenType()) { 552 r_offset = static_cast<ElfXX_Addr>( 553 frag_ref->frag()->getParent()->getSection().addr() + 554 frag_ref->getOutputOffset()); 555 } 556 else { 557 r_offset = static_cast<ElfXX_Addr>(frag_ref->getOutputOffset()); 558 } 559 560 if( relocation->symInfo() == NULL ) 561 r_sym = 0; 562 else 563 r_sym = static_cast<ElfXX_Word>( 564 target().getSymbolIdx(relocation->symInfo()->outSymbol())); 565 566 target().emitRelocation(*rel, relocation->type(), 567 r_sym, r_offset, relocation->addend()); 568 } 569} 570 571 572/// getSectEntrySize - compute ElfXX_Shdr::sh_entsize 573template<size_t SIZE> 574uint64_t ELFObjectWriter::getSectEntrySize(const LDSection& pSection) const 575{ 576 typedef typename ELFSizeTraits<SIZE>::Word ElfXX_Word; 577 typedef typename ELFSizeTraits<SIZE>::Sym ElfXX_Sym; 578 typedef typename ELFSizeTraits<SIZE>::Rel ElfXX_Rel; 579 typedef typename ELFSizeTraits<SIZE>::Rela ElfXX_Rela; 580 typedef typename ELFSizeTraits<SIZE>::Dyn ElfXX_Dyn; 581 582 if (llvm::ELF::SHT_DYNSYM == pSection.type() || 583 llvm::ELF::SHT_SYMTAB == pSection.type()) 584 return sizeof(ElfXX_Sym); 585 if (llvm::ELF::SHT_REL == pSection.type()) 586 return sizeof(ElfXX_Rel); 587 if (llvm::ELF::SHT_RELA == pSection.type()) 588 return sizeof(ElfXX_Rela); 589 if (llvm::ELF::SHT_HASH == pSection.type() || 590 llvm::ELF::SHT_GNU_HASH == pSection.type()) 591 return sizeof(ElfXX_Word); 592 if (llvm::ELF::SHT_DYNAMIC == pSection.type()) 593 return sizeof(ElfXX_Dyn); 594 // FIXME: We should get the entsize from input since the size of each 595 // character is specified in the section header's sh_entsize field. 596 // For example, traditional string is 0x1, UCS-2 is 0x2, ... and so on. 597 // Ref: http://www.sco.com/developers/gabi/2003-12-17/ch4.sheader.html 598 if (pSection.flag() & llvm::ELF::SHF_STRINGS) 599 return 0x1; 600 return 0x0; 601} 602 603/// getSectLink - compute ElfXX_Shdr::sh_link 604uint64_t ELFObjectWriter::getSectLink(const LDSection& pSection, 605 const LinkerConfig& pConfig) const 606{ 607 if (llvm::ELF::SHT_SYMTAB == pSection.type()) 608 return target().getOutputFormat()->getStrTab().index(); 609 if (llvm::ELF::SHT_DYNSYM == pSection.type()) 610 return target().getOutputFormat()->getDynStrTab().index(); 611 if (llvm::ELF::SHT_DYNAMIC == pSection.type()) 612 return target().getOutputFormat()->getDynStrTab().index(); 613 if (llvm::ELF::SHT_HASH == pSection.type() || 614 llvm::ELF::SHT_GNU_HASH == pSection.type()) 615 return target().getOutputFormat()->getDynSymTab().index(); 616 if (llvm::ELF::SHT_REL == pSection.type() || 617 llvm::ELF::SHT_RELA == pSection.type()) { 618 if (LinkerConfig::Object == pConfig.codeGenType()) 619 return target().getOutputFormat()->getSymTab().index(); 620 else 621 return target().getOutputFormat()->getDynSymTab().index(); 622 } 623 // FIXME: currently we link ARM_EXIDX section to output text section here 624 if (llvm::ELF::SHT_ARM_EXIDX == pSection.type()) 625 return target().getOutputFormat()->getText().index(); 626 return llvm::ELF::SHN_UNDEF; 627} 628 629/// getSectInfo - compute ElfXX_Shdr::sh_info 630uint64_t ELFObjectWriter::getSectInfo(const LDSection& pSection) const 631{ 632 if (llvm::ELF::SHT_SYMTAB == pSection.type() || 633 llvm::ELF::SHT_DYNSYM == pSection.type()) 634 return pSection.getInfo(); 635 636 if (llvm::ELF::SHT_REL == pSection.type() || 637 llvm::ELF::SHT_RELA == pSection.type()) { 638 const LDSection* info_link = pSection.getLink(); 639 if (NULL != info_link) 640 return info_link->index(); 641 } 642 643 return 0x0; 644} 645 646/// getLastStartOffset 647template<> 648uint64_t ELFObjectWriter::getLastStartOffset<32>(const Module& pModule) const 649{ 650 const LDSection* lastSect = pModule.back(); 651 assert(lastSect != NULL); 652 return Align<32>(lastSect->offset() + lastSect->size()); 653} 654 655/// getLastStartOffset 656template<> 657uint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const 658{ 659 const LDSection* lastSect = pModule.back(); 660 assert(lastSect != NULL); 661 return Align<64>(lastSect->offset() + lastSect->size()); 662} 663 664/// emitSectionData 665void ELFObjectWriter::emitSectionData(const SectionData& pSD, 666 MemoryRegion& pRegion) const 667{ 668 SectionData::const_iterator fragIter, fragEnd = pSD.end(); 669 size_t cur_offset = 0; 670 for (fragIter = pSD.begin(); fragIter != fragEnd; ++fragIter) { 671 size_t size = fragIter->size(); 672 switch(fragIter->getKind()) { 673 case Fragment::Region: { 674 const RegionFragment& region_frag = llvm::cast<RegionFragment>(*fragIter); 675 const char* from = region_frag.getRegion().begin(); 676 memcpy(pRegion.begin() + cur_offset, from, size); 677 break; 678 } 679 case Fragment::Alignment: { 680 // TODO: emit values with different sizes (> 1 byte), and emit nops 681 const AlignFragment& align_frag = llvm::cast<AlignFragment>(*fragIter); 682 uint64_t count = size / align_frag.getValueSize(); 683 switch (align_frag.getValueSize()) { 684 case 1u: 685 std::memset(pRegion.begin() + cur_offset, 686 align_frag.getValue(), 687 count); 688 break; 689 default: 690 llvm::report_fatal_error("unsupported value size for align fragment emission yet.\n"); 691 break; 692 } 693 break; 694 } 695 case Fragment::Fillment: { 696 const FillFragment& fill_frag = llvm::cast<FillFragment>(*fragIter); 697 if (0 == size || 698 0 == fill_frag.getValueSize() || 699 0 == fill_frag.size()) { 700 // ignore virtual fillment 701 break; 702 } 703 704 uint64_t num_tiles = fill_frag.size() / fill_frag.getValueSize(); 705 for (uint64_t i = 0; i != num_tiles; ++i) { 706 std::memset(pRegion.begin() + cur_offset, 707 fill_frag.getValue(), 708 fill_frag.getValueSize()); 709 } 710 break; 711 } 712 case Fragment::Stub: { 713 const Stub& stub_frag = llvm::cast<Stub>(*fragIter); 714 memcpy(pRegion.begin() + cur_offset, stub_frag.getContent(), size); 715 break; 716 } 717 case Fragment::Null: { 718 assert(0x0 == size); 719 break; 720 } 721 case Fragment::Target: 722 llvm::report_fatal_error("Target fragment should not be in a regular section.\n"); 723 break; 724 default: 725 llvm::report_fatal_error("invalid fragment should not be in a regular section.\n"); 726 break; 727 } 728 cur_offset += size; 729 } 730} 731 732