1//===- ELFWriter.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 10#include <cstdlib> 11#include <cstring> 12 13#include <llvm/Support/ELF.h> 14#include <llvm/Support/Casting.h> 15 16#include <mcld/ADT/SizeTraits.h> 17#include <mcld/MC/MCLDInfo.h> 18#include <mcld/MC/MCLinker.h> 19#include <mcld/LD/AlignFragment.h> 20#include <mcld/LD/FillFragment.h> 21#include <mcld/LD/RegionFragment.h> 22#include <mcld/LD/ELFWriter.h> 23#include <mcld/LD/LDSymbol.h> 24#include <mcld/LD/LDSection.h> 25#include <mcld/LD/Layout.h> 26#include <mcld/LD/ELFSegment.h> 27#include <mcld/LD/ELFSegmentFactory.h> 28#include <mcld/Target/GNULDBackend.h> 29#include <mcld/Support/MemoryRegion.h> 30 31using namespace llvm::ELF; 32using namespace mcld; 33 34/// writeELF32Header - write ELF header 35void ELFWriter::writeELF32Header(const MCLDInfo& pLDInfo, 36 const Layout& pLayout, 37 const GNULDBackend& pBackend, 38 Output& pOutput) const 39{ 40 assert(pOutput.hasMemArea()); 41 42 // ELF header must start from 0x0 43 MemoryRegion *region = pOutput.memArea()->request(0, 44 sizeof(Elf32_Ehdr)); 45 Elf32_Ehdr* header = (Elf32_Ehdr*)region->start(); 46 47 memcpy(header->e_ident, ElfMagic, EI_MAG3+1); 48 49 header->e_ident[EI_CLASS] = ELFCLASS32; 50 header->e_ident[EI_DATA] = pBackend.isLittleEndian()? 51 ELFDATA2LSB : ELFDATA2MSB; 52 header->e_ident[EI_VERSION] = pBackend.ELFVersion(); 53 header->e_ident[EI_OSABI] = pBackend.OSABI(); 54 header->e_ident[EI_ABIVERSION] = pBackend.ABIVersion(); 55 56 // FIXME: add processor-specific and core file types. 57 switch(pOutput.type()) { 58 case Output::Object: 59 header->e_type = ET_REL; 60 break; 61 case Output::DynObj: 62 header->e_type = ET_DYN; 63 break; 64 case Output::Exec: 65 header->e_type = ET_EXEC; 66 break; 67 default: 68 llvm::errs() << "unspported output file type: " << pOutput.type() << ".\n"; 69 header->e_type = ET_NONE; 70 } 71 header->e_machine = pBackend.machine(); 72 header->e_version = header->e_ident[EI_VERSION]; 73 header->e_entry = getEntryPoint(pLDInfo, pLayout, pBackend, pOutput); 74 header->e_phoff = sizeof(Elf32_Ehdr); 75 header->e_shoff = getELF32LastStartOffset(pOutput); 76 header->e_flags = pBackend.flags(); 77 header->e_ehsize = sizeof(Elf32_Ehdr); 78 header->e_phentsize = sizeof(Elf32_Phdr); 79 header->e_phnum = pBackend.numOfSegments(); 80 header->e_shentsize = sizeof(Elf32_Shdr); 81 header->e_shnum = pOutput.context()->numOfSections(); 82 header->e_shstrndx = pOutput.context()->getSectionIdx(".shstrtab"); 83} 84 85/// writeELF64Header - write ELF header 86void ELFWriter::writeELF64Header(const MCLDInfo& pLDInfo, 87 const Layout& pLayout, 88 const GNULDBackend& pBackend, 89 Output& pOutput) const 90{ 91 assert(pOutput.hasMemArea()); 92 93 // ELF header must start from 0x0 94 MemoryRegion *region = pOutput.memArea()->request(0, 95 sizeof(Elf64_Ehdr)); 96 Elf64_Ehdr* header = (Elf64_Ehdr*)region->start(); 97 98 memcpy(header->e_ident, ElfMagic, EI_MAG3+1); 99 100 header->e_ident[EI_CLASS] = ELFCLASS64; 101 header->e_ident[EI_DATA] = pBackend.isLittleEndian()? 102 ELFDATA2LSB : ELFDATA2MSB; 103 header->e_ident[EI_VERSION] = pBackend.ELFVersion(); 104 header->e_ident[EI_OSABI] = pBackend.OSABI(); 105 header->e_ident[EI_ABIVERSION] = pBackend.ABIVersion(); 106 107 // FIXME: add processor-specific and core file types. 108 switch(pOutput.type()) { 109 case Output::Object: 110 header->e_type = ET_REL; 111 break; 112 case Output::DynObj: 113 header->e_type = ET_DYN; 114 break; 115 case Output::Exec: 116 header->e_type = ET_EXEC; 117 break; 118 default: 119 llvm::errs() << "unspported output file type: " << pOutput.type() << ".\n"; 120 header->e_type = ET_NONE; 121 } 122 header->e_machine = pBackend.machine(); 123 header->e_version = header->e_ident[EI_VERSION]; 124 header->e_entry = getEntryPoint(pLDInfo, pLayout, pBackend, pOutput); 125 header->e_phoff = sizeof(Elf64_Ehdr); 126 header->e_shoff = getELF64LastStartOffset(pOutput); 127 header->e_flags = pBackend.flags(); 128 header->e_ehsize = sizeof(Elf64_Ehdr); 129 header->e_phentsize = sizeof(Elf64_Phdr); 130 header->e_phnum = pBackend.numOfSegments(); 131 header->e_shentsize = sizeof(Elf64_Shdr); 132 header->e_shnum = pOutput.context()->numOfSections(); 133 header->e_shstrndx = pOutput.context()->getSectionIdx(".shstrtab"); 134} 135 136/// getEntryPoint 137uint64_t ELFWriter::getEntryPoint(const MCLDInfo& pLDInfo, 138 const Layout& pLayout, 139 const GNULDBackend& pBackend, 140 const Output& pOutput) const 141{ 142 143 llvm::StringRef entry_name; 144 if (pLDInfo.options().hasEntry()) 145 entry_name = pLDInfo.options().entry(); 146 else 147 entry_name = pBackend.entry(); 148 149 uint64_t result = 0x0; 150 151 bool issue_warning = (pLDInfo.options().hasEntry() 152 && (pOutput.type() != Output::Object) 153 && (pOutput.type() != Output::DynObj)); 154 155 const LDSymbol* entry_symbol = pLDInfo.getNamePool().findSymbol(entry_name); 156 157 // found the symbol 158 if (NULL != entry_symbol) { 159 if (entry_symbol->desc() != ResolveInfo::Define && issue_warning) { 160 llvm::errs() << "WARNING: entry symbol '" 161 << entry_symbol->name() 162 << "' exists but is not defined.\n"; 163 } 164 result = entry_symbol->value(); 165 } 166 // not in the symbol pool 167 else { 168 // We should parse entry as a number. 169 // @ref GNU ld manual, Options -e. e.g., -e 0x1000. 170 char* endptr; 171 result = strtoull(entry_name.data(), &endptr, 0); 172 if (*endptr != '\0') { 173 if (issue_warning) { 174 llvm::errs() << "cannot find entry symbol '" 175 << entry_name.data() 176 << "'.\n"; 177 } 178 result = 0x0; 179 } 180 } 181 return result; 182} 183 184/// emitELF32SectionHeader - emit Elf32_Shdr 185void 186ELFWriter::emitELF32SectionHeader(Output& pOutput, MCLinker& pLinker) const 187{ 188 // emit section header 189 unsigned int sectNum = pOutput.context()->numOfSections(); 190 unsigned int header_size = sizeof(Elf32_Shdr) * sectNum; 191 MemoryRegion* region = pOutput.memArea()->request( 192 getELF32LastStartOffset(pOutput), 193 header_size); 194 Elf32_Shdr* shdr = (Elf32_Shdr*)region->start(); 195 196 // Iterate the SectionTable in LDContext 197 unsigned int sectIdx = 0; 198 unsigned int shstridx = 0; // NULL section has empty name 199 for (; sectIdx < sectNum; ++sectIdx) { 200 const LDSection *ld_sect = pOutput.context()->getSection(sectIdx); 201 shdr[sectIdx].sh_name = shstridx; 202 shdr[sectIdx].sh_type = ld_sect->type(); 203 shdr[sectIdx].sh_flags = ld_sect->flag(); 204 shdr[sectIdx].sh_addr = ld_sect->addr(); 205 shdr[sectIdx].sh_offset = ld_sect->offset(); 206 shdr[sectIdx].sh_size = ld_sect->size(); 207 shdr[sectIdx].sh_addralign = ld_sect->align(); 208 shdr[sectIdx].sh_entsize = getELF32SectEntrySize(*ld_sect); 209 shdr[sectIdx].sh_link = getSectLink(*ld_sect, pOutput); 210 shdr[sectIdx].sh_info = getSectInfo(*ld_sect, pOutput); 211 212 // adjust strshidx 213 shstridx += ld_sect->name().size() + 1; 214 } 215} 216 217/// emitELF64SectionHeader - emit Elf64_Shdr 218void 219ELFWriter::emitELF64SectionHeader(Output& pOutput, MCLinker& pLinker) const 220{ 221 // emit section header 222 unsigned int sectNum = pOutput.context()->numOfSections(); 223 unsigned int header_size = sizeof(Elf64_Shdr) * sectNum; 224 MemoryRegion* region = pOutput.memArea()->request( 225 getELF64LastStartOffset(pOutput), 226 header_size); 227 Elf64_Shdr* shdr = (Elf64_Shdr*)region->start(); 228 229 // Iterate the SectionTable in LDContext 230 unsigned int sectIdx = 0; 231 unsigned int shstridx = 0; // NULL section has empty name 232 for (; sectIdx < sectNum; ++sectIdx) { 233 const LDSection *ld_sect = pOutput.context()->getSection(sectIdx); 234 shdr[sectIdx].sh_name = shstridx; 235 shdr[sectIdx].sh_type = ld_sect->type(); 236 shdr[sectIdx].sh_flags = ld_sect->flag(); 237 shdr[sectIdx].sh_addr = ld_sect->addr(); 238 shdr[sectIdx].sh_offset = ld_sect->offset(); 239 shdr[sectIdx].sh_size = ld_sect->size(); 240 shdr[sectIdx].sh_addralign = (ld_sect->hasSectionData())? 241 ld_sect->getSectionData()->getAlignment(): 242 0x0; 243 244 shdr[sectIdx].sh_entsize = getELF64SectEntrySize(*ld_sect); 245 shdr[sectIdx].sh_link = getSectLink(*ld_sect, pOutput); 246 shdr[sectIdx].sh_info = getSectInfo(*ld_sect, pOutput); 247 248 // adjust strshidx 249 shstridx += ld_sect->name().size() + 1; 250 } 251} 252 253 254/// emitELF32ProgramHeader - emit Elf32_Phdr 255void ELFWriter::emitELF32ProgramHeader(Output& pOutput, 256 const GNULDBackend& pBackend) const 257{ 258 assert(pOutput.hasMemArea()); 259 260 uint64_t start_offset, phdr_size; 261 262 start_offset = sizeof(Elf32_Ehdr); 263 phdr_size = sizeof(Elf32_Phdr); 264 // Program header must start directly after ELF header 265 MemoryRegion *region = pOutput.memArea()->request(start_offset, 266 pBackend.numOfSegments() * phdr_size); 267 268 Elf32_Phdr* phdr = (Elf32_Phdr*)region->start(); 269 270 // Iterate the elf segment table in GNULDBackend 271 size_t index = 0; 272 ELFSegmentFactory::const_iterator seg = pBackend.elfSegmentTable().begin(), 273 segEnd = pBackend.elfSegmentTable().end(); 274 for (; seg != segEnd; ++seg, ++index) { 275 phdr[index].p_type = (*seg).type(); 276 phdr[index].p_flags = (*seg).flag(); 277 phdr[index].p_offset = (*seg).offset(); 278 phdr[index].p_vaddr = (*seg).vaddr(); 279 phdr[index].p_paddr = (*seg).paddr(); 280 phdr[index].p_filesz = (*seg).filesz(); 281 phdr[index].p_memsz = (*seg).memsz(); 282 phdr[index].p_align = (*seg).align(); 283 } 284} 285 286/// emitELF64ProgramHeader - emit ElfR64Phdr 287void ELFWriter::emitELF64ProgramHeader(Output& pOutput, 288 const GNULDBackend& pBackend) const 289{ 290 assert(pOutput.hasMemArea()); 291 292 uint64_t start_offset, phdr_size; 293 294 start_offset = sizeof(Elf64_Ehdr); 295 phdr_size = sizeof(Elf64_Phdr); 296 // Program header must start directly after ELF header 297 MemoryRegion *region = pOutput.memArea()->request(start_offset, 298 pBackend.numOfSegments() * phdr_size); 299 Elf64_Phdr* phdr = (Elf64_Phdr*)region->start(); 300 301 // Iterate the elf segment table in GNULDBackend 302 size_t index = 0; 303 ELFSegmentFactory::const_iterator seg = pBackend.elfSegmentTable().begin(), 304 segEnd = pBackend.elfSegmentTable().end(); 305 for (; seg != segEnd; ++seg, ++index) { 306 phdr[index].p_type = (*seg).type(); 307 phdr[index].p_flags = (*seg).flag(); 308 phdr[index].p_offset = (*seg).offset(); 309 phdr[index].p_vaddr = (*seg).vaddr(); 310 phdr[index].p_paddr = (*seg).paddr(); 311 phdr[index].p_filesz = (*seg).filesz(); 312 phdr[index].p_memsz = (*seg).memsz(); 313 phdr[index].p_align = (*seg).align(); 314 } 315} 316 317/// emitELF32ShStrTab - emit section string table 318void ELFWriter::emitELF32ShStrTab(Output& pOutput, MCLinker& pLinker) const 319{ 320 uint64_t shstroffset = getELF32LastStartOffset(pOutput); 321 322 // get shstrtab 323 LDSection& shstrtab = pLinker.getOrCreateOutputSectHdr(".shstrtab", 324 LDFileFormat::NamePool, 325 SHT_STRTAB, 326 0x0); 327 if (0 != shstrtab.size()) 328 llvm::report_fatal_error(".shstrtab has been set.\n"); 329 330 // compute size 331 unsigned int shstrsize = 0; 332 LDContext::const_sect_iterator section, sectEnd = pOutput.context()->sectEnd(); 333 for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) { 334 shstrsize += (*section)->name().size() + 1; 335 } 336 337 shstrtab.setSize(shstrsize); 338 shstrtab.setOffset(shstroffset); 339 340 // write out data 341 MemoryRegion* region = pOutput.memArea()->request(shstrtab.offset(), 342 shstrtab.size()); 343 unsigned char* data = region->start(); 344 shstrsize = 0; 345 for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) { 346 strcpy((char*)(data + shstrsize), (*section)->name().c_str()); 347 shstrsize += (*section)->name().size() + 1; 348 } 349 350 shstrtab.setKind(LDFileFormat::NamePool); 351 shstrtab.setType(llvm::ELF::SHT_STRTAB); 352 shstrtab.setFlag(0x0); 353 shstrtab.setAddr(0x0); 354} 355 356 357/// emitELF64ShStrTab - emit section string table 358void ELFWriter::emitELF64ShStrTab(Output& pOutput, MCLinker& pLinker) const 359{ 360 uint64_t shstroffset = getELF64LastStartOffset(pOutput); 361 362 // get shstrtab 363 LDSection& shstrtab = pLinker.getOrCreateOutputSectHdr(".shstrtab", 364 LDFileFormat::NamePool, 365 SHT_STRTAB, 366 0x0); 367 if (0 != shstrtab.size()) 368 llvm::report_fatal_error(".shstrtab has been set.\n"); 369 370 // compute offset 371 372 // compute size 373 unsigned int shstrsize = 0; 374 LDContext::const_sect_iterator section, sectEnd = pOutput.context()->sectEnd(); 375 for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) { 376 shstrsize += (*section)->name().size() + 1; 377 } 378 379 shstrtab.setSize(shstrsize); 380 shstrtab.setOffset(shstroffset); 381 382 // write out data 383 MemoryRegion* region = pOutput.memArea()->request(shstrtab.offset(), 384 shstrtab.size()); 385 unsigned char* data = region->start(); 386 shstrsize = 0; 387 for (section = pOutput.context()->sectBegin(); section != sectEnd; ++section) { 388 strcpy((char*)(data + shstrsize), (*section)->name().c_str()); 389 shstrsize += (*section)->name().size() + 1; 390 } 391 392 shstrtab.setKind(LDFileFormat::NamePool); 393 shstrtab.setType(llvm::ELF::SHT_STRTAB); 394 shstrtab.setFlag(0x0); 395 shstrtab.setAddr(0x0); 396} 397 398/// emitSectionData 399void 400ELFWriter::emitSectionData(const Layout& pLayout, 401 const LDSection& pSection, 402 MemoryRegion& pRegion) const 403{ 404 const SectionData* data = pSection.getSectionData(); 405 SectionData::const_iterator fragIter, fragEnd = data->end(); 406 size_t cur_offset = 0; 407 for (fragIter = data->begin(); fragIter != fragEnd; ++fragIter) { 408 size_t size = computeFragmentSize(pLayout, *fragIter); 409 switch(fragIter->getKind()) { 410 case Fragment::Region: { 411 const RegionFragment& region_frag = llvm::cast<RegionFragment>(*fragIter); 412 const uint8_t* from = region_frag.getRegion().start(); 413 memcpy(pRegion.getBuffer(cur_offset), from, size); 414 break; 415 } 416 case Fragment::Alignment: { 417 // TODO: emit values with different sizes (> 1 byte), and emit nops 418 AlignFragment& align_frag = llvm::cast<AlignFragment>(*fragIter); 419 uint64_t count = size / align_frag.getValueSize(); 420 switch (align_frag.getValueSize()) { 421 case 1u: 422 std::memset(pRegion.getBuffer(cur_offset), 423 align_frag.getValue(), 424 count); 425 break; 426 default: 427 llvm::report_fatal_error("unsupported value size for align fragment emission yet.\n"); 428 break; 429 } 430 break; 431 } 432 case Fragment::Fillment: { 433 FillFragment& fill_frag = llvm::cast<FillFragment>(*fragIter); 434 if (0 == size || 435 0 == fill_frag.getValueSize() || 436 0 == fill_frag.getSize()) { 437 // ignore virtual fillment 438 break; 439 } 440 441 uint64_t num_tiles = fill_frag.getSize() / fill_frag.getValueSize(); 442 for (uint64_t i = 0; i != num_tiles; ++i) { 443 std::memset(pRegion.getBuffer(cur_offset), 444 fill_frag.getValue(), 445 fill_frag.getValueSize()); 446 } 447 break; 448 } 449 case Fragment::Relocation: 450 llvm::report_fatal_error("relocation fragment should not be in a regular section.\n"); 451 break; 452 case Fragment::Target: 453 llvm::report_fatal_error("Target fragment should not be in a regular section.\n"); 454 break; 455 default: 456 llvm::report_fatal_error("invalid fragment should not be in a regular section.\n"); 457 break; 458 } 459 cur_offset += size; 460 } 461} 462 463/// emitRelocation 464void ELFWriter::emitRelocation(const Layout& pLayout, 465 const Output& pOutput, 466 const LDSection& pSection, 467 MemoryRegion& pRegion) const 468{ 469 const SectionData* sect_data = pSection.getSectionData(); 470 assert(NULL != sect_data && "SectionData is NULL in emitRelocation!"); 471 472 if (pSection.type() == SHT_REL) 473 emitRel(pLayout, pOutput, *sect_data, pRegion); 474 else if (pSection.type() == SHT_RELA) 475 emitRela(pLayout, pOutput, *sect_data, pRegion); 476 else 477 llvm::report_fatal_error("unsupported relocation section type!"); 478} 479 480 481/// emitRel 482void ELFWriter::emitRel(const Layout& pLayout, 483 const Output& pOutput, 484 const SectionData& pSectionData, 485 MemoryRegion& pRegion) const 486{ 487 Elf32_Rel* rel = reinterpret_cast<Elf32_Rel*>(pRegion.start()); 488 489 Relocation* relocation = 0; 490 FragmentRef* frag_ref = 0; 491 492 for (SectionData::const_iterator it = pSectionData.begin(), 493 ie = pSectionData.end(); it != ie; ++it, ++rel) { 494 495 relocation = &(llvm::cast<Relocation>(*it)); 496 frag_ref = &(relocation->targetRef()); 497 498 if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) { 499 rel->r_offset = static_cast<Elf32_Addr>( 500 frag_ref->frag()->getParent()->getSection().addr() + 501 pLayout.getOutputOffset(*frag_ref)); 502 } 503 else { 504 rel->r_offset = static_cast<Elf32_Addr>( 505 frag_ref->frag()->getParent()->getSection().offset() + 506 pLayout.getOutputOffset(*frag_ref)); 507 } 508 509 Elf32_Word Index; 510 if( relocation->symInfo() == NULL ) 511 Index = 0; 512 else 513 Index = static_cast<Elf32_Word>( 514 f_Backend.getSymbolIdx(relocation->symInfo()->outSymbol())); 515 516 rel->setSymbolAndType(Index, relocation->type()); 517 } 518} 519 520/// emitRela 521void ELFWriter::emitRela(const Layout& pLayout, 522 const Output& pOutput, 523 const SectionData& pSectionData, 524 MemoryRegion& pRegion) const 525{ 526 Elf32_Rela* rel = reinterpret_cast<Elf32_Rela*>(pRegion.start()); 527 528 Relocation* relocation = 0; 529 FragmentRef* frag_ref = 0; 530 531 for (SectionData::const_iterator it = pSectionData.begin(), 532 ie = pSectionData.end(); it != ie; ++it, ++rel) { 533 534 relocation = &(llvm::cast<Relocation>(*it)); 535 frag_ref = &(relocation->targetRef()); 536 537 if(pOutput.type() == Output::DynObj || pOutput.type() == Output::Exec) { 538 rel->r_offset = static_cast<Elf32_Addr>( 539 frag_ref->frag()->getParent()->getSection().addr() + 540 pLayout.getOutputOffset(*frag_ref)); 541 } 542 else { 543 rel->r_offset = static_cast<Elf32_Addr>( 544 frag_ref->frag()->getParent()->getSection().offset() + 545 pLayout.getOutputOffset(*frag_ref)); 546 } 547 548 Elf32_Word Index; 549 if( relocation->symInfo() == NULL ) 550 Index = 0; 551 else 552 Index = static_cast<Elf32_Word>( 553 f_Backend.getSymbolIdx(relocation->symInfo()->outSymbol())); 554 555 rel->setSymbolAndType(Index, relocation->type()); 556 rel->r_addend = relocation->addend(); 557 } 558} 559 560/// getELF32SectEntrySize - compute Elf32_Shdr::sh_entsize 561uint64_t ELFWriter::getELF32SectEntrySize(const LDSection& pSection) const 562{ 563 if (llvm::ELF::SHT_DYNSYM == pSection.type() || 564 llvm::ELF::SHT_SYMTAB == pSection.type()) 565 return sizeof(llvm::ELF::Elf32_Sym); 566 if (llvm::ELF::SHT_REL == pSection.type()) 567 return sizeof(llvm::ELF::Elf32_Rel); 568 if (llvm::ELF::SHT_RELA == pSection.type()) 569 return sizeof(llvm::ELF::Elf32_Rela); 570 if (llvm::ELF::SHT_HASH == pSection.type()) 571 return sizeof(llvm::ELF::Elf32_Word); 572 if (llvm::ELF::SHT_DYNAMIC == pSection.type()) 573 return sizeof(llvm::ELF::Elf32_Dyn); 574 return 0x0; 575} 576 577/// getELF64SectEntrySize - compute Elf64_Shdr::sh_entsize 578uint64_t ELFWriter::getELF64SectEntrySize(const LDSection& pSection) const 579{ 580 if (llvm::ELF::SHT_DYNSYM == pSection.type() || 581 llvm::ELF::SHT_SYMTAB == pSection.type()) 582 return sizeof(llvm::ELF::Elf64_Sym); 583 if (llvm::ELF::SHT_REL == pSection.type()) 584 return sizeof(llvm::ELF::Elf64_Rel); 585 if (llvm::ELF::SHT_RELA == pSection.type()) 586 return sizeof(llvm::ELF::Elf64_Rela); 587 if (llvm::ELF::SHT_HASH == pSection.type()) 588 return sizeof(llvm::ELF::Elf64_Word); 589 if (llvm::ELF::SHT_DYNAMIC == pSection.type()) 590 return sizeof(llvm::ELF::Elf64_Dyn); 591 return 0x0; 592} 593 594/// getSectLink - compute ElfXX_Shdr::sh_link 595uint64_t ELFWriter::getSectLink(const LDSection& pSection, const Output& pOutput) const 596{ 597 const LDContext* context = pOutput.context(); 598 if (llvm::ELF::SHT_SYMTAB == pSection.type()) 599 return context->getSectionIdx(".strtab"); 600 if (llvm::ELF::SHT_DYNSYM == pSection.type()) 601 return context->getSectionIdx(".dynstr"); 602 if (llvm::ELF::SHT_DYNAMIC == pSection.type()) 603 return context->getSectionIdx(".dynstr"); 604 if (llvm::ELF::SHT_HASH == pSection.type()) 605 return context->getSectionIdx(".dynsym"); 606 if (llvm::ELF::SHT_REL == pSection.type() || 607 llvm::ELF::SHT_RELA == pSection.type()) { 608 if (pOutput.type() == Output::Object) 609 return context->getSectionIdx(".symtab"); 610 else 611 return context->getSectionIdx(".dynsym"); 612 } 613 return llvm::ELF::SHN_UNDEF; 614} 615 616/// getSectInfo - compute ElfXX_Shdr::sh_info 617uint64_t ELFWriter::getSectInfo(const LDSection& pSection, const Output& pOutput) const 618{ 619 const LDSection* info_link = pSection.getLink(); 620 if (NULL == info_link) 621 return 0x0; 622 return info_link->index(); 623} 624 625/// getELF32LastStartOffset 626uint64_t ELFWriter::getELF32LastStartOffset(const Output& pOutput) const 627{ 628 LDSection* lastSect = pOutput.context()->getSectionTable().back(); 629 assert(lastSect != NULL); 630 return Align<32>(lastSect->offset() + lastSect->size()); 631} 632 633/// getELF64LastStartOffset 634uint64_t ELFWriter::getELF64LastStartOffset(const Output& pOutput) const 635{ 636 LDSection* lastSect = pOutput.context()->getSectionTable().back(); 637 assert(lastSect != NULL); 638 return Align<64>(lastSect->offset() + lastSect->size()); 639} 640 641