std::vector<Container *> &SegmentContainer::getInnerContainers()
{
    if (innerContainers.empty())
    {
        ELFFile *efile = dynamic_cast<ELFFile *>(getFile());
#ifdef DEBUG
        assert(efile != nullptr);
#endif
        ELFIO::elfio *interpretor = efile->getELFIO();
        ELFIO::segment *segment = interpretor->segments[index];

        std::vector<Container *> &topLevel = efile->getTopLevelContainers();
        SectionContentsContainer *sectionContents =
            dynamic_cast<SectionContentsContainer *>(topLevel[4]);
#ifdef DEBUG
        assert(sectionContents != nullptr);
#endif
        std::vector<Container *> &sections = sectionContents->getInnerContainers();

        for (unsigned int i = 0; i < segment->get_sections_num(); ++i)
            addInnerContainer(sections[segment->get_section_index_at(i)]);
    }

    return innerContainers;
}
Beispiel #2
0
// Build the infrastructure for symbol lookup via name
TInt E32ImageFile_ELF::DoSymbolLookupHeader(ELFFile &aElfFile, TInt aBaseOffset)
	{
	if(!IsNamedLookupEnabled())
		return 0;
	
	aElfFile.SetLookupTblBase(aBaseOffset);
	return aElfFile.GetLookupTblSize(); 
	}
Beispiel #3
0
TInt E32ImageFile_ELF::CopyCode(char *p, ELFFile &aElfFile)
//
// Copies the files code sections to p
// returns the number of bytes copied or KErrGeneral
//
	{
	TInt size=aElfFile.GetCodeSize();
	memcpy(p, (char *)aElfFile.GetCode(), size);
	p+=ALIGN4(size);
	return iHdr->iCodeSize = size;
	}
Beispiel #4
0
// Partially parse the shared object file so that we can call
// getSoName on this object.
template <class ELFT> void SharedFile<ELFT>::parseSoName() {
  typedef typename ELFT::Dyn Elf_Dyn;
  typedef typename ELFT::uint uintX_t;
  const Elf_Shdr *DynamicSec = nullptr;

  const ELFFile<ELFT> Obj = this->ELFObj;
  for (const Elf_Shdr &Sec : Obj.sections()) {
    switch (Sec.sh_type) {
    default:
      continue;
    case SHT_DYNSYM:
      this->Symtab = &Sec;
      break;
    case SHT_DYNAMIC:
      DynamicSec = &Sec;
      break;
    case SHT_SYMTAB_SHNDX:
      this->SymtabSHNDX = check(Obj.getSHNDXTable(Sec));
      break;
    case SHT_GNU_versym:
      this->VersymSec = &Sec;
      break;
    case SHT_GNU_verdef:
      this->VerdefSec = &Sec;
      break;
    }
  }

  this->initStringTable();

  // DSOs are identified by soname, and they usually contain
  // DT_SONAME tag in their header. But if they are missing,
  // filenames are used as default sonames.
  SoName = sys::path::filename(this->getName());

  if (!DynamicSec)
    return;

  ArrayRef<Elf_Dyn> Arr =
      check(Obj.template getSectionContentsAsArray<Elf_Dyn>(DynamicSec),
            getFilename(this) + ": getSectionContentsAsArray failed");
  for (const Elf_Dyn &Dyn : Arr) {
    if (Dyn.d_tag == DT_SONAME) {
      uintX_t Val = Dyn.getVal();
      if (Val >= this->StringTable.size())
        fatal(getFilename(this) + ": invalid DT_SONAME entry");
      SoName = StringRef(this->StringTable.data() + Val);
      return;
    }
  }
}
Beispiel #5
0
// Partially parse the shared object file so that we can call
// getSoName on this object.
template <class ELFT> void SharedFile<ELFT>::parseSoName() {
  const Elf_Shdr *DynamicSec = nullptr;
  const ELFFile<ELFT> Obj = this->getObj();
  ArrayRef<Elf_Shdr> Sections = check(Obj.sections(), toString(this));

  // Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d.
  for (const Elf_Shdr &Sec : Sections) {
    switch (Sec.sh_type) {
    default:
      continue;
    case SHT_DYNSYM:
      this->initSymtab(Sections, &Sec);
      break;
    case SHT_DYNAMIC:
      DynamicSec = &Sec;
      break;
    case SHT_SYMTAB_SHNDX:
      this->SymtabSHNDX =
          check(Obj.getSHNDXTable(Sec, Sections), toString(this));
      break;
    case SHT_GNU_versym:
      this->VersymSec = &Sec;
      break;
    case SHT_GNU_verdef:
      this->VerdefSec = &Sec;
      break;
    }
  }

  if (this->VersymSec && this->Symbols.empty())
    error("SHT_GNU_versym should be associated with symbol table");

  // Search for a DT_SONAME tag to initialize this->SoName.
  if (!DynamicSec)
    return;
  ArrayRef<Elf_Dyn> Arr =
      check(Obj.template getSectionContentsAsArray<Elf_Dyn>(DynamicSec),
            toString(this));
  for (const Elf_Dyn &Dyn : Arr) {
    if (Dyn.d_tag == DT_SONAME) {
      uint64_t Val = Dyn.getVal();
      if (Val >= this->StringTable.size())
        fatal(toString(this) + ": invalid DT_SONAME entry");
      SoName = this->StringTable.data() + Val;
      return;
    }
  }
}
Beispiel #6
0
TInt E32ImageFile_ELF::DoCodeHeader(ELFFile &aElfFile)
//
// Calculate the code parts of the ELFFile
//
	{

	TInt size=ALIGN4(aElfFile.GetCodeSize());
	iHdr->iCodeSize = iHdr->iTextSize = size;
	// make it the offset from the beginning of the file.....
	if(iHdr->iExportDirCount==0)
		iHdr->iExportDirOffset = 0;
	else
		iHdr->iExportDirOffset = aElfFile.GetExportTableOffset() + iHdr->iCodeOffset;

	return size;
	}
