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