This commit is contained in:
Igor Pavlov 2024-06-19 00:00:00 +00:00
parent 89a73b9012
commit a7a1d4a241
32 changed files with 400 additions and 161 deletions

View file

@ -1,5 +1,5 @@
; LzFindOpt.asm -- ASM version of GetMatchesSpecN_2() function
; 2021-07-21: Igor Pavlov : Public domain
; 2024-06-18: Igor Pavlov : Public domain
;
ifndef x64
@ -11,10 +11,31 @@ include 7zAsm.asm
MY_ASM_START
_TEXT$LZFINDOPT SEGMENT ALIGN(64) 'CODE'
ifndef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT
if (IS_LINUX gt 0)
Z7_LZ_FIND_OPT_ASM_USE_SEGMENT equ 1
else
Z7_LZ_FIND_OPT_ASM_USE_SEGMENT equ 1
endif
endif
ifdef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT
_TEXT$LZFINDOPT SEGMENT ALIGN(64) 'CODE'
MY_ALIGN macro num:req
align num
; align 16
endm
else
MY_ALIGN macro num:req
; We expect that ".text" is aligned for 16-bytes.
; So we don't need large alignment inside our function.
align 16
endm
endif
MY_ALIGN_16 macro
MY_ALIGN 16
endm
MY_ALIGN_32 macro
@ -136,7 +157,11 @@ COPY_VAR_64 macro dest_var, src_var
endm
ifdef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT
; MY_ALIGN_64
else
MY_ALIGN_16
endif
MY_PROC GetMatchesSpecN_2, 13
MY_PUSH_PRESERVED_ABI_REGS
mov r0, RSP
@ -508,6 +533,8 @@ fin:
MY_POP_PRESERVED_ABI_REGS
MY_ENDP
ifdef Z7_LZ_FIND_OPT_ASM_USE_SEGMENT
_TEXT$LZFINDOPT ENDS
endif
end

View file

@ -1,5 +1,5 @@
; LzmaDecOpt.asm -- ASM version of LzmaDec_DecodeReal_3() function
; 2021-02-23: Igor Pavlov : Public domain
; 2024-06-18: Igor Pavlov : Public domain
;
; 3 - is the code compatibility version of LzmaDec_DecodeReal_*()
; function for check at link time.
@ -17,11 +17,41 @@ include 7zAsm.asm
MY_ASM_START
_TEXT$LZMADECOPT SEGMENT ALIGN(64) 'CODE'
; if Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT is defined, we use additional SEGMENT with 64-byte alignment.
; if Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT is not defined, we use default SEGMENT (where default 16-byte alignment of segment is expected).
; The performance is almost identical in our tests.
; But the performance can depend from position of lzmadec code inside instruction cache
; or micro-op cache line (depending from low address bits in 32-byte/64-byte cache lines).
; And 64-byte alignment provides a more consistent speed regardless
; of the code's position in the executable.
; But also it's possible that code without Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT can be
; slightly faster than 64-bytes aligned code in some cases, if offset of lzmadec
; code in 64-byte block after compilation provides better speed by some reason.
; Note that Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT adds an extra section to the ELF file.
; If you don't want to get that extra section, do not define Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT.
ifndef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT
if (IS_LINUX gt 0)
Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT equ 1
else
Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT equ 1
endif
endif
ifdef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT
_TEXT$LZMADECOPT SEGMENT ALIGN(64) 'CODE'
MY_ALIGN macro num:req
align num
; align 16
endm
else
MY_ALIGN macro num:req
; We expect that ".text" is aligned for 16-bytes.
; So we don't need large alignment inside out function.
align 16
endm
endif
MY_ALIGN_16 macro
MY_ALIGN 16
@ -610,7 +640,11 @@ PARAM_lzma equ REG_ABI_PARAM_0
PARAM_limit equ REG_ABI_PARAM_1
PARAM_bufLimit equ REG_ABI_PARAM_2
ifdef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT
; MY_ALIGN_64
else
MY_ALIGN_16
endif
MY_PROC LzmaDec_DecodeReal_3, 3
MY_PUSH_PRESERVED_ABI_REGS
@ -1298,6 +1332,8 @@ fin:
MY_POP_PRESERVED_ABI_REGS
MY_ENDP
ifdef Z7_LZMA_DEC_OPT_ASM_USE_SEGMENT
_TEXT$LZMADECOPT ENDS
endif
end

View file

@ -1,5 +1,5 @@
; Sha1Opt.asm -- SHA-1 optimized code for SHA-1 x86 hardware instructions
; 2021-03-10 : Igor Pavlov : Public domain
; 2024-06-16 : Igor Pavlov : Public domain
include 7zAsm.asm
@ -20,7 +20,7 @@ MY_ASM_START
CONST SEGMENT
CONST SEGMENT READONLY
align 16
Reverse_Endian_Mask db 15,14,13,12, 11,10,9,8, 7,6,5,4, 3,2,1,0

View file

@ -1,5 +1,5 @@
; Sha256Opt.asm -- SHA-256 optimized code for SHA-256 x86 hardware instructions
; 2022-04-17 : Igor Pavlov : Public domain
; 2024-06-16 : Igor Pavlov : Public domain
include 7zAsm.asm
@ -20,7 +20,7 @@ endif
EXTRN K_CONST:xmmword
@
CONST SEGMENT
CONST SEGMENT READONLY
align 16
Reverse_Endian_Mask db 3,2,1,0, 7,6,5,4, 11,10,9,8, 15,14,13,12

View file