Beispiel #7
0
std::vector<typename ELFFile<T>::Elf_Shdr> elf_sections(const ELFFile<T> &elf) {
    typedef typename ELFFile<T>::Elf_Shdr hdr;

    auto er_hdrs = elf.sections();
    if (!er_hdrs) return std::vector<hdr>();
    auto hdrs = er_hdrs.get();
    return std::vector<hdr>(hdrs.begin(), hdrs.end());
}
Beispiel #8
0
std::vector<typename ELFFile<T>::Elf_Phdr> elf_program_headers(const ELFFile<T> &elf) {
    typedef typename ELFFile<T>::Elf_Phdr hdr;

    auto er_hdrs = elf.program_headers();
    if (!er_hdrs) return std::vector<hdr>();
    auto hdrs = er_hdrs.get();
    return std::vector<hdr>(hdrs.begin(), hdrs.end());
}
Beispiel #9
0
TBool E32ImageFile_ELF::SetUpLookupTable(ELFFile &aElfFile)
// Symbol lookup by name is enabled. Create the symbol table with names
// and their values.
{
	if(!aElfFile.SetUpLookupTable() )
		return FALSE;
	SetSymNameLookup(TRUE);
	return TRUE;
}
Beispiel #10
0
template <class ELFT> std::vector<StringRef> LazyObjectFile::getElfSymbols() {
  typedef typename ELFT::Shdr Elf_Shdr;
  typedef typename ELFT::Sym Elf_Sym;
  typedef typename ELFT::SymRange Elf_Sym_Range;

  const ELFFile<ELFT> Obj = createELFObj<ELFT>(this->MB);
  for (const Elf_Shdr &Sec : Obj.sections()) {
    if (Sec.sh_type != SHT_SYMTAB)
      continue;
    Elf_Sym_Range Syms = Obj.symbols(&Sec);
    uint32_t FirstNonLocal = Sec.sh_info;
    StringRef StringTable = check(Obj.getStringTableForSymtab(Sec));
    std::vector<StringRef> V;
    for (const Elf_Sym &Sym : Syms.slice(FirstNonLocal))
      if (Sym.st_shndx != SHN_UNDEF)
        V.push_back(check(Sym.getName(StringTable)));
    return V;
  }
  return {};
}
Beispiel #11
0
// Partially parse the shared object file so that we can call
// getSoName on this object.
template <class ELFT> void SharedFile<ELFT>::parseSoName() {
  typedef typename ELFT::Dyn Elf_Dyn;
  typedef typename ELFT::uint uintX_t;
  const Elf_Shdr *DynamicSec = nullptr;

  const ELFFile<ELFT> Obj = this->ELFObj;
  for (const Elf_Shdr &Sec : Obj.sections()) {
    switch (Sec.sh_type) {
    default:
      continue;
    case SHT_DYNSYM:
      this->Symtab = &Sec;
      break;
    case SHT_DYNAMIC:
      DynamicSec = &Sec;
      break;
    case SHT_SYMTAB_SHNDX:
      this->SymtabSHNDX = check(Obj.getSHNDXTable(Sec));
      break;
    }
  }

  this->initStringTable();
  SoName = this->getName();

  if (!DynamicSec)
    return;
  auto *Begin =
      reinterpret_cast<const Elf_Dyn *>(Obj.base() + DynamicSec->sh_offset);
  const Elf_Dyn *End = Begin + DynamicSec->sh_size / sizeof(Elf_Dyn);

  for (const Elf_Dyn &Dyn : make_range(Begin, End)) {
    if (Dyn.d_tag == DT_SONAME) {
      uintX_t Val = Dyn.getVal();
      if (Val >= this->StringTable.size())
        fatal("invalid DT_SONAME entry");
      SoName = StringRef(this->StringTable.data() + Val);
      return;
    }
  }
}
Beispiel #12
0
TInt E32ImageFile_ELF::DoDataHeader(ELFFile &aElfFile, TUint aDataBase)
	{

	if (aDataBase==0 && aElfFile.iDataSegmentHdr)
		aDataBase=aElfFile.iDataSegmentHdr->p_vaddr;
	TInt size=0;

	iHdr->iDataBase=aDataBase;

	if (aElfFile.HasInitialisedData())
		{
	        size=ALIGN4(aElfFile.GetDataSize());
		iHdr->iDataOffset = iHdr->iCodeOffset + iHdr->iCodeSize;
		iHdr->iDataSize = size;
		}
	if (aElfFile.HasBssData())
		{
		iHdr->iBssSize = ALIGN4(aElfFile.GetBssSize());
		}
	return size;
	}
