diff options
Diffstat (limited to '')
-rw-r--r-- | CPP/7zip/Archive/ElfHandler.cpp | 94 |
1 files changed, 67 insertions, 27 deletions
diff --git a/CPP/7zip/Archive/ElfHandler.cpp b/CPP/7zip/Archive/ElfHandler.cpp index 7e1facc..e31b4ae 100644 --- a/CPP/7zip/Archive/ElfHandler.cpp +++ b/CPP/7zip/Archive/ElfHandler.cpp | |||
@@ -155,6 +155,7 @@ bool CHeader::Parse(const Byte *p) | |||
155 | // The program header table itself. | 155 | // The program header table itself. |
156 | 156 | ||
157 | #define PT_PHDR 6 | 157 | #define PT_PHDR 6 |
158 | #define PT_GNU_STACK 0x6474e551 | ||
158 | 159 | ||
159 | static const CUInt32PCharPair g_SegnmentTypes[] = | 160 | static const CUInt32PCharPair g_SegnmentTypes[] = |
160 | { | 161 | { |
@@ -167,7 +168,7 @@ static const CUInt32PCharPair g_SegnmentTypes[] = | |||
167 | { 6, "Program header table" }, | 168 | { 6, "Program header table" }, |
168 | { 7, "TLS" }, | 169 | { 7, "TLS" }, |
169 | { 0x6474e550, "GNU_EH_FRAME" }, | 170 | { 0x6474e550, "GNU_EH_FRAME" }, |
170 | { 0x6474e551, "GNU_STACK" }, | 171 | { PT_GNU_STACK, "GNU_STACK" }, |
171 | { 0x6474e552, "GNU_RELRO" } | 172 | { 0x6474e552, "GNU_RELRO" } |
172 | }; | 173 | }; |
173 | 174 | ||
@@ -607,6 +608,7 @@ static const CUInt32PCharPair g_OS[] = | |||
607 | 608 | ||
608 | #define k_Machine_MIPS 8 | 609 | #define k_Machine_MIPS 8 |
609 | #define k_Machine_ARM 40 | 610 | #define k_Machine_ARM 40 |
611 | #define k_Machine_RISCV 243 | ||
610 | 612 | ||
611 | /* | 613 | /* |
612 | #define EF_ARM_ABIMASK 0xFF000000 | 614 | #define EF_ARM_ABIMASK 0xFF000000 |
@@ -640,6 +642,15 @@ static const CUInt32PCharPair g_MIPS_Flags[] = | |||
640 | { 27, "MDMX" } | 642 | { 27, "MDMX" } |
641 | }; | 643 | }; |
642 | 644 | ||
645 | static const char * const g_RISCV_Flags[] = | ||
646 | { | ||
647 | "RVC", | ||
648 | NULL, | ||
649 | NULL, | ||
650 | "RVE", | ||
651 | "TSO" | ||
652 | }; | ||
653 | |||
643 | 654 | ||
644 | // #define ET_NONE 0 | 655 | // #define ET_NONE 0 |
645 | #define ET_REL 1 | 656 | #define ET_REL 1 |
@@ -670,6 +681,8 @@ Z7_CLASS_IMP_CHandler_IInArchive_1( | |||
670 | CHeader _header; | 681 | CHeader _header; |
671 | bool _headersError; | 682 | bool _headersError; |
672 | bool _allowTail; | 683 | bool _allowTail; |
684 | bool _stackFlags_Defined; | ||
685 | UInt32 _stackFlags; | ||
673 | 686 | ||
674 | void GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showNULL) const; | 687 | void GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showNULL) const; |
675 | HRESULT Open2(IInStream *stream); | 688 | HRESULT Open2(IInStream *stream); |
@@ -706,6 +719,7 @@ static const Byte kArcProps[] = | |||
706 | kpidBigEndian, | 719 | kpidBigEndian, |
707 | kpidHostOS, | 720 | kpidHostOS, |
708 | kpidCharacts, | 721 | kpidCharacts, |
722 | kpidComment, | ||
709 | kpidHeadersSize | 723 | kpidHeadersSize |
710 | }; | 724 | }; |
711 | 725 | ||
@@ -782,6 +796,23 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) | |||
782 | s.Add_Space(); | 796 | s.Add_Space(); |
783 | s += FlagsToString(g_MIPS_Flags, Z7_ARRAY_SIZE(g_MIPS_Flags), flags); | 797 | s += FlagsToString(g_MIPS_Flags, Z7_ARRAY_SIZE(g_MIPS_Flags), flags); |
784 | } | 798 | } |
799 | else if (_header.Machine == k_Machine_RISCV) | ||
800 | { | ||
801 | s += "FLOAT_"; | ||
802 | const UInt32 fl = (flags >> 1) & 3; | ||
803 | /* | ||
804 | static const char * const g_RISCV_Flags_Float[] = | ||
805 | { "SOFT", "SINGLE", "DOUBLE", "QUAD" }; | ||
806 | s += g_RISCV_Flags_Float[fl]; | ||
807 | */ | ||
808 | if (fl) | ||
809 | s.Add_UInt32(16u << fl); | ||
810 | else | ||
811 | s += "SOFT"; | ||
812 | s.Add_Space(); | ||
813 | flags &= ~(UInt32)6; | ||
814 | s += FlagsToString(g_RISCV_Flags, Z7_ARRAY_SIZE(g_RISCV_Flags), flags); | ||
815 | } | ||
785 | else | 816 | else |
786 | { | 817 | { |
787 | char sz[16]; | 818 | char sz[16]; |
@@ -795,6 +826,14 @@ Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)) | |||
795 | 826 | ||
796 | case kpidHostOS: PAIR_TO_PROP(g_OS, _header.Os, prop); break; | 827 | case kpidHostOS: PAIR_TO_PROP(g_OS, _header.Os, prop); break; |
797 | case kpidCharacts: TYPE_TO_PROP(g_Types, _header.Type, prop); break; | 828 | case kpidCharacts: TYPE_TO_PROP(g_Types, _header.Type, prop); break; |
829 | case kpidComment: | ||
830 | if (_stackFlags_Defined) | ||
831 | { | ||
832 | AString s ("STACK: "); | ||
833 | s += FlagsToString(g_SegmentFlags, Z7_ARRAY_SIZE(g_SegmentFlags), _stackFlags); | ||
834 | prop = s; | ||
835 | } | ||
836 | break; | ||
798 | case kpidExtension: | 837 | case kpidExtension: |
799 | { | 838 | { |
800 | const char *s = NULL; | 839 | const char *s = NULL; |
@@ -913,9 +952,13 @@ HRESULT CHandler::Open2(IInStream *stream) | |||
913 | CSegment seg; | 952 | CSegment seg; |
914 | seg.Parse(p, _header.Mode64, _header.Be); | 953 | seg.Parse(p, _header.Mode64, _header.Be); |
915 | seg.UpdateTotalSize(_totalSize); | 954 | seg.UpdateTotalSize(_totalSize); |
916 | if (addSegments) | 955 | if (seg.Type == PT_GNU_STACK && !_stackFlags_Defined) |
917 | if (seg.Type != PT_PHDR) | 956 | { |
918 | _segments.AddInReserved(seg); | 957 | _stackFlags = seg.Flags; |
958 | _stackFlags_Defined = true; | ||
959 | } | ||
960 | if (addSegments && seg.Type != PT_PHDR) | ||
961 | _segments.AddInReserved(seg); | ||
919 | } | 962 | } |
920 | } | 963 | } |
921 | 964 | ||
@@ -1002,6 +1045,7 @@ Z7_COM7F_IMF(CHandler::Close()) | |||
1002 | { | 1045 | { |
1003 | _totalSize = 0; | 1046 | _totalSize = 0; |
1004 | _headersError = false; | 1047 | _headersError = false; |
1048 | _stackFlags_Defined = false; | ||
1005 | 1049 | ||
1006 | _inStream.Release(); | 1050 | _inStream.Release(); |
1007 | _segments.Clear(); | 1051 | _segments.Clear(); |
@@ -1034,26 +1078,23 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, | |||
1034 | _segments[index].Size : | 1078 | _segments[index].Size : |
1035 | _sections[index - _segments.Size()].GetSize(); | 1079 | _sections[index - _segments.Size()].GetSize(); |
1036 | } | 1080 | } |
1037 | extractCallback->SetTotal(totalSize); | 1081 | RINOK(extractCallback->SetTotal(totalSize)) |
1038 | 1082 | ||
1039 | UInt64 currentTotalSize = 0; | 1083 | UInt64 currentTotalSize = 0; |
1040 | UInt64 currentItemSize; | 1084 | UInt64 currentItemSize; |
1041 | 1085 | ||
1042 | NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); | 1086 | CMyComPtr2_Create<ICompressCoder, NCompress::CCopyCoder> copyCoder; |
1043 | CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; | 1087 | CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps; |
1044 | |||
1045 | CLocalProgress *lps = new CLocalProgress; | ||
1046 | CMyComPtr<ICompressProgressInfo> progress = lps; | ||
1047 | lps->Init(extractCallback, false); | 1088 | lps->Init(extractCallback, false); |
1089 | CMyComPtr2_Create<ISequentialInStream, CLimitedSequentialInStream> inStream; | ||
1090 | inStream->SetStream(_inStream); | ||
1048 | 1091 | ||
1049 | CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; | 1092 | for (i = 0;; i++, currentTotalSize += currentItemSize) |
1050 | CMyComPtr<ISequentialInStream> inStream(streamSpec); | ||
1051 | streamSpec->SetStream(_inStream); | ||
1052 | |||
1053 | for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize) | ||
1054 | { | 1093 | { |
1055 | lps->InSize = lps->OutSize = currentTotalSize; | 1094 | lps->InSize = lps->OutSize = currentTotalSize; |
1056 | RINOK(lps->SetCur()) | 1095 | RINOK(lps->SetCur()) |
1096 | if (i >= numItems) | ||
1097 | break; | ||
1057 | const Int32 askMode = testMode ? | 1098 | const Int32 askMode = testMode ? |
1058 | NExtract::NAskMode::kTest : | 1099 | NExtract::NAskMode::kTest : |
1059 | NExtract::NAskMode::kExtract; | 1100 | NExtract::NAskMode::kExtract; |
@@ -1071,18 +1112,17 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems, | |||
1071 | currentItemSize = item.GetSize(); | 1112 | currentItemSize = item.GetSize(); |
1072 | offset = item.Offset; | 1113 | offset = item.Offset; |
1073 | } | 1114 | } |
1074 | 1115 | { | |
1075 | CMyComPtr<ISequentialOutStream> outStream; | 1116 | CMyComPtr<ISequentialOutStream> outStream; |
1076 | RINOK(extractCallback->GetStream(index, &outStream, askMode)) | 1117 | RINOK(extractCallback->GetStream(index, &outStream, askMode)) |
1077 | if (!testMode && !outStream) | 1118 | if (!testMode && !outStream) |
1078 | continue; | 1119 | continue; |
1079 | 1120 | RINOK(extractCallback->PrepareOperation(askMode)) | |
1080 | RINOK(extractCallback->PrepareOperation(askMode)) | 1121 | RINOK(InStream_SeekSet(_inStream, offset)) |
1081 | RINOK(InStream_SeekSet(_inStream, offset)) | 1122 | inStream->Init(currentItemSize); |
1082 | streamSpec->Init(currentItemSize); | 1123 | RINOK(copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps)) |
1083 | RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)) | 1124 | } |
1084 | outStream.Release(); | 1125 | RINOK(extractCallback->SetOperationResult(copyCoder->TotalSize == currentItemSize ? |
1085 | RINOK(extractCallback->SetOperationResult(copyCoderSpec->TotalSize == currentItemSize ? | ||
1086 | NExtract::NOperationResult::kOK: | 1126 | NExtract::NOperationResult::kOK: |
1087 | NExtract::NOperationResult::kDataError)) | 1127 | NExtract::NOperationResult::kDataError)) |
1088 | } | 1128 | } |