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