Beispiel #13
0
std::vector<typename ELFFile<T>::Elf_Shdr> elf_sections(const ELFFile<T> &elf) {
    typedef typename ELFFile<T>::Elf_Shdr hdr;

    auto secs = elf.sections();
    return std::vector<hdr>(secs.begin(), secs.end());
}
Beispiel #14
0
error_or<std::string> elf_section_name(const ELFFile<T> &elf, const typename ELFFile<T>::Elf_Shdr *sec) {
    auto er_name = elf.getSectionName(sec);
    if (!er_name) return failure(toString(er_name.takeError()));
    return success(er_name.get().str());
}
Beispiel #15
0
TUint E32ImageFile_ELF::CopyExportSymInfo(char *p, ELFFile &aElfFile)
	{
	iHdr->iCodeSize += aElfFile.GetLookupTblSize();
	iHdr->iTextSize = iHdr->iCodeSize ;
	return aElfFile.GetSymLookupSection(p);
	}
Beispiel #16
0
error_or<std::string> elf_section_name(const ELFFile<T> &elf, const typename ELFFile<T>::Elf_Shdr *sec) {
    auto er_name = elf.getSectionName(sec);
    if (error_code er = er_name) return failure(er.message());
    return success(er_name->str());
}
Beispiel #17
0
std::vector<typename ELFFile<T>::Elf_Phdr> elf_program_headers(const ELFFile<T> &elf) {
    typedef typename ELFFile<T>::Elf_Phdr hdr;

    return std::vector<hdr>(elf.begin_program_headers(), elf.end_program_headers());
}
Beispiel #18
0
std::vector<typename ELFFile<T>::Elf_Shdr> elf_sections(const ELFFile<T> &elf) {
    typedef typename ELFFile<T>::Elf_Shdr hdr;

    return std::vector<hdr>(elf.begin_sections(), elf.end_sections());
}
Beispiel #19
0
void E32ImageFile_ELF::SetUpExceptions(ELFFile &aElfFile)
    {
    aElfFile.GetExceptionIndexInfo(iHdr->iExceptionDescriptor);
    }
