diff options
Diffstat (limited to 'src/libs/7zip/win/CPP/7zip/Archive/MachoHandler.cpp')
-rw-r--r-- | src/libs/7zip/win/CPP/7zip/Archive/MachoHandler.cpp | 500 |
1 files changed, 0 insertions, 500 deletions
diff --git a/src/libs/7zip/win/CPP/7zip/Archive/MachoHandler.cpp b/src/libs/7zip/win/CPP/7zip/Archive/MachoHandler.cpp deleted file mode 100644 index a6261f34d..000000000 --- a/src/libs/7zip/win/CPP/7zip/Archive/MachoHandler.cpp +++ /dev/null @@ -1,500 +0,0 @@ -// MachoHandler.cpp - -#include "StdAfx.h" - -#include "../../../C/CpuArch.h" - -#include "Common/Buffer.h" -#include "Common/ComTry.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 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 NMacho { - -#define MACH_ARCH_ABI64 (1 << 24) -#define MACH_MACHINE_386 7 -#define MACH_MACHINE_ARM 12 -#define MACH_MACHINE_SPARC 14 -#define MACH_MACHINE_PPC 18 - -#define MACH_MACHINE_PPC64 (MACH_ARCH_ABI64 | MACH_MACHINE_PPC) -#define MACH_MACHINE_AMD64 (MACH_ARCH_ABI64 | MACH_MACHINE_386) - -#define MACH_CMD_SEGMENT_32 1 -#define MACH_CMD_SEGMENT_64 0x19 - -#define MACH_SECT_TYPE_MASK 0x000000FF -#define MACH_SECT_ATTR_MASK 0xFFFFFF00 - -#define MACH_SECT_ATTR_ZEROFILL 1 - -static const char *g_SectTypes[] = -{ - "REGULAR", - "ZEROFILL", - "CSTRINGS", - "4BYTE_LITERALS", - "8BYTE_LITERALS", - "LITERAL_POINTERS", - "NON_LAZY_SYMBOL_POINTERS", - "LAZY_SYMBOL_POINTERS", - "SYMBOL_STUBS", - "MOD_INIT_FUNC_POINTERS", - "MOD_TERM_FUNC_POINTERS", - "COALESCED", - "GB_ZEROFILL", - "INTERPOSING", - "16BYTE_LITERALS" -}; - -static const char *g_FileTypes[] = -{ - "0", - "OBJECT", - "EXECUTE", - "FVMLIB", - "CORE", - "PRELOAD", - "DYLIB", - "DYLINKER", - "BUNDLE", - "DYLIB_STUB", - "DSYM" -}; - -static const CUInt32PCharPair g_Flags[] = -{ - { 31, "PURE_INSTRUCTIONS" }, - { 30, "NO_TOC" }, - { 29, "STRIP_STATIC_SYMS" }, - { 28, "NO_DEAD_STRIP" }, - { 27, "LIVE_SUPPORT" }, - { 26, "SELF_MODIFYING_CODE" }, - { 25, "DEBUG" }, - { 10, "SOME_INSTRUCTIONS" }, - { 9, "EXT_RELOC" }, - { 8, "LOC_RELOC" } -}; - -static const CUInt32PCharPair g_MachinePairs[] = -{ - { MACH_MACHINE_386, "x86" }, - { MACH_MACHINE_ARM, "ARM" }, - { MACH_MACHINE_SPARC, "SPARC" }, - { MACH_MACHINE_PPC, "PowerPC" }, - { MACH_MACHINE_PPC64, "PowerPC 64-bit" }, - { MACH_MACHINE_AMD64, "x64" } -}; - -static const int kNameSize = 16; - -struct CSegment -{ - char Name[kNameSize]; -}; - -struct CSection -{ - char Name[kNameSize]; - char SegName[kNameSize]; - UInt64 Va; - UInt64 Pa; - UInt64 VSize; - UInt64 PSize; - - UInt32 Flags; - int SegmentIndex; - - bool IsDummy; - - CSection(): IsDummy(false) {} - // UInt64 GetPackSize() const { return Flags == MACH_SECT_ATTR_ZEROFILL ? 0 : Size; } - UInt64 GetPackSize() const { return PSize; } -}; - - -class CHandler: - public IInArchive, - public CMyUnknownImp -{ - CMyComPtr<IInStream> _inStream; - CObjectVector<CSegment> _segments; - CObjectVector<CSection> _sections; - bool _mode64; - bool _be; - UInt32 _machine; - UInt32 _type; - UInt32 _headersSize; - UInt64 _totalSize; - HRESULT Open2(ISequentialInStream *stream); - bool Parse(const Byte *buf, UInt32 size); -public: - MY_UNKNOWN_IMP1(IInArchive) - INTERFACE_IInArchive(;) -}; - -bool CHandler::Parse(const Byte *buf, UInt32 size) -{ - bool mode64 = _mode64; - bool be = _be; - - const Byte *bufStart = buf; - bool reduceCommands = false; - if (size < 512) - return false; - - _machine = Get32(buf + 4, be); - _type = Get32(buf + 0xC, be); - - UInt32 numCommands = Get32(buf + 0x10, be); - UInt32 commandsSize = Get32(buf + 0x14, be); - if (commandsSize > size) - return false; - - if (commandsSize > (1 << 24) || numCommands > (1 << 18)) - return false; - - if (numCommands > 16) - { - reduceCommands = true; - numCommands = 16; - } - - _headersSize = 0; - - buf += 0x1C; - size -= 0x1C; - - if (mode64) - { - buf += 4; - size -= 4; - } - - _totalSize = (UInt32)(buf - bufStart); - if (commandsSize < size) - size = commandsSize; - - for (UInt32 cmdIndex = 0; cmdIndex < numCommands; cmdIndex++) - { - if (size < 8) - return false; - UInt32 cmd = Get32(buf, be); - UInt32 cmdSize = Get32(buf + 4, be); - if (size < cmdSize) - return false; - if (cmd == MACH_CMD_SEGMENT_32 || cmd == MACH_CMD_SEGMENT_64) - { - UInt32 offs = (cmd == MACH_CMD_SEGMENT_64) ? 0x48 : 0x38; - if (cmdSize < offs) - break; - - UInt64 vmAddr, vmSize, phAddr, phSize; - - { - if (cmd == MACH_CMD_SEGMENT_64) - { - vmAddr = Get64(buf + 0x18, be); - vmSize = Get64(buf + 0x20, be); - phAddr = Get64(buf + 0x28, be); - phSize = Get64(buf + 0x30, be); - } - else - { - vmAddr = Get32(buf + 0x18, be); - vmSize = Get32(buf + 0x1C, be); - phAddr = Get32(buf + 0x20, be); - phSize = Get32(buf + 0x24, be); - } - { - UInt64 totalSize = phAddr + phSize; - if (totalSize > _totalSize) - _totalSize = totalSize; - } - } - - CSegment seg; - memcpy(seg.Name, buf + 8, kNameSize); - _segments.Add(seg); - - UInt32 numSections = Get32(buf + offs - 8, be); - if (numSections > (1 << 8)) - return false; - - if (numSections == 0) - { - CSection section; - section.IsDummy = true; - section.SegmentIndex = _segments.Size() - 1; - section.Va = vmAddr; - section.PSize = phSize; - section.VSize = vmSize; - section.Pa = phAddr; - section.Flags = 0; - _sections.Add(section); - } - else do - { - CSection section; - UInt32 headerSize = (cmd == MACH_CMD_SEGMENT_64) ? 0x50 : 0x44; - const Byte *p = buf + offs; - if (cmdSize - offs < headerSize) - break; - if (cmd == MACH_CMD_SEGMENT_64) - { - section.Va = Get64(p + 0x20, be); - section.VSize = Get64(p + 0x28, be); - section.Pa = Get32(p + 0x30, be); - section.Flags = Get32(p + 0x40, be); - } - else - { - section.Va = Get32(p + 0x20, be); - section.VSize = Get32(p + 0x24, be); - section.Pa = Get32(p + 0x28, be); - section.Flags = Get32(p + 0x38, be); - } - if (section.Flags == MACH_SECT_ATTR_ZEROFILL) - section.PSize = 0; - else - section.PSize = section.VSize; - memcpy(section.Name, p, kNameSize); - memcpy(section.SegName, p + kNameSize, kNameSize); - section.SegmentIndex = _segments.Size() - 1; - _sections.Add(section); - offs += headerSize; - } - while (--numSections); - - if (offs != cmdSize) - return false; - } - buf += cmdSize; - size -= cmdSize; - } - _headersSize = (UInt32)(buf - bufStart); - return reduceCommands || (size == 0); -} - -static STATPROPSTG kArcProps[] = -{ - { NULL, kpidCpu, VT_BSTR}, - { NULL, kpidBit64, VT_BOOL}, - { NULL, kpidBigEndian, VT_BOOL}, - { NULL, kpidCharacts, VT_BSTR}, - { NULL, kpidPhySize, VT_UI8}, - { NULL, kpidHeadersSize, VT_UI4} -}; - -static STATPROPSTG kProps[] = -{ - { NULL, kpidPath, VT_BSTR}, - { NULL, kpidSize, VT_UI8}, - { NULL, kpidPackSize, VT_UI8}, - { 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 kpidCpu: PAIR_TO_PROP(g_MachinePairs, _machine, prop); break; - case kpidCharacts: TYPE_TO_PROP(g_FileTypes, _type, prop); break; - case kpidPhySize: prop = _totalSize; break; - case kpidHeadersSize: prop = _headersSize; break; - case kpidBit64: if (_mode64) prop = _mode64; break; - case kpidBigEndian: if (_be) prop = _be; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -static AString GetName(const char *name) -{ - char res[kNameSize + 1]; - memcpy(res, name, kNameSize); - res[kNameSize] = 0; - return res; -} - -static AString SectFlagsToString(UInt32 flags) -{ - AString res = TypeToString(g_SectTypes, sizeof(g_SectTypes) / sizeof(g_SectTypes[0]), - flags & MACH_SECT_TYPE_MASK); - AString s = FlagsToString(g_Flags, sizeof(g_Flags) / sizeof(g_Flags[0]), - flags & MACH_SECT_ATTR_MASK); - if (!s.IsEmpty()) - { - res += ' '; - res += s; - } - return res; -} - -STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) -{ - COM_TRY_BEGIN - NCOM::CPropVariant prop; - const CSection &item = _sections[index]; - switch(propID) - { - case kpidPath: - { - AString s = GetName(_segments[item.SegmentIndex].Name); - if (!item.IsDummy) - s += GetName(item.Name); - StringToProp(s, prop); - break; - } - case kpidSize: /* prop = (UInt64)item.VSize; break; */ - case kpidPackSize: prop = (UInt64)item.GetPackSize(); break; - case kpidCharacts: if (!item.IsDummy) StringToProp(SectFlagsToString(item.Flags), prop); break; - case kpidOffset: prop = item.Pa; break; - case kpidVa: prop = item.Va; break; - } - prop.Detach(value); - return S_OK; - COM_TRY_END -} - -HRESULT CHandler::Open2(ISequentialInStream *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)); - UInt32 sig = GetUi32(buf); - bool be, mode64; - switch(sig) - { - case 0xCEFAEDFE: be = true; mode64 = false; break; - case 0xCFFAEDFE: be = true; mode64 = true; break; - case 0xFEEDFACE: be = false; mode64 = false; break; - case 0xFEEDFACF: be = false; mode64 = true; break; - default: return S_FALSE; - } - processed = kBufSize - kSigSize; - RINOK(ReadStream(stream, buf + kSigSize, &processed)); - _mode64 = mode64; - _be = be; - return Parse(buf, (UInt32)processed + kSigSize) ? 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(); - _segments.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]].GetPackSize(); - 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 CSection &item = _sections[index]; - currentItemSize = item.GetPackSize(); - - CMyComPtr<ISequentialOutStream> outStream; - RINOK(extractCallback->GetStream(index, &outStream, askMode)); - if (!testMode && !outStream) - continue; - - RINOK(extractCallback->PrepareOperation(askMode)); - RINOK(_inStream->Seek(item.Pa, 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"MachO", L"", 0, 0xDF, { 0 }, 0, false, CreateArc, 0 }; - -REGISTER_ARC(Macho) - -}} |