@ -1,7 +1,7 @@
#define MY_VER_MAJOR 24
#define MY_VER_MINOR 06
#define MY_VER_MINOR 07
#define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "24.06"
#define MY_VERSION_NUMBERS "24.07"
#define MY_VERSION MY_VERSION_NUMBERS
#ifdef MY_CPU_NAME
@ -10,7 +10,7 @@
#define MY_VERSION_CPU MY_VERSION
#endif
#define MY_DATE "2024-05-26"
#define MY_DATE "2024-06-19"
#undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov"

View file

@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code
2024-05-18 : Igor Pavlov : Public domain */
2024-06-17 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_CPU_ARCH_H
#define ZIP7_INC_CPU_ARCH_H
@ -564,6 +564,7 @@ problem-4 : performace:
#define SetBe32a(p, v) { *(UInt32 *)(void *)(p) = (v); }
#define SetBe16a(p, v) { *(UInt16 *)(void *)(p) = (v); }
#define GetUi64a(p) GetUi64(p)
#define GetUi32a(p) GetUi32(p)
#define GetUi16a(p) GetUi16(p)
#define SetUi32a(p, v) SetUi32(p, v)
@ -571,6 +572,7 @@ problem-4 : performace:
#elif defined(MY_CPU_LE)
#define GetUi64a(p) (*(const UInt64 *)(const void *)(p))
#define GetUi32a(p) (*(const UInt32 *)(const void *)(p))
#define GetUi16a(p) (*(const UInt16 *)(const void *)(p))
#define SetUi32a(p, v) { *(UInt32 *)(void *)(p) = (v); }

View file

