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