aboutsummaryrefslogtreecommitdiff
path: root/CPP/7zip/Archive/ElfHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--CPP/7zip/Archive/ElfHandler.cpp94
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
159static const CUInt32PCharPair g_SegnmentTypes[] = 160static 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
645static 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 }