This commit is contained in:
Igor Pavlov
2023-12-22 17:17:05 +00:00
committed by Kornel
parent ec44a8a070
commit a36c48cece
954 changed files with 42199 additions and 25482 deletions

View File

@@ -156,18 +156,22 @@ bool CHeader::Parse(const Byte *p)
#define PT_PHDR 6
static const char * const g_SegnmentTypes[] =
static const CUInt32PCharPair g_SegnmentTypes[] =
{
"Unused"
, "Loadable segment"
, "Dynamic linking tables"
, "Program interpreter path name"
, "Note section"
, "SHLIB"
, "Program header table"
, "TLS"
{ 0, "Unused" },
{ 1, "Loadable segment" },
{ 2, "Dynamic linking tables" },
{ 3, "Program interpreter path name" },
{ 4, "Note section" },
{ 5, "SHLIB" },
{ 6, "Program header table" },
{ 7, "TLS" },
{ 0x6474e550, "GNU_EH_FRAME" },
{ 0x6474e551, "GNU_STACK" },
{ 0x6474e552, "GNU_RELRO" }
};
static const char * const g_SegmentFlags[] =
{
"Execute"
@@ -271,6 +275,7 @@ static const CUInt32PCharPair g_SectTypes[] =
{ 16, "PREINIT_ARRAY" },
{ 17, "GROUP" },
{ 18, "SYMTAB_SHNDX" },
{ 0x6ffffff5, "GNU_ATTRIBUTES" },
{ 0x6ffffff6, "GNU_HASH" },
{ 0x6ffffffd, "GNU_verdef" },
@@ -654,11 +659,9 @@ static const char * const g_Types[] =
class CHandler:
public IInArchive,
public IArchiveAllowTail,
public CMyUnknownImp
{
Z7_CLASS_IMP_CHandler_IInArchive_1(
IArchiveAllowTail
)
CRecordVector<CSegment> _segments;
CRecordVector<CSection> _sections;
CByteBuffer _namesData;
@@ -671,10 +674,6 @@ class CHandler:
void GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showNULL) const;
HRESULT Open2(IInStream *stream);
public:
MY_UNKNOWN_IMP2(IInArchive, IArchiveAllowTail)
INTERFACE_IInArchive(;)
STDMETHOD(AllowTail)(Int32 allowTail);
CHandler(): _allowTail(false) {}
};
@@ -683,7 +682,7 @@ void CHandler::GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showN
if (index >= _sections.Size())
return;
const CSection &section = _sections[index];
UInt32 offset = section.Name;
const UInt32 offset = section.Name;
if (index == SHN_UNDEF /* && section.Type == SHT_NULL && offset == 0 */)
{
if (showNULL)
@@ -732,7 +731,7 @@ static const CStatProp kProps[] =
IMP_IInArchive_Props_WITH_NAME
IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
@@ -747,27 +746,27 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidCpu:
{
AString s;
if (_header.Machine < ARRAY_SIZE(g_Machines))
if (_header.Machine < Z7_ARRAY_SIZE(g_Machines))
{
const char *name = g_Machines[_header.Machine];
if (name)
s = name;
}
if (s.IsEmpty())
s = TypePairToString(g_MachinePairs, ARRAY_SIZE(g_MachinePairs), _header.Machine);
s = TypePairToString(g_MachinePairs, Z7_ARRAY_SIZE(g_MachinePairs), _header.Machine);
UInt32 flags = _header.Flags;
if (flags != 0)
{
s.Add_Space();
if (_header.Machine == k_Machine_ARM)
{
s += FlagsToString(g_ARM_Flags, ARRAY_SIZE(g_ARM_Flags), flags & (((UInt32)1 << 24) - 1));
s += FlagsToString(g_ARM_Flags, Z7_ARRAY_SIZE(g_ARM_Flags), flags & (((UInt32)1 << 24) - 1));
s += " ABI:";
s.Add_UInt32(flags >> 24);
}
else if (_header.Machine == k_Machine_MIPS)
{
UInt32 ver = flags >> 28;
const UInt32 ver = flags >> 28;
s += "v";
s.Add_UInt32(ver);
flags &= (((UInt32)1 << 28) - 1);
@@ -781,7 +780,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
flags &= ~((UInt32)7 << 12);
s.Add_Space();
s += FlagsToString(g_MIPS_Flags, ARRAY_SIZE(g_MIPS_Flags), flags);
s += FlagsToString(g_MIPS_Flags, Z7_ARRAY_SIZE(g_MIPS_Flags), flags);
}
else
{
@@ -822,7 +821,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
COM_TRY_END
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
@@ -843,7 +842,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidSize:
case kpidPackSize: prop = (UInt64)item.Size; break;
case kpidVirtualSize: prop = (UInt64)item.VSize; break;
case kpidType: TYPE_TO_PROP(g_SegnmentTypes, item.Type, prop); break;
case kpidType: PAIR_TO_PROP(g_SegnmentTypes, item.Type, prop); break;
case kpidCharacts: FLAGS_TO_PROP(g_SegmentFlags, item.Flags, prop); break;
}
@@ -875,7 +874,7 @@ HRESULT CHandler::Open2(IInStream *stream)
{
const UInt32 kStartSize = kHeaderSize64;
Byte h[kStartSize];
RINOK(ReadStream_FALSE(stream, h, kStartSize));
RINOK(ReadStream_FALSE(stream, h, kStartSize))
if (h[0] != 0x7F || h[1] != 'E' || h[2] != 'L' || h[3] != 'F')
return S_FALSE;
if (!_header.Parse(h))
@@ -894,14 +893,14 @@ HRESULT CHandler::Open2(IInStream *stream)
if (_header.NumSegments != 0)
{
if (_header.ProgOffset > (UInt64)1 << 60) return S_FALSE;
RINOK(stream->Seek(_header.ProgOffset, STREAM_SEEK_SET, NULL));
size_t size = (size_t)_header.SegmentEntrySize * _header.NumSegments;
RINOK(InStream_SeekSet(stream, _header.ProgOffset))
const size_t size = (size_t)_header.SegmentEntrySize * _header.NumSegments;
CByteArr buf(size);
RINOK(ReadStream_FALSE(stream, buf, size));
RINOK(ReadStream_FALSE(stream, buf, size))
UInt64 total = _header.ProgOffset + size;
const UInt64 total = _header.ProgOffset + size;
if (_totalSize < total)
_totalSize = total;
@@ -923,12 +922,12 @@ HRESULT CHandler::Open2(IInStream *stream)
if (_header.NumSections != 0)
{
if (_header.SectOffset > (UInt64)1 << 60) return S_FALSE;
RINOK(stream->Seek(_header.SectOffset, STREAM_SEEK_SET, NULL));
RINOK(InStream_SeekSet(stream, _header.SectOffset))
size_t size = (size_t)_header.SectionEntrySize * _header.NumSections;
CByteArr buf(size);
RINOK(ReadStream_FALSE(stream, buf, size));
RINOK(ReadStream_FALSE(stream, buf, size))
UInt64 total = _header.SectOffset + size;
if (_totalSize < total)
@@ -957,14 +956,14 @@ HRESULT CHandler::Open2(IInStream *stream)
if (_header.NamesSectIndex < _sections.Size())
{
const CSection &sect = _sections[_header.NamesSectIndex];
UInt64 size = sect.GetSize();
const UInt64 size = sect.GetSize();
if (size != 0
&& size < ((UInt64)1 << 31)
&& (Int64)sect.Offset >= 0)
{
_namesData.Alloc((size_t)size);
RINOK(stream->Seek(sect.Offset, STREAM_SEEK_SET, NULL));
RINOK(ReadStream_FALSE(stream, _namesData, (size_t)size));
RINOK(InStream_SeekSet(stream, sect.Offset))
RINOK(ReadStream_FALSE(stream, _namesData, (size_t)size))
}
}
@@ -979,7 +978,7 @@ HRESULT CHandler::Open2(IInStream *stream)
if (!_allowTail)
{
UInt64 fileSize;
RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize));
RINOK(InStream_GetSize_SeekToEnd(stream, fileSize))
if (fileSize > _totalSize)
return S_FALSE;
}
@@ -987,19 +986,19 @@ HRESULT CHandler::Open2(IInStream *stream)
return S_OK;
}
STDMETHODIMP CHandler::Open(IInStream *inStream,
Z7_COM7F_IMF(CHandler::Open(IInStream *inStream,
const UInt64 * /* maxCheckStartPosition */,
IArchiveOpenCallback * /* openArchiveCallback */)
IArchiveOpenCallback * /* openArchiveCallback */))
{
COM_TRY_BEGIN
Close();
RINOK(Open2(inStream));
RINOK(Open2(inStream))
_inStream = inStream;
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
Z7_COM7F_IMF(CHandler::Close())
{
_totalSize = 0;
_headersError = false;
@@ -1011,17 +1010,17 @@ STDMETHODIMP CHandler::Close()
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
{
*numItems = _segments.Size() + _sections.Size();
return S_OK;
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback))
{
COM_TRY_BEGIN
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
const bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
numItems = _segments.Size() + _sections.Size();
if (numItems == 0)
@@ -1030,7 +1029,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
UInt32 i;
for (i = 0; i < numItems; i++)
{
UInt32 index = allFilesMode ? i : indices[i];
const UInt32 index = allFilesMode ? i : indices[i];
totalSize += (index < _segments.Size()) ?
_segments[index].Size :
_sections[index - _segments.Size()].GetSize();
@@ -1054,11 +1053,11 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
{
lps->InSize = lps->OutSize = currentTotalSize;
RINOK(lps->SetCur());
Int32 askMode = testMode ?
RINOK(lps->SetCur())
const Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
UInt32 index = allFilesMode ? i : indices[i];
const UInt32 index = allFilesMode ? i : indices[i];
UInt64 offset;
if (index < _segments.Size())
{
@@ -1074,24 +1073,24 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
CMyComPtr<ISequentialOutStream> outStream;
RINOK(extractCallback->GetStream(index, &outStream, askMode));
RINOK(extractCallback->GetStream(index, &outStream, askMode))
if (!testMode && !outStream)
continue;
RINOK(extractCallback->PrepareOperation(askMode));
RINOK(_inStream->Seek(offset, STREAM_SEEK_SET, NULL));
RINOK(extractCallback->PrepareOperation(askMode))
RINOK(InStream_SeekSet(_inStream, offset))
streamSpec->Init(currentItemSize);
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress))
outStream.Release();
RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ?
NExtract::NOperationResult::kOK:
NExtract::NOperationResult::kDataError));
NExtract::NOperationResult::kDataError))
}
return S_OK;
COM_TRY_END
}
STDMETHODIMP CHandler::AllowTail(Int32 allowTail)
Z7_COM7F_IMF(CHandler::AllowTail(Int32 allowTail))
{
_allowTail = IntToBool(allowTail);
return S_OK;
@@ -1100,7 +1099,7 @@ STDMETHODIMP CHandler::AllowTail(Int32 allowTail)
static const Byte k_Signature[] = { 0x7F, 'E', 'L', 'F' };
REGISTER_ARC_I(
"ELF", "elf", 0, 0xDE,
"ELF", "elf", NULL, 0xDE,
k_Signature,
0,
NArcInfoFlags::kPreArc,