1*f6dc9357SAndroid Build Coastguard Worker // ElfHandler.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../C/CpuArch.h"
6*f6dc9357SAndroid Build Coastguard Worker
7*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/ComTry.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/IntToString.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../../Common/MyBuffer.h"
10*f6dc9357SAndroid Build Coastguard Worker
11*f6dc9357SAndroid Build Coastguard Worker #include "../../Windows/PropVariantUtils.h"
12*f6dc9357SAndroid Build Coastguard Worker
13*f6dc9357SAndroid Build Coastguard Worker #include "../Common/LimitedStreams.h"
14*f6dc9357SAndroid Build Coastguard Worker #include "../Common/ProgressUtils.h"
15*f6dc9357SAndroid Build Coastguard Worker #include "../Common/RegisterArc.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StreamUtils.h"
17*f6dc9357SAndroid Build Coastguard Worker
18*f6dc9357SAndroid Build Coastguard Worker #include "../Compress/CopyCoder.h"
19*f6dc9357SAndroid Build Coastguard Worker
20*f6dc9357SAndroid Build Coastguard Worker // #define Z7_ELF_SHOW_DETAILS
21*f6dc9357SAndroid Build Coastguard Worker
22*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
23*f6dc9357SAndroid Build Coastguard Worker
Get16(const Byte * p,bool be)24*f6dc9357SAndroid Build Coastguard Worker static UInt16 Get16(const Byte *p, bool be) { if (be) return GetBe16a(p); return GetUi16a(p); }
Get32(const Byte * p,bool be)25*f6dc9357SAndroid Build Coastguard Worker static UInt32 Get32(const Byte *p, bool be) { if (be) return GetBe32a(p); return GetUi32a(p); }
Get64(const Byte * p,bool be)26*f6dc9357SAndroid Build Coastguard Worker static UInt64 Get64(const Byte *p, bool be) { if (be) return GetBe64a(p); return GetUi64a(p); }
27*f6dc9357SAndroid Build Coastguard Worker
28*f6dc9357SAndroid Build Coastguard Worker #define G16(offs, v) v = Get16(p + (offs), be)
29*f6dc9357SAndroid Build Coastguard Worker #define G32(offs, v) v = Get32(p + (offs), be)
30*f6dc9357SAndroid Build Coastguard Worker #define G64(offs, v) v = Get64(p + (offs), be)
31*f6dc9357SAndroid Build Coastguard Worker
32*f6dc9357SAndroid Build Coastguard Worker namespace NArchive {
33*f6dc9357SAndroid Build Coastguard Worker namespace NElf {
34*f6dc9357SAndroid Build Coastguard Worker
35*f6dc9357SAndroid Build Coastguard Worker /*
36*f6dc9357SAndroid Build Coastguard Worker ELF Structure example:
37*f6dc9357SAndroid Build Coastguard Worker {
38*f6dc9357SAndroid Build Coastguard Worker Header
39*f6dc9357SAndroid Build Coastguard Worker Program header table (is used at runtime) (list of segment metadata records)
40*f6dc9357SAndroid Build Coastguard Worker {
41*f6dc9357SAndroid Build Coastguard Worker Segment (Read)
42*f6dc9357SAndroid Build Coastguard Worker Segment : PT_PHDR : header table itself
43*f6dc9357SAndroid Build Coastguard Worker Segment : PT_INTERP
44*f6dc9357SAndroid Build Coastguard Worker Segment : PT_NOTE
45*f6dc9357SAndroid Build Coastguard Worker .rela.dyn (RELA, ALLOC)
46*f6dc9357SAndroid Build Coastguard Worker Segment (Execute/Read)
47*f6dc9357SAndroid Build Coastguard Worker .text section (PROGBITS, SHF_ALLOC | SHF_EXECINSTR)
48*f6dc9357SAndroid Build Coastguard Worker Segment (Read)
49*f6dc9357SAndroid Build Coastguard Worker .rodata (PROGBITS, SHF_ALLOC | SHF_WRITE)
50*f6dc9357SAndroid Build Coastguard Worker Segment : PT_GNU_EH_FRAME
51*f6dc9357SAndroid Build Coastguard Worker .eh_frame_hdr
52*f6dc9357SAndroid Build Coastguard Worker .eh_frame
53*f6dc9357SAndroid Build Coastguard Worker .gcc_except_table
54*f6dc9357SAndroid Build Coastguard Worker ...
55*f6dc9357SAndroid Build Coastguard Worker Segment (Write/Read) (VaSize > Size)
56*f6dc9357SAndroid Build Coastguard Worker Segment (Read) : PT_GNU_RELRO
57*f6dc9357SAndroid Build Coastguard Worker Segment (Write/Read)
58*f6dc9357SAndroid Build Coastguard Worker .data
59*f6dc9357SAndroid Build Coastguard Worker .bss (Size == 0) (VSize != 0)
60*f6dc9357SAndroid Build Coastguard Worker }
61*f6dc9357SAndroid Build Coastguard Worker .comment (VA == 0)
62*f6dc9357SAndroid Build Coastguard Worker .shstrtab (VA == 0)
63*f6dc9357SAndroid Build Coastguard Worker Section header table (the data for linking and relocation)
64*f6dc9357SAndroid Build Coastguard Worker }
65*f6dc9357SAndroid Build Coastguard Worker
66*f6dc9357SAndroid Build Coastguard Worker Last top level segment contains .bss section that requires additional VA space.
67*f6dc9357SAndroid Build Coastguard Worker So (VaSize > Size) for that segment.
68*f6dc9357SAndroid Build Coastguard Worker
69*f6dc9357SAndroid Build Coastguard Worker Segments can be unsorted (by offset) in table.
70*f6dc9357SAndroid Build Coastguard Worker Top level segments has Type=PT_LOAD : "Loadable segment".
71*f6dc9357SAndroid Build Coastguard Worker Top level segments usually are aligned for page size (4 KB).
72*f6dc9357SAndroid Build Coastguard Worker Another segments (non PT_LOAD segments) are inside PT_LOAD segments.
73*f6dc9357SAndroid Build Coastguard Worker
74*f6dc9357SAndroid Build Coastguard Worker (VA-offset == 0) is possible for some sections and segments at the beginning of file.
75*f6dc9357SAndroid Build Coastguard Worker (VA-offset == 4KB*N) for most sections and segments where (Size != 0),
76*f6dc9357SAndroid Build Coastguard Worker (VA-offset != 4KB*N) for .bss section (last section), because (Size == 0),
77*f6dc9357SAndroid Build Coastguard Worker and that section is not mapped from image file.
78*f6dc9357SAndroid Build Coastguard Worker Some files contain additional "virtual" 4 KB page in VA space after
79*f6dc9357SAndroid Build Coastguard Worker end of data of top level segments (PT_LOAD) before new top level segments.
80*f6dc9357SAndroid Build Coastguard Worker So (VA-offset) value can increase by 4 KB step.
81*f6dc9357SAndroid Build Coastguard Worker */
82*f6dc9357SAndroid Build Coastguard Worker
83*f6dc9357SAndroid Build Coastguard Worker #define ELF_CLASS_32 1
84*f6dc9357SAndroid Build Coastguard Worker #define ELF_CLASS_64 2
85*f6dc9357SAndroid Build Coastguard Worker
86*f6dc9357SAndroid Build Coastguard Worker #define ELF_DATA_2LSB 1
87*f6dc9357SAndroid Build Coastguard Worker #define ELF_DATA_2MSB 2
88*f6dc9357SAndroid Build Coastguard Worker
89*f6dc9357SAndroid Build Coastguard Worker static const unsigned kHeaderSize32 = 0x34;
90*f6dc9357SAndroid Build Coastguard Worker static const unsigned kHeaderSize64 = 0x40;
91*f6dc9357SAndroid Build Coastguard Worker
92*f6dc9357SAndroid Build Coastguard Worker static const unsigned kSegmentSize32 = 0x20;
93*f6dc9357SAndroid Build Coastguard Worker static const unsigned kSegmentSize64 = 0x38;
94*f6dc9357SAndroid Build Coastguard Worker
95*f6dc9357SAndroid Build Coastguard Worker static const unsigned kSectionSize32 = 0x28;
96*f6dc9357SAndroid Build Coastguard Worker static const unsigned kSectionSize64 = 0x40;
97*f6dc9357SAndroid Build Coastguard Worker
98*f6dc9357SAndroid Build Coastguard Worker struct CHeader
99*f6dc9357SAndroid Build Coastguard Worker {
100*f6dc9357SAndroid Build Coastguard Worker bool Mode64;
101*f6dc9357SAndroid Build Coastguard Worker bool Be;
102*f6dc9357SAndroid Build Coastguard Worker Byte Os;
103*f6dc9357SAndroid Build Coastguard Worker Byte AbiVer;
104*f6dc9357SAndroid Build Coastguard Worker
105*f6dc9357SAndroid Build Coastguard Worker UInt16 Type;
106*f6dc9357SAndroid Build Coastguard Worker UInt16 Machine;
107*f6dc9357SAndroid Build Coastguard Worker // UInt32 Version;
108*f6dc9357SAndroid Build Coastguard Worker
109*f6dc9357SAndroid Build Coastguard Worker // UInt64 EntryVa;
110*f6dc9357SAndroid Build Coastguard Worker UInt64 ProgOffset;
111*f6dc9357SAndroid Build Coastguard Worker UInt64 SectOffset;
112*f6dc9357SAndroid Build Coastguard Worker UInt32 Flags;
113*f6dc9357SAndroid Build Coastguard Worker UInt16 HeaderSize;
114*f6dc9357SAndroid Build Coastguard Worker UInt16 SegmentEntrySize;
115*f6dc9357SAndroid Build Coastguard Worker UInt16 NumSegments;
116*f6dc9357SAndroid Build Coastguard Worker UInt16 SectionEntrySize;
117*f6dc9357SAndroid Build Coastguard Worker UInt16 NumSections;
118*f6dc9357SAndroid Build Coastguard Worker UInt16 NamesSectIndex;
119*f6dc9357SAndroid Build Coastguard Worker
120*f6dc9357SAndroid Build Coastguard Worker bool Parse(const Byte *p);
121*f6dc9357SAndroid Build Coastguard Worker
GetHeadersSizeNArchive::NElf::CHeader122*f6dc9357SAndroid Build Coastguard Worker UInt32 GetHeadersSize() const { return (UInt32)HeaderSize +
123*f6dc9357SAndroid Build Coastguard Worker (UInt32)NumSegments * SegmentEntrySize +
124*f6dc9357SAndroid Build Coastguard Worker (UInt32)NumSections * SectionEntrySize; }
125*f6dc9357SAndroid Build Coastguard Worker };
126*f6dc9357SAndroid Build Coastguard Worker
Parse(const Byte * p)127*f6dc9357SAndroid Build Coastguard Worker bool CHeader::Parse(const Byte *p)
128*f6dc9357SAndroid Build Coastguard Worker {
129*f6dc9357SAndroid Build Coastguard Worker switch (p[4])
130*f6dc9357SAndroid Build Coastguard Worker {
131*f6dc9357SAndroid Build Coastguard Worker case ELF_CLASS_32: Mode64 = false; break;
132*f6dc9357SAndroid Build Coastguard Worker case ELF_CLASS_64: Mode64 = true; break;
133*f6dc9357SAndroid Build Coastguard Worker default: return false;
134*f6dc9357SAndroid Build Coastguard Worker }
135*f6dc9357SAndroid Build Coastguard Worker bool be;
136*f6dc9357SAndroid Build Coastguard Worker switch (p[5])
137*f6dc9357SAndroid Build Coastguard Worker {
138*f6dc9357SAndroid Build Coastguard Worker case ELF_DATA_2LSB: be = false; break;
139*f6dc9357SAndroid Build Coastguard Worker case ELF_DATA_2MSB: be = true; break;
140*f6dc9357SAndroid Build Coastguard Worker default: return false;
141*f6dc9357SAndroid Build Coastguard Worker }
142*f6dc9357SAndroid Build Coastguard Worker Be = be;
143*f6dc9357SAndroid Build Coastguard Worker if (p[6] != 1) // Version
144*f6dc9357SAndroid Build Coastguard Worker return false;
145*f6dc9357SAndroid Build Coastguard Worker Os = p[7];
146*f6dc9357SAndroid Build Coastguard Worker // AbiVer = p[8];
147*f6dc9357SAndroid Build Coastguard Worker for (int i = 9; i < 16; i++)
148*f6dc9357SAndroid Build Coastguard Worker if (p[i] != 0)
149*f6dc9357SAndroid Build Coastguard Worker return false;
150*f6dc9357SAndroid Build Coastguard Worker
151*f6dc9357SAndroid Build Coastguard Worker G16(0x10, Type);
152*f6dc9357SAndroid Build Coastguard Worker G16(0x12, Machine);
153*f6dc9357SAndroid Build Coastguard Worker if (Get32(p + 0x14, be) != 1) // Version
154*f6dc9357SAndroid Build Coastguard Worker return false;
155*f6dc9357SAndroid Build Coastguard Worker
156*f6dc9357SAndroid Build Coastguard Worker if (Mode64)
157*f6dc9357SAndroid Build Coastguard Worker {
158*f6dc9357SAndroid Build Coastguard Worker // G64(0x18, EntryVa);
159*f6dc9357SAndroid Build Coastguard Worker G64(0x20, ProgOffset); // == kHeaderSize64 == 0x40 usually
160*f6dc9357SAndroid Build Coastguard Worker G64(0x28, SectOffset);
161*f6dc9357SAndroid Build Coastguard Worker p += 0x30;
162*f6dc9357SAndroid Build Coastguard Worker // we expect that fields are aligned
163*f6dc9357SAndroid Build Coastguard Worker if (ProgOffset & 7) return false;
164*f6dc9357SAndroid Build Coastguard Worker if (SectOffset & 7) return false;
165*f6dc9357SAndroid Build Coastguard Worker }
166*f6dc9357SAndroid Build Coastguard Worker else
167*f6dc9357SAndroid Build Coastguard Worker {
168*f6dc9357SAndroid Build Coastguard Worker // G32(0x18, EntryVa);
169*f6dc9357SAndroid Build Coastguard Worker G32(0x1C, ProgOffset); // == kHeaderSize32 == 0x34 usually
170*f6dc9357SAndroid Build Coastguard Worker G32(0x20, SectOffset);
171*f6dc9357SAndroid Build Coastguard Worker p += 0x24;
172*f6dc9357SAndroid Build Coastguard Worker if (ProgOffset & 3) return false;
173*f6dc9357SAndroid Build Coastguard Worker if (SectOffset & 3) return false;
174*f6dc9357SAndroid Build Coastguard Worker }
175*f6dc9357SAndroid Build Coastguard Worker
176*f6dc9357SAndroid Build Coastguard Worker G32(0, Flags);
177*f6dc9357SAndroid Build Coastguard Worker G16(4, HeaderSize);
178*f6dc9357SAndroid Build Coastguard Worker if (HeaderSize != (Mode64 ? kHeaderSize64 : kHeaderSize32))
179*f6dc9357SAndroid Build Coastguard Worker return false;
180*f6dc9357SAndroid Build Coastguard Worker
181*f6dc9357SAndroid Build Coastguard Worker G16(6, SegmentEntrySize);
182*f6dc9357SAndroid Build Coastguard Worker G16(8, NumSegments);
183*f6dc9357SAndroid Build Coastguard Worker G16(10, SectionEntrySize);
184*f6dc9357SAndroid Build Coastguard Worker G16(12, NumSections);
185*f6dc9357SAndroid Build Coastguard Worker G16(14, NamesSectIndex);
186*f6dc9357SAndroid Build Coastguard Worker
187*f6dc9357SAndroid Build Coastguard Worker if (ProgOffset < HeaderSize && (ProgOffset || NumSegments)) return false;
188*f6dc9357SAndroid Build Coastguard Worker if (SectOffset < HeaderSize && (SectOffset || NumSections)) return false;
189*f6dc9357SAndroid Build Coastguard Worker
190*f6dc9357SAndroid Build Coastguard Worker if (SegmentEntrySize == 0) { if (NumSegments) return false; }
191*f6dc9357SAndroid Build Coastguard Worker else if (SegmentEntrySize != (Mode64 ? kSegmentSize64 : kSegmentSize32)) return false;
192*f6dc9357SAndroid Build Coastguard Worker
193*f6dc9357SAndroid Build Coastguard Worker if (SectionEntrySize == 0) { if (NumSections) return false; }
194*f6dc9357SAndroid Build Coastguard Worker else if (SectionEntrySize != (Mode64 ? kSectionSize64 : kSectionSize32)) return false;
195*f6dc9357SAndroid Build Coastguard Worker
196*f6dc9357SAndroid Build Coastguard Worker return true;
197*f6dc9357SAndroid Build Coastguard Worker }
198*f6dc9357SAndroid Build Coastguard Worker
199*f6dc9357SAndroid Build Coastguard Worker
200*f6dc9357SAndroid Build Coastguard Worker #define PT_PHDR 6 // The program header table itself.
201*f6dc9357SAndroid Build Coastguard Worker #define PT_GNU_STACK 0x6474e551
202*f6dc9357SAndroid Build Coastguard Worker
203*f6dc9357SAndroid Build Coastguard Worker static const CUInt32PCharPair g_SegnmentTypes[] =
204*f6dc9357SAndroid Build Coastguard Worker {
205*f6dc9357SAndroid Build Coastguard Worker { 0, "Unused" },
206*f6dc9357SAndroid Build Coastguard Worker { 1, "Loadable segment" },
207*f6dc9357SAndroid Build Coastguard Worker { 2, "Dynamic linking tables" },
208*f6dc9357SAndroid Build Coastguard Worker { 3, "Program interpreter path name" },
209*f6dc9357SAndroid Build Coastguard Worker { 4, "Note section" },
210*f6dc9357SAndroid Build Coastguard Worker { 5, "SHLIB" },
211*f6dc9357SAndroid Build Coastguard Worker { 6, "Program header table" },
212*f6dc9357SAndroid Build Coastguard Worker { 7, "TLS" },
213*f6dc9357SAndroid Build Coastguard Worker { 0x6474e550, "GNU_EH_FRAME" },
214*f6dc9357SAndroid Build Coastguard Worker { PT_GNU_STACK, "GNU_STACK" },
215*f6dc9357SAndroid Build Coastguard Worker { 0x6474e552, "GNU_RELRO" }
216*f6dc9357SAndroid Build Coastguard Worker };
217*f6dc9357SAndroid Build Coastguard Worker
218*f6dc9357SAndroid Build Coastguard Worker
219*f6dc9357SAndroid Build Coastguard Worker static const char * const g_SegmentFlags[] =
220*f6dc9357SAndroid Build Coastguard Worker {
221*f6dc9357SAndroid Build Coastguard Worker "Execute"
222*f6dc9357SAndroid Build Coastguard Worker , "Write"
223*f6dc9357SAndroid Build Coastguard Worker , "Read"
224*f6dc9357SAndroid Build Coastguard Worker };
225*f6dc9357SAndroid Build Coastguard Worker
226*f6dc9357SAndroid Build Coastguard Worker struct CSegment
227*f6dc9357SAndroid Build Coastguard Worker {
228*f6dc9357SAndroid Build Coastguard Worker UInt32 Type;
229*f6dc9357SAndroid Build Coastguard Worker UInt32 Flags;
230*f6dc9357SAndroid Build Coastguard Worker UInt64 Offset;
231*f6dc9357SAndroid Build Coastguard Worker UInt64 Va;
232*f6dc9357SAndroid Build Coastguard Worker UInt64 Size; // size in file
233*f6dc9357SAndroid Build Coastguard Worker UInt64 VSize; // size in memory
234*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_ELF_SHOW_DETAILS
235*f6dc9357SAndroid Build Coastguard Worker UInt64 Pa; // usually == Va, or == 0
236*f6dc9357SAndroid Build Coastguard Worker UInt64 Align; // if (Align != 0), condition must be met:
237*f6dc9357SAndroid Build Coastguard Worker // (VSize % Align == Offset % Alig)
238*f6dc9357SAndroid Build Coastguard Worker #endif
UpdateTotalSizeNArchive::NElf::CSegment239*f6dc9357SAndroid Build Coastguard Worker void UpdateTotalSize(UInt64 &totalSize)
240*f6dc9357SAndroid Build Coastguard Worker {
241*f6dc9357SAndroid Build Coastguard Worker const UInt64 t = Offset + Size;
242*f6dc9357SAndroid Build Coastguard Worker if (totalSize < t)
243*f6dc9357SAndroid Build Coastguard Worker totalSize = t;
244*f6dc9357SAndroid Build Coastguard Worker }
245*f6dc9357SAndroid Build Coastguard Worker void Parse(const Byte *p, bool mode64, bool be);
246*f6dc9357SAndroid Build Coastguard Worker };
247*f6dc9357SAndroid Build Coastguard Worker
Parse(const Byte * p,bool mode64,bool be)248*f6dc9357SAndroid Build Coastguard Worker void CSegment::Parse(const Byte *p, bool mode64, bool be)
249*f6dc9357SAndroid Build Coastguard Worker {
250*f6dc9357SAndroid Build Coastguard Worker G32(0, Type);
251*f6dc9357SAndroid Build Coastguard Worker if (mode64)
252*f6dc9357SAndroid Build Coastguard Worker {
253*f6dc9357SAndroid Build Coastguard Worker G32(4, Flags);
254*f6dc9357SAndroid Build Coastguard Worker G64(8, Offset);
255*f6dc9357SAndroid Build Coastguard Worker G64(0x10, Va);
256*f6dc9357SAndroid Build Coastguard Worker G64(0x20, Size);
257*f6dc9357SAndroid Build Coastguard Worker G64(0x28, VSize);
258*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_ELF_SHOW_DETAILS
259*f6dc9357SAndroid Build Coastguard Worker G64(0x18, Pa);
260*f6dc9357SAndroid Build Coastguard Worker G64(0x30, Align);
261*f6dc9357SAndroid Build Coastguard Worker #endif
262*f6dc9357SAndroid Build Coastguard Worker }
263*f6dc9357SAndroid Build Coastguard Worker else
264*f6dc9357SAndroid Build Coastguard Worker {
265*f6dc9357SAndroid Build Coastguard Worker G32(4, Offset);
266*f6dc9357SAndroid Build Coastguard Worker G32(8, Va);
267*f6dc9357SAndroid Build Coastguard Worker G32(0x10, Size);
268*f6dc9357SAndroid Build Coastguard Worker G32(0x14, VSize);
269*f6dc9357SAndroid Build Coastguard Worker G32(0x18, Flags);
270*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_ELF_SHOW_DETAILS
271*f6dc9357SAndroid Build Coastguard Worker G32(0x0C, Pa);
272*f6dc9357SAndroid Build Coastguard Worker G32(0x1C, Align);
273*f6dc9357SAndroid Build Coastguard Worker #endif
274*f6dc9357SAndroid Build Coastguard Worker }
275*f6dc9357SAndroid Build Coastguard Worker }
276*f6dc9357SAndroid Build Coastguard Worker
277*f6dc9357SAndroid Build Coastguard Worker // Section_index = 0 means NO section
278*f6dc9357SAndroid Build Coastguard Worker
279*f6dc9357SAndroid Build Coastguard Worker #define SHN_UNDEF 0
280*f6dc9357SAndroid Build Coastguard Worker
281*f6dc9357SAndroid Build Coastguard Worker // Section types
282*f6dc9357SAndroid Build Coastguard Worker
283*f6dc9357SAndroid Build Coastguard Worker /*
284*f6dc9357SAndroid Build Coastguard Worker #define SHT_NULL 0
285*f6dc9357SAndroid Build Coastguard Worker #define SHT_PROGBITS 1
286*f6dc9357SAndroid Build Coastguard Worker #define SHT_SYMTAB 2
287*f6dc9357SAndroid Build Coastguard Worker #define SHT_STRTAB 3
288*f6dc9357SAndroid Build Coastguard Worker #define SHT_RELA 4
289*f6dc9357SAndroid Build Coastguard Worker #define SHT_HASH 5
290*f6dc9357SAndroid Build Coastguard Worker #define SHT_DYNAMIC 6
291*f6dc9357SAndroid Build Coastguard Worker #define SHT_NOTE 7
292*f6dc9357SAndroid Build Coastguard Worker */
293*f6dc9357SAndroid Build Coastguard Worker #define SHT_NOBITS 8
294*f6dc9357SAndroid Build Coastguard Worker /*
295*f6dc9357SAndroid Build Coastguard Worker #define SHT_REL 9
296*f6dc9357SAndroid Build Coastguard Worker #define SHT_SHLIB 10
297*f6dc9357SAndroid Build Coastguard Worker #define SHT_DYNSYM 11
298*f6dc9357SAndroid Build Coastguard Worker #define SHT_UNKNOWN12 12
299*f6dc9357SAndroid Build Coastguard Worker #define SHT_UNKNOWN13 13
300*f6dc9357SAndroid Build Coastguard Worker #define SHT_INIT_ARRAY 14
301*f6dc9357SAndroid Build Coastguard Worker #define SHT_FINI_ARRAY 15
302*f6dc9357SAndroid Build Coastguard Worker #define SHT_PREINIT_ARRAY 16
303*f6dc9357SAndroid Build Coastguard Worker #define SHT_GROUP 17
304*f6dc9357SAndroid Build Coastguard Worker #define SHT_SYMTAB_SHNDX 18
305*f6dc9357SAndroid Build Coastguard Worker */
306*f6dc9357SAndroid Build Coastguard Worker
307*f6dc9357SAndroid Build Coastguard Worker static const CUInt32PCharPair g_SectTypes[] =
308*f6dc9357SAndroid Build Coastguard Worker {
309*f6dc9357SAndroid Build Coastguard Worker { 0, "NULL" },
310*f6dc9357SAndroid Build Coastguard Worker { 1, "PROGBITS" },
311*f6dc9357SAndroid Build Coastguard Worker { 2, "SYMTAB" },
312*f6dc9357SAndroid Build Coastguard Worker { 3, "STRTAB" },
313*f6dc9357SAndroid Build Coastguard Worker { 4, "RELA" },
314*f6dc9357SAndroid Build Coastguard Worker { 5, "HASH" },
315*f6dc9357SAndroid Build Coastguard Worker { 6, "DYNAMIC" },
316*f6dc9357SAndroid Build Coastguard Worker { 7, "NOTE" },
317*f6dc9357SAndroid Build Coastguard Worker { 8, "NOBITS" },
318*f6dc9357SAndroid Build Coastguard Worker { 9, "REL" },
319*f6dc9357SAndroid Build Coastguard Worker { 10, "SHLIB" },
320*f6dc9357SAndroid Build Coastguard Worker { 11, "DYNSYM" },
321*f6dc9357SAndroid Build Coastguard Worker { 12, "UNKNOWN12" },
322*f6dc9357SAndroid Build Coastguard Worker { 13, "UNKNOWN13" },
323*f6dc9357SAndroid Build Coastguard Worker { 14, "INIT_ARRAY" },
324*f6dc9357SAndroid Build Coastguard Worker { 15, "FINI_ARRAY" },
325*f6dc9357SAndroid Build Coastguard Worker { 16, "PREINIT_ARRAY" },
326*f6dc9357SAndroid Build Coastguard Worker { 17, "GROUP" },
327*f6dc9357SAndroid Build Coastguard Worker { 18, "SYMTAB_SHNDX" },
328*f6dc9357SAndroid Build Coastguard Worker
329*f6dc9357SAndroid Build Coastguard Worker { 0x6ffffff5, "GNU_ATTRIBUTES" },
330*f6dc9357SAndroid Build Coastguard Worker { 0x6ffffff6, "GNU_HASH" },
331*f6dc9357SAndroid Build Coastguard Worker { 0x6ffffffd, "GNU_verdef" },
332*f6dc9357SAndroid Build Coastguard Worker { 0x6ffffffe, "GNU_verneed" },
333*f6dc9357SAndroid Build Coastguard Worker { 0x6fffffff, "GNU_versym" },
334*f6dc9357SAndroid Build Coastguard Worker // { 0x70000001, "X86_64_UNWIND" },
335*f6dc9357SAndroid Build Coastguard Worker { 0x70000001, "ARM_EXIDX" },
336*f6dc9357SAndroid Build Coastguard Worker { 0x70000002, "ARM_PREEMPTMAP" },
337*f6dc9357SAndroid Build Coastguard Worker { 0x70000003, "ARM_ATTRIBUTES" },
338*f6dc9357SAndroid Build Coastguard Worker { 0x70000004, "ARM_DEBUGOVERLAY" },
339*f6dc9357SAndroid Build Coastguard Worker { 0x70000005, "ARM_OVERLAYSECTION" }
340*f6dc9357SAndroid Build Coastguard Worker };
341*f6dc9357SAndroid Build Coastguard Worker
342*f6dc9357SAndroid Build Coastguard Worker
343*f6dc9357SAndroid Build Coastguard Worker // SHF_ flags
344*f6dc9357SAndroid Build Coastguard Worker static const CUInt32PCharPair g_SectionFlags[] =
345*f6dc9357SAndroid Build Coastguard Worker {
346*f6dc9357SAndroid Build Coastguard Worker { 0, "WRITE" },
347*f6dc9357SAndroid Build Coastguard Worker { 1, "ALLOC" },
348*f6dc9357SAndroid Build Coastguard Worker { 2, "EXECINSTR" },
349*f6dc9357SAndroid Build Coastguard Worker
350*f6dc9357SAndroid Build Coastguard Worker { 4, "MERGE" },
351*f6dc9357SAndroid Build Coastguard Worker { 5, "STRINGS" },
352*f6dc9357SAndroid Build Coastguard Worker { 6, "INFO_LINK" },
353*f6dc9357SAndroid Build Coastguard Worker { 7, "LINK_ORDER" },
354*f6dc9357SAndroid Build Coastguard Worker { 8, "OS_NONCONFORMING" },
355*f6dc9357SAndroid Build Coastguard Worker { 9, "GROUP" },
356*f6dc9357SAndroid Build Coastguard Worker { 10, "TLS" },
357*f6dc9357SAndroid Build Coastguard Worker { 11, "COMPRESSED" },
358*f6dc9357SAndroid Build Coastguard Worker { 12, "DP_SECTION" },
359*f6dc9357SAndroid Build Coastguard Worker { 13, "XCORE_SHF_CP_SECTION" },
360*f6dc9357SAndroid Build Coastguard Worker { 28, "64_LARGE" },
361*f6dc9357SAndroid Build Coastguard Worker };
362*f6dc9357SAndroid Build Coastguard Worker
363*f6dc9357SAndroid Build Coastguard Worker struct CSection
364*f6dc9357SAndroid Build Coastguard Worker {
365*f6dc9357SAndroid Build Coastguard Worker UInt32 Name;
366*f6dc9357SAndroid Build Coastguard Worker UInt32 Type;
367*f6dc9357SAndroid Build Coastguard Worker UInt64 Flags;
368*f6dc9357SAndroid Build Coastguard Worker UInt64 Va;
369*f6dc9357SAndroid Build Coastguard Worker UInt64 Offset;
370*f6dc9357SAndroid Build Coastguard Worker UInt64 VSize;
371*f6dc9357SAndroid Build Coastguard Worker UInt32 Link;
372*f6dc9357SAndroid Build Coastguard Worker UInt32 Info;
373*f6dc9357SAndroid Build Coastguard Worker UInt64 AddrAlign;
374*f6dc9357SAndroid Build Coastguard Worker UInt64 EntSize;
375*f6dc9357SAndroid Build Coastguard Worker
GetSizeNArchive::NElf::CSection376*f6dc9357SAndroid Build Coastguard Worker UInt64 GetSize() const { return Type == SHT_NOBITS ? 0 : VSize; }
377*f6dc9357SAndroid Build Coastguard Worker
UpdateTotalSizeNArchive::NElf::CSection378*f6dc9357SAndroid Build Coastguard Worker void UpdateTotalSize(UInt64 &totalSize)
379*f6dc9357SAndroid Build Coastguard Worker {
380*f6dc9357SAndroid Build Coastguard Worker const UInt64 t = Offset + GetSize();
381*f6dc9357SAndroid Build Coastguard Worker if (totalSize < t)
382*f6dc9357SAndroid Build Coastguard Worker totalSize = t;
383*f6dc9357SAndroid Build Coastguard Worker }
384*f6dc9357SAndroid Build Coastguard Worker bool Parse(const Byte *p, bool mode64, bool be);
385*f6dc9357SAndroid Build Coastguard Worker };
386*f6dc9357SAndroid Build Coastguard Worker
Parse(const Byte * p,bool mode64,bool be)387*f6dc9357SAndroid Build Coastguard Worker bool CSection::Parse(const Byte *p, bool mode64, bool be)
388*f6dc9357SAndroid Build Coastguard Worker {
389*f6dc9357SAndroid Build Coastguard Worker G32(0, Name);
390*f6dc9357SAndroid Build Coastguard Worker G32(4, Type);
391*f6dc9357SAndroid Build Coastguard Worker if (mode64)
392*f6dc9357SAndroid Build Coastguard Worker {
393*f6dc9357SAndroid Build Coastguard Worker G64(0x08, Flags);
394*f6dc9357SAndroid Build Coastguard Worker G64(0x10, Va);
395*f6dc9357SAndroid Build Coastguard Worker G64(0x18, Offset);
396*f6dc9357SAndroid Build Coastguard Worker G64(0x20, VSize);
397*f6dc9357SAndroid Build Coastguard Worker G32(0x28, Link);
398*f6dc9357SAndroid Build Coastguard Worker G32(0x2C, Info);
399*f6dc9357SAndroid Build Coastguard Worker G64(0x30, AddrAlign);
400*f6dc9357SAndroid Build Coastguard Worker G64(0x38, EntSize);
401*f6dc9357SAndroid Build Coastguard Worker }
402*f6dc9357SAndroid Build Coastguard Worker else
403*f6dc9357SAndroid Build Coastguard Worker {
404*f6dc9357SAndroid Build Coastguard Worker G32(0x08, Flags);
405*f6dc9357SAndroid Build Coastguard Worker G32(0x0C, Va);
406*f6dc9357SAndroid Build Coastguard Worker G32(0x10, Offset);
407*f6dc9357SAndroid Build Coastguard Worker G32(0x14, VSize);
408*f6dc9357SAndroid Build Coastguard Worker G32(0x18, Link);
409*f6dc9357SAndroid Build Coastguard Worker G32(0x1C, Info);
410*f6dc9357SAndroid Build Coastguard Worker G32(0x20, AddrAlign);
411*f6dc9357SAndroid Build Coastguard Worker G32(0x24, EntSize);
412*f6dc9357SAndroid Build Coastguard Worker }
413*f6dc9357SAndroid Build Coastguard Worker if (EntSize >= ((UInt32)1 << 31))
414*f6dc9357SAndroid Build Coastguard Worker return false;
415*f6dc9357SAndroid Build Coastguard Worker if (EntSize >= ((UInt32)1 << 10) &&
416*f6dc9357SAndroid Build Coastguard Worker EntSize >= VSize &&
417*f6dc9357SAndroid Build Coastguard Worker VSize != 0)
418*f6dc9357SAndroid Build Coastguard Worker return false;
419*f6dc9357SAndroid Build Coastguard Worker return true;
420*f6dc9357SAndroid Build Coastguard Worker }
421*f6dc9357SAndroid Build Coastguard Worker
422*f6dc9357SAndroid Build Coastguard Worker
423*f6dc9357SAndroid Build Coastguard Worker static const char * const g_Machines[] =
424*f6dc9357SAndroid Build Coastguard Worker {
425*f6dc9357SAndroid Build Coastguard Worker "None"
426*f6dc9357SAndroid Build Coastguard Worker , "AT&T WE 32100"
427*f6dc9357SAndroid Build Coastguard Worker , "SPARC"
428*f6dc9357SAndroid Build Coastguard Worker , "Intel 386"
429*f6dc9357SAndroid Build Coastguard Worker , "Motorola 68000"
430*f6dc9357SAndroid Build Coastguard Worker , "Motorola 88000"
431*f6dc9357SAndroid Build Coastguard Worker , "Intel 486"
432*f6dc9357SAndroid Build Coastguard Worker , "Intel i860"
433*f6dc9357SAndroid Build Coastguard Worker , "MIPS"
434*f6dc9357SAndroid Build Coastguard Worker , "IBM S/370"
435*f6dc9357SAndroid Build Coastguard Worker , "MIPS RS3000 LE"
436*f6dc9357SAndroid Build Coastguard Worker , "RS6000"
437*f6dc9357SAndroid Build Coastguard Worker , NULL
438*f6dc9357SAndroid Build Coastguard Worker , NULL
439*f6dc9357SAndroid Build Coastguard Worker , NULL
440*f6dc9357SAndroid Build Coastguard Worker , "PA-RISC"
441*f6dc9357SAndroid Build Coastguard Worker , "nCUBE"
442*f6dc9357SAndroid Build Coastguard Worker , "Fujitsu VPP500"
443*f6dc9357SAndroid Build Coastguard Worker , "SPARC 32+"
444*f6dc9357SAndroid Build Coastguard Worker , "Intel i960"
445*f6dc9357SAndroid Build Coastguard Worker , "PowerPC"
446*f6dc9357SAndroid Build Coastguard Worker , "PowerPC 64-bit"
447*f6dc9357SAndroid Build Coastguard Worker , "IBM S/390"
448*f6dc9357SAndroid Build Coastguard Worker , "SPU"
449*f6dc9357SAndroid Build Coastguard Worker , NULL
450*f6dc9357SAndroid Build Coastguard Worker , NULL
451*f6dc9357SAndroid Build Coastguard Worker , NULL
452*f6dc9357SAndroid Build Coastguard Worker , NULL
453*f6dc9357SAndroid Build Coastguard Worker , NULL
454*f6dc9357SAndroid Build Coastguard Worker , NULL
455*f6dc9357SAndroid Build Coastguard Worker , NULL
456*f6dc9357SAndroid Build Coastguard Worker , NULL
457*f6dc9357SAndroid Build Coastguard Worker , NULL
458*f6dc9357SAndroid Build Coastguard Worker , NULL
459*f6dc9357SAndroid Build Coastguard Worker , NULL
460*f6dc9357SAndroid Build Coastguard Worker , NULL
461*f6dc9357SAndroid Build Coastguard Worker , "NEX v800"
462*f6dc9357SAndroid Build Coastguard Worker , "Fujitsu FR20"
463*f6dc9357SAndroid Build Coastguard Worker , "TRW RH-32"
464*f6dc9357SAndroid Build Coastguard Worker , "Motorola RCE"
465*f6dc9357SAndroid Build Coastguard Worker , "ARM"
466*f6dc9357SAndroid Build Coastguard Worker , "Alpha-STD"
467*f6dc9357SAndroid Build Coastguard Worker , "Hitachi SH"
468*f6dc9357SAndroid Build Coastguard Worker , "SPARC-V9"
469*f6dc9357SAndroid Build Coastguard Worker , "Siemens Tricore"
470*f6dc9357SAndroid Build Coastguard Worker , "ARC"
471*f6dc9357SAndroid Build Coastguard Worker , "H8/300"
472*f6dc9357SAndroid Build Coastguard Worker , "H8/300H"
473*f6dc9357SAndroid Build Coastguard Worker , "H8S"
474*f6dc9357SAndroid Build Coastguard Worker , "H8/500"
475*f6dc9357SAndroid Build Coastguard Worker , "IA-64"
476*f6dc9357SAndroid Build Coastguard Worker , "Stanford MIPS-X"
477*f6dc9357SAndroid Build Coastguard Worker , "Motorola ColdFire"
478*f6dc9357SAndroid Build Coastguard Worker , "M68HC12"
479*f6dc9357SAndroid Build Coastguard Worker , "Fujitsu MMA"
480*f6dc9357SAndroid Build Coastguard Worker , "Siemens PCP"
481*f6dc9357SAndroid Build Coastguard Worker , "Sony nCPU"
482*f6dc9357SAndroid Build Coastguard Worker , "Denso NDR1"
483*f6dc9357SAndroid Build Coastguard Worker , "Motorola StarCore"
484*f6dc9357SAndroid Build Coastguard Worker , "Toyota ME16"
485*f6dc9357SAndroid Build Coastguard Worker , "ST100"
486*f6dc9357SAndroid Build Coastguard Worker , "Advanced Logic TinyJ"
487*f6dc9357SAndroid Build Coastguard Worker , "AMD64"
488*f6dc9357SAndroid Build Coastguard Worker , "Sony DSP"
489*f6dc9357SAndroid Build Coastguard Worker , NULL
490*f6dc9357SAndroid Build Coastguard Worker , NULL
491*f6dc9357SAndroid Build Coastguard Worker , "Siemens FX66"
492*f6dc9357SAndroid Build Coastguard Worker , "ST9+"
493*f6dc9357SAndroid Build Coastguard Worker , "ST7"
494*f6dc9357SAndroid Build Coastguard Worker , "MC68HC16"
495*f6dc9357SAndroid Build Coastguard Worker , "MC68HC11"
496*f6dc9357SAndroid Build Coastguard Worker , "MC68HC08"
497*f6dc9357SAndroid Build Coastguard Worker , "MC68HC05"
498*f6dc9357SAndroid Build Coastguard Worker , "Silicon Graphics SVx"
499*f6dc9357SAndroid Build Coastguard Worker , "ST19"
500*f6dc9357SAndroid Build Coastguard Worker , "Digital VAX"
501*f6dc9357SAndroid Build Coastguard Worker , "Axis CRIS"
502*f6dc9357SAndroid Build Coastguard Worker , "Infineon JAVELIN"
503*f6dc9357SAndroid Build Coastguard Worker , "Element 14 FirePath"
504*f6dc9357SAndroid Build Coastguard Worker , "LSI ZSP"
505*f6dc9357SAndroid Build Coastguard Worker , "MMIX"
506*f6dc9357SAndroid Build Coastguard Worker , "HUANY"
507*f6dc9357SAndroid Build Coastguard Worker , "SiTera Prism"
508*f6dc9357SAndroid Build Coastguard Worker , "Atmel AVR"
509*f6dc9357SAndroid Build Coastguard Worker , "Fujitsu FR30"
510*f6dc9357SAndroid Build Coastguard Worker , "Mitsubishi D10V"
511*f6dc9357SAndroid Build Coastguard Worker , "Mitsubishi D30V"
512*f6dc9357SAndroid Build Coastguard Worker , "NEC v850"
513*f6dc9357SAndroid Build Coastguard Worker , "Mitsubishi M32R"
514*f6dc9357SAndroid Build Coastguard Worker , "Matsushita MN10300"
515*f6dc9357SAndroid Build Coastguard Worker , "Matsushita MN10200"
516*f6dc9357SAndroid Build Coastguard Worker , "picoJava"
517*f6dc9357SAndroid Build Coastguard Worker , "OpenRISC"
518*f6dc9357SAndroid Build Coastguard Worker , "ARC Tangent-A5"
519*f6dc9357SAndroid Build Coastguard Worker , "Tensilica Xtensa"
520*f6dc9357SAndroid Build Coastguard Worker , "Alphamosaic VideoCore"
521*f6dc9357SAndroid Build Coastguard Worker , "Thompson MM GPP"
522*f6dc9357SAndroid Build Coastguard Worker , "National Semiconductor 32K"
523*f6dc9357SAndroid Build Coastguard Worker , "Tenor Network TPC"
524*f6dc9357SAndroid Build Coastguard Worker , "Trebia SNP 1000"
525*f6dc9357SAndroid Build Coastguard Worker , "ST200"
526*f6dc9357SAndroid Build Coastguard Worker , "Ubicom IP2xxx"
527*f6dc9357SAndroid Build Coastguard Worker , "MAX"
528*f6dc9357SAndroid Build Coastguard Worker , "NS CompactRISC"
529*f6dc9357SAndroid Build Coastguard Worker , "Fujitsu F2MC16"
530*f6dc9357SAndroid Build Coastguard Worker , "TI msp430"
531*f6dc9357SAndroid Build Coastguard Worker , "Blackfin (DSP)"
532*f6dc9357SAndroid Build Coastguard Worker , "SE S1C33"
533*f6dc9357SAndroid Build Coastguard Worker , "Sharp embedded"
534*f6dc9357SAndroid Build Coastguard Worker , "Arca RISC"
535*f6dc9357SAndroid Build Coastguard Worker , "Unicore"
536*f6dc9357SAndroid Build Coastguard Worker , "eXcess"
537*f6dc9357SAndroid Build Coastguard Worker , "DXP"
538*f6dc9357SAndroid Build Coastguard Worker , "Altera Nios II"
539*f6dc9357SAndroid Build Coastguard Worker , "NS CRX"
540*f6dc9357SAndroid Build Coastguard Worker , "Motorola XGATE"
541*f6dc9357SAndroid Build Coastguard Worker , "Infineon C16x/XC16x"
542*f6dc9357SAndroid Build Coastguard Worker , "Renesas M16C"
543*f6dc9357SAndroid Build Coastguard Worker , "Microchip Technology dsPIC30F"
544*f6dc9357SAndroid Build Coastguard Worker , "Freescale CE"
545*f6dc9357SAndroid Build Coastguard Worker , "Renesas M32C"
546*f6dc9357SAndroid Build Coastguard Worker , NULL
547*f6dc9357SAndroid Build Coastguard Worker , NULL
548*f6dc9357SAndroid Build Coastguard Worker , NULL
549*f6dc9357SAndroid Build Coastguard Worker , NULL
550*f6dc9357SAndroid Build Coastguard Worker , NULL
551*f6dc9357SAndroid Build Coastguard Worker , NULL
552*f6dc9357SAndroid Build Coastguard Worker , NULL
553*f6dc9357SAndroid Build Coastguard Worker , NULL
554*f6dc9357SAndroid Build Coastguard Worker , NULL
555*f6dc9357SAndroid Build Coastguard Worker , NULL
556*f6dc9357SAndroid Build Coastguard Worker , "Altium TSK3000"
557*f6dc9357SAndroid Build Coastguard Worker , "Freescale RS08"
558*f6dc9357SAndroid Build Coastguard Worker , "Analog Devices SHARC"
559*f6dc9357SAndroid Build Coastguard Worker , "Cyan Technology eCOG2"
560*f6dc9357SAndroid Build Coastguard Worker , "Sunplus S+core7 RISC"
561*f6dc9357SAndroid Build Coastguard Worker , "NJR 24-bit DSP"
562*f6dc9357SAndroid Build Coastguard Worker , "Broadcom VideoCore III"
563*f6dc9357SAndroid Build Coastguard Worker , "Lattice FPGA"
564*f6dc9357SAndroid Build Coastguard Worker , "SE C17"
565*f6dc9357SAndroid Build Coastguard Worker , "TI TMS320C6000"
566*f6dc9357SAndroid Build Coastguard Worker , "TI TMS320C2000"
567*f6dc9357SAndroid Build Coastguard Worker , "TI TMS320C55x"
568*f6dc9357SAndroid Build Coastguard Worker , NULL
569*f6dc9357SAndroid Build Coastguard Worker , NULL
570*f6dc9357SAndroid Build Coastguard Worker , NULL
571*f6dc9357SAndroid Build Coastguard Worker , NULL
572*f6dc9357SAndroid Build Coastguard Worker , NULL
573*f6dc9357SAndroid Build Coastguard Worker , NULL
574*f6dc9357SAndroid Build Coastguard Worker , NULL
575*f6dc9357SAndroid Build Coastguard Worker , NULL
576*f6dc9357SAndroid Build Coastguard Worker , NULL
577*f6dc9357SAndroid Build Coastguard Worker , NULL
578*f6dc9357SAndroid Build Coastguard Worker , NULL
579*f6dc9357SAndroid Build Coastguard Worker , NULL
580*f6dc9357SAndroid Build Coastguard Worker , NULL
581*f6dc9357SAndroid Build Coastguard Worker , NULL
582*f6dc9357SAndroid Build Coastguard Worker , NULL
583*f6dc9357SAndroid Build Coastguard Worker , NULL
584*f6dc9357SAndroid Build Coastguard Worker , NULL
585*f6dc9357SAndroid Build Coastguard Worker , "STM 64bit VLIW Data Signal"
586*f6dc9357SAndroid Build Coastguard Worker , "Cypress M8C"
587*f6dc9357SAndroid Build Coastguard Worker , "Renesas R32C"
588*f6dc9357SAndroid Build Coastguard Worker , "NXP TriMedia"
589*f6dc9357SAndroid Build Coastguard Worker , "Qualcomm Hexagon"
590*f6dc9357SAndroid Build Coastguard Worker , "Intel 8051"
591*f6dc9357SAndroid Build Coastguard Worker , "STMicroelectronics STxP7x"
592*f6dc9357SAndroid Build Coastguard Worker , "Andes"
593*f6dc9357SAndroid Build Coastguard Worker , "Cyan Technology eCOG1X"
594*f6dc9357SAndroid Build Coastguard Worker , "Dallas Semiconductor MAXQ30"
595*f6dc9357SAndroid Build Coastguard Worker , "NJR 16-bit DSP"
596*f6dc9357SAndroid Build Coastguard Worker , "M2000"
597*f6dc9357SAndroid Build Coastguard Worker , "Cray NV2"
598*f6dc9357SAndroid Build Coastguard Worker , "Renesas RX"
599*f6dc9357SAndroid Build Coastguard Worker , "Imagination Technologies META"
600*f6dc9357SAndroid Build Coastguard Worker , "MCST Elbrus"
601*f6dc9357SAndroid Build Coastguard Worker , "Cyan Technology eCOG16"
602*f6dc9357SAndroid Build Coastguard Worker , "National Semiconductor CR16"
603*f6dc9357SAndroid Build Coastguard Worker , "Freescale ETPUnit"
604*f6dc9357SAndroid Build Coastguard Worker , "Infineon SLE9X"
605*f6dc9357SAndroid Build Coastguard Worker , "Intel L10M"
606*f6dc9357SAndroid Build Coastguard Worker , "Intel K10M"
607*f6dc9357SAndroid Build Coastguard Worker , NULL
608*f6dc9357SAndroid Build Coastguard Worker , "ARM64"
609*f6dc9357SAndroid Build Coastguard Worker , NULL
610*f6dc9357SAndroid Build Coastguard Worker , "Atmel AVR32"
611*f6dc9357SAndroid Build Coastguard Worker , "STM8"
612*f6dc9357SAndroid Build Coastguard Worker , "Tilera TILE64"
613*f6dc9357SAndroid Build Coastguard Worker , "Tilera TILEPro"
614*f6dc9357SAndroid Build Coastguard Worker , "Xilinx MicroBlaze"
615*f6dc9357SAndroid Build Coastguard Worker , "NVIDIA CUDA"
616*f6dc9357SAndroid Build Coastguard Worker , "Tilera TILE-Gx"
617*f6dc9357SAndroid Build Coastguard Worker , "CloudShield"
618*f6dc9357SAndroid Build Coastguard Worker , "KIPO-KAIST Core-A 1st"
619*f6dc9357SAndroid Build Coastguard Worker , "KIPO-KAIST Core-A 2nd"
620*f6dc9357SAndroid Build Coastguard Worker , "Synopsys ARCompact V2"
621*f6dc9357SAndroid Build Coastguard Worker , "Open8"
622*f6dc9357SAndroid Build Coastguard Worker , "Renesas RL78"
623*f6dc9357SAndroid Build Coastguard Worker , "Broadcom VideoCore V"
624*f6dc9357SAndroid Build Coastguard Worker , "Renesas 78KOR"
625*f6dc9357SAndroid Build Coastguard Worker , "Freescale 56800EX" // 200
626*f6dc9357SAndroid Build Coastguard Worker };
627*f6dc9357SAndroid Build Coastguard Worker
628*f6dc9357SAndroid Build Coastguard Worker static const CUInt32PCharPair g_MachinePairs[] =
629*f6dc9357SAndroid Build Coastguard Worker {
630*f6dc9357SAndroid Build Coastguard Worker { 243, "RISC-V" },
631*f6dc9357SAndroid Build Coastguard Worker { 258, "LoongArch" },
632*f6dc9357SAndroid Build Coastguard Worker { 0x9026, "Alpha" }, // EM_ALPHA_EXP, obsolete, (used by NetBSD/alpha) (written in the absence of an ABI)
633*f6dc9357SAndroid Build Coastguard Worker { 0xbaab, "Xilinx MicroBlaze" }
634*f6dc9357SAndroid Build Coastguard Worker };
635*f6dc9357SAndroid Build Coastguard Worker
636*f6dc9357SAndroid Build Coastguard Worker static const CUInt32PCharPair g_OS[] =
637*f6dc9357SAndroid Build Coastguard Worker {
638*f6dc9357SAndroid Build Coastguard Worker { 0, "None" },
639*f6dc9357SAndroid Build Coastguard Worker { 1, "HP-UX" },
640*f6dc9357SAndroid Build Coastguard Worker { 2, "NetBSD" },
641*f6dc9357SAndroid Build Coastguard Worker { 3, "Linux" },
642*f6dc9357SAndroid Build Coastguard Worker { 4, "Hurd" },
643*f6dc9357SAndroid Build Coastguard Worker
644*f6dc9357SAndroid Build Coastguard Worker { 6, "Solaris" },
645*f6dc9357SAndroid Build Coastguard Worker { 7, "AIX" },
646*f6dc9357SAndroid Build Coastguard Worker { 8, "IRIX" },
647*f6dc9357SAndroid Build Coastguard Worker { 9, "FreeBSD" },
648*f6dc9357SAndroid Build Coastguard Worker { 10, "TRU64" },
649*f6dc9357SAndroid Build Coastguard Worker { 11, "Novell Modesto" },
650*f6dc9357SAndroid Build Coastguard Worker { 12, "OpenBSD" },
651*f6dc9357SAndroid Build Coastguard Worker { 13, "OpenVMS" },
652*f6dc9357SAndroid Build Coastguard Worker { 14, "HP NSK" },
653*f6dc9357SAndroid Build Coastguard Worker { 15, "AROS" },
654*f6dc9357SAndroid Build Coastguard Worker { 16, "FenixOS" },
655*f6dc9357SAndroid Build Coastguard Worker { 17, "CloudABI" },
656*f6dc9357SAndroid Build Coastguard Worker { 18, "OpenVOS" },
657*f6dc9357SAndroid Build Coastguard Worker { 64, "Bare-metal TMS320C6000" },
658*f6dc9357SAndroid Build Coastguard Worker { 65, "Linux TMS320C6000" },
659*f6dc9357SAndroid Build Coastguard Worker { 97, "ARM" },
660*f6dc9357SAndroid Build Coastguard Worker { 255, "Standalone" }
661*f6dc9357SAndroid Build Coastguard Worker };
662*f6dc9357SAndroid Build Coastguard Worker
663*f6dc9357SAndroid Build Coastguard Worker #define k_Machine_MIPS 8
664*f6dc9357SAndroid Build Coastguard Worker #define k_Machine_ARM 40
665*f6dc9357SAndroid Build Coastguard Worker #define k_Machine_RISCV 243
666*f6dc9357SAndroid Build Coastguard Worker
667*f6dc9357SAndroid Build Coastguard Worker /*
668*f6dc9357SAndroid Build Coastguard Worker #define EF_ARM_ABIMASK 0xFF000000
669*f6dc9357SAndroid Build Coastguard Worker #define EF_ARM_BE8 0x00800000
670*f6dc9357SAndroid Build Coastguard Worker #define EF_ARM_GCCMASK 0x00400FFF
671*f6dc9357SAndroid Build Coastguard Worker #define EF_ARM_ABI_FLOAT_SOFT 0x00000200
672*f6dc9357SAndroid Build Coastguard Worker #define EF_ARM_ABI_FLOAT_HARD 0x00000400
673*f6dc9357SAndroid Build Coastguard Worker */
674*f6dc9357SAndroid Build Coastguard Worker
675*f6dc9357SAndroid Build Coastguard Worker static const CUInt32PCharPair g_ARM_Flags[] =
676*f6dc9357SAndroid Build Coastguard Worker {
677*f6dc9357SAndroid Build Coastguard Worker { 1, "HasEntry" },
678*f6dc9357SAndroid Build Coastguard Worker { 9, "SF" },
679*f6dc9357SAndroid Build Coastguard Worker { 10, "HF" },
680*f6dc9357SAndroid Build Coastguard Worker { 23, "BE8" }
681*f6dc9357SAndroid Build Coastguard Worker };
682*f6dc9357SAndroid Build Coastguard Worker
683*f6dc9357SAndroid Build Coastguard Worker
684*f6dc9357SAndroid Build Coastguard Worker static const CUInt32PCharPair g_MIPS_Flags[] =
685*f6dc9357SAndroid Build Coastguard Worker {
686*f6dc9357SAndroid Build Coastguard Worker { 0, "NOREORDER" },
687*f6dc9357SAndroid Build Coastguard Worker { 1, "PIC" },
688*f6dc9357SAndroid Build Coastguard Worker { 2, "CPIC" },
689*f6dc9357SAndroid Build Coastguard Worker { 3, "XGOT" },
690*f6dc9357SAndroid Build Coastguard Worker { 4, "64BIT_WHIRL" },
691*f6dc9357SAndroid Build Coastguard Worker { 5, "ABI2" },
692*f6dc9357SAndroid Build Coastguard Worker { 6, "ABI_ON32" },
693*f6dc9357SAndroid Build Coastguard Worker { 10, "NAN2008" },
694*f6dc9357SAndroid Build Coastguard Worker { 25, "MicroMIPS" },
695*f6dc9357SAndroid Build Coastguard Worker { 26, "M16" },
696*f6dc9357SAndroid Build Coastguard Worker { 27, "MDMX" }
697*f6dc9357SAndroid Build Coastguard Worker };
698*f6dc9357SAndroid Build Coastguard Worker
699*f6dc9357SAndroid Build Coastguard Worker static const char * const g_RISCV_Flags[] =
700*f6dc9357SAndroid Build Coastguard Worker {
701*f6dc9357SAndroid Build Coastguard Worker "RVC",
702*f6dc9357SAndroid Build Coastguard Worker NULL,
703*f6dc9357SAndroid Build Coastguard Worker NULL,
704*f6dc9357SAndroid Build Coastguard Worker "RVE",
705*f6dc9357SAndroid Build Coastguard Worker "TSO"
706*f6dc9357SAndroid Build Coastguard Worker };
707*f6dc9357SAndroid Build Coastguard Worker
708*f6dc9357SAndroid Build Coastguard Worker
709*f6dc9357SAndroid Build Coastguard Worker // #define ET_NONE 0
710*f6dc9357SAndroid Build Coastguard Worker #define ET_REL 1
711*f6dc9357SAndroid Build Coastguard Worker // #define ET_EXEC 2
712*f6dc9357SAndroid Build Coastguard Worker #define ET_DYN 3
713*f6dc9357SAndroid Build Coastguard Worker // #define ET_CORE 4
714*f6dc9357SAndroid Build Coastguard Worker
715*f6dc9357SAndroid Build Coastguard Worker static const char * const g_Types[] =
716*f6dc9357SAndroid Build Coastguard Worker {
717*f6dc9357SAndroid Build Coastguard Worker "None"
718*f6dc9357SAndroid Build Coastguard Worker , "Relocatable file"
719*f6dc9357SAndroid Build Coastguard Worker , "Executable file"
720*f6dc9357SAndroid Build Coastguard Worker , "Shared object file"
721*f6dc9357SAndroid Build Coastguard Worker , "Core file"
722*f6dc9357SAndroid Build Coastguard Worker };
723*f6dc9357SAndroid Build Coastguard Worker
724*f6dc9357SAndroid Build Coastguard Worker
725*f6dc9357SAndroid Build Coastguard Worker
726*f6dc9357SAndroid Build Coastguard Worker
727*f6dc9357SAndroid Build Coastguard Worker Z7_CLASS_IMP_CHandler_IInArchive_1(
728*f6dc9357SAndroid Build Coastguard Worker IArchiveAllowTail
729*f6dc9357SAndroid Build Coastguard Worker )
730*f6dc9357SAndroid Build Coastguard Worker CRecordVector<CSegment> _segments;
731*f6dc9357SAndroid Build Coastguard Worker CRecordVector<CSection> _sections;
732*f6dc9357SAndroid Build Coastguard Worker CByteBuffer _namesData;
733*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<IInStream> _inStream;
734*f6dc9357SAndroid Build Coastguard Worker UInt64 _totalSize;
735*f6dc9357SAndroid Build Coastguard Worker CHeader _header;
736*f6dc9357SAndroid Build Coastguard Worker bool _headersError;
737*f6dc9357SAndroid Build Coastguard Worker bool _allowTail;
738*f6dc9357SAndroid Build Coastguard Worker bool _stackFlags_Defined;
739*f6dc9357SAndroid Build Coastguard Worker UInt32 _stackFlags;
740*f6dc9357SAndroid Build Coastguard Worker
741*f6dc9357SAndroid Build Coastguard Worker void GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showNULL) const;
742*f6dc9357SAndroid Build Coastguard Worker HRESULT Open2(IInStream *stream);
743*f6dc9357SAndroid Build Coastguard Worker public:
744*f6dc9357SAndroid Build Coastguard Worker CHandler(): _allowTail(false) {}
745*f6dc9357SAndroid Build Coastguard Worker };
746*f6dc9357SAndroid Build Coastguard Worker
747*f6dc9357SAndroid Build Coastguard Worker void CHandler::GetSectionName(UInt32 index, NCOM::CPropVariant &prop, bool showNULL) const
748*f6dc9357SAndroid Build Coastguard Worker {
749*f6dc9357SAndroid Build Coastguard Worker if (index >= _sections.Size())
750*f6dc9357SAndroid Build Coastguard Worker prop = index; // it's possible for some file, but maybe it's ERROR case
751*f6dc9357SAndroid Build Coastguard Worker else
752*f6dc9357SAndroid Build Coastguard Worker {
753*f6dc9357SAndroid Build Coastguard Worker const CSection §ion = _sections[index];
754*f6dc9357SAndroid Build Coastguard Worker const UInt32 offset = section.Name;
755*f6dc9357SAndroid Build Coastguard Worker if (index == SHN_UNDEF /* && section.Type == SHT_NULL && offset == 0 */)
756*f6dc9357SAndroid Build Coastguard Worker {
757*f6dc9357SAndroid Build Coastguard Worker if (showNULL)
758*f6dc9357SAndroid Build Coastguard Worker prop = "NULL";
759*f6dc9357SAndroid Build Coastguard Worker return;
760*f6dc9357SAndroid Build Coastguard Worker }
761*f6dc9357SAndroid Build Coastguard Worker const Byte *p = _namesData;
762*f6dc9357SAndroid Build Coastguard Worker const size_t size = _namesData.Size();
763*f6dc9357SAndroid Build Coastguard Worker for (size_t i = offset; i < size; i++)
764*f6dc9357SAndroid Build Coastguard Worker if (p[i] == 0)
765*f6dc9357SAndroid Build Coastguard Worker {
766*f6dc9357SAndroid Build Coastguard Worker prop = (const char *)(p + offset);
767*f6dc9357SAndroid Build Coastguard Worker return;
768*f6dc9357SAndroid Build Coastguard Worker }
769*f6dc9357SAndroid Build Coastguard Worker prop = "ERROR";
770*f6dc9357SAndroid Build Coastguard Worker }
771*f6dc9357SAndroid Build Coastguard Worker }
772*f6dc9357SAndroid Build Coastguard Worker
773*f6dc9357SAndroid Build Coastguard Worker static const Byte kArcProps[] =
774*f6dc9357SAndroid Build Coastguard Worker {
775*f6dc9357SAndroid Build Coastguard Worker kpidCpu,
776*f6dc9357SAndroid Build Coastguard Worker kpidBit64,
777*f6dc9357SAndroid Build Coastguard Worker kpidBigEndian,
778*f6dc9357SAndroid Build Coastguard Worker kpidHostOS,
779*f6dc9357SAndroid Build Coastguard Worker kpidCharacts,
780*f6dc9357SAndroid Build Coastguard Worker kpidComment,
781*f6dc9357SAndroid Build Coastguard Worker kpidHeadersSize
782*f6dc9357SAndroid Build Coastguard Worker };
783*f6dc9357SAndroid Build Coastguard Worker
784*f6dc9357SAndroid Build Coastguard Worker enum
785*f6dc9357SAndroid Build Coastguard Worker {
786*f6dc9357SAndroid Build Coastguard Worker kpidLinkSection = kpidUserDefined,
787*f6dc9357SAndroid Build Coastguard Worker kpidInfoSection,
788*f6dc9357SAndroid Build Coastguard Worker kpidEntrySize
789*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_ELF_SHOW_DETAILS
790*f6dc9357SAndroid Build Coastguard Worker // , kpidAlign
791*f6dc9357SAndroid Build Coastguard Worker , kpidPa
792*f6dc9357SAndroid Build Coastguard Worker , kpidDelta
793*f6dc9357SAndroid Build Coastguard Worker , kpidOffsetEnd
794*f6dc9357SAndroid Build Coastguard Worker #endif
795*f6dc9357SAndroid Build Coastguard Worker };
796*f6dc9357SAndroid Build Coastguard Worker
797*f6dc9357SAndroid Build Coastguard Worker static const CStatProp kProps[] =
798*f6dc9357SAndroid Build Coastguard Worker {
799*f6dc9357SAndroid Build Coastguard Worker { NULL, kpidPath, VT_BSTR },
800*f6dc9357SAndroid Build Coastguard Worker { NULL, kpidSize, VT_UI8 },
801*f6dc9357SAndroid Build Coastguard Worker { NULL, kpidVirtualSize, VT_UI8 },
802*f6dc9357SAndroid Build Coastguard Worker { NULL, kpidOffset, VT_UI8 },
803*f6dc9357SAndroid Build Coastguard Worker { NULL, kpidVa, VT_UI8 },
804*f6dc9357SAndroid Build Coastguard Worker { NULL, kpidType, VT_BSTR },
805*f6dc9357SAndroid Build Coastguard Worker { NULL, kpidCharacts, VT_BSTR }
806*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_ELF_SHOW_DETAILS
807*f6dc9357SAndroid Build Coastguard Worker // , { "Align", kpidAlign, VT_UI8 }
808*f6dc9357SAndroid Build Coastguard Worker , { NULL, kpidClusterSize, VT_UI8 }
809*f6dc9357SAndroid Build Coastguard Worker , { "PA", kpidPa, VT_UI8 }
810*f6dc9357SAndroid Build Coastguard Worker , { "End offset", kpidOffsetEnd, VT_UI8 }
811*f6dc9357SAndroid Build Coastguard Worker , { "Delta (VA-Offset)", kpidDelta, VT_UI8 }
812*f6dc9357SAndroid Build Coastguard Worker #endif
813*f6dc9357SAndroid Build Coastguard Worker , { "Entry Size", kpidEntrySize, VT_UI8}
814*f6dc9357SAndroid Build Coastguard Worker , { "Link Section", kpidLinkSection, VT_BSTR}
815*f6dc9357SAndroid Build Coastguard Worker , { "Info Section", kpidInfoSection, VT_BSTR}
816*f6dc9357SAndroid Build Coastguard Worker };
817*f6dc9357SAndroid Build Coastguard Worker
818*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_Props_WITH_NAME
819*f6dc9357SAndroid Build Coastguard Worker IMP_IInArchive_ArcProps
820*f6dc9357SAndroid Build Coastguard Worker
821*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
822*f6dc9357SAndroid Build Coastguard Worker {
823*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
824*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
825*f6dc9357SAndroid Build Coastguard Worker switch (propID)
826*f6dc9357SAndroid Build Coastguard Worker {
827*f6dc9357SAndroid Build Coastguard Worker case kpidPhySize: prop = _totalSize; break;
828*f6dc9357SAndroid Build Coastguard Worker case kpidHeadersSize: prop = _header.GetHeadersSize(); break;
829*f6dc9357SAndroid Build Coastguard Worker case kpidBit64: if (_header.Mode64) prop = _header.Mode64; break;
830*f6dc9357SAndroid Build Coastguard Worker case kpidBigEndian: if (_header.Be) prop = _header.Be; break;
831*f6dc9357SAndroid Build Coastguard Worker case kpidShortComment:
832*f6dc9357SAndroid Build Coastguard Worker
833*f6dc9357SAndroid Build Coastguard Worker case kpidCpu:
834*f6dc9357SAndroid Build Coastguard Worker {
835*f6dc9357SAndroid Build Coastguard Worker AString s;
836*f6dc9357SAndroid Build Coastguard Worker if (_header.Machine < Z7_ARRAY_SIZE(g_Machines))
837*f6dc9357SAndroid Build Coastguard Worker {
838*f6dc9357SAndroid Build Coastguard Worker const char *name = g_Machines[_header.Machine];
839*f6dc9357SAndroid Build Coastguard Worker if (name)
840*f6dc9357SAndroid Build Coastguard Worker s = name;
841*f6dc9357SAndroid Build Coastguard Worker }
842*f6dc9357SAndroid Build Coastguard Worker if (s.IsEmpty())
843*f6dc9357SAndroid Build Coastguard Worker s = TypePairToString(g_MachinePairs, Z7_ARRAY_SIZE(g_MachinePairs), _header.Machine);
844*f6dc9357SAndroid Build Coastguard Worker UInt32 flags = _header.Flags;
845*f6dc9357SAndroid Build Coastguard Worker if (flags)
846*f6dc9357SAndroid Build Coastguard Worker {
847*f6dc9357SAndroid Build Coastguard Worker s.Add_Space();
848*f6dc9357SAndroid Build Coastguard Worker if (_header.Machine == k_Machine_ARM)
849*f6dc9357SAndroid Build Coastguard Worker {
850*f6dc9357SAndroid Build Coastguard Worker s += FlagsToString(g_ARM_Flags, Z7_ARRAY_SIZE(g_ARM_Flags), flags & (((UInt32)1 << 24) - 1));
851*f6dc9357SAndroid Build Coastguard Worker s += " ABI:";
852*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(flags >> 24);
853*f6dc9357SAndroid Build Coastguard Worker }
854*f6dc9357SAndroid Build Coastguard Worker else if (_header.Machine == k_Machine_MIPS)
855*f6dc9357SAndroid Build Coastguard Worker {
856*f6dc9357SAndroid Build Coastguard Worker const UInt32 ver = flags >> 28;
857*f6dc9357SAndroid Build Coastguard Worker s.Add_Char('v');
858*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(ver);
859*f6dc9357SAndroid Build Coastguard Worker flags &= ((UInt32)1 << 28) - 1;
860*f6dc9357SAndroid Build Coastguard Worker const UInt32 abi = (flags >> 12) & 7;
861*f6dc9357SAndroid Build Coastguard Worker if (abi)
862*f6dc9357SAndroid Build Coastguard Worker {
863*f6dc9357SAndroid Build Coastguard Worker s += " ABI:";
864*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(abi);
865*f6dc9357SAndroid Build Coastguard Worker }
866*f6dc9357SAndroid Build Coastguard Worker flags &= ~((UInt32)7 << 12);
867*f6dc9357SAndroid Build Coastguard Worker s.Add_Space();
868*f6dc9357SAndroid Build Coastguard Worker s += FlagsToString(g_MIPS_Flags, Z7_ARRAY_SIZE(g_MIPS_Flags), flags);
869*f6dc9357SAndroid Build Coastguard Worker }
870*f6dc9357SAndroid Build Coastguard Worker else if (_header.Machine == k_Machine_RISCV)
871*f6dc9357SAndroid Build Coastguard Worker {
872*f6dc9357SAndroid Build Coastguard Worker s += "FLOAT_";
873*f6dc9357SAndroid Build Coastguard Worker const UInt32 fl = (flags >> 1) & 3;
874*f6dc9357SAndroid Build Coastguard Worker /*
875*f6dc9357SAndroid Build Coastguard Worker static const char * const g_RISCV_Flags_Float[] =
876*f6dc9357SAndroid Build Coastguard Worker { "SOFT", "SINGLE", "DOUBLE", "QUAD" };
877*f6dc9357SAndroid Build Coastguard Worker s += g_RISCV_Flags_Float[fl];
878*f6dc9357SAndroid Build Coastguard Worker */
879*f6dc9357SAndroid Build Coastguard Worker if (fl)
880*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(16u << fl);
881*f6dc9357SAndroid Build Coastguard Worker else
882*f6dc9357SAndroid Build Coastguard Worker s += "SOFT";
883*f6dc9357SAndroid Build Coastguard Worker s.Add_Space();
884*f6dc9357SAndroid Build Coastguard Worker flags &= ~(UInt32)6;
885*f6dc9357SAndroid Build Coastguard Worker s += FlagsToString(g_RISCV_Flags, Z7_ARRAY_SIZE(g_RISCV_Flags), flags);
886*f6dc9357SAndroid Build Coastguard Worker }
887*f6dc9357SAndroid Build Coastguard Worker #if 0
888*f6dc9357SAndroid Build Coastguard Worker #define k_Machine_LOONGARCH 258
889*f6dc9357SAndroid Build Coastguard Worker else if (_header.Machine == k_Machine_LOONGARCH)
890*f6dc9357SAndroid Build Coastguard Worker {
891*f6dc9357SAndroid Build Coastguard Worker s += "ABI:";
892*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32((flags >> 6) & 3);
893*f6dc9357SAndroid Build Coastguard Worker s.Add_Dot();
894*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32((flags >> 3) & 7);
895*f6dc9357SAndroid Build Coastguard Worker s.Add_Dot();
896*f6dc9357SAndroid Build Coastguard Worker #if 1
897*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(flags & 7);
898*f6dc9357SAndroid Build Coastguard Worker #else
899*f6dc9357SAndroid Build Coastguard Worker static const char k_LoongArch_Float_Type[8] = { '0', 's', 'f', 'd', '4' ,'5', '6', '7' };
900*f6dc9357SAndroid Build Coastguard Worker s.Add_Char(k_LoongArch_Float_Type[flags & 7]);
901*f6dc9357SAndroid Build Coastguard Worker #endif
902*f6dc9357SAndroid Build Coastguard Worker flags &= ~(UInt32)0xff;
903*f6dc9357SAndroid Build Coastguard Worker if (flags)
904*f6dc9357SAndroid Build Coastguard Worker {
905*f6dc9357SAndroid Build Coastguard Worker s.Add_Colon();
906*f6dc9357SAndroid Build Coastguard Worker char sz[16];
907*f6dc9357SAndroid Build Coastguard Worker ConvertUInt32ToHex(flags, sz);
908*f6dc9357SAndroid Build Coastguard Worker s += sz;
909*f6dc9357SAndroid Build Coastguard Worker }
910*f6dc9357SAndroid Build Coastguard Worker }
911*f6dc9357SAndroid Build Coastguard Worker #endif
912*f6dc9357SAndroid Build Coastguard Worker else
913*f6dc9357SAndroid Build Coastguard Worker {
914*f6dc9357SAndroid Build Coastguard Worker char sz[16];
915*f6dc9357SAndroid Build Coastguard Worker ConvertUInt32ToHex(flags, sz);
916*f6dc9357SAndroid Build Coastguard Worker s += sz;
917*f6dc9357SAndroid Build Coastguard Worker }
918*f6dc9357SAndroid Build Coastguard Worker }
919*f6dc9357SAndroid Build Coastguard Worker prop = s;
920*f6dc9357SAndroid Build Coastguard Worker break;
921*f6dc9357SAndroid Build Coastguard Worker }
922*f6dc9357SAndroid Build Coastguard Worker
923*f6dc9357SAndroid Build Coastguard Worker case kpidHostOS: PAIR_TO_PROP(g_OS, _header.Os, prop); break;
924*f6dc9357SAndroid Build Coastguard Worker case kpidCharacts: TYPE_TO_PROP(g_Types, _header.Type, prop); break;
925*f6dc9357SAndroid Build Coastguard Worker case kpidComment:
926*f6dc9357SAndroid Build Coastguard Worker {
927*f6dc9357SAndroid Build Coastguard Worker AString s;
928*f6dc9357SAndroid Build Coastguard Worker if (_stackFlags_Defined)
929*f6dc9357SAndroid Build Coastguard Worker {
930*f6dc9357SAndroid Build Coastguard Worker s += "STACK: ";
931*f6dc9357SAndroid Build Coastguard Worker s += FlagsToString(g_SegmentFlags, Z7_ARRAY_SIZE(g_SegmentFlags), _stackFlags);
932*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
933*f6dc9357SAndroid Build Coastguard Worker /*
934*f6dc9357SAndroid Build Coastguard Worker if (_header.EntryVa)
935*f6dc9357SAndroid Build Coastguard Worker {
936*f6dc9357SAndroid Build Coastguard Worker s += "Entry point: 0x";
937*f6dc9357SAndroid Build Coastguard Worker char temp[16 + 4];
938*f6dc9357SAndroid Build Coastguard Worker ConvertUInt64ToHex(_header.EntryVa, temp);
939*f6dc9357SAndroid Build Coastguard Worker s += temp;
940*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
941*f6dc9357SAndroid Build Coastguard Worker }
942*f6dc9357SAndroid Build Coastguard Worker */
943*f6dc9357SAndroid Build Coastguard Worker }
944*f6dc9357SAndroid Build Coastguard Worker if (_header.NumSegments)
945*f6dc9357SAndroid Build Coastguard Worker {
946*f6dc9357SAndroid Build Coastguard Worker s += "Segments: ";
947*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(_header.NumSegments);
948*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
949*f6dc9357SAndroid Build Coastguard Worker }
950*f6dc9357SAndroid Build Coastguard Worker if (_header.NumSections)
951*f6dc9357SAndroid Build Coastguard Worker {
952*f6dc9357SAndroid Build Coastguard Worker s += "Sections: ";
953*f6dc9357SAndroid Build Coastguard Worker s.Add_UInt32(_header.NumSections);
954*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
955*f6dc9357SAndroid Build Coastguard Worker }
956*f6dc9357SAndroid Build Coastguard Worker prop = s;
957*f6dc9357SAndroid Build Coastguard Worker break;
958*f6dc9357SAndroid Build Coastguard Worker }
959*f6dc9357SAndroid Build Coastguard Worker case kpidExtension:
960*f6dc9357SAndroid Build Coastguard Worker {
961*f6dc9357SAndroid Build Coastguard Worker const char *s = NULL;
962*f6dc9357SAndroid Build Coastguard Worker if (_header.Type == ET_DYN)
963*f6dc9357SAndroid Build Coastguard Worker s = "so";
964*f6dc9357SAndroid Build Coastguard Worker else if (_header.Type == ET_REL)
965*f6dc9357SAndroid Build Coastguard Worker s = "o";
966*f6dc9357SAndroid Build Coastguard Worker if (s)
967*f6dc9357SAndroid Build Coastguard Worker prop = s;
968*f6dc9357SAndroid Build Coastguard Worker break;
969*f6dc9357SAndroid Build Coastguard Worker }
970*f6dc9357SAndroid Build Coastguard Worker // case kpidIsSelfExe: prop = (_header.Type != ET_DYN) && (_header.Type == ET_REL); break;
971*f6dc9357SAndroid Build Coastguard Worker case kpidErrorFlags:
972*f6dc9357SAndroid Build Coastguard Worker {
973*f6dc9357SAndroid Build Coastguard Worker UInt32 flags = 0;
974*f6dc9357SAndroid Build Coastguard Worker if (_headersError) flags |= kpv_ErrorFlags_HeadersError;
975*f6dc9357SAndroid Build Coastguard Worker if (flags != 0)
976*f6dc9357SAndroid Build Coastguard Worker prop = flags;
977*f6dc9357SAndroid Build Coastguard Worker break;
978*f6dc9357SAndroid Build Coastguard Worker }
979*f6dc9357SAndroid Build Coastguard Worker }
980*f6dc9357SAndroid Build Coastguard Worker prop.Detach(value);
981*f6dc9357SAndroid Build Coastguard Worker return S_OK;
982*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
983*f6dc9357SAndroid Build Coastguard Worker }
984*f6dc9357SAndroid Build Coastguard Worker
985*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
986*f6dc9357SAndroid Build Coastguard Worker {
987*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
988*f6dc9357SAndroid Build Coastguard Worker NCOM::CPropVariant prop;
989*f6dc9357SAndroid Build Coastguard Worker if (index < _segments.Size())
990*f6dc9357SAndroid Build Coastguard Worker {
991*f6dc9357SAndroid Build Coastguard Worker const CSegment &item = _segments[index];
992*f6dc9357SAndroid Build Coastguard Worker switch (propID)
993*f6dc9357SAndroid Build Coastguard Worker {
994*f6dc9357SAndroid Build Coastguard Worker case kpidPath:
995*f6dc9357SAndroid Build Coastguard Worker {
996*f6dc9357SAndroid Build Coastguard Worker char sz[16];
997*f6dc9357SAndroid Build Coastguard Worker ConvertUInt32ToString(index, sz);
998*f6dc9357SAndroid Build Coastguard Worker prop = sz;
999*f6dc9357SAndroid Build Coastguard Worker break;
1000*f6dc9357SAndroid Build Coastguard Worker }
1001*f6dc9357SAndroid Build Coastguard Worker case kpidOffset: prop = item.Offset; break;
1002*f6dc9357SAndroid Build Coastguard Worker case kpidVa: prop = item.Va; break;
1003*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_ELF_SHOW_DETAILS
1004*f6dc9357SAndroid Build Coastguard Worker case kpidDelta: if (item.Va) { prop = item.Va - item.Offset; } break;
1005*f6dc9357SAndroid Build Coastguard Worker case kpidOffsetEnd: prop = item.Offset + item.Size; break;
1006*f6dc9357SAndroid Build Coastguard Worker case kpidPa: prop = item.Pa; break;
1007*f6dc9357SAndroid Build Coastguard Worker case kpidClusterSize: prop = item.Align; break;
1008*f6dc9357SAndroid Build Coastguard Worker #endif
1009*f6dc9357SAndroid Build Coastguard Worker case kpidSize:
1010*f6dc9357SAndroid Build Coastguard Worker case kpidPackSize: prop = (UInt64)item.Size; break;
1011*f6dc9357SAndroid Build Coastguard Worker case kpidVirtualSize: prop = (UInt64)item.VSize; break;
1012*f6dc9357SAndroid Build Coastguard Worker case kpidType: PAIR_TO_PROP(g_SegnmentTypes, item.Type, prop); break;
1013*f6dc9357SAndroid Build Coastguard Worker case kpidCharacts: FLAGS_TO_PROP(g_SegmentFlags, item.Flags, prop); break;
1014*f6dc9357SAndroid Build Coastguard Worker }
1015*f6dc9357SAndroid Build Coastguard Worker }
1016*f6dc9357SAndroid Build Coastguard Worker else
1017*f6dc9357SAndroid Build Coastguard Worker {
1018*f6dc9357SAndroid Build Coastguard Worker index -= _segments.Size();
1019*f6dc9357SAndroid Build Coastguard Worker const CSection &item = _sections[index];
1020*f6dc9357SAndroid Build Coastguard Worker switch (propID)
1021*f6dc9357SAndroid Build Coastguard Worker {
1022*f6dc9357SAndroid Build Coastguard Worker case kpidPath: GetSectionName(index, prop, true); break;
1023*f6dc9357SAndroid Build Coastguard Worker case kpidOffset: prop = item.Offset; break;
1024*f6dc9357SAndroid Build Coastguard Worker case kpidVa: prop = item.Va; break;
1025*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_ELF_SHOW_DETAILS
1026*f6dc9357SAndroid Build Coastguard Worker case kpidDelta: if (item.Va) { prop = item.Va - item.Offset; } break;
1027*f6dc9357SAndroid Build Coastguard Worker case kpidOffsetEnd: prop = item.Offset + item.GetSize(); break;
1028*f6dc9357SAndroid Build Coastguard Worker #endif
1029*f6dc9357SAndroid Build Coastguard Worker case kpidSize:
1030*f6dc9357SAndroid Build Coastguard Worker case kpidPackSize: prop = (UInt64)(item.Type == SHT_NOBITS ? 0 : item.VSize); break;
1031*f6dc9357SAndroid Build Coastguard Worker case kpidVirtualSize: prop = item.GetSize(); break;
1032*f6dc9357SAndroid Build Coastguard Worker case kpidType: PAIR_TO_PROP(g_SectTypes, item.Type, prop); break;
1033*f6dc9357SAndroid Build Coastguard Worker case kpidCharacts: FLAGS_TO_PROP(g_SectionFlags, (UInt32)item.Flags, prop); break;
1034*f6dc9357SAndroid Build Coastguard Worker // case kpidAlign: prop = item.Align; break;
1035*f6dc9357SAndroid Build Coastguard Worker case kpidLinkSection: GetSectionName(item.Link, prop, false); break;
1036*f6dc9357SAndroid Build Coastguard Worker case kpidInfoSection: GetSectionName(item.Info, prop, false); break;
1037*f6dc9357SAndroid Build Coastguard Worker case kpidEntrySize: prop = (UInt64)item.EntSize; break;
1038*f6dc9357SAndroid Build Coastguard Worker }
1039*f6dc9357SAndroid Build Coastguard Worker }
1040*f6dc9357SAndroid Build Coastguard Worker prop.Detach(value);
1041*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1042*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
1043*f6dc9357SAndroid Build Coastguard Worker }
1044*f6dc9357SAndroid Build Coastguard Worker
1045*f6dc9357SAndroid Build Coastguard Worker HRESULT CHandler::Open2(IInStream *stream)
1046*f6dc9357SAndroid Build Coastguard Worker {
1047*f6dc9357SAndroid Build Coastguard Worker {
1048*f6dc9357SAndroid Build Coastguard Worker const UInt32 kStartSize = kHeaderSize64;
1049*f6dc9357SAndroid Build Coastguard Worker UInt64 h64[kStartSize / 8];
1050*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadStream_FALSE(stream, h64, kStartSize))
1051*f6dc9357SAndroid Build Coastguard Worker const Byte *h = (const Byte *)(const void *)h64;
1052*f6dc9357SAndroid Build Coastguard Worker if (GetUi32a(h) != 0x464c457f)
1053*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1054*f6dc9357SAndroid Build Coastguard Worker if (!_header.Parse(h))
1055*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1056*f6dc9357SAndroid Build Coastguard Worker }
1057*f6dc9357SAndroid Build Coastguard Worker
1058*f6dc9357SAndroid Build Coastguard Worker _totalSize = _header.HeaderSize;
1059*f6dc9357SAndroid Build Coastguard Worker
1060*f6dc9357SAndroid Build Coastguard Worker bool addSegments = false;
1061*f6dc9357SAndroid Build Coastguard Worker bool addSections = false;
1062*f6dc9357SAndroid Build Coastguard Worker // first section usually is NULL (with zero offsets and zero sizes).
1063*f6dc9357SAndroid Build Coastguard Worker if (_header.NumSegments == 0 || _header.NumSections > 1)
1064*f6dc9357SAndroid Build Coastguard Worker addSections = true;
1065*f6dc9357SAndroid Build Coastguard Worker else
1066*f6dc9357SAndroid Build Coastguard Worker addSegments = true;
1067*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_ELF_SHOW_DETAILS
1068*f6dc9357SAndroid Build Coastguard Worker addSections = true;
1069*f6dc9357SAndroid Build Coastguard Worker addSegments = true;
1070*f6dc9357SAndroid Build Coastguard Worker #endif
1071*f6dc9357SAndroid Build Coastguard Worker
1072*f6dc9357SAndroid Build Coastguard Worker if (_header.NumSegments)
1073*f6dc9357SAndroid Build Coastguard Worker {
1074*f6dc9357SAndroid Build Coastguard Worker if (_header.ProgOffset > (UInt64)1 << 60) return S_FALSE;
1075*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(stream, _header.ProgOffset))
1076*f6dc9357SAndroid Build Coastguard Worker const size_t size = (size_t)_header.SegmentEntrySize * _header.NumSegments;
1077*f6dc9357SAndroid Build Coastguard Worker CByteArr buf(size);
1078*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadStream_FALSE(stream, buf, size))
1079*f6dc9357SAndroid Build Coastguard Worker {
1080*f6dc9357SAndroid Build Coastguard Worker const UInt64 total = _header.ProgOffset + size;
1081*f6dc9357SAndroid Build Coastguard Worker if (_totalSize < total)
1082*f6dc9357SAndroid Build Coastguard Worker _totalSize = total;
1083*f6dc9357SAndroid Build Coastguard Worker }
1084*f6dc9357SAndroid Build Coastguard Worker if (addSegments)
1085*f6dc9357SAndroid Build Coastguard Worker _segments.ClearAndReserve(_header.NumSegments);
1086*f6dc9357SAndroid Build Coastguard Worker const Byte *p = buf;
1087*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < _header.NumSegments; i++, p += _header.SegmentEntrySize)
1088*f6dc9357SAndroid Build Coastguard Worker {
1089*f6dc9357SAndroid Build Coastguard Worker CSegment seg;
1090*f6dc9357SAndroid Build Coastguard Worker seg.Parse(p, _header.Mode64, _header.Be);
1091*f6dc9357SAndroid Build Coastguard Worker seg.UpdateTotalSize(_totalSize);
1092*f6dc9357SAndroid Build Coastguard Worker if (seg.Type == PT_GNU_STACK && !_stackFlags_Defined)
1093*f6dc9357SAndroid Build Coastguard Worker {
1094*f6dc9357SAndroid Build Coastguard Worker _stackFlags = seg.Flags;
1095*f6dc9357SAndroid Build Coastguard Worker _stackFlags_Defined = true;
1096*f6dc9357SAndroid Build Coastguard Worker }
1097*f6dc9357SAndroid Build Coastguard Worker if (addSegments
1098*f6dc9357SAndroid Build Coastguard Worker // we don't show program header table segment
1099*f6dc9357SAndroid Build Coastguard Worker && seg.Type != PT_PHDR
1100*f6dc9357SAndroid Build Coastguard Worker )
1101*f6dc9357SAndroid Build Coastguard Worker _segments.AddInReserved(seg);
1102*f6dc9357SAndroid Build Coastguard Worker }
1103*f6dc9357SAndroid Build Coastguard Worker }
1104*f6dc9357SAndroid Build Coastguard Worker
1105*f6dc9357SAndroid Build Coastguard Worker if (_header.NumSections)
1106*f6dc9357SAndroid Build Coastguard Worker {
1107*f6dc9357SAndroid Build Coastguard Worker if (_header.SectOffset > (UInt64)1 << 60) return S_FALSE;
1108*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(stream, _header.SectOffset))
1109*f6dc9357SAndroid Build Coastguard Worker const size_t size = (size_t)_header.SectionEntrySize * _header.NumSections;
1110*f6dc9357SAndroid Build Coastguard Worker CByteArr buf(size);
1111*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadStream_FALSE(stream, buf, size))
1112*f6dc9357SAndroid Build Coastguard Worker {
1113*f6dc9357SAndroid Build Coastguard Worker const UInt64 total = _header.SectOffset + size;
1114*f6dc9357SAndroid Build Coastguard Worker if (_totalSize < total)
1115*f6dc9357SAndroid Build Coastguard Worker _totalSize = total;
1116*f6dc9357SAndroid Build Coastguard Worker }
1117*f6dc9357SAndroid Build Coastguard Worker if (addSections)
1118*f6dc9357SAndroid Build Coastguard Worker _sections.ClearAndReserve(_header.NumSections);
1119*f6dc9357SAndroid Build Coastguard Worker const Byte *p = buf;
1120*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0; i < _header.NumSections; i++, p += _header.SectionEntrySize)
1121*f6dc9357SAndroid Build Coastguard Worker {
1122*f6dc9357SAndroid Build Coastguard Worker CSection sect;
1123*f6dc9357SAndroid Build Coastguard Worker if (!sect.Parse(p, _header.Mode64, _header.Be))
1124*f6dc9357SAndroid Build Coastguard Worker {
1125*f6dc9357SAndroid Build Coastguard Worker _headersError = true;
1126*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1127*f6dc9357SAndroid Build Coastguard Worker }
1128*f6dc9357SAndroid Build Coastguard Worker sect.UpdateTotalSize(_totalSize);
1129*f6dc9357SAndroid Build Coastguard Worker if (addSections)
1130*f6dc9357SAndroid Build Coastguard Worker _sections.AddInReserved(sect);
1131*f6dc9357SAndroid Build Coastguard Worker }
1132*f6dc9357SAndroid Build Coastguard Worker }
1133*f6dc9357SAndroid Build Coastguard Worker
1134*f6dc9357SAndroid Build Coastguard Worker if (addSections)
1135*f6dc9357SAndroid Build Coastguard Worker {
1136*f6dc9357SAndroid Build Coastguard Worker if (_header.NamesSectIndex < _sections.Size())
1137*f6dc9357SAndroid Build Coastguard Worker {
1138*f6dc9357SAndroid Build Coastguard Worker const CSection § = _sections[_header.NamesSectIndex];
1139*f6dc9357SAndroid Build Coastguard Worker const UInt64 size = sect.GetSize();
1140*f6dc9357SAndroid Build Coastguard Worker if (size && size < ((UInt64)1 << 31)
1141*f6dc9357SAndroid Build Coastguard Worker && (Int64)sect.Offset >= 0)
1142*f6dc9357SAndroid Build Coastguard Worker {
1143*f6dc9357SAndroid Build Coastguard Worker _namesData.Alloc((size_t)size);
1144*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(stream, sect.Offset))
1145*f6dc9357SAndroid Build Coastguard Worker RINOK(ReadStream_FALSE(stream, _namesData, (size_t)size))
1146*f6dc9357SAndroid Build Coastguard Worker }
1147*f6dc9357SAndroid Build Coastguard Worker }
1148*f6dc9357SAndroid Build Coastguard Worker /*
1149*f6dc9357SAndroid Build Coastguard Worker // we cannot delete "NULL" sections,
1150*f6dc9357SAndroid Build Coastguard Worker // because we have links to sections array via indexes
1151*f6dc9357SAndroid Build Coastguard Worker for (int i = _sections.Size() - 1; i >= 0; i--)
1152*f6dc9357SAndroid Build Coastguard Worker if (_sections[i].Type == SHT_NULL)
1153*f6dc9357SAndroid Build Coastguard Worker _items.Delete(i);
1154*f6dc9357SAndroid Build Coastguard Worker */
1155*f6dc9357SAndroid Build Coastguard Worker }
1156*f6dc9357SAndroid Build Coastguard Worker
1157*f6dc9357SAndroid Build Coastguard Worker if (!_allowTail)
1158*f6dc9357SAndroid Build Coastguard Worker {
1159*f6dc9357SAndroid Build Coastguard Worker UInt64 fileSize;
1160*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_GetSize_SeekToEnd(stream, fileSize))
1161*f6dc9357SAndroid Build Coastguard Worker if (fileSize > _totalSize)
1162*f6dc9357SAndroid Build Coastguard Worker return S_FALSE;
1163*f6dc9357SAndroid Build Coastguard Worker }
1164*f6dc9357SAndroid Build Coastguard Worker
1165*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1166*f6dc9357SAndroid Build Coastguard Worker }
1167*f6dc9357SAndroid Build Coastguard Worker
1168*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Open(IInStream *inStream,
1169*f6dc9357SAndroid Build Coastguard Worker const UInt64 * /* maxCheckStartPosition */,
1170*f6dc9357SAndroid Build Coastguard Worker IArchiveOpenCallback * /* openArchiveCallback */))
1171*f6dc9357SAndroid Build Coastguard Worker {
1172*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
1173*f6dc9357SAndroid Build Coastguard Worker Close();
1174*f6dc9357SAndroid Build Coastguard Worker RINOK(Open2(inStream))
1175*f6dc9357SAndroid Build Coastguard Worker _inStream = inStream;
1176*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1177*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
1178*f6dc9357SAndroid Build Coastguard Worker }
1179*f6dc9357SAndroid Build Coastguard Worker
1180*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Close())
1181*f6dc9357SAndroid Build Coastguard Worker {
1182*f6dc9357SAndroid Build Coastguard Worker _totalSize = 0;
1183*f6dc9357SAndroid Build Coastguard Worker _headersError = false;
1184*f6dc9357SAndroid Build Coastguard Worker _stackFlags_Defined = false;
1185*f6dc9357SAndroid Build Coastguard Worker
1186*f6dc9357SAndroid Build Coastguard Worker _inStream.Release();
1187*f6dc9357SAndroid Build Coastguard Worker _segments.Clear();
1188*f6dc9357SAndroid Build Coastguard Worker _sections.Clear();
1189*f6dc9357SAndroid Build Coastguard Worker _namesData.Free();
1190*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1191*f6dc9357SAndroid Build Coastguard Worker }
1192*f6dc9357SAndroid Build Coastguard Worker
1193*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
1194*f6dc9357SAndroid Build Coastguard Worker {
1195*f6dc9357SAndroid Build Coastguard Worker *numItems = _segments.Size() + _sections.Size();
1196*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1197*f6dc9357SAndroid Build Coastguard Worker }
1198*f6dc9357SAndroid Build Coastguard Worker
1199*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
1200*f6dc9357SAndroid Build Coastguard Worker Int32 testMode, IArchiveExtractCallback *extractCallback))
1201*f6dc9357SAndroid Build Coastguard Worker {
1202*f6dc9357SAndroid Build Coastguard Worker COM_TRY_BEGIN
1203*f6dc9357SAndroid Build Coastguard Worker const bool allFilesMode = (numItems == (UInt32)(Int32)-1);
1204*f6dc9357SAndroid Build Coastguard Worker if (allFilesMode)
1205*f6dc9357SAndroid Build Coastguard Worker numItems = _segments.Size() + _sections.Size();
1206*f6dc9357SAndroid Build Coastguard Worker if (numItems == 0)
1207*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1208*f6dc9357SAndroid Build Coastguard Worker UInt64 totalSize = 0;
1209*f6dc9357SAndroid Build Coastguard Worker UInt32 i;
1210*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < numItems; i++)
1211*f6dc9357SAndroid Build Coastguard Worker {
1212*f6dc9357SAndroid Build Coastguard Worker const UInt32 index = allFilesMode ? i : indices[i];
1213*f6dc9357SAndroid Build Coastguard Worker totalSize += (index < _segments.Size()) ?
1214*f6dc9357SAndroid Build Coastguard Worker _segments[index].Size :
1215*f6dc9357SAndroid Build Coastguard Worker _sections[index - _segments.Size()].GetSize();
1216*f6dc9357SAndroid Build Coastguard Worker }
1217*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->SetTotal(totalSize))
1218*f6dc9357SAndroid Build Coastguard Worker
1219*f6dc9357SAndroid Build Coastguard Worker totalSize = 0;
1220*f6dc9357SAndroid Build Coastguard Worker UInt64 currentItemSize;
1221*f6dc9357SAndroid Build Coastguard Worker
1222*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<ICompressCoder, NCompress::CCopyCoder> copyCoder;
1223*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
1224*f6dc9357SAndroid Build Coastguard Worker lps->Init(extractCallback, false);
1225*f6dc9357SAndroid Build Coastguard Worker CMyComPtr2_Create<ISequentialInStream, CLimitedSequentialInStream> inStream;
1226*f6dc9357SAndroid Build Coastguard Worker inStream->SetStream(_inStream);
1227*f6dc9357SAndroid Build Coastguard Worker
1228*f6dc9357SAndroid Build Coastguard Worker for (i = 0;; i++, totalSize += currentItemSize)
1229*f6dc9357SAndroid Build Coastguard Worker {
1230*f6dc9357SAndroid Build Coastguard Worker lps->InSize = lps->OutSize = totalSize;
1231*f6dc9357SAndroid Build Coastguard Worker RINOK(lps->SetCur())
1232*f6dc9357SAndroid Build Coastguard Worker if (i >= numItems)
1233*f6dc9357SAndroid Build Coastguard Worker break;
1234*f6dc9357SAndroid Build Coastguard Worker const Int32 askMode = testMode ?
1235*f6dc9357SAndroid Build Coastguard Worker NExtract::NAskMode::kTest :
1236*f6dc9357SAndroid Build Coastguard Worker NExtract::NAskMode::kExtract;
1237*f6dc9357SAndroid Build Coastguard Worker const UInt32 index = allFilesMode ? i : indices[i];
1238*f6dc9357SAndroid Build Coastguard Worker UInt64 offset;
1239*f6dc9357SAndroid Build Coastguard Worker if (index < _segments.Size())
1240*f6dc9357SAndroid Build Coastguard Worker {
1241*f6dc9357SAndroid Build Coastguard Worker const CSegment &item = _segments[index];
1242*f6dc9357SAndroid Build Coastguard Worker currentItemSize = item.Size;
1243*f6dc9357SAndroid Build Coastguard Worker offset = item.Offset;
1244*f6dc9357SAndroid Build Coastguard Worker }
1245*f6dc9357SAndroid Build Coastguard Worker else
1246*f6dc9357SAndroid Build Coastguard Worker {
1247*f6dc9357SAndroid Build Coastguard Worker const CSection &item = _sections[index - _segments.Size()];
1248*f6dc9357SAndroid Build Coastguard Worker currentItemSize = item.GetSize();
1249*f6dc9357SAndroid Build Coastguard Worker offset = item.Offset;
1250*f6dc9357SAndroid Build Coastguard Worker }
1251*f6dc9357SAndroid Build Coastguard Worker {
1252*f6dc9357SAndroid Build Coastguard Worker CMyComPtr<ISequentialOutStream> outStream;
1253*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->GetStream(index, &outStream, askMode))
1254*f6dc9357SAndroid Build Coastguard Worker if (!testMode && !outStream)
1255*f6dc9357SAndroid Build Coastguard Worker continue;
1256*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->PrepareOperation(askMode))
1257*f6dc9357SAndroid Build Coastguard Worker RINOK(InStream_SeekSet(_inStream, offset))
1258*f6dc9357SAndroid Build Coastguard Worker inStream->Init(currentItemSize);
1259*f6dc9357SAndroid Build Coastguard Worker RINOK(copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps))
1260*f6dc9357SAndroid Build Coastguard Worker }
1261*f6dc9357SAndroid Build Coastguard Worker RINOK(extractCallback->SetOperationResult(copyCoder->TotalSize == currentItemSize ?
1262*f6dc9357SAndroid Build Coastguard Worker NExtract::NOperationResult::kOK:
1263*f6dc9357SAndroid Build Coastguard Worker NExtract::NOperationResult::kDataError))
1264*f6dc9357SAndroid Build Coastguard Worker }
1265*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1266*f6dc9357SAndroid Build Coastguard Worker COM_TRY_END
1267*f6dc9357SAndroid Build Coastguard Worker }
1268*f6dc9357SAndroid Build Coastguard Worker
1269*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CHandler::AllowTail(Int32 allowTail))
1270*f6dc9357SAndroid Build Coastguard Worker {
1271*f6dc9357SAndroid Build Coastguard Worker _allowTail = IntToBool(allowTail);
1272*f6dc9357SAndroid Build Coastguard Worker return S_OK;
1273*f6dc9357SAndroid Build Coastguard Worker }
1274*f6dc9357SAndroid Build Coastguard Worker
1275*f6dc9357SAndroid Build Coastguard Worker static const Byte k_Signature[] = { 0x7F, 'E', 'L', 'F' };
1276*f6dc9357SAndroid Build Coastguard Worker
1277*f6dc9357SAndroid Build Coastguard Worker REGISTER_ARC_I(
1278*f6dc9357SAndroid Build Coastguard Worker "ELF", "elf", NULL, 0xDE,
1279*f6dc9357SAndroid Build Coastguard Worker k_Signature,
1280*f6dc9357SAndroid Build Coastguard Worker 0,
1281*f6dc9357SAndroid Build Coastguard Worker NArcInfoFlags::kPreArc,
1282*f6dc9357SAndroid Build Coastguard Worker NULL)
1283*f6dc9357SAndroid Build Coastguard Worker
1284*f6dc9357SAndroid Build Coastguard Worker }}
1285