std::vector<Container *> &SHTEntryContainer::getInnerContainers()
{
    if (innerContainers.empty())
    {
        Container *container;
        ELFFile *efile = dynamic_cast<ELFFile *>(getFile());
        ELFIO::elfio *elfData = efile->getELFIO();
        ELFIO::section *entry = elfData->sections[index];

        int offset = elfData->get_sections_offset() + index * elfData->get_section_entry_size();

        container = new Container(getFile(), false, std::make_pair(offset, offset + sizeof(ELFIO::Elf32_Word)));
        container->setName("sh_name: " + ("\"" + std::string(entry->get_name())) + "\"");
        addInnerContainer(container);
        offset += sizeof(ELFIO::Elf32_Word);

        container = new Container(getFile(), false, std::make_pair(offset, offset + sizeof(ELFIO::Elf32_Word)));
        int sh_type = entry->get_type();
        std::string sh_type_string = "";

        switch(sh_type)
        {
            case SHT_NULL:
                sh_type_string = "SHT_NULL";
                break;
            case SHT_PROGBITS:
                sh_type_string = "SHT_PROGBITS";
                break;
            case SHT_SYMTAB :
                sh_type_string = "SHT_SYMTAB";
                break;
            case SHT_STRTAB:
                sh_type_string = "SHT_STRTAB";
                break;
            case SHT_RELA:
                sh_type_string = "SHT_RELA";
                break;
            case SHT_HASH:
                sh_type_string = "SHT_HASH";
                break;
            case SHT_DYNAMIC:
                sh_type_string = "SHT_DYNAMIC";
                break;
            case SHT_NOTE :
                sh_type_string = "SHT_NOTE";
                break;
            case SHT_NOBITS:
                sh_type_string = "SHT_NOBITS";
                break;
            case SHT_REL:
                sh_type_string = "SHT_REL";
                break;
            case SHT_SHLIB:
                sh_type_string = "SHT_SHLIB";
                break;
            case SHT_DYNSYM:
                sh_type_string = "SHT_DYNSYM";
                break;
            case SHT_INIT_ARRAY:
                sh_type_string = "SHT_INIT_ARRAY";
                break;
            case SHT_FINI_ARRAY:
                sh_type_string = "SHT_FINI_ARRAY";
                break;
            case SHT_PREINIT_ARRAY:
                sh_type_string = "SHT_PREINIT_ARRAY";
                break;
            case SHT_GROUP:
                sh_type_string = "SHT_GROUP";
                break;
            case SHT_SYMTAB_SHNDX:
                sh_type_string = "SHT_SYMTAB_SHNDX";
                break;
            case SHT_LOOS:
                sh_type_string = "SHT_LOOS";
                break;
            case SHT_HIOS:
                sh_type_string = "SHT_HIOS";
                break;
            case SHT_LOPROC:
                sh_type_string = "SHT_LOPROC";
                break;
            case SHT_HIPROC:
                sh_type_string = "SHT_HIPROC";
                break;
            case SHT_LOUSER:
                sh_type_string = "SHT_LOUSER";
                break;
            case SHT_HIUSER:
                sh_type_string = "SHT_HIUSER";
                break;
            default:
                sh_type_string = printHex(sh_type);
                break;
        }

        container->setName("sh_type: " + sh_type_string);
        addInnerContainer(container);
        offset += sizeof(ELFIO::Elf32_Word);

        container = new Container(getFile(), false, std::make_pair(offset, offset + sizeof(ELFIO::Elf32_Word)));
        std::string sh_flags_string = "";
        ELFIO::Elf_Xword flags = entry->get_flags();

        if (flags & SHF_WRITE)
            sh_flags_string += "SHF_WRITE ";
        if (flags & SHF_ALLOC)
            sh_flags_string += "SHF_ALLOC ";
        if (flags & SHF_EXECINSTR)
            sh_flags_string += "SHF_EXECINSTR ";
        if (flags & SHF_MERGE)
            sh_flags_string += "SHF_MERGE ";
        if (flags & SHF_STRINGS)
            sh_flags_string += "SHF_STRINGS ";
        if (flags & SHF_INFO_LINK)
            sh_flags_string += "SHF_INFO_LINK ";
        if (flags & SHF_LINK_ORDER)
            sh_flags_string += "SHF_LINK_ORDER ";
        if (flags & SHF_OS_NONCONFORMING)
            sh_flags_string += "SHF_OS_NONCONFORMING ";
        if (flags & SHF_GROUP)
            sh_flags_string += "SHF_GROUP ";
        if (flags & SHF_TLS)
            sh_flags_string += "SHF_TLS ";
        if (flags & SHF_COMPRESSED)
            sh_flags_string += "SHF_COMPRESSED ";
        if (flags & SHF_MASKOS)
            sh_flags_string += "SHF_MASKOS ";
        if (flags & SHF_MASKPROC)
            sh_flags_string += "SHF_MASKPROC ";

        container->setName("sh_flags: " + sh_flags_string);
        addInnerContainer(container);
        offset += sizeof(ELFIO::Elf32_Word);

        container = new Container(getFile(), false, std::make_pair(offset, offset + sizeof(ELFIO::Elf32_Addr)));
        container->setName("sh_addr: " + printHex(entry->get_address()));
        addInnerContainer(container);
        offset += sizeof(ELFIO::Elf32_Addr);

        container = new Container(getFile(), false, std::make_pair(offset, offset + sizeof(ELFIO::Elf32_Off)));
        container->setName("sh_offset: " + printHex(entry->get_offset()));
        addInnerContainer(container);
        offset += sizeof(ELFIO::Elf32_Off);

        container = new Container(getFile(), false, std::make_pair(offset, offset + sizeof(ELFIO::Elf32_Word)));
        container->setName("sh_size: " + std::to_string(entry->get_size()));
        addInnerContainer(container);
        offset += sizeof(ELFIO::Elf32_Word);

        container = new Container(getFile(), false, std::make_pair(offset, offset + sizeof(ELFIO::Elf32_Word)));
        container->setName("sh_link: " + std::to_string(entry->get_link()));
        addInnerContainer(container);
        offset += sizeof(ELFIO::Elf32_Word);

        container = new Container(getFile(), false, std::make_pair(offset, offset + sizeof(ELFIO::Elf32_Word)));
        container->setName("sh_info: " + std::to_string(entry->get_info()));
        addInnerContainer(container);
        offset += sizeof(ELFIO::Elf32_Word);

        container = new Container(getFile(), false, std::make_pair(offset, offset + sizeof(ELFIO::Elf32_Word)));
        container->setName("sh_addralign: " + std::to_string(entry->get_addr_align()));
        addInnerContainer(container);
        offset += sizeof(ELFIO::Elf32_Word);

        container = new Container(getFile(), false, std::make_pair(offset, offset + sizeof(ELFIO::Elf32_Word)));
        container->setName("sh_entsize: " + std::to_string(entry->get_entry_size()));
        addInnerContainer(container);
        offset += sizeof(ELFIO::Elf32_Word);
    }

    return innerContainers;
}
Beispiel #21
0
TInt E32ImageFile_ELF::Translate(const char* aFileName, TUint aDataBase, TBool aAllowDllData, \
								 TBool aSymLkupEnabled)
