diff options
Diffstat (limited to 'src/libs/7zip/win/CPP/7zip/Archive/ElfHandler.cpp')
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/ElfHandler.cpp | 534 |
1 files changed, 0 insertions, 534 deletions
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/ElfHandler.cpp b/src/libs/7zip/win/CPP/7zip/Archive/ElfHandler.cpp deleted file mode 100644 index c4ad78e9e..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/ElfHandler.cpp +++ /dev/null @@ -1,534 +0,0 @@ -// ElfHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "Common/Buffer.h" -#include "Common/ComTry.h" -#include "Common/IntToString.h" - -#include "Windows/PropVariantUtils.h" - -#include "../Common/LimitedStreams.h" -#include "../Common/ProgressUtils.h" -#include "../Common/RegisterArc.h" -#include "../Common/StreamUtils.h" - -#include "../Compress/CopyCoder.h" - -static UInt16 Get16(const Byte *p, int be) { if (be) return GetBe16(p); return GetUi16(p); } -static UInt32 Get32(const Byte *p, int be) { if (be) return GetBe32(p); return GetUi32(p); } -static UInt64 Get64(const Byte *p, int be) { if (be) return GetBe64(p); return GetUi64(p); } - -using namespace NWindows; - -namespace NArchive { -namespace NElf { - -#define ELF_CLASS_32 1 -#define ELF_CLASS_64 2 - -#define ELF_DATA_2LSB 1 -#define ELF_DATA_2MSB 2 - -#define NUM_SCAN_SECTIONS_MAX (1 << 6) - -struct CHeader -{ - bool Mode64; - bool Be; - Byte Os; - Byte AbiVer; - - UInt16 Type; - UInt16 Machine; - // UInt32 Version; - - // UInt64 EntryVa; - UInt64 ProgOffset; - UInt64 SectOffset; - UInt32 Flags; - UInt16 ElfHeaderSize; - UInt16 SegmentEntrySize; - UInt16 NumSegments; - UInt16 SectEntrySize; - UInt16 NumSections; - // UInt16 SectNameStringTableIndex; - - bool Parse(const Byte *buf); - - bool CheckSegmentEntrySize() const - { - return (Mode64 && SegmentEntrySize == 0x38) || (!Mode64 && SegmentEntrySize == 0x20); - }; - - UInt64 GetHeadersSize() const - { return ElfHeaderSize + - (UInt64)SegmentEntrySize * NumSegments + - (UInt64)SectEntrySize * NumSections; } - -}; - -bool CHeader::Parse(const Byte *p) -{ - switch(p[4]) - { - case ELF_CLASS_32: Mode64 = false; break; - case ELF_CLASS_64: Mode64 = true; break; - default: return false; - } - bool be; - switch(p[5]) - { - case ELF_DATA_2LSB: be = false; break; - case ELF_DATA_2MSB: be = true; break; - default: return false; - } - Be = be; - if (p[6] != 1) // Version - return false; - Os = p[7]; - AbiVer = p[8]; - for (int i = 9; i < 16; i++) - if (p[i] != 0) - return false; - - Type = Get16(p + 0x10, be); - Machine = Get16(p + 0x12, be); - if (Get32(p + 0x14, be) != 1) // Version - return false; - - if (Mode64) - { - // EntryVa = Get64(p + 0x18, be); - ProgOffset = Get64(p + 0x20, be); - SectOffset = Get64(p + 0x28, be); - p += 0x30; - } - else - { - // EntryVa = Get32(p + 0x18, be); - ProgOffset = Get32(p + 0x1C, be); - SectOffset = Get32(p + 0x20, be); - p += 0x24; - } - - Flags = Get32(p + 0, be); - ElfHeaderSize = Get16(p + 4, be); - SegmentEntrySize = Get16(p + 6, be); - NumSegments = Get16(p + 8, be); - SectEntrySize = Get16(p + 10, be); - NumSections = Get16(p + 12, be); - // SectNameStringTableIndex = Get16(p + 14, be); - return CheckSegmentEntrySize(); -} - -struct CSegment -{ - UInt32 Type; - UInt32 Flags; - UInt64 Offset; - UInt64 Va; - // UInt64 Pa; - UInt64 PSize; - UInt64 VSize; - // UInt64 Align; - - void UpdateTotalSize(UInt64 &totalSize) - { - UInt64 t = Offset + PSize; - if (t > totalSize) - totalSize = t; - } - void Parse(const Byte *p, bool mode64, bool be); -}; - -void CSegment::Parse(const Byte *p, bool mode64, bool be) -{ - Type = Get32(p, be); - if (mode64) - { - Flags = Get32(p + 4, be); - Offset = Get64(p + 8, be); - Va = Get64(p + 0x10, be); - // Pa = Get64(p + 0x18, be); - PSize = Get64(p + 0x20, be); - VSize = Get64(p + 0x28, be); - // Align = Get64(p + 0x30, be); - } - else - { - Offset = Get32(p + 4, be); - Va = Get32(p + 8, be); - // Pa = Get32(p + 12, be); - PSize = Get32(p + 16, be); - VSize = Get32(p + 20, be); - Flags = Get32(p + 24, be); - // Align = Get32(p + 28, be); - } -} - -static const CUInt32PCharPair g_MachinePairs[] = -{ - { 0, "None" }, - { 1, "AT&T WE 32100" }, - { 2, "SPARC" }, - { 3, "Intel 386" }, - { 4, "Motorola 68000" }, - { 5, "Motorola 88000" }, - { 6, "Intel 486" }, - { 7, "Intel i860" }, - { 8, "MIPS" }, - { 9, "IBM S/370" }, - { 10, "MIPS RS3000 LE" }, - { 11, "RS6000" }, - - { 15, "PA-RISC" }, - { 16, "nCUBE" }, - { 17, "Fujitsu VPP500" }, - { 18, "SPARC 32+" }, - { 19, "Intel i960" }, - { 20, "PowerPC" }, - { 21, "PowerPC 64-bit" }, - { 22, "IBM S/390" }, - - { 36, "NEX v800" }, - { 37, "Fujitsu FR20" }, - { 38, "TRW RH-32" }, - { 39, "Motorola RCE" }, - { 40, "ARM" }, - { 41, "Alpha" }, - { 42, "Hitachi SH" }, - { 43, "SPARC-V9" }, - { 44, "Siemens Tricore" }, - { 45, "ARC" }, - { 46, "H8/300" }, - { 47, "H8/300H" }, - { 48, "H8S" }, - { 49, "H8/500" }, - { 50, "IA-64" }, - { 51, "Stanford MIPS-X" }, - { 52, "Motorola ColdFire" }, - { 53, "M68HC12" }, - { 54, "Fujitsu MMA" }, - { 55, "Siemens PCP" }, - { 56, "Sony nCPU" }, - { 57, "Denso NDR1" }, - { 58, "Motorola StarCore" }, - { 59, "Toyota ME16" }, - { 60, "ST100" }, - { 61, "Advanced Logic TinyJ" }, - { 62, "AMD64" }, - { 63, "Sony DSP" }, - - { 66, "Siemens FX66" }, - { 67, "ST9+" }, - { 68, "ST7" }, - { 69, "MC68HC16" }, - { 70, "MC68HC11" }, - { 71, "MC68HC08" }, - { 72, "MC68HC05" }, - { 73, "Silicon Graphics SVx" }, - { 74, "ST19" }, - { 75, "Digital VAX" }, - { 76, "Axis CRIS" }, - { 77, "Infineon JAVELIN" }, - { 78, "Element 14 FirePath" }, - { 79, "LSI ZSP" }, - { 80, "MMIX" }, - { 81, "HUANY" }, - { 82, "SiTera Prism" }, - { 83, "Atmel AVR" }, - { 84, "Fujitsu FR30" }, - { 85, "Mitsubishi D10V" }, - { 86, "Mitsubishi D30V" }, - { 87, "NEC v850" }, - { 88, "Mitsubishi M32R" }, - { 89, "Matsushita MN10300" }, - { 90, "Matsushita MN10200" }, - { 91, "picoJava" }, - { 92, "OpenRISC" }, - { 93, "ARC Tangent-A5" }, - { 94, "Tensilica Xtensa" }, - { 0x9026, "Alpha" } -}; - -static const CUInt32PCharPair g_AbiOS[] = -{ - { 0, "None" }, - { 1, "HP-UX" }, - { 2, "NetBSD" }, - { 3, "Linux" }, - - { 6, "Solaris" }, - { 7, "AIX" }, - { 8, "IRIX" }, - { 9, "FreeBSD" }, - { 10, "TRU64" }, - { 11, "Novell Modesto" }, - { 12, "OpenBSD" }, - { 13, "OpenVMS" }, - { 14, "HP NSK" }, - { 15, "AROS" }, - { 97, "ARM" }, - { 255, "Standalone" } -}; - -static const CUInt32PCharPair g_SegmentFlags[] = -{ - { 0, "Execute" }, - { 1, "Write" }, - { 2, "Read" } -}; - -static const char *g_Types[] = -{ - "None", - "Relocatable file", - "Executable file", - "Shared object file", - "Core file" -}; - -static const char *g_SegnmentTypes[] = -{ - "Unused", - "Loadable segment", - "Dynamic linking tables", - "Program interpreter path name", - "Note section", - "SHLIB", - "Program header table", - "TLS" -}; - -class CHandler: - public IInArchive, - public CMyUnknownImp -{ - CMyComPtr<IInStream> _inStream; - CObjectVector<CSegment> _sections; - UInt32 _peOffset; - CHeader _header; - UInt64 _totalSize; - HRESULT Open2(IInStream *stream); - bool Parse(const Byte *buf, UInt32 size); -public: - MY_UNKNOWN_IMP1(IInArchive) - INTERFACE_IInArchive(;) -}; - -#define ELF_PT_PHDR 6 - -bool CHandler::Parse(const Byte *buf, UInt32 size) -{ - if (size < 64) - return false; - if (!_header.Parse(buf)) - return false; - if (_header.ProgOffset > size || - _header.ProgOffset + (UInt64)_header.SegmentEntrySize * _header.NumSegments > size || - _header.NumSegments > NUM_SCAN_SECTIONS_MAX) - return false; - const Byte *p = buf + _header.ProgOffset; - _totalSize = _header.ProgOffset; - - for (int i = 0; i < _header.NumSegments; i++, p += _header.SegmentEntrySize) - { - CSegment sect; - sect.Parse(p, _header.Mode64, _header.Be); - sect.UpdateTotalSize(_totalSize); - if (sect.Type != ELF_PT_PHDR) - _sections.Add(sect); - } - UInt64 total2 = _header.SectOffset + (UInt64)_header.SectEntrySize * _header.NumSections; - if (total2 > _totalSize) - _totalSize = total2; - return true; -} - -STATPROPSTG kArcProps[] = -{ - { NULL, kpidCpu, VT_BSTR}, - { NULL, kpidBit64, VT_BOOL}, - { NULL, kpidBigEndian, VT_BOOL}, - { NULL, kpidHostOS, VT_BSTR}, - { NULL, kpidCharacts, VT_BSTR}, - { NULL, kpidPhySize, VT_UI8}, - { NULL, kpidHeadersSize, VT_UI8} - }; - -STATPROPSTG kProps[] = -{ - { NULL, kpidPath, VT_BSTR}, - { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackSize, VT_UI8}, - { NULL, kpidType, VT_BSTR}, - { NULL, kpidCharacts, VT_BSTR}, - { NULL, kpidOffset, VT_UI8}, - { NULL, kpidVa, VT_UI8} -}; - -IMP_IInArchive_Props -IMP_IInArchive_ArcProps - -STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - switch(propID) - { - case kpidPhySize: prop = _totalSize; break; - case kpidHeadersSize: prop = _header.GetHeadersSize(); break; - case kpidBit64: if (_header.Mode64) prop = _header.Mode64; break; - case kpidBigEndian: if (_header.Be) prop = _header.Be; break; - case kpidCpu: PAIR_TO_PROP(g_MachinePairs, _header.Machine, prop); break; - case kpidHostOS: PAIR_TO_PROP(g_AbiOS, _header.Os, prop); break; - case kpidCharacts: TYPE_TO_PROP(g_Types, _header.Type, prop); break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - const CSegment &item = _sections[index]; - switch(propID) - { - case kpidPath: - { - wchar_t sz[32]; - ConvertUInt64ToString(index, sz); - prop = sz; - break; - } - case kpidSize: prop = (UInt64)item.VSize; break; - case kpidPackSize: prop = (UInt64)item.PSize; break; - case kpidOffset: prop = item.Offset; break; - case kpidVa: prop = item.Va; break; - case kpidType: TYPE_TO_PROP(g_SegnmentTypes, item.Type, prop); break; - case kpidCharacts: FLAGS_TO_PROP(g_SegmentFlags, item.Flags, prop); break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -HRESULT CHandler::Open2(IInStream *stream) -{ - const UInt32 kBufSize = 1 << 18; - const UInt32 kSigSize = 4; - - CByteBuffer buffer; - buffer.SetCapacity(kBufSize); - Byte *buf = buffer; - - size_t processed = kSigSize; - RINOK(ReadStream_FALSE(stream, buf, processed)); - if (buf[0] != 0x7F || buf[1] != 'E' || buf[2] != 'L' || buf[3] != 'F') - return S_FALSE; - processed = kBufSize - kSigSize; - RINOK(ReadStream(stream, buf + kSigSize, &processed)); - processed += kSigSize; - if (!Parse(buf, (UInt32)processed)) - return S_FALSE; - UInt64 fileSize; - RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize)); - return (fileSize == _totalSize) ? S_OK : S_FALSE; -} - -STDMETHODIMP CHandler::Open(IInStream *inStream, - const UInt64 * /* maxCheckStartPosition */, - IArchiveOpenCallback * /* openArchiveCallback */) -{ - COM_TRY_BEGIN - Close(); - RINOK(Open2(inStream)); - _inStream = inStream; - return S_OK; - COM_TRY_END -} - -STDMETHODIMP CHandler::Close() -{ - _inStream.Release(); - _sections.Clear(); - return S_OK; -} - -STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) -{ - *numItems = _sections.Size(); - return S_OK; -} - -STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, - Int32 testMode, IArchiveExtractCallback *extractCallback) -{ - COM_TRY_BEGIN - bool allFilesMode = (numItems == (UInt32)-1); - if (allFilesMode) - numItems = _sections.Size(); - if (numItems == 0) - return S_OK; - UInt64 totalSize = 0; - UInt32 i; - for (i = 0; i < numItems; i++) - totalSize += _sections[allFilesMode ? i : indices[i]].PSize; - extractCallback->SetTotal(totalSize); - - UInt64 currentTotalSize = 0; - UInt64 currentItemSize; - - NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); - CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; - - CLocalProgress *lps = new CLocalProgress; - CMyComPtr<ICompressProgressInfo> progress = lps; - lps->Init(extractCallback, false); - - CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; - CMyComPtr<ISequentialInStream> inStream(streamSpec); - streamSpec->SetStream(_inStream); - - for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) - { - lps->InSize = lps->OutSize = currentTotalSize; - RINOK(lps->SetCur()); - Int32 askMode = testMode ? - NExtract::NAskMode::kTest : - NExtract::NAskMode::kExtract; - UInt32 index = allFilesMode ? i : indices[i]; - const CSegment &item = _sections[index]; - currentItemSize = item.PSize; - - CMyComPtr<ISequentialOutStream> outStream; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - if (!testMode && !outStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(_inStream->Seek(item.Offset, STREAM_SEEK_SET, NULL)); - streamSpec->Init(currentItemSize); - RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); - outStream.Release(); - RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ? - NExtract::NOperationResult::kOK: - NExtract::NOperationResult::kDataError)); - } - return S_OK; - COM_TRY_END -} - -static IInArchive *CreateArc() { return new CHandler; } - -static CArcInfo g_ArcInfo = - { L"ELF", L"", 0, 0xDE, { 0 }, 0, false, CreateArc, 0 }; - -REGISTER_ARC(Elf) - -}} |