@ -1,5 +1,5 @@
/* ZstdDec.c -- Zstd Decoder
2024-05-26 : the code was developed by Igor Pavlov, using Zstandard format
2024-06-18 : the code was developed by Igor Pavlov, using Zstandard format
specification and original zstd decoder code as reference code.
original zstd decoder code: Copyright (c) Facebook, Inc. All rights reserved.
This source code is licensed under BSD 3-Clause License.
@ -1308,8 +1308,10 @@ FSE_Decode_SeqTable(CFseRecord * const table,
in->len--;
{
const Byte *ptr = in->ptr;
const Byte sym = ptr[0];
const unsigned sym = ptr[0];
in->ptr = ptr + 1;
if (sym >= numSymbolsMax)
return SZ_ERROR_DATA;
table[0] = (FastInt32)sym
#if defined(Z7_ZSTD_DEC_USE_ML_PLUS3)
+ (numSymbolsMax == NUM_ML_SYMBOLS ? MATCH_LEN_MIN : 0)

View file

@ -220,6 +220,9 @@ endif
all: $(O) $(PROGPATH) $(STATIC_TARGET)
# we need $(O) as order-only-prerequisites:
$(OBJS): | $(O)
$(O):
$(MY_MKDIR) $(O)

View file

@ -219,6 +219,14 @@ static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode)
}
/*
Filters don't improve the compression ratio for relocatable object files (".o").
But we can get compression ratio gain, if we compress object
files and executables in same solid block.
So we use filters for relocatable object files (".o"):
*/
// #define Z7_7Z_CREATE_ARC_DISABLE_FILTER_FOR_OBJ
/* ---------- ELF ---------- */
#define ELF_SIG 0x464C457F
@ -258,6 +266,12 @@ static int Parse_ELF(const Byte *buf, size_t size, CFilterMode *filterMode)
default: return 0;
}
#ifdef Z7_7Z_CREATE_ARC_DISABLE_FILTER_FOR_OBJ
#define ELF_ET_REL 1
if (Get16(buf + 0x10, be) == ELF_ET_REL)
return 0;
#endif
switch (Get16(buf + 0x12, be))
{
case 3:
@ -318,6 +332,12 @@ static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode
default: return 0;
}
#ifdef Z7_7Z_CREATE_ARC_DISABLE_FILTER_FOR_OBJ
#define MACH_TYPE_OBJECT 1
if (Get32(buf + 0xC, be) == MACH_TYPE_OBJECT)
return 0;
#endif
switch (Get32(buf + 4, be))
{
case MACH_MACHINE_386:

View file

@ -17,11 +17,13 @@
#include "../Compress/CopyCoder.h"
// #define Z7_ELF_SHOW_DETAILS
using namespace NWindows;
static UInt16 Get16(const Byte *p, bool be) { if (be) return GetBe16(p); return GetUi16(p); }
static UInt32 Get32(const Byte *p, bool be) { if (be) return GetBe32(p); return GetUi32(p); }
static UInt64 Get64(const Byte *p, bool be) { if (be) return GetBe64(p); return GetUi64(p); }
static UInt16 Get16(const Byte *p, bool be) { if (be) return GetBe16a(p); return GetUi16a(p); }
static UInt32 Get32(const Byte *p, bool be) { if (be) return GetBe32a(p); return GetUi32a(p); }
static UInt64 Get64(const Byte *p, bool be) { if (be) return GetBe64a(p); return GetUi64a(p); }
#define G16(offs, v) v = Get16(p + (offs), be)
#define G32(offs, v) v = Get32(p + (offs), be)
@ -31,14 +33,51 @@ namespace NArchive {
namespace NElf {
/*
ELF Structure for most files (real order can be different):
ELF Structure example:
{
Header
Program (segment) header table (used at runtime)
Segment1 (Section ... Section)
Segment2
Program header table (is used at runtime) (list of segment metadata records)
{
Segment (Read)
Segment : PT_PHDR : header table itself
Segment : PT_INTERP
Segment : PT_NOTE
.rela.dyn (RELA, ALLOC)
Segment (Execute/Read)
.text section (PROGBITS, SHF_ALLOC | SHF_EXECINSTR)
Segment (Read)
.rodata (PROGBITS, SHF_ALLOC | SHF_WRITE)
Segment : PT_GNU_EH_FRAME
.eh_frame_hdr
.eh_frame
.gcc_except_table
...
SegmentN
Segment (Write/Read) (VaSize > Size)
Segment (Read) : PT_GNU_RELRO
Segment (Write/Read)
.data
.bss (Size == 0) (VSize != 0)
}
.comment (VA == 0)
.shstrtab (VA == 0)
Section header table (the data for linking and relocation)
}
Last top level segment contains .bss section that requires additional VA space.
So (VaSize > Size) for that segment.
Segments can be unsorted (by offset) in table.
Top level segments has Type=PT_LOAD : "Loadable segment".
Top level segments usually are aligned for page size (4 KB).
Another segments (non PT_LOAD segments) are inside PT_LOAD segments.
(VA-offset == 0) is possible for some sections and segments at the beginning of file.
(VA-offset == 4KB*N) for most sections and segments where (Size != 0),
(VA-offset != 4KB*N) for .bss section (last section), because (Size == 0),
and that section is not mapped from image file.
Some files contain additional "virtual" 4 KB page in VA space after
end of data of top level segments (PT_LOAD) before new top level segments.
So (VA-offset) value can increase by 4 KB step.
*/
#define ELF_CLASS_32 1
@ -47,14 +86,14 @@ namespace NElf {
#define ELF_DATA_2LSB 1
#define ELF_DATA_2MSB 2
static const UInt32 kHeaderSize32 = 0x34;
static const UInt32 kHeaderSize64 = 0x40;
static const unsigned kHeaderSize32 = 0x34;
static const unsigned kHeaderSize64 = 0x40;
static const UInt32 kSegmentSize32 = 0x20;
static const UInt32 kSegmentSize64 = 0x38;
static const unsigned kSegmentSize32 = 0x20;
static const unsigned kSegmentSize64 = 0x38;
static const UInt32 kSectionSize32 = 0x28;
static const UInt32 kSectionSize64 = 0x40;
static const unsigned kSectionSize32 = 0x28;
static const unsigned kSectionSize64 = 0x40;
struct CHeader
{
@ -78,9 +117,9 @@ struct CHeader
UInt16 NumSections;
UInt16 NamesSectIndex;
bool Parse(const Byte *buf);
bool Parse(const Byte *p);
UInt64 GetHeadersSize() const { return (UInt64)HeaderSize +
UInt32 GetHeadersSize() const { return (UInt32)HeaderSize +
(UInt32)NumSegments * SegmentEntrySize +
(UInt32)NumSections * SectionEntrySize; }
};
@ -104,7 +143,7 @@ bool CHeader::Parse(const Byte *p)
if (p[6] != 1) // Version
return false;
Os = p[7];
AbiVer = p[8];
// AbiVer = p[8];
for (int i = 9; i < 16; i++)
if (p[i] != 0)
return false;
@ -117,16 +156,21 @@ bool CHeader::Parse(const Byte *p)
if (Mode64)
{
// G64(0x18, EntryVa);
G64(0x20, ProgOffset);
G64(0x20, ProgOffset); // == kHeaderSize64 == 0x40 usually
G64(0x28, SectOffset);
p += 0x30;
// we expect that fields are aligned
if (ProgOffset & 7) return false;
if (SectOffset & 7) return false;
}
else
{
// G32(0x18, EntryVa);
G32(0x1C, ProgOffset);
G32(0x1C, ProgOffset); // == kHeaderSize32 == 0x34 usually
G32(0x20, SectOffset);
p += 0x24;
if (ProgOffset & 3) return false;
if (SectOffset & 3) return false;
}
G32(0, Flags);
@ -140,21 +184,20 @@ bool CHeader::Parse(const Byte *p)
G16(12, NumSections);
G16(14, NamesSectIndex);
if (ProgOffset < HeaderSize && (ProgOffset != 0 || NumSegments != 0)) return false;
if (SectOffset < HeaderSize && (SectOffset != 0 || NumSections != 0)) return false;
if (ProgOffset < HeaderSize && (ProgOffset || NumSegments)) return false;
if (SectOffset < HeaderSize && (SectOffset || NumSections)) return false;
if (SegmentEntrySize == 0) { if (NumSegments != 0) return false; }
if (SegmentEntrySize == 0) { if (NumSegments) return false; }
else if (SegmentEntrySize != (Mode64 ? kSegmentSize64 : kSegmentSize32)) return false;
if (SectionEntrySize == 0) { if (NumSections != 0) return false; }
if (SectionEntrySize == 0) { if (NumSections) return false; }
else if (SectionEntrySize != (Mode64 ? kSectionSize64 : kSectionSize32)) return false;
return true;
}
// The program header table itself.
#define PT_PHDR 6
#define PT_PHDR 6 // The program header table itself.
#define PT_GNU_STACK 0x6474e551
static const CUInt32PCharPair g_SegnmentTypes[] =
@ -186,14 +229,16 @@ struct CSegment
UInt32 Flags;
UInt64 Offset;
UInt64 Va;
// UInt64 Pa;
UInt64 Size;
UInt64 VSize;
UInt64 Align;
UInt64 Size; // size in file
UInt64 VSize; // size in memory
#ifdef Z7_ELF_SHOW_DETAILS
UInt64 Pa; // usually == Va, or == 0
UInt64 Align; // if (Align != 0), condition must be met:
// (VSize % Align == Offset % Alig)
#endif
void UpdateTotalSize(UInt64 &totalSize)
{
UInt64 t = Offset + Size;
const UInt64 t = Offset + Size;
if (totalSize < t)
totalSize = t;
}
@ -208,20 +253,24 @@ void CSegment::Parse(const Byte *p, bool mode64, bool be)
G32(4, Flags);
G64(8, Offset);
G64(0x10, Va);
// G64(0x18, Pa);
G64(0x20, Size);
G64(0x28, VSize);
#ifdef Z7_ELF_SHOW_DETAILS
G64(0x18, Pa);
G64(0x30, Align);
#endif
}
else
{
G32(4, Offset);
G32(8, Va);
// G32(0x0C, Pa);
G32(0x10, Size);
G32(0x14, VSize);
G32(0x18, Flags);
#ifdef Z7_ELF_SHOW_DETAILS
G32(0x0C, Pa);
G32(0x1C, Align);
#endif
}
}
@ -290,6 +339,8 @@ static const CUInt32PCharPair g_SectTypes[] =
{ 0x70000005, "ARM_OVERLAYSECTION" }
};
// SHF_ flags
static const CUInt32PCharPair g_SectionFlags[] =
{
{ 0, "WRITE" },
@ -303,7 +354,7 @@ static const CUInt32PCharPair g_SectionFlags[] =
{ 8, "OS_NONCONFORMING" },
{ 9, "GROUP" },
{ 10, "TLS" },
{ 11, "CP_SECTION" },
{ 11, "COMPRESSED" },
{ 12, "DP_SECTION" },
{ 13, "XCORE_SHF_CP_SECTION" },
{ 28, "64_LARGE" },
@ -326,7 +377,7 @@ struct CSection
void UpdateTotalSize(UInt64 &totalSize)
{
UInt64 t = Offset + GetSize();
const UInt64 t = Offset + GetSize();
if (totalSize < t)
totalSize = t;
}
@ -412,7 +463,7 @@ static const char * const g_Machines[] =
, "TRW RH-32"
, "Motorola RCE"
, "ARM"
, "Alpha"
, "Alpha-STD"
, "Hitachi SH"
, "SPARC-V9"
, "Siemens Tricore"
@ -577,8 +628,8 @@ static const char * const g_Machines[] =
static const CUInt32PCharPair g_MachinePairs[] =
{
{ 243, "RISC-V" },
{ 47787, "Xilinx MicroBlaze" }
// { 0x9026, "Alpha" }
{ 0x9026, "Alpha" }, // EM_ALPHA_EXP, obsolete, (used by NetBSD/alpha) (written in the absence of an ABI)
{ 0xbaab, "Xilinx MicroBlaze" }
};
static const CUInt32PCharPair g_OS[] =
@ -600,6 +651,8 @@ static const CUInt32PCharPair g_OS[] =
{ 14, "HP NSK" },
{ 15, "AROS" },
{ 16, "FenixOS" },
{ 17, "CloudABI" },
{ 18, "OpenVOS" },
{ 64, "Bare-metal TMS320C6000" },
{ 65, "Linux TMS320C6000" },
{ 97, "ARM" },
@ -693,7 +746,9 @@ public:
void CHandler::GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showNULL) const
{
if (index >= _sections.Size())
return;
prop = index; // it's possible for some file, but maybe it's ERROR case
else
{
const CSection &section = _sections[index];
const UInt32 offset = section.Name;
if (index == SHN_UNDEF /* && section.Type == SHT_NULL && offset == 0 */)
@ -703,13 +758,15 @@ void CHandler::GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showN
return;
}
const Byte *p = _namesData;
size_t size = _namesData.Size();
const size_t size = _namesData.Size();
for (size_t i = offset; i < size; i++)
if (p[i] == 0)
{
prop = (const char *)(p + offset);
return;
}
prop = "ERROR";
}
}
static const Byte kArcProps[] =
@ -726,7 +783,14 @@ static const Byte kArcProps[] =
enum
{
kpidLinkSection = kpidUserDefined,
kpidInfoSection
kpidInfoSection,
kpidEntrySize
#ifdef Z7_ELF_SHOW_DETAILS
// , kpidAlign
, kpidPa
, kpidDelta
, kpidOffsetEnd
#endif
};
static const CStatProp kProps[] =
@ -738,6 +802,14 @@ static const CStatProp kProps[] =
{ NULL, kpidVa, VT_UI8 },
{ NULL, kpidType, VT_BSTR },
{ NULL, kpidCharacts, VT_BSTR }
#ifdef Z7_ELF_SHOW_DETAILS
// , { "Align", kpidAlign, VT_UI8 }
, { NULL, kpidClusterSize, VT_UI8 }
, { "PA", kpidPa, VT_UI8 }
, { "End offset", kpidOffsetEnd, VT_UI8 }
, { "Delta (VA-Offset)", kpidDelta, VT_UI8 }
#endif
, { "Entry Size", kpidEntrySize, VT_UI8}
, { "Link Section", kpidLinkSection, VT_BSTR}
, { "Info Section", kpidInfoSection, VT_BSTR}
};
@ -769,7 +841,7 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
if (s.IsEmpty())
s = TypePairToString(g_MachinePairs, Z7_ARRAY_SIZE(g_MachinePairs), _header.Machine);
UInt32 flags = _header.Flags;
if (flags != 0)
if (flags)
{
s.Add_Space();
if (_header.Machine == k_Machine_ARM)
@ -783,10 +855,10 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
const UInt32 ver = flags >> 28;
s += "v";
s.Add_UInt32(ver);
flags &= (((UInt32)1 << 28) - 1);
flags &= ((UInt32)1 << 28) - 1;
UInt32 abi = (flags >> 12) & 7;
if (abi != 0)
const UInt32 abi = (flags >> 12) & 7;
if (abi)
{
s += " ABI:";
s.Add_UInt32(abi);
@ -827,13 +899,39 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
case kpidHostOS: PAIR_TO_PROP(g_OS, _header.Os, prop); break;
case kpidCharacts: TYPE_TO_PROP(g_Types, _header.Type, prop); break;
case kpidComment:
{
AString s;
if (_stackFlags_Defined)
{
AString s ("STACK: ");
s += "STACK: ";
s += FlagsToString(g_SegmentFlags, Z7_ARRAY_SIZE(g_SegmentFlags), _stackFlags);
prop = s;
s.Add_LF();
/*
if (_header.EntryVa)
{
s += "Entry point: 0x";
char temp[16 + 4];
ConvertUInt64ToHex(_header.EntryVa, temp);
s += temp;
s.Add_LF();
}
*/
}
if (_header.NumSegments)
{
s += "Segments: ";
s.Add_UInt32(_header.NumSegments);
s.Add_LF();
}
if (_header.NumSections)
{
s += "Sections: ";
s.Add_UInt32(_header.NumSections);
s.Add_LF();
}
prop = s;
break;
}
case kpidExtension:
{
const char *s = NULL;
@ -878,12 +976,17 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
}
case kpidOffset: prop = item.Offset; break;
case kpidVa: prop = item.Va; break;
#ifdef Z7_ELF_SHOW_DETAILS
case kpidDelta: if (item.Va) { prop = item.Va - item.Offset; } break;
case kpidOffsetEnd: prop = item.Offset + item.Size; break;
case kpidPa: prop = item.Pa; break;
case kpidClusterSize: prop = item.Align; break;
#endif
case kpidSize:
case kpidPackSize: prop = (UInt64)item.Size; break;
case kpidVirtualSize: prop = (UInt64)item.VSize; break;
case kpidType: PAIR_TO_PROP(g_SegnmentTypes, item.Type, prop); break;
case kpidCharacts: FLAGS_TO_PROP(g_SegmentFlags, item.Flags, prop); break;
}
}
else
@ -895,13 +998,19 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPath: GetSectionName(index, prop, true); break;
case kpidOffset: prop = item.Offset; break;
case kpidVa: prop = item.Va; break;
#ifdef Z7_ELF_SHOW_DETAILS
case kpidDelta: if (item.Va) { prop = item.Va - item.Offset; } break;
case kpidOffsetEnd: prop = item.Offset + item.GetSize(); break;
#endif
case kpidSize:
case kpidPackSize: prop = (UInt64)(item.Type == SHT_NOBITS ? 0 : item.VSize); break;
case kpidVirtualSize: prop = item.GetSize(); break;
case kpidType: PAIR_TO_PROP(g_SectTypes, item.Type, prop); break;
case kpidCharacts: FLAGS_TO_PROP(g_SectionFlags, (UInt32)item.Flags, prop); break;
// case kpidAlign: prop = item.Align; break;
case kpidLinkSection: GetSectionName(item.Link, prop, false); break;
case kpidInfoSection: GetSectionName(item.Info, prop, false); break;
case kpidEntrySize: prop = (UInt64)item.EntSize; break;
}
}
prop.Detach(value);
@ -911,42 +1020,46 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
HRESULT CHandler::Open2(IInStream *stream)
{
{
const UInt32 kStartSize = kHeaderSize64;
Byte h[kStartSize];
RINOK(ReadStream_FALSE(stream, h, kStartSize))
if (h[0] != 0x7F || h[1] != 'E' || h[2] != 'L' || h[3] != 'F')
UInt64 h64[kStartSize / 8];
RINOK(ReadStream_FALSE(stream, h64, kStartSize))
const Byte *h = (const Byte *)(const void *)h64;
if (GetUi32a(h) != 0x464c457f)
return S_FALSE;
if (!_header.Parse(h))
return S_FALSE;
}
_totalSize = _header.HeaderSize;
bool addSegments = false;
bool addSections = false;
if (_header.NumSections > 1)
// first section usually is NULL (with zero offsets and zero sizes).
if (_header.NumSegments == 0 || _header.NumSections > 1)
addSections = true;
else
addSegments = true;
#ifdef Z7_ELF_SHOW_DETAILS
addSections = true;
addSegments = true;
#endif
if (_header.NumSegments != 0)
if (_header.NumSegments)
{
if (_header.ProgOffset > (UInt64)1 << 60) return S_FALSE;
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))
{
const UInt64 total = _header.ProgOffset + size;
if (_totalSize < total)
_totalSize = total;
const Byte *p = buf;
}
if (addSegments)
_segments.ClearAndReserve(_header.NumSegments);
const Byte *p = buf;
for (unsigned i = 0; i < _header.NumSegments; i++, p += _header.SegmentEntrySize)
{
CSegment seg;
@ -957,29 +1070,29 @@ HRESULT CHandler::Open2(IInStream *stream)
_stackFlags = seg.Flags;
_stackFlags_Defined = true;
}
if (addSegments && seg.Type != PT_PHDR)
if (addSegments
// we don't show program header table segment
&& seg.Type != PT_PHDR
)
_segments.AddInReserved(seg);
}
}
if (_header.NumSections != 0)
if (_header.NumSections)
{
if (_header.SectOffset > (UInt64)1 << 60) return S_FALSE;
RINOK(InStream_SeekSet(stream, _header.SectOffset))
size_t size = (size_t)_header.SectionEntrySize * _header.NumSections;
const size_t size = (size_t)_header.SectionEntrySize * _header.NumSections;
CByteArr buf(size);
RINOK(ReadStream_FALSE(stream, buf, size))
UInt64 total = _header.SectOffset + size;
{
const UInt64 total = _header.SectOffset + size;
if (_totalSize < total)
_totalSize = total;
const Byte *p = buf;
}
if (addSections)
_sections.ClearAndReserve(_header.NumSections);
const Byte *p = buf;
for (unsigned i = 0; i < _header.NumSections; i++, p += _header.SectionEntrySize)
{
CSection sect;
@ -1000,8 +1113,7 @@ HRESULT CHandler::Open2(IInStream *stream)
{
const CSection &sect = _sections[_header.NamesSectIndex];
const UInt64 size = sect.GetSize();
if (size != 0
&& size < ((UInt64)1 << 31)
if (size && size < ((UInt64)1 << 31)
&& (Int64)sect.Offset >= 0)
{
_namesData.Alloc((size_t)size);
@ -1009,9 +1121,9 @@ HRESULT CHandler::Open2(IInStream *stream)
RINOK(ReadStream_FALSE(stream, _namesData, (size_t)size))
}
}
/*
// we will not delete NULL sections, since we have links to section via indexes
// we cannot delete "NULL" sections,
// because we have links to sections array via indexes
for (int i = _sections.Size() - 1; i >= 0; i--)
if (_sections[i].Type == SHT_NULL)
_items.Delete(i);
@ -1080,7 +1192,7 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
RINOK(extractCallback->SetTotal(totalSize))
UInt64 currentTotalSize = 0;
totalSize = 0;
UInt64 currentItemSize;
CMyComPtr2_Create<ICompressCoder, NCompress::CCopyCoder> copyCoder;
@ -1089,9 +1201,9 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr2_Create<ISequentialInStream, CLimitedSequentialInStream> inStream;
inStream->SetStream(_inStream);
for (i = 0;; i++, currentTotalSize += currentItemSize)
for (i = 0;; i++, totalSize += currentItemSize)
{
lps->InSize = lps->OutSize = currentTotalSize;
lps->InSize = lps->OutSize = totalSize;
RINOK(lps->SetCur())
if (i >= numItems)
break;

View file

@ -473,8 +473,8 @@ Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break;
}
case kpidIsDir: prop = item.IsDir(); break;
case kpidSize: prop = item.Size; break;
case kpidPackSize: prop = item.PackSize; break;
case kpidSize: prop = (UInt64)item.Size; break;
case kpidPackSize: prop = (UInt64)item.PackSize; break;
case kpidCRC: prop = (UInt32)item.CRC; break;
case kpidHostOS: PAIR_TO_PROP(g_OsPairs, item.OsId, prop); break;
case kpidMTime:

View file

@ -1579,6 +1579,8 @@ HRESULT CHandler::OpenCapsule(IInStream *stream)
|| _h.CapsuleImageSize < _h.HeaderSize
|| _h.OffsetToCapsuleBody < _h.HeaderSize
|| _h.OffsetToCapsuleBody > _h.CapsuleImageSize
|| _h.CapsuleImageSize > (1u << 30) // to reduce false detection
|| _h.HeaderSize > (1u << 28) // to reduce false detection
)
return S_FALSE;
_phySize = _h.CapsuleImageSize;
@ -1587,7 +1589,7 @@ HRESULT CHandler::OpenCapsule(IInStream *stream)
_h.OffsetToSplitInformation != 0 )
return E_NOTIMPL;
unsigned bufIndex = AddBuf(_h.CapsuleImageSize);
const unsigned bufIndex = AddBuf(_h.CapsuleImageSize);
CByteBuffer &buf0 = _bufs[bufIndex];
memcpy(buf0, buf, kHeaderSize);
ReadStream_FALSE(stream, buf0 + kHeaderSize, _h.CapsuleImageSize - kHeaderSize);

View file

@ -422,7 +422,7 @@ int Main2(
{
CExtractCallbackConsole *ecs = new CExtractCallbackConsole;
CMyComPtr<IFolderArchiveExtractCallback> extractCallback = ecs;
ecs->Init(g_StdStream, &g_StdErr, g_StdStream);
ecs->Init(g_StdStream, &g_StdErr, g_StdStream, false);
#ifndef Z7_NO_CRYPTO
ecs->PasswordIsDefined = passwordEnabled;

View file

@ -196,29 +196,17 @@ static void x86_Filter(Byte *data, UInt32 size, Int32 *history)
const Byte b = p[0];
if (b == 0x48)
if ((b & 0x80) == 0) // REX (0x48 or 0x4c)
{
if (p[1] == 0x8B)
const unsigned b2 = p[2] - 0x5; // [RIP + disp32]
if (b2 & 0x7)
continue;
if (p[1] != 0x8d) // LEA
{
if ((p[2] & 0xF7) != 0x5)
if (p[1] != 0x8b || b != 0x48 || (b2 & 0xf7))
continue;
// MOV RAX / RCX, [RIP + disp32]
}
else if (p[1] == 0x8D) // LEA
{
if ((p[2] & 0x7) != 0x5)
continue;
// LEA R**, []
}
else
continue;
codeLen = 3;
}
else if (b == 0x4C)
{
if (p[1] != 0x8D || (p[2] & 0x7) != 0x5)
continue;
// LEA R*, []
codeLen = 3;
}
else if (b == 0xE8)

View file

@ -1039,6 +1039,9 @@ void CArcCmdLineParser::Parse1(const UStringVector &commandStrings,
options.TechMode = parser[NKey::kTechMode].ThereIs;
options.ShowTime = parser[NKey::kShowTime].ThereIs;
if (parser[NKey::kDisablePercents].ThereIs)
options.DisablePercents = true;
if (parser[NKey::kDisablePercents].ThereIs
|| options.StdOutMode
|| !options.IsStdOutTerminal)

View file

@ -60,6 +60,8 @@ struct CArcCmdLineOptions
bool StdInMode;
bool StdOutMode;
bool EnableHeaders;
bool DisablePercents;
bool YesToAll;
bool ShowDialog;
@ -132,6 +134,7 @@ struct CArcCmdLineOptions
StdOutMode(false),
EnableHeaders(false),
DisablePercents(false),
YesToAll(false),
ShowDialog(false),

View file

@ -343,7 +343,7 @@ Z7_COM7F_IMF(CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int3
default: s = "???"; requiredLevel = 2;
}
bool show2 = (LogLevel >= requiredLevel && _so);
const bool show2 = (LogLevel >= requiredLevel && _so);
if (show2)
{
@ -373,6 +373,7 @@ Z7_COM7F_IMF(CExtractCallbackConsole::PrepareOperation(const wchar_t *name, Int3
if (NeedFlush)
_so->Flush();
// _so->Flush(); // for debug only
}
if (NeedPercents())

View file

@ -44,7 +44,7 @@ class CExtractScanConsole Z7_final: public IDirItemsCallback
// CErrorPathCodes2 ScanErrors;
bool NeedPercents() const { return _percent._so != NULL; }
bool NeedPercents() const { return _percent._so && !_percent.DisablePrint; }
void ClosePercentsAndFlush()
{
@ -56,11 +56,16 @@ class CExtractScanConsole Z7_final: public IDirItemsCallback
public:
void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream)
void Init(
CStdOutStream *outStream,
CStdOutStream *errorStream,
CStdOutStream *percentStream,
bool disablePercents)
{
_so = outStream;
_se = errorStream;
_percent._so = percentStream;
_percent.DisablePrint = disablePercents;
}
void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; }
@ -177,9 +182,13 @@ public:
void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; }
void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream)
void Init(
CStdOutStream *outStream,
CStdOutStream *errorStream,
CStdOutStream *percentStream,
bool disablePercents)
{
COpenCallbackConsole::Init(outStream, errorStream, percentStream);
COpenCallbackConsole::Init(outStream, errorStream, percentStream, disablePercents);
NumTryArcs = 0;

View file

@ -1155,7 +1155,7 @@ HRESULT ListArchives(
CArchiveLink arcLink;
COpenCallbackConsole openCallback;
openCallback.Init(&g_StdOut, g_ErrStream, NULL);
openCallback.Init(&g_StdOut, g_ErrStream, NULL, listOptions.DisablePercents);
#ifndef Z7_NO_CRYPTO

View file

@ -11,10 +11,12 @@ struct CListOptions
{
bool ExcludeDirItems;
bool ExcludeFileItems;
bool DisablePercents;
CListOptions():
ExcludeDirItems(false),
ExcludeFileItems(false)
ExcludeFileItems(false),
DisablePercents(false)
{}
};

View file

@ -1280,7 +1280,9 @@ int Main2(
{
CExtractScanConsole scan;
scan.Init(options.EnableHeaders ? g_StdStream : NULL, g_ErrStream, percentsStream);
scan.Init(options.EnableHeaders ? g_StdStream : NULL,
g_ErrStream, percentsStream,
options.DisablePercents);
scan.SetWindowWidth(consoleWidth);
if (g_StdStream && options.EnableHeaders)
@ -1330,7 +1332,7 @@ int Main2(
ecs->Password = options.Password;
#endif
ecs->Init(g_StdStream, g_ErrStream, percentsStream);
ecs->Init(g_StdStream, g_ErrStream, percentsStream, options.DisablePercents);
ecs->MultiArcMode = (ArchivePathsSorted.Size() > 1);
ecs->LogLevel = options.LogLevel;
@ -1494,6 +1496,7 @@ int Main2(
CListOptions lo;
lo.ExcludeDirItems = options.Censor.ExcludeDirItems;
lo.ExcludeFileItems = options.Censor.ExcludeFileItems;
lo.DisablePercents = options.DisablePercents;
hresultMain = ListArchives(
lo,
@ -1538,7 +1541,7 @@ int Main2(
uo.SfxModule = kDefaultSfxModule;
COpenCallbackConsole openCallback;
openCallback.Init(g_StdStream, g_ErrStream, percentsStream);
openCallback.Init(g_StdStream, g_ErrStream, percentsStream, options.DisablePercents);
#ifndef Z7_NO_CRYPTO
bool passwordIsDefined =
@ -1563,7 +1566,7 @@ int Main2(
callback.StdOutMode = uo.StdOutMode;
callback.Init(
// NULL,
g_StdStream, g_ErrStream, percentsStream);
g_StdStream, g_ErrStream, percentsStream, options.DisablePercents);
CUpdateErrorInfo errorInfo;
@ -1598,7 +1601,7 @@ int Main2(
if (percentsStream)
callback.SetWindowWidth(consoleWidth);
callback.Init(g_StdStream, g_ErrStream, percentsStream);
callback.Init(g_StdStream, g_ErrStream, percentsStream, options.DisablePercents);
callback.PrintHeaders = options.EnableHeaders;
callback.PrintFields = options.ListFields;

View file

@ -22,7 +22,7 @@ protected:
bool _totalFilesDefined;
// bool _totalBytesDefined;
bool NeedPercents() const { return _percent._so != NULL; }
bool NeedPercents() const { return _percent._so && !_percent.DisablePrint; }
public:
@ -49,11 +49,16 @@ public:
virtual ~COpenCallbackConsole() {}
void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream)
void Init(
CStdOutStream *outStream,
CStdOutStream *errorStream,
CStdOutStream *percentStream,
bool disablePercents)
{
_so = outStream;
_se = errorStream;
_percent._so = percentStream;
_percent.DisablePrint = disablePercents;
}
Z7_IFACE_IMP(IOpenCallbackUI)

View file

@ -88,6 +88,8 @@ void CPercentPrinter::GetPercents()
void CPercentPrinter::Print()
{
if (DisablePrint)
return;
DWORD tick = 0;
if (_tickStep != 0)
tick = GetTickCount();

View file

@ -43,12 +43,14 @@ class CPercentPrinter: public CPercentPrinterState
public:
CStdOutStream *_so;
bool DisablePrint;
bool NeedFlush;
unsigned MaxLen;
CPercentPrinter(UInt32 tickStep = 200):
_tickStep(tickStep),
_prevTick(0),
DisablePrint(false),
NeedFlush(true),
MaxLen(80 - 1)
{}

View file

@ -64,13 +64,18 @@ public:
void SetWindowWidth(unsigned width) { _percent.MaxLen = width - 1; }
void Init(CStdOutStream *outStream, CStdOutStream *errorStream, CStdOutStream *percentStream)
void Init(
CStdOutStream *outStream,
CStdOutStream *errorStream,
CStdOutStream *percentStream,
bool disablePercents)
{
FailedFiles.Clear();
_so = outStream;
_se = errorStream;
_percent._so = percentStream;
_percent.DisablePrint = disablePercents;
}
void ClosePercents2()

View file

@ -939,7 +939,8 @@ void CBrowseDialog2::OnDelete(/* bool toRecycleBin */)
s.Add_LF();
s += s2;
}
if (::MessageBoxW((HWND)*this, s, LangString(titleID), MB_OKCANCEL | MB_ICONQUESTION) != IDOK)
if (::MessageBoxW((HWND)*this, s, LangString(titleID),
MB_YESNOCANCEL | MB_ICONQUESTION) != IDYES)
return;
}