//
// Translate a ELF format file to a E32Image file
//
	
{
	iSource = EElfFile;
	ELFFile elffile;
	if (!elffile.Init((const TText * const)aFileName)) return KErrGeneral;
		
	iFileName = strdup(aFileName);

	Adjust(ALIGN4(sizeof(E32ImageHeaderV)));	// fixed for now because holes not supported
	SetDefaultHeader();
	iHdr->iDllRefTableCount = elffile.NumberOfImportDlls();
	iHdr->iExportDirCount = elffile.NumberOfExports();
	iHdr->iCodeBase = elffile.iLinkedBase;

	if(aSymLkupEnabled)
	{
		if( !SetUpLookupTable(elffile) )
			return KErrGeneral;
	}


	TInt size = ALIGN4(sizeof(E32ImageHeaderV));	// fixed for now because holes not supported
	iHdr->iCodeOffset = size;
	TInt pos = size;
	size+=DoCodeHeader(elffile);

	size += DoSymbolLookupHeader(elffile, size - pos);

	TInt nimports=elffile.NumberOfImports();
	TInt importSectionSize;
	char *newImportSection=CreateImportSection(elffile, importSectionSize);

	TInt t=DoDataHeader(elffile, aDataBase);
	if (t>0)
		{
		iHdr->iDataOffset = size;
		size += t;
		}
	if (importSectionSize!=0)
		{
		iHdr->iImportOffset=size;
		size+=ALIGN4(importSectionSize);
		}

	char *newCodeRelocs=NULL;
	char *newDataRelocs=NULL;
	TInt codeRelocSize=0, dataRelocSize=0;
	TInt nCodeRelocs=elffile.NumberOfCodeRelocs();
	TInt nDataRelocs=elffile.NumberOfDataRelocs();
	if (nCodeRelocs + nDataRelocs)
		{
		Elf32_Rel **codeRelocs=new Elf32_Rel * [nCodeRelocs];
		Elf32_Rel **dataRelocs=new Elf32_Rel * [nDataRelocs];
		if (!elffile.GetRelocs(codeRelocs, dataRelocs)) return KErrGeneral;
		       
		FixRelocs(elffile, codeRelocs, dataRelocs);
		if (elffile.iCodeSegmentHdr)
			newCodeRelocs=CreateRelocs(elffile, codeRelocs, nCodeRelocs, codeRelocSize, elffile.iCodeSegmentHdr->p_vaddr);
		if (elffile.iDataSegmentHdr)
			newDataRelocs=CreateRelocs(elffile, dataRelocs, nDataRelocs, dataRelocSize, elffile.iDataSegmentHdr->p_vaddr);
		if (codeRelocSize)
			{
			iHdr->iCodeRelocOffset = size;
			size += codeRelocSize;
			}
		if (dataRelocSize)
			{
			iHdr->iDataRelocOffset = size;
			size += dataRelocSize;
			}
		delete [] codeRelocs;
		delete [] dataRelocs;
		}

	Adjust(size);
	t=CopyCode(iData + pos, elffile);
	if (t<0)
		return KErrGeneral;
	pos += t;
	t = CopyExportSymInfo(iData+pos, elffile);
	if (t<0)
		return KErrGeneral;
	pos += t;

	pos += CopyData(iData + pos, elffile);
	if (nimports)
		{
		memcpy(iData + pos, newImportSection, importSectionSize);
		pos += ALIGN4(importSectionSize);
		}
	if (codeRelocSize)
		{
		memcpy(iData + pos, newCodeRelocs, codeRelocSize);
		pos += codeRelocSize;
		}
	if (dataRelocSize)
		{
		memcpy(iData + pos, newDataRelocs, dataRelocSize);
		pos += dataRelocSize;
		}

	// locate the entry point
	TUint entryPointOffset=elffile.GetEntryPointOffset();

	// Arrange a header for this E32 Image
	iHdr->iCpuIdentifier = (TUint16)ECpuArmV4;
	// Import format is ELF-derived
	iHdr->iFlags |= KImageImpFmt_ELF;
	// ABI is ARM EABI
	iHdr->iFlags |= KImageABI_EABI;
	if (ImageIsDll(elffile))
		{
		iHdr->iFlags |= KImageDll;
		if (iHdr->iDataSize && !aAllowDllData)
			return Print(EError, "Dll '%s' has initialised data.\n", iFileName);
		if (iHdr->iBssSize  && !aAllowDllData)
			return Print(EError, "Dll '%s' has uninitialised data.\n", iFileName);
		}
	iHdr->iHeapSizeMin = elffile.iHeapCommittedSize;
	iHdr->iHeapSizeMax = elffile.iHeapReservedSize;
	iHdr->iStackSize = elffile.iStackCommittedSize;
	iHdr->iEntryPoint = entryPointOffset;
	TInt r = DetermineEntryPointType();
	if (r == KErrCorrupt)
		return Print(EError, "File '%s': Bad Entry Point.\n", iFileName);
	else if (r == KErrNotSupported)
		return Print(EError, "File '%s': Bad Entry Point Type.\n", iFileName);

	SetUpExceptions(elffile);

	delete [] newImportSection;
	delete [] newCodeRelocs;
	delete [] newDataRelocs;

	return KErrNone;
	}
Beispiel #22
0
TInt E32ImageFile_ELF::CopyData(char *p, ELFFile &aElfFile)
	{
	TInt size=aElfFile.GetDataSize();
	if (size) memcpy(p, (char *)aElfFile.GetData(), size);
	return size;
	}
Beispiel #23
0
TBool E32ImageFile_ELF::ImageIsDll(ELFFile& aElfFile)
    {
    return aElfFile.ImageIsDll();
    }