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