Don't assume ELFFile iterates over the program headers.
It will stop doing so shortly. llvm-svn: 242832
This commit is contained in:
		
							parent
							
								
									af346433b1
								
							
						
					
					
						commit
						1cb8a19bcb
					
				| 
						 | 
				
			
			@ -55,6 +55,8 @@ template <class ELFT> bool DynamicFile<ELFT>::canParse(file_magic magic) {
 | 
			
		|||
 | 
			
		||||
template <class ELFT> std::error_code DynamicFile<ELFT>::doParse() {
 | 
			
		||||
  typedef llvm::object::ELFFile<ELFT> ELFO;
 | 
			
		||||
  typedef typename ELFO::Elf_Shdr Elf_Shdr;
 | 
			
		||||
  typedef typename ELFO::Elf_Dyn Elf_Dyn;
 | 
			
		||||
 | 
			
		||||
  std::error_code ec;
 | 
			
		||||
  _objFile.reset(new ELFO(_mb->getBuffer(), ec));
 | 
			
		||||
| 
						 | 
				
			
			@ -63,16 +65,39 @@ template <class ELFT> std::error_code DynamicFile<ELFT>::doParse() {
 | 
			
		|||
 | 
			
		||||
  ELFO &obj = *_objFile;
 | 
			
		||||
 | 
			
		||||
  _soname = obj.getLoadName();
 | 
			
		||||
  if (_soname.empty())
 | 
			
		||||
    _soname = llvm::sys::path::filename(path());
 | 
			
		||||
  const char *base = _mb->getBuffer().data();
 | 
			
		||||
  const Elf_Dyn *dynStart = nullptr;
 | 
			
		||||
  const Elf_Dyn *dynEnd = nullptr;
 | 
			
		||||
  for (const Elf_Shdr &sec : obj.sections()) {
 | 
			
		||||
    if (sec.sh_type == llvm::ELF::SHT_DYNAMIC) {
 | 
			
		||||
      dynStart = reinterpret_cast<const Elf_Dyn *>(base + sec.sh_offset);
 | 
			
		||||
      uint64_t size = sec.sh_size;
 | 
			
		||||
      if (size % sizeof(Elf_Dyn))
 | 
			
		||||
        return llvm::object::object_error::parse_failed;
 | 
			
		||||
      dynEnd = dynStart + size / sizeof(Elf_Dyn);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const typename ELFO::Elf_Shdr *dynSymSec = obj.getDotDynSymSec();
 | 
			
		||||
  const Elf_Shdr *dynSymSec = obj.getDotDynSymSec();
 | 
			
		||||
  ErrorOr<StringRef> strTableOrErr = obj.getStringTableForSymtab(*dynSymSec);
 | 
			
		||||
  if (std::error_code ec = strTableOrErr.getError())
 | 
			
		||||
    return ec;
 | 
			
		||||
  StringRef stringTable = *strTableOrErr;
 | 
			
		||||
 | 
			
		||||
  for (const Elf_Dyn &dyn : llvm::make_range(dynStart, dynEnd)) {
 | 
			
		||||
    if (dyn.d_tag == llvm::ELF::DT_SONAME) {
 | 
			
		||||
      uint64_t offset = dyn.getVal();
 | 
			
		||||
      if (offset >= stringTable.size())
 | 
			
		||||
        return llvm::object::object_error::parse_failed;
 | 
			
		||||
      _soname = StringRef(stringTable.data() + offset);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (_soname.empty())
 | 
			
		||||
    _soname = llvm::sys::path::filename(path());
 | 
			
		||||
 | 
			
		||||
  // Create a map from names to dynamic symbol table entries.
 | 
			
		||||
  // TODO: This should use the object file's build in hash table instead if
 | 
			
		||||
  // it exists.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue