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