ELFReader.cpp revision d0fbbb227051be16931a1aa9b4a7722ac039c698
1//===- ELFReader.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/ELFReader.h> 10 11#include <mcld/IRBuilder.h> 12#include <mcld/Fragment/FillFragment.h> 13#include <mcld/LD/EhFrame.h> 14#include <mcld/LD/SectionData.h> 15#include <mcld/Target/GNULDBackend.h> 16#include <mcld/Support/MemoryArea.h> 17#include <mcld/Support/MemoryRegion.h> 18#include <mcld/Support/MsgHandling.h> 19#include <mcld/Object/ObjectBuilder.h> 20 21#include <cstring> 22 23#include <llvm/ADT/StringRef.h> 24#include <llvm/ADT/Twine.h> 25#include <llvm/Support/ELF.h> 26#include <llvm/Support/Host.h> 27 28using namespace mcld; 29 30//===----------------------------------------------------------------------===// 31// ELFReaderIF 32//===----------------------------------------------------------------------===// 33/// getSymType 34ResolveInfo::Type ELFReaderIF::getSymType(uint8_t pInfo, uint16_t pShndx) const 35{ 36 ResolveInfo::Type result = static_cast<ResolveInfo::Type>(pInfo & 0xF); 37 if (llvm::ELF::SHN_ABS == pShndx && ResolveInfo::Section == result) { 38 // In Mips, __gp_disp is a special section symbol. Its name comes from 39 // .strtab, not .shstrtab. However, it is unique. Only it is also a ABS 40 // symbol. So here is a tricky to identify __gp_disp and convert it to 41 // Object symbol. 42 return ResolveInfo::Object; 43 } 44 45 return result; 46} 47 48/// getSymDesc 49ResolveInfo::Desc ELFReaderIF::getSymDesc(uint16_t pShndx, const Input& pInput) const 50{ 51 if (pShndx == llvm::ELF::SHN_UNDEF) 52 return ResolveInfo::Undefined; 53 54 if (pShndx < llvm::ELF::SHN_LORESERVE) { 55 // an ELF symbol defined in a section which we are not including 56 // must be treated as an Undefined. 57 // @ref Google gold linker: symtab.cc: 1086 58 if (NULL == pInput.context()->getSection(pShndx) || 59 LDFileFormat::Ignore == pInput.context()->getSection(pShndx)->kind()) 60 return ResolveInfo::Undefined; 61 return ResolveInfo::Define; 62 } 63 64 if (pShndx == llvm::ELF::SHN_ABS) 65 return ResolveInfo::Define; 66 67 if (pShndx == llvm::ELF::SHN_COMMON) 68 return ResolveInfo::Common; 69 70 // FIXME: ELF weak alias should be ResolveInfo::Indirect 71 return ResolveInfo::NoneDesc; 72} 73 74/// getSymBinding 75ResolveInfo::Binding 76ELFReaderIF::getSymBinding(uint8_t pBinding, uint16_t pShndx, uint8_t pVis) const 77{ 78 79 // TODO: 80 // if --just-symbols option is enabled, the symbol must covert to Absolute 81 82 switch(pBinding) { 83 case llvm::ELF::STB_LOCAL: 84 return ResolveInfo::Local; 85 case llvm::ELF::STB_GLOBAL: 86 return ResolveInfo::Global; 87 case llvm::ELF::STB_WEAK: 88 return ResolveInfo::Weak; 89 } 90 91 if (pShndx == llvm::ELF::SHN_ABS) 92 return ResolveInfo::Absolute; 93 94 return ResolveInfo::NoneBinding; 95} 96 97/// getSymFragmentRef 98FragmentRef* 99ELFReaderIF::getSymFragmentRef(Input& pInput, 100 uint16_t pShndx, 101 uint32_t pOffset) const 102{ 103 104 if (Input::DynObj == pInput.type()) 105 return FragmentRef::Null(); 106 107 if (pShndx == llvm::ELF::SHN_UNDEF) 108 return FragmentRef::Null(); 109 110 if (pShndx >= llvm::ELF::SHN_LORESERVE) // including ABS and COMMON 111 return FragmentRef::Null(); 112 113 LDSection* sect_hdr = pInput.context()->getSection(pShndx); 114 115 if (NULL == sect_hdr) 116 unreachable(diag::unreachable_invalid_section_idx) << pShndx 117 << pInput.path().native(); 118 119 if (LDFileFormat::Ignore == sect_hdr->kind()) 120 return FragmentRef::Null(); 121 122 if (LDFileFormat::Group == sect_hdr->kind()) 123 return FragmentRef::Null(); 124 125 return FragmentRef::Create(*sect_hdr, pOffset); 126} 127 128/// getSymVisibility 129ResolveInfo::Visibility 130ELFReaderIF::getSymVisibility(uint8_t pVis) const 131{ 132 return static_cast<ResolveInfo::Visibility>(pVis); 133} 134 135/// getSymValue - get the section offset of the symbol. 136uint64_t ELFReaderIF::getSymValue(uint64_t pValue, 137 uint16_t pShndx, 138 const Input& pInput) const 139{ 140 if (Input::Object == pInput.type()) { 141 // In relocatable files, st_value holds alignment constraints for a symbol 142 // whose section index is SHN_COMMON 143 if (pShndx == llvm::ELF::SHN_COMMON || pShndx == llvm::ELF::SHN_ABS) { 144 return pValue; 145 } 146 147 // In relocatable files, st_value holds a section offset for a defined symbol. 148 // TODO: 149 // if --just-symbols option are enabled, convert the value from section offset 150 // to virtual address by adding input section's virtual address. 151 // The section's virtual address in relocatable files is normally zero, but 152 // people can use link script to change it. 153 return pValue; 154 } 155 156 // In executable and shared object files, st_value holds a virtual address. 157 // the virtual address is useless during linking. 158 return 0x0; 159} 160 161//===----------------------------------------------------------------------===// 162// ELFReader<32, true> 163//===----------------------------------------------------------------------===// 164/// constructor 165ELFReader<32, true>::ELFReader(GNULDBackend& pBackend) 166 : ELFReaderIF(pBackend) { 167} 168 169/// destructor 170ELFReader<32, true>::~ELFReader() 171{ 172} 173 174/// isELF - is this a ELF file 175bool ELFReader<32, true>::isELF(void* pELFHeader) const 176{ 177 llvm::ELF::Elf32_Ehdr* hdr = 178 reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader); 179 if (0 == memcmp(llvm::ELF::ElfMagic, hdr, 4)) 180 return true; 181 return false; 182} 183 184/// readRegularSection - read a regular section and create fragments. 185bool 186ELFReader<32, true>::readRegularSection(Input& pInput, SectionData& pSD) const 187{ 188 uint32_t offset = pInput.fileOffset() + pSD.getSection().offset(); 189 uint32_t size = pSD.getSection().size(); 190 191 Fragment* frag = IRBuilder::CreateRegion(pInput, offset, size); 192 ObjectBuilder::AppendFragment(*frag, pSD); 193 return true; 194} 195 196/// readSymbols - read ELF symbols and create LDSymbol 197bool ELFReader<32, true>::readSymbols(Input& pInput, 198 IRBuilder& pBuilder, 199 const MemoryRegion& pRegion, 200 const char* pStrTab) const 201{ 202 // get number of symbols 203 size_t entsize = pRegion.size()/sizeof(llvm::ELF::Elf32_Sym); 204 const llvm::ELF::Elf32_Sym* symtab = 205 reinterpret_cast<const llvm::ELF::Elf32_Sym*>(pRegion.start()); 206 207 uint32_t st_name = 0x0; 208 uint32_t st_value = 0x0; 209 uint32_t st_size = 0x0; 210 uint8_t st_info = 0x0; 211 uint8_t st_other = 0x0; 212 uint16_t st_shndx = 0x0; 213 214 // skip the first NULL symbol 215 pInput.context()->addSymbol(LDSymbol::Null()); 216 217 for (size_t idx = 1; idx < entsize; ++idx) { 218 st_info = symtab[idx].st_info; 219 st_other = symtab[idx].st_other; 220 221 if (llvm::sys::isLittleEndianHost()) { 222 st_name = symtab[idx].st_name; 223 st_value = symtab[idx].st_value; 224 st_size = symtab[idx].st_size; 225 st_shndx = symtab[idx].st_shndx; 226 } 227 else { 228 st_name = mcld::bswap32(symtab[idx].st_name); 229 st_value = mcld::bswap32(symtab[idx].st_value); 230 st_size = mcld::bswap32(symtab[idx].st_size); 231 st_shndx = mcld::bswap16(symtab[idx].st_shndx); 232 } 233 234 // If the section should not be included, set the st_shndx SHN_UNDEF 235 // - A section in interrelated groups are not included. 236 if (pInput.type() == Input::Object && 237 st_shndx < llvm::ELF::SHN_LORESERVE && 238 st_shndx != llvm::ELF::SHN_UNDEF) { 239 if (NULL == pInput.context()->getSection(st_shndx)) 240 st_shndx = llvm::ELF::SHN_UNDEF; 241 } 242 243 // get ld_type 244 ResolveInfo::Type ld_type = getSymType(st_info, st_shndx); 245 246 // get ld_desc 247 ResolveInfo::Desc ld_desc = getSymDesc(st_shndx, pInput); 248 249 // get ld_binding 250 ResolveInfo::Binding ld_binding = getSymBinding((st_info >> 4), st_shndx, st_other); 251 252 // get ld_value - ld_value must be section relative. 253 uint64_t ld_value = getSymValue(st_value, st_shndx, pInput); 254 255 // get ld_vis 256 ResolveInfo::Visibility ld_vis = getSymVisibility(st_other); 257 258 // get section 259 LDSection* section = NULL; 260 if (st_shndx < llvm::ELF::SHN_LORESERVE) // including ABS and COMMON 261 section = pInput.context()->getSection(st_shndx); 262 263 // get ld_name 264 std::string ld_name; 265 if (ResolveInfo::Section == ld_type) { 266 // Section symbol's st_name is the section index. 267 assert(NULL != section && "get a invalid section"); 268 ld_name = section->name(); 269 } 270 else { 271 ld_name = std::string(pStrTab + st_name); 272 } 273 274 pBuilder.AddSymbol(pInput, 275 ld_name, 276 ld_type, 277 ld_desc, 278 ld_binding, 279 st_size, 280 ld_value, 281 section, ld_vis); 282 } // end of for loop 283 return true; 284} 285 286//===----------------------------------------------------------------------===// 287// ELFReader::read relocations - read ELF rela and rel, and create Relocation 288//===----------------------------------------------------------------------===// 289/// ELFReader::readRela - read ELF rela and create Relocation 290bool ELFReader<32, true>::readRela(Input& pInput, 291 LDSection& pSection, 292 const MemoryRegion& pRegion) const 293{ 294 // get the number of rela 295 size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rela); 296 const llvm::ELF::Elf32_Rela* relaTab = 297 reinterpret_cast<const llvm::ELF::Elf32_Rela*>(pRegion.start()); 298 299 for (size_t idx=0; idx < entsize; ++idx) { 300 uint32_t r_offset = 0x0; 301 uint32_t r_info = 0x0; 302 int32_t r_addend = 0; 303 if (llvm::sys::isLittleEndianHost()) { 304 r_offset = relaTab[idx].r_offset; 305 r_info = relaTab[idx].r_info; 306 r_addend = relaTab[idx].r_addend; 307 } 308 else { 309 r_offset = mcld::bswap32(relaTab[idx].r_offset); 310 r_info = mcld::bswap32(relaTab[idx].r_info); 311 r_addend = mcld::bswap32(relaTab[idx].r_addend); 312 } 313 314 uint8_t r_type = static_cast<unsigned char>(r_info); 315 uint32_t r_sym = (r_info >> 8); 316 LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 317 if (NULL == symbol) { 318 fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 319 } 320 321 IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset, r_addend); 322 } // end of for 323 return true; 324} 325 326/// readRel - read ELF rel and create Relocation 327bool ELFReader<32, true>::readRel(Input& pInput, 328 LDSection& pSection, 329 const MemoryRegion& pRegion) const 330{ 331 // get the number of rel 332 size_t entsize = pRegion.size() / sizeof(llvm::ELF::Elf32_Rel); 333 const llvm::ELF::Elf32_Rel* relTab = 334 reinterpret_cast<const llvm::ELF::Elf32_Rel*>(pRegion.start()); 335 336 for (size_t idx=0; idx < entsize; ++idx) { 337 uint32_t r_offset = 0x0; 338 uint32_t r_info = 0x0; 339 if (llvm::sys::isLittleEndianHost()) { 340 r_offset = relTab[idx].r_offset; 341 r_info = relTab[idx].r_info; 342 } 343 else { 344 r_offset = mcld::bswap32(relTab[idx].r_offset); 345 r_info = mcld::bswap32(relTab[idx].r_info); 346 } 347 348 uint8_t r_type = static_cast<unsigned char>(r_info); 349 uint32_t r_sym = (r_info >> 8); 350 351 LDSymbol* symbol = pInput.context()->getSymbol(r_sym); 352 if (NULL == symbol) { 353 fatal(diag::err_cannot_read_symbol) << r_sym << pInput.path(); 354 } 355 356 IRBuilder::AddRelocation(pSection, r_type, *symbol, r_offset); 357 } // end of for 358 return true; 359} 360 361/// isMyEndian - is this ELF file in the same endian to me? 362bool ELFReader<32, true>::isMyEndian(void* pELFHeader) const 363{ 364 llvm::ELF::Elf32_Ehdr* hdr = 365 reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader); 366 367 return (hdr->e_ident[llvm::ELF::EI_DATA] == llvm::ELF::ELFDATA2LSB); 368} 369 370/// isMyMachine - is this ELF file generated for the same machine. 371bool ELFReader<32, true>::isMyMachine(void* pELFHeader) const 372{ 373 llvm::ELF::Elf32_Ehdr* hdr = 374 reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader); 375 376 if (llvm::sys::isLittleEndianHost()) 377 return (hdr->e_machine == target().getInfo().machine()); 378 return (mcld::bswap16(hdr->e_machine) == target().getInfo().machine()); 379} 380 381/// fileType - return the file type 382Input::Type ELFReader<32, true>::fileType(void* pELFHeader) const 383{ 384 llvm::ELF::Elf32_Ehdr* hdr = 385 reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader); 386 uint32_t type = 0x0; 387 if (llvm::sys::isLittleEndianHost()) 388 type = hdr->e_type; 389 else 390 type = mcld::bswap16(hdr->e_type); 391 392 switch(type) { 393 case llvm::ELF::ET_REL: 394 return Input::Object; 395 case llvm::ELF::ET_EXEC: 396 return Input::Exec; 397 case llvm::ELF::ET_DYN: 398 return Input::DynObj; 399 case llvm::ELF::ET_CORE: 400 return Input::CoreFile; 401 case llvm::ELF::ET_NONE: 402 default: 403 return Input::Unknown; 404 } 405} 406 407/// readSectionHeaders - read ELF section header table and create LDSections 408bool 409ELFReader<32, true>::readSectionHeaders(Input& pInput, void* pELFHeader) const 410{ 411 llvm::ELF::Elf32_Ehdr* ehdr = 412 reinterpret_cast<llvm::ELF::Elf32_Ehdr*>(pELFHeader); 413 414 uint32_t shoff = 0x0; 415 uint16_t shentsize = 0x0; 416 uint16_t shnum = 0x0; 417 uint16_t shstrtab = 0x0; 418 419 if (llvm::sys::isLittleEndianHost()) { 420 shoff = ehdr->e_shoff; 421 shentsize = ehdr->e_shentsize; 422 shnum = ehdr->e_shnum; 423 shstrtab = ehdr->e_shstrndx; 424 } 425 else { 426 shoff = mcld::bswap32(ehdr->e_shoff); 427 shentsize = mcld::bswap16(ehdr->e_shentsize); 428 shnum = mcld::bswap16(ehdr->e_shnum); 429 shstrtab = mcld::bswap16(ehdr->e_shstrndx); 430 } 431 432 // If the file has no section header table, e_shoff holds zero. 433 if (0x0 == shoff) 434 return true; 435 436 MemoryRegion* shdr_region = pInput.memArea()->request( 437 pInput.fileOffset() + shoff, shnum*shentsize); 438 llvm::ELF::Elf32_Shdr* shdrTab = 439 reinterpret_cast<llvm::ELF::Elf32_Shdr*>(shdr_region->start()); 440 441 uint32_t sh_name = 0x0; 442 uint32_t sh_type = 0x0; 443 uint32_t sh_flags = 0x0; 444 uint32_t sh_offset = 0x0; 445 uint32_t sh_size = 0x0; 446 uint32_t sh_link = 0x0; 447 uint32_t sh_info = 0x0; 448 uint32_t sh_addralign = 0x0; 449 450 // get .shstrtab first 451 llvm::ELF::Elf32_Shdr* shdr = &shdrTab[shstrtab]; 452 if (llvm::sys::isLittleEndianHost()) { 453 sh_offset = shdr->sh_offset; 454 sh_size = shdr->sh_size; 455 } 456 else { 457 sh_offset = mcld::bswap32(shdr->sh_offset); 458 sh_size = mcld::bswap32(shdr->sh_size); 459 } 460 461 MemoryRegion* sect_name_region = pInput.memArea()->request( 462 pInput.fileOffset() + sh_offset, sh_size); 463 const char* sect_name = 464 reinterpret_cast<const char*>(sect_name_region->start()); 465 466 LinkInfoList link_info_list; 467 468 // create all LDSections, including first NULL section. 469 for (size_t idx = 0; idx < shnum; ++idx) { 470 if (llvm::sys::isLittleEndianHost()) { 471 sh_name = shdrTab[idx].sh_name; 472 sh_type = shdrTab[idx].sh_type; 473 sh_flags = shdrTab[idx].sh_flags; 474 sh_offset = shdrTab[idx].sh_offset; 475 sh_size = shdrTab[idx].sh_size; 476 sh_link = shdrTab[idx].sh_link; 477 sh_info = shdrTab[idx].sh_info; 478 sh_addralign = shdrTab[idx].sh_addralign; 479 } 480 else { 481 sh_name = mcld::bswap32(shdrTab[idx].sh_name); 482 sh_type = mcld::bswap32(shdrTab[idx].sh_type); 483 sh_flags = mcld::bswap32(shdrTab[idx].sh_flags); 484 sh_offset = mcld::bswap32(shdrTab[idx].sh_offset); 485 sh_size = mcld::bswap32(shdrTab[idx].sh_size); 486 sh_link = mcld::bswap32(shdrTab[idx].sh_link); 487 sh_info = mcld::bswap32(shdrTab[idx].sh_info); 488 sh_addralign = mcld::bswap32(shdrTab[idx].sh_addralign); 489 } 490 491 LDSection* section = IRBuilder::CreateELFHeader(pInput, 492 sect_name+sh_name, 493 sh_type, 494 sh_flags, 495 sh_addralign); 496 section->setSize(sh_size); 497 section->setOffset(sh_offset); 498 section->setInfo(sh_info); 499 500 if (sh_link != 0x0 || sh_info != 0x0) { 501 LinkInfo link_info = { section, sh_link, sh_info }; 502 link_info_list.push_back(link_info); 503 } 504 } // end of for 505 506 // set up InfoLink 507 LinkInfoList::iterator info, infoEnd = link_info_list.end(); 508 for (info = link_info_list.begin(); info != infoEnd; ++info) { 509 if (LDFileFormat::NamePool == info->section->kind() || 510 LDFileFormat::Group == info->section->kind() || 511 LDFileFormat::Note == info->section->kind()) { 512 info->section->setLink(pInput.context()->getSection(info->sh_link)); 513 continue; 514 } 515 if (LDFileFormat::Relocation == info->section->kind()) { 516 info->section->setLink(pInput.context()->getSection(info->sh_info)); 517 continue; 518 } 519 } 520 521 pInput.memArea()->release(shdr_region); 522 pInput.memArea()->release(sect_name_region); 523 524 return true; 525} 526 527/// readSignature - read a symbol from the given Input and index in symtab 528/// This is used to get the signature of a group section. 529ResolveInfo* ELFReader<32, true>::readSignature(Input& pInput, 530 LDSection& pSymTab, 531 uint32_t pSymIdx) const 532{ 533 LDSection* symtab = &pSymTab; 534 LDSection* strtab = symtab->getLink(); 535 assert(NULL != symtab && NULL != strtab); 536 537 uint32_t offset = pInput.fileOffset() + symtab->offset() + 538 sizeof(llvm::ELF::Elf32_Sym) * pSymIdx; 539 MemoryRegion* symbol_region = 540 pInput.memArea()->request(offset, sizeof(llvm::ELF::Elf32_Sym)); 541 llvm::ELF::Elf32_Sym* entry = 542 reinterpret_cast<llvm::ELF::Elf32_Sym*>(symbol_region->start()); 543 544 uint32_t st_name = 0x0; 545 uint8_t st_info = 0x0; 546 uint8_t st_other = 0x0; 547 uint16_t st_shndx = 0x0; 548 st_info = entry->st_info; 549 st_other = entry->st_other; 550 if (llvm::sys::isLittleEndianHost()) { 551 st_name = entry->st_name; 552 st_shndx = entry->st_shndx; 553 } 554 else { 555 st_name = mcld::bswap32(entry->st_name); 556 st_shndx = mcld::bswap16(entry->st_shndx); 557 } 558 559 MemoryRegion* strtab_region = pInput.memArea()->request( 560 pInput.fileOffset() + strtab->offset(), strtab->size()); 561 562 // get ld_name 563 llvm::StringRef ld_name( 564 reinterpret_cast<char*>(strtab_region->start() + st_name)); 565 566 ResolveInfo* result = ResolveInfo::Create(ld_name); 567 result->setSource(pInput.type() == Input::DynObj); 568 result->setType(static_cast<ResolveInfo::Type>(st_info & 0xF)); 569 result->setDesc(getSymDesc(st_shndx, pInput)); 570 result->setBinding(getSymBinding((st_info >> 4), st_shndx, st_other)); 571 result->setVisibility(getSymVisibility(st_other)); 572 573 // release regions 574 pInput.memArea()->release(symbol_region); 575 pInput.memArea()->release(strtab_region); 576 577 return result; 578} 579 580/// readDynamic - read ELF .dynamic in input dynobj 581bool ELFReader<32, true>::readDynamic(Input& pInput) const 582{ 583 assert(pInput.type() == Input::DynObj); 584 const LDSection* dynamic_sect = pInput.context()->getSection(".dynamic"); 585 if (NULL == dynamic_sect) { 586 fatal(diag::err_cannot_read_section) << ".dynamic"; 587 } 588 const LDSection* dynstr_sect = dynamic_sect->getLink(); 589 if (NULL == dynstr_sect) { 590 fatal(diag::err_cannot_read_section) << ".dynstr"; 591 } 592 593 MemoryRegion* dynamic_region = pInput.memArea()->request( 594 pInput.fileOffset() + dynamic_sect->offset(), dynamic_sect->size()); 595 596 MemoryRegion* dynstr_region = pInput.memArea()->request( 597 pInput.fileOffset() + dynstr_sect->offset(), dynstr_sect->size()); 598 599 assert(NULL != dynamic_region && NULL != dynstr_region); 600 601 const llvm::ELF::Elf32_Dyn* dynamic = 602 (llvm::ELF::Elf32_Dyn*) dynamic_region->start(); 603 const char* dynstr = (const char*) dynstr_region->start(); 604 bool hasSOName = false; 605 size_t numOfEntries = dynamic_sect->size() / sizeof(llvm::ELF::Elf32_Dyn); 606 607 for (size_t idx = 0; idx < numOfEntries; ++idx) { 608 609 llvm::ELF::Elf32_Sword d_tag = 0x0; 610 llvm::ELF::Elf32_Word d_val = 0x0; 611 612 if (llvm::sys::isLittleEndianHost()) { 613 d_tag = dynamic[idx].d_tag; 614 d_val = dynamic[idx].d_un.d_val; 615 } else { 616 d_tag = mcld::bswap32(dynamic[idx].d_tag); 617 d_val = mcld::bswap32(dynamic[idx].d_un.d_val); 618 } 619 620 switch (d_tag) { 621 case llvm::ELF::DT_SONAME: 622 assert(d_val < dynstr_sect->size()); 623 pInput.setName(sys::fs::Path(dynstr + d_val).filename().native()); 624 hasSOName = true; 625 break; 626 case llvm::ELF::DT_NEEDED: 627 // TODO: 628 break; 629 case llvm::ELF::DT_NULL: 630 default: 631 break; 632 } 633 } 634 635 // if there is no SONAME in .dynamic, then set it from input path 636 if (!hasSOName) 637 pInput.setName(pInput.path().filename().native()); 638 639 pInput.memArea()->release(dynamic_region); 640 pInput.memArea()->release(dynstr_region); 641 return true; 642} 643 644