View file

@ -609,7 +609,7 @@ HRESULT CPanel::OpenParentArchiveFolder()
if (folderLink.WasChanged(newFileInfo))
{
UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, folderLink.RelPath);
if (::MessageBoxW((HWND)*this, message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
if (::MessageBoxW((HWND)*this, message, L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION) == IDYES)
{
if (OnOpenItemChanged(folderLink.FileIndex, fs2us(folderLink.FilePath),
folderLinkPrev.UsePassword, folderLinkPrev.Password) != S_OK)
@ -1249,7 +1249,7 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param)
}
{
const UString message = MyFormatNew(IDS_WANT_UPDATE_MODIFIED_FILE, tpi->RelPath);
if (::MessageBoxW(g_HWND, message, L"7-Zip", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
if (::MessageBoxW(g_HWND, message, L"7-Zip", MB_YESNOCANCEL | MB_ICONQUESTION) == IDYES)
{
// DEBUG_PRINT_NUM("SendMessage", GetCurrentThreadId());
if (SendMessage(tpi->Window, kOpenItemChanged, 0, (LONG_PTR)tpi.get()) != 1)

View file

@ -244,7 +244,8 @@ Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
messageID = IDS_WANT_TO_DELETE_ITEMS;
messageParam = NumberToString(indices.Size());
}
if (::MessageBoxW(GetParent(), MyFormatNew(messageID, messageParam), LangString(titleID), MB_OKCANCEL | MB_ICONQUESTION) != IDOK)
if (::MessageBoxW(GetParent(), MyFormatNew(messageID, messageParam), LangString(titleID),
MB_YESNOCANCEL | MB_ICONQUESTION) != IDYES)
return;
CDisableNotify disableNotify(*this);

View file

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<?define VerMajor = "24" ?>
<?define VerMinor = "06" ?>
<?define VerMinor = "07" ?>
<?define VerBuild = "00" ?>
<?define MmVer = "$(var.VerMajor).$(var.VerMinor)" ?>
<?define MmHex = "$(var.VerMajor)$(var.VerMinor)" ?>

View file

@ -1,6 +1,6 @@
LZMA compression
----------------
Version: 24.06
Version: 24.07
This file describes LZMA encoding and decoding functions written in C language.

View file

@ -1,4 +1,4 @@
7-Zip 24.06 Sources
7-Zip 24.07 Sources
-------------------
7-Zip is a file archiver for Windows.

View file

@ -1,6 +1,16 @@
HISTORY of the 7-Zip source code
--------------------------------
24.07 2024-06-19
-------------------------
- Changes in files:
Asm/x86/Sha256Opt.asm
Asm/x86/Sha1Opt.asm
Now it uses "READONLY" flag for constant array segment.
It fixes an issue where ".rodata" section in 7-Zip for x86/x64 Linux had a "WRITE" attribute.
- The bug was fixed: 7-Zip could crash for some incorrect ZSTD archives.
24.06 2024-05-26
-------------------------
- The bug was fixed: 7-Zip could not unpack some ZSTD archives.