Coverage Report

Created: 2025-11-15 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/upx/src/p_lx_elf.h
Line
Count
Source
1
/* p_lx_elf.h --
2
3
   This file is part of the UPX executable compressor.
4
5
   Copyright (C) 1996-2025 Markus Franz Xaver Johannes Oberhumer
6
   Copyright (C) 1996-2025 Laszlo Molnar
7
   Copyright (C) 2000-2025 John F. Reiser
8
   All Rights Reserved.
9
10
   UPX and the UCL library are free software; you can redistribute them
11
   and/or modify them under the terms of the GNU General Public License as
12
   published by the Free Software Foundation; either version 2 of
13
   the License, or (at your option) any later version.
14
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
20
   You should have received a copy of the GNU General Public License
21
   along with this program; see the file COPYING.
22
   If not, write to the Free Software Foundation, Inc.,
23
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25
   Markus F.X.J. Oberhumer              Laszlo Molnar
26
   <markus@oberhumer.com>               <ezerotven+github@gmail.com>
27
28
   John F. Reiser
29
   <jreiser@users.sourceforge.net>
30
 */
31
32
33
#pragma once
34
#ifndef __UPX_P_LX_ELF_H  //{
35
#define __UPX_P_LX_ELF_H 1
36
37
typedef upx_uint32_t u32_t;  // easier to type; more narrow
38
typedef upx_uint64_t u64_t;  // easier to type; more narrow
39
40
class PackLinuxElf : public PackUnix
41
{
42
    typedef PackUnix super;
43
public:
44
    PackLinuxElf(InputFile *f);
45
    virtual ~PackLinuxElf();
46
    /*virtual void buildLoader(const Filter *);*/
47
236k
    virtual int getVersion() const override { return 14; } // upx-3.96 cannot unpack, for instance
48
6.34k
    virtual bool canUnpackVersion(int version) const override { return (version >= 11); }
49
7.50k
    virtual tribool canUnpack() override { return super::canUnpack(); } // bool, except -1: format known, but not packed
50
51
protected:
52
    virtual const int *getCompressionMethods(int method, int level) const override;
53
54
    // All other virtual functions in this class must be pure virtual
55
    // because they depend on Elf32 or Elf64 data structures, which differ.
56
57
    virtual void pack1(OutputFile *, Filter &) override = 0;  // generate executable header
58
    virtual int  pack2(OutputFile *, Filter &) override = 0;  // append compressed data
59
    virtual off_t pack3(OutputFile *, Filter &) override = 0;  // append loader
60
    //virtual void pack4(OutputFile *, Filter &) override = 0;  // append pack header
61
62
    virtual unsigned pack2_shlib_overlay_init(OutputFile *fo);
63
    virtual unsigned pack2_shlib_overlay_compress(MemBuffer &obuf,
64
        upx_byte const *inp, unsigned u_len);
65
    virtual unsigned pack2_shlib_overlay_write(OutputFile *fo, MemBuffer &obuf,
66
        unsigned hdr_u_len, unsigned hdr_c_len);
67
68
    virtual void generateElfHdr(
69
        OutputFile *,
70
        void const *proto,
71
        unsigned const brka
72
    ) = 0;
73
    virtual void defineSymbols(Filter const *);
74
    virtual void addStubEntrySections(Filter const *, unsigned m_decompr);
75
    virtual void unpack(OutputFile *fo) override;
76
    unsigned old_data_off, old_data_len;  // un_shlib
77
78
    virtual upx_uint64_t elf_unsigned_dynamic(unsigned) const = 0;
79
    static unsigned elf_hash(char const *) /*const*/;
80
    static unsigned gnu_hash(char const *) /*const*/;
81
82
protected:
83
    static unsigned int const asl_delta = (1u<<12);  // --android-shlib extra page
84
    unsigned e_type;
85
    unsigned e_phnum;       /* Program header table entry count */
86
    unsigned e_shnum;
87
    unsigned e_shstrndx;
88
    MemBuffer file_image;   // if ET_DYN investigation
89
    MemBuffer lowmem;  // at least including PT_LOAD[0]
90
    MemBuffer mb_shdr;      // Shdr might not be near Phdr
91
    MemBuffer mb_dt_offsets;  // file offset of various DT_ tables
92
    unsigned *dt_offsets;  // index by dt_table[]
93
    unsigned symnum_max;
94
    unsigned strtab_max;
95
    char const *dynstr;   // from DT_STRTAB
96
97
    unsigned sz_phdrs;  // sizeof Phdr[]
98
    unsigned sz_elf_hdrs;  // all Elf headers
99
    unsigned sz_pack2;  // after pack2(), before loader
100
    unsigned sz_pack2a;  // after pack2() of all PT_LOAD
101
    unsigned lg2_page;  // log2(PAGE_SIZE)
102
    unsigned page_size;  // 1u<<lg2_page
103
    bool is_pie;  // is Position-Independent-Executable (ET_DYN main program)
104
    unsigned is_asl;  // is Android Shared Library
105
    unsigned xct_off;  // shared library: file offset of SHT_EXECINSTR
106
    unsigned hatch_off;  // file offset of escape hatch
107
    unsigned o_binfo;  // offset to first b_info
108
    upx_off_t so_slide;
109
    upx_uint64_t load_va;  // PT_LOAD[0].p_vaddr
110
    upx_uint64_t xct_va;  // minimum SHT_EXECINSTR virtual address
111
    upx_uint64_t jni_onload_va;  // runtime &JNI_OnLoad
112
    upx_uint64_t user_init_va;
113
    void *user_init_rp;  // Elf32_Rel *, Elf64_Rela *, ...
114
    upx_uint64_t plt_va, plt_off;
115
    unsigned user_init_off;  // within file_image
116
    unsigned linfo_off;
117
    unsigned loader_offset;  // during de-compression
118
119
    upx_uint16_t  e_machine;
120
    unsigned char ei_class;
121
    unsigned char ei_data;
122
    unsigned char ei_osabi;
123
    unsigned char prev_method;
124
    char const *osabi_note;
125
    unsigned upx_dt_init;  // DT_INIT, DT_PREINIT_ARRAY, DT_INIT_ARRAY
126
    static unsigned const DT_NUM = 34;  // elf.h
127
    unsigned dt_table[DT_NUM];  // 1+ index of DT_xxxxx in PT_DYNAMIC
128
129
    MemBuffer mb_shstrtab;   // via ElfXX_Shdr
130
    char const *shstrtab;
131
    MemBuffer jump_slots;  // is_asl de-compression fixing
132
    MemBuffer buildid_data;
133
    MemBuffer note_body;  // concatenated contents of PT_NOTEs, if any
134
    unsigned note_size;  // total size of PT_NOTEs
135
    int o_elf_shnum; // num output Shdrs
136
    static const unsigned char o_shstrtab[];
137
};
138
139
class PackLinuxElf32 : public PackLinuxElf
140
{
141
    typedef PackLinuxElf super;
142
public:
143
    PackLinuxElf32(InputFile *f);
144
    virtual ~PackLinuxElf32();
145
protected:
146
    virtual void PackLinuxElf32help1(InputFile *f);
147
    virtual int checkEhdr(Elf32_Ehdr const *ehdr) const;
148
    virtual bool canPackOSABI(Elf32_Ehdr const *);
149
    virtual tribool canPack() override;
150
    virtual tribool canUnpack() override; // bool, except -1: format known, but not packed
151
152
    // These ARM routines are essentially common to big/little endian,
153
    // but the class hierarchy splits after this class.
154
    virtual void ARM_defineSymbols(Filter const *ft);
155
    virtual void ARM_updateLoader(OutputFile *);
156
    virtual int  ARM_is_QNX(void);
157
158
    virtual upx_uint64_t canPack_Shdr(Elf32_Phdr const *pload_x0);
159
    virtual void pack1(OutputFile *, Filter &) override;  // generate executable header
160
    virtual void asl_pack2_Shdrs(OutputFile *, unsigned pre_xct_top);  // AndroidSharedLibrary processes Shdrs
161
    virtual void asl_slide_Shdrs();  // by so_slide if above xct_off
162
    virtual unsigned slide_sh_offset(Elf32_Shdr *shdr);
163
    virtual int  pack2(OutputFile *, Filter &) override;  // append compressed data
164
    virtual int  pack2_shlib(OutputFile *fo, Filter &ft, unsigned pre_xct_top);
165
    virtual off_t pack3(OutputFile *, Filter &) override;  // append loader
166
    virtual void pack4(OutputFile *, Filter &) override;  // append pack header
167
    virtual unsigned forward_Shdrs(OutputFile *fo, Elf32_Ehdr *ehdro);
168
    virtual void unpack(OutputFile *fo) override;
169
    virtual void un_asl_dynsym(unsigned orig_file_size, OutputFile *);
170
    virtual void un_shlib_1(
171
        OutputFile *const fo,
172
        MemBuffer &o_elfhdrs,
173
        unsigned &c_adler,
174
        unsigned &u_adler,
175
        unsigned const orig_file_size
176
    );
177
    virtual void un_DT_INIT(
178
        unsigned old_dtinit,
179
        Elf32_Phdr const *phdro,
180
        Elf32_Phdr const *dynhdr,  // in phdri
181
        OutputFile *fo
182
    );
183
    virtual void unRel32(unsigned dt_rel, Elf32_Rel *rel0, unsigned relsz,
184
        MemBuffer &membuf, unsigned const load_off, OutputFile *fo);
185
186
    virtual void generateElfHdr(
187
        OutputFile *,
188
        void const *proto,
189
        unsigned const brka
190
    ) override;
191
    virtual void defineSymbols(Filter const *) override;
192
    virtual void buildLinuxLoader(
193
        upx_byte const *const proto,  // assembly-only sections
194
        unsigned const szproto,
195
        upx_byte const *const fold,  // linked assembly + C section
196
        unsigned const szfold,
197
        Filter const *ft
198
    );
199
    virtual off_t getbrk(const Elf32_Phdr *phdr, int e_phnum) const;
200
    virtual void patchLoader() override;
201
    virtual void updateLoader(OutputFile *fo) override;
202
    virtual unsigned find_LOAD_gap(Elf32_Phdr const *const phdri, unsigned const k,
203
        unsigned const e_phnum);
204
    virtual off_t getbase(const Elf32_Phdr *phdr, int e_phnum) const;
205
    bool calls_crt1(Elf32_Rel const *rel, int sz);
206
207
    virtual Elf32_Sym const *elf_lookup(char const *) const;
208
    virtual unsigned elf_get_offset_from_address(unsigned) const;
209
    virtual unsigned elf_get_offset_from_Phdrs(unsigned, Elf32_Phdr const *phdr0) const;
210
    virtual Elf32_Phdr const *elf_find_Phdr_for_va(unsigned addr, Elf32_Phdr const *phdr, unsigned phnum);
211
    Elf32_Phdr const *elf_find_ptype(unsigned type, Elf32_Phdr const *phdr0, unsigned phnum);
212
    Elf32_Shdr const *elf_find_section_name(char const *) const;
213
    Elf32_Shdr       *elf_find_section_type(unsigned) const;
214
    Elf32_Dyn        *elf_find_dynptr(unsigned) const;
215
    unsigned elf_find_table_size(unsigned dt_type, unsigned sh_type);
216
    void sort_DT32_offsets(Elf32_Dyn const *const dynp0);
217
218
    int is_LOAD(Elf32_Phdr const *phdr) const;  // beware confusion with (1+ LO_PROC)
219
    unsigned check_pt_load(Elf32_Phdr const *);
220
    unsigned check_pt_dynamic(Elf32_Phdr const *);
221
    void invert_pt_dynamic(Elf32_Dyn const *, unsigned dt_filesz);
222
    void *elf_find_dynamic(unsigned) const;
223
    Elf32_Dyn const *elf_has_dynamic(unsigned) const;
224
    virtual upx_uint64_t elf_unsigned_dynamic(unsigned) const override;
225
    unsigned find_dt_ndx(unsigned rva);
226
    virtual int adjABS(Elf32_Sym *sym, unsigned delta);
227
    void add_phdrx(Elf32_Phdr const *);
228
229
    char const *get_str_name(unsigned st_name, unsigned symnum) const;
230
    char const *get_dynsym_name(unsigned symnum, unsigned relnum) const;
231
protected:
232
    Elf32_Ehdr  ehdri; // from input file
233
    Elf32_Phdr *phdri; // for  input file
234
    Elf32_Shdr *shdri; // from input file
235
    Elf32_Shdr *shdro; // for  output file
236
    static unsigned const END_PHDRX = 5;
237
    Elf32_Phdr const *phdrx[END_PHDRX];  // "extra" arch-specific Phdr
238
    unsigned n_phdrx;  // number actually used
239
    unsigned sz_phdrx;  // total size of bodies
240
    unsigned e_phoff;
241
    unsigned e_shoff;
242
    unsigned sz_dynseg;  // PT_DYNAMIC.p_memsz
243
    unsigned n_jmp_slot;
244
    unsigned plt_off;
245
    unsigned page_mask;  // AND clears the offset-within-page
246
247
    Elf32_Dyn          *dynseg;   // from PT_DYNAMIC
248
    unsigned int const *hashtab, *hashend;  // from DT_HASH
249
    unsigned int const *gashtab, *gashend;  // from DT_GNU_HASH
250
    Elf32_Sym          *dynsym;   // DT_SYMTAB; 'const' except [0] for decompressor
251
    Elf32_Sym    const *jni_onload_sym;
252
253
    Elf32_Shdr       *sec_strndx;
254
    Elf32_Shdr const *sec_dynsym;
255
    Elf32_Shdr const *sec_dynstr;
256
    Elf32_Shdr       *sec_arm_attr;  // SHT_ARM_ATTRIBUTES;
257
258
    packed_struct(cprElfHdr1) {
259
        Elf32_Ehdr ehdr;
260
        Elf32_Phdr phdr[1];
261
        l_info linfo;
262
    };
263
264
    packed_struct(cprElfHdr2) {
265
        Elf32_Ehdr ehdr;
266
        Elf32_Phdr phdr[2];
267
        l_info linfo;
268
    };
269
270
    packed_struct(cprElfHdr3) {
271
        Elf32_Ehdr ehdr;
272
        Elf32_Phdr phdr[3];
273
        l_info linfo;
274
    };
275
276
    packed_struct(cprElfHdr4) {
277
        Elf32_Ehdr ehdr;
278
        Elf32_Phdr phdr[4];
279
        l_info linfo;
280
    };
281
282
    packed_struct(cprElfHdrNetBSD) {
283
        Elf32_Ehdr ehdr;
284
        Elf32_Phdr phdr[4];
285
        unsigned char notes[512];
286
    };
287
288
    cprElfHdrNetBSD elfout;
289
290
    packed_struct(cprElfShdr3) {
291
        Elf32_Shdr shdr[3];
292
    };
293
294
    cprElfShdr3 shdrout;
295
296
    struct Elf32_Nhdr {
297
        unsigned namesz;
298
        unsigned descsz;
299
        unsigned type;
300
        //unsigned char body[0];
301
    };
302
303
0
    static void compileTimeAssertions() {
304
0
        COMPILE_TIME_ASSERT(sizeof(cprElfHdr1) == 52 + 1*32 + 12)
305
0
        COMPILE_TIME_ASSERT(sizeof(cprElfHdr2) == 52 + 2*32 + 12)
306
0
        COMPILE_TIME_ASSERT(sizeof(cprElfHdr3) == 52 + 3*32 + 12)
307
0
        COMPILE_TIME_ASSERT(sizeof(cprElfHdrNetBSD) == 52 + 4*32 + 512)
308
0
        COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr1)
309
0
        COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr2)
310
0
        COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr3)
311
0
        COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdrNetBSD)
312
0
    }
313
};
314
315
316
class PackLinuxElf64 : public PackLinuxElf
317
{
318
    typedef PackLinuxElf super;
319
public:
320
    PackLinuxElf64(InputFile *f);
321
    virtual ~PackLinuxElf64();
322
    /*virtual void buildLoader(const Filter *);*/
323
324
protected:
325
    virtual void PackLinuxElf64help1(InputFile *f);
326
    virtual int checkEhdr(Elf64_Ehdr const *ehdr) const;
327
    virtual tribool canPack() override;
328
    virtual tribool canUnpack() override; // bool, except -1: format known, but not packed
329
330
    virtual upx_uint64_t canPack_Shdr(Elf64_Phdr const *pload_x0);
331
    virtual void pack1(OutputFile *, Filter &) override;  // generate executable header
332
    virtual void asl_pack2_Shdrs(OutputFile *, unsigned pre_xct_top);  // AndroidSharedLibrary processes Shdrs
333
    virtual void asl_slide_Shdrs();  // by so_slide if above xct_off
334
    virtual unsigned slide_sh_offset(Elf64_Shdr *shdr);
335
    virtual int  pack2(OutputFile *, Filter &) override;  // append compressed data
336
    virtual int  pack2_shlib(OutputFile *fo, Filter &ft, unsigned pre_xct_top);
337
    virtual off_t pack3(OutputFile *, Filter &) override;  // append loader
338
    virtual void pack4(OutputFile *, Filter &) override;  // append pack header
339
    virtual unsigned forward_Shdrs(OutputFile *fo, Elf64_Ehdr *ehdro);
340
    virtual void unpack(OutputFile *fo) override;
341
    virtual void un_asl_dynsym(unsigned orig_file_size, OutputFile *);
342
    virtual void un_shlib_1(
343
        OutputFile *const fo,
344
        MemBuffer &o_elfhdrs,
345
        unsigned &c_adler,
346
        unsigned &u_adler,
347
        unsigned const orig_file_size
348
    );
349
    virtual void un_DT_INIT(
350
        unsigned old_dtinit,
351
        Elf64_Phdr const *phdro,
352
        Elf64_Phdr const *dynhdr,  // in phdri
353
        OutputFile *fo
354
    );
355
    virtual void unRela64(upx_uint64_t dt_rela, Elf64_Rela *rela0, unsigned relasz,
356
        upx_uint64_t const old_dtinit, OutputFile *fo);
357
358
    virtual void generateElfHdr(
359
        OutputFile *,
360
        void const *proto,
361
        unsigned const brka
362
    ) override;
363
    virtual void defineSymbols(Filter const *) override;
364
    virtual void buildLinuxLoader(
365
        upx_byte const *const proto,  // assembly-only sections
366
        unsigned const szproto,
367
        upx_byte const *const fold,  // linked assembly + C section
368
        unsigned const szfold,
369
        Filter const *ft
370
    );
371
    virtual off_t getbrk(const Elf64_Phdr *phdr, int e_phnum) const;
372
    virtual void patchLoader() override;
373
    virtual void updateLoader(OutputFile *fo) override;
374
    virtual unsigned find_LOAD_gap(Elf64_Phdr const *const phdri, unsigned const k,
375
        unsigned const e_phnum);
376
    bool calls_crt1(Elf64_Rela const *rela, int sz);
377
378
    virtual Elf64_Sym const *elf_lookup(char const *) const;
379
    virtual upx_uint64_t elf_get_offset_from_address(upx_uint64_t) const;
380
    virtual Elf64_Phdr const *elf_find_Phdr_for_va(upx_uint64_t addr, Elf64_Phdr const *phdr, unsigned phnum);
381
    Elf64_Phdr const *elf_find_ptype(unsigned type, Elf64_Phdr const *phdr0, unsigned phnum);
382
    Elf64_Shdr const *elf_find_section_name(char const *) const;
383
    Elf64_Shdr       *elf_find_section_type(unsigned) const;
384
    Elf64_Dyn        *elf_find_dynptr(unsigned) const;
385
    unsigned elf_find_table_size(unsigned dt_type, unsigned sh_type);
386
    void sort_DT64_offsets(Elf64_Dyn const *const dynp0);
387
    int is_LOAD(Elf64_Phdr const *phdr) const;  // beware confusion with (1+ LO_PROC)
388
    upx_uint64_t check_pt_load(Elf64_Phdr const *);
389
    upx_uint64_t check_pt_dynamic(Elf64_Phdr const *);
390
    void invert_pt_dynamic(Elf64_Dyn const *, upx_uint64_t dt_filesz);
391
    void *elf_find_dynamic(unsigned) const;
392
    Elf64_Dyn const *elf_has_dynamic(unsigned) const;
393
    virtual upx_uint64_t elf_unsigned_dynamic(unsigned) const override;
394
    unsigned find_dt_ndx(u64_t rva);
395
    virtual int adjABS(Elf64_Sym *sym, unsigned long delta);
396
    void add_phdrx(Elf64_Phdr const *);
397
398
    char const *get_str_name(unsigned st_name, unsigned symnum) const;
399
    char const *get_dynsym_name(unsigned symnum, unsigned relnum) const;
400
protected:
401
    Elf64_Ehdr  ehdri; // from input file
402
    Elf64_Phdr *phdri; // for  input file
403
    Elf64_Shdr *shdri; // from input file
404
    Elf64_Shdr *shdro; // for  output file
405
    static unsigned const END_PHDRX = 5;
406
    Elf64_Phdr const *phdrx[END_PHDRX];  // "extra" arch-specific Phdr
407
    unsigned n_phdrx;  // number actually used
408
    unsigned sz_phdrx;  // total size of bodies
409
    upx_uint64_t e_phoff;
410
    upx_uint64_t e_shoff;
411
    upx_uint64_t sz_dynseg;  // PT_DYNAMIC.p_memsz
412
    unsigned n_jmp_slot;
413
    upx_uint64_t page_mask;  // AND clears the offset-within-page
414
415
    Elf64_Dyn          *dynseg;   // from PT_DYNAMIC
416
    unsigned int const *hashtab, *hashend;  // from DT_HASH
417
    unsigned int const *gashtab, *gashend;  // from DT_GNU_HASH
418
    Elf64_Sym          *dynsym;   // DT_SYMTAB; 'const' except [0] for decompressor
419
    Elf64_Sym    const *jni_onload_sym;
420
421
    Elf64_Shdr       *sec_strndx;
422
    Elf64_Shdr       *sec_dynsym;
423
    Elf64_Shdr const *sec_dynstr;
424
    Elf64_Shdr       *sec_arm_attr;  // SHT_ARM_ATTRIBUTES;
425
426
    packed_struct(cprElfHdr1) {
427
        Elf64_Ehdr ehdr;
428
        Elf64_Phdr phdr[1];
429
        l_info linfo;
430
    };
431
432
    packed_struct(cprElfHdr2) {
433
        Elf64_Ehdr ehdr;
434
        Elf64_Phdr phdr[2];
435
        l_info linfo;
436
    };
437
438
    packed_struct(cprElfHdr3) {
439
        Elf64_Ehdr ehdr;
440
        Elf64_Phdr phdr[3];
441
        l_info linfo;
442
    };
443
444
    packed_struct(cprElfHdr4) {
445
        Elf64_Ehdr ehdr;
446
        Elf64_Phdr phdr[4];
447
        l_info linfo;
448
    };
449
450
    cprElfHdr4 elfout;
451
452
    packed_struct(cprElfShdr3) {
453
        Elf64_Shdr shdr[3];
454
    };
455
456
    cprElfShdr3 shdrout;
457
458
0
    static void compileTimeAssertions() {
459
0
        COMPILE_TIME_ASSERT(sizeof(cprElfHdr1) == 64 + 1*56 + 12)
460
0
        COMPILE_TIME_ASSERT(sizeof(cprElfHdr2) == 64 + 2*56 + 12)
461
0
        COMPILE_TIME_ASSERT(sizeof(cprElfHdr3) == 64 + 3*56 + 12)
462
0
        COMPILE_TIME_ASSERT(sizeof(cprElfHdr4) == 64 + 4*56 + 12)
463
0
        COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr1)
464
0
        COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr2)
465
0
        COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr3)
466
0
        COMPILE_TIME_ASSERT_ALIGNED1(cprElfHdr4)
467
0
    }
468
};
469
470
class PackLinuxElf32Be : public PackLinuxElf32
471
{
472
    typedef PackLinuxElf32 super;
473
protected:
474
48.8k
    PackLinuxElf32Be(InputFile *f) : super(f) {
475
48.8k
        bele = &N_BELE_RTP::be_policy;
476
48.8k
        PackLinuxElf32help1(f);
477
48.8k
    }
478
};
479
480
class PackLinuxElf32Le : public PackLinuxElf32
481
{
482
    typedef PackLinuxElf32 super;
483
protected:
484
120k
    PackLinuxElf32Le(InputFile *f) : super(f) {
485
120k
        bele = &N_BELE_RTP::le_policy;
486
120k
        PackLinuxElf32help1(f);
487
120k
    }
488
};
489
490
class PackLinuxElf64Le : public PackLinuxElf64
491
{
492
    typedef PackLinuxElf64 super;
493
protected:
494
51.8k
    PackLinuxElf64Le(InputFile *f) : super(f) {
495
51.8k
        lg2_page=16;
496
51.8k
        page_size=1u<<lg2_page;
497
51.8k
        bele = &N_BELE_RTP::le_policy;
498
51.8k
        PackLinuxElf64help1(f);
499
51.8k
    }
500
};
501
502
class PackLinuxElf64Be : public PackLinuxElf64
503
{
504
    typedef PackLinuxElf64 super;
505
protected:
506
16.0k
    PackLinuxElf64Be(InputFile *f) : super(f) {
507
16.0k
        lg2_page=16;
508
16.0k
        page_size=1u<<lg2_page;
509
16.0k
        bele = &N_BELE_RTP::be_policy;
510
16.0k
        PackLinuxElf64help1(f);
511
16.0k
    }
512
};
513
514
515
/*************************************************************************
516
// linux/elf64amd
517
**************************************************************************/
518
519
class PackLinuxElf64amd : public PackLinuxElf64Le
520
{
521
    typedef PackLinuxElf64Le super;
522
public:
523
    PackLinuxElf64amd(InputFile *f);
524
    virtual ~PackLinuxElf64amd();
525
19.9k
    virtual int getFormat() const override { return UPX_F_LINUX_ELF64_AMD64; }
526
8
    virtual const char *getName() const override { return "linux/amd64"; }
527
0
    virtual const char *getFullName(const options_t *) const override { return "amd64-linux.elf"; }
528
    virtual const int *getFilters() const override;
529
protected:
530
    virtual void pack1(OutputFile *, Filter &) override;  // generate executable header
531
    virtual void buildLoader(const Filter *) override;
532
    virtual Linker* newLinker() const override;
533
    virtual void defineSymbols(Filter const *) override;
534
};
535
536
class PackLinuxElf64arm : public PackLinuxElf64Le
537
{
538
    typedef PackLinuxElf64Le super;
539
public:
540
    PackLinuxElf64arm(InputFile *f);
541
    virtual ~PackLinuxElf64arm();
542
16.4k
    virtual int getFormat() const override { return UPX_F_LINUX_ELF64_ARM64; }
543
7
    virtual const char *getName() const override { return "linux/arm64"; }
544
0
    virtual const char *getFullName(const options_t *) const override { return "arm64-linux.elf"; }
545
    virtual const int *getFilters() const override;
546
protected:
547
    virtual void pack1(OutputFile *, Filter &) override;  // generate executable header
548
    virtual void buildLoader(const Filter *) override;
549
    virtual Linker* newLinker() const override;
550
    virtual void defineSymbols(Filter const *) override;
551
};
552
553
554
/*************************************************************************
555
// linux/elf32ppc
556
**************************************************************************/
557
558
class PackLinuxElf32ppc : public PackLinuxElf32Be
559
{
560
    typedef PackLinuxElf32Be super;
561
public:
562
    PackLinuxElf32ppc(InputFile *f);
563
    virtual ~PackLinuxElf32ppc();
564
16.3k
    virtual int getFormat() const override { return UPX_F_LINUX_ELF32_PPC32; }
565
5
    virtual const char *getName() const override { return "linux/ppc32"; }
566
0
    virtual const char *getFullName(const options_t *) const override { return "powerpc-linux.elf"; }
567
    virtual const int *getFilters() const override;
568
protected:
569
    virtual void pack1(OutputFile *, Filter &) override;  // generate executable header
570
    virtual void buildLoader(const Filter *) override;
571
    virtual Linker* newLinker() const override;
572
};
573
574
/*************************************************************************
575
// linux/elf64ppcle
576
**************************************************************************/
577
578
class PackLinuxElf64ppcle : public PackLinuxElf64Le
579
{
580
    typedef PackLinuxElf64Le super;
581
public:
582
    PackLinuxElf64ppcle(InputFile *f);
583
    virtual ~PackLinuxElf64ppcle();
584
14.3k
    virtual int getFormat() const override { return UPX_F_LINUX_ELF64_PPC64LE; }
585
4
    virtual const char *getName() const override { return "linux/ppc64le"; }
586
0
    virtual const char *getFullName(const options_t *) const override { return "powerpc64le-linux.elf"; }
587
    virtual const int *getFilters() const override;
588
protected:
589
    unsigned lg2_page;  // log2(PAGE_SIZE)
590
    unsigned page_size;  // 1u<<lg2_page
591
    virtual void pack1(OutputFile *, Filter &) override;  // generate executable header
592
    virtual void buildLoader(const Filter *) override;
593
    virtual Linker* newLinker() const override;
594
};
595
596
597
class PackLinuxElf64ppc : public PackLinuxElf64Be
598
{
599
    typedef PackLinuxElf64Be super;
600
public:
601
    PackLinuxElf64ppc(InputFile *f);
602
    virtual ~PackLinuxElf64ppc();
603
14.3k
    virtual int getFormat() const override { return UPX_F_LINUX_ELF64_PPC64; }
604
2
    virtual const char *getName() const override { return "linux/ppc64"; }
605
0
    virtual const char *getFullName(const options_t *) const override { return "powerpc64-linux.elf"; }
606
    virtual const int *getFilters() const override;
607
protected:
608
    unsigned lg2_page;  // log2(PAGE_SIZE)
609
    unsigned page_size;  // 1u<<lg2_page
610
    virtual void pack1(OutputFile *, Filter &) override;  // generate executable header
611
    virtual void buildLoader(const Filter *) override;
612
    virtual Linker* newLinker() const override;
613
};
614
615
616
/*************************************************************************
617
// linux/elf386
618
**************************************************************************/
619
620
class PackLinuxElf32x86 : public PackLinuxElf32Le
621
{
622
    typedef PackLinuxElf32Le super;
623
public:
624
    PackLinuxElf32x86(InputFile *f);
625
    virtual ~PackLinuxElf32x86();
626
22.8k
    virtual int getFormat() const override { return UPX_F_LINUX_ELF_i386; }
627
7
    virtual const char *getName() const override { return "linux/i386"; }
628
0
    virtual const char *getFullName(const options_t *) const override { return "i386-linux.elf"; }
629
    virtual const int *getFilters() const override;
630
    virtual tribool canUnpack() override; // bool, except -1: format known, but not packed
631
632
protected:
633
    virtual void pack1(OutputFile *, Filter &) override;  // generate executable header
634
635
    virtual void buildLoader(const Filter *) override;
636
    virtual void addStubEntrySections(Filter const *, unsigned m_decompr) override;
637
    virtual Linker* newLinker() const override;
638
    virtual void defineSymbols(Filter const *) override;
639
};
640
641
class PackBSDElf32x86 : public PackLinuxElf32x86
642
{
643
    typedef PackLinuxElf32x86 super;
644
public:
645
    PackBSDElf32x86(InputFile *f);
646
    virtual ~PackBSDElf32x86();
647
    virtual int getFormat() const override = 0;
648
    virtual const char *getName() const override = 0;
649
    virtual const char *getFullName(const options_t *) const override = 0;
650
651
protected:
652
    virtual void pack1(OutputFile *, Filter &) override;  // generate executable header
653
654
    virtual void buildLoader(const Filter *) override;
655
};
656
657
class PackFreeBSDElf32x86 : public PackBSDElf32x86
658
{
659
    typedef PackBSDElf32x86 super;
660
public:
661
    PackFreeBSDElf32x86(InputFile *f);
662
    virtual ~PackFreeBSDElf32x86();
663
22.9k
    virtual int getFormat() const override { return UPX_F_BSD_ELF_i386; }
664
0
    virtual const char *getName() const override { return "freebsd/i386"; }
665
0
    virtual const char *getFullName(const options_t *) const override { return "i386-freebsd.elf"; }
666
};
667
668
class PackNetBSDElf32x86 : public PackLinuxElf32x86
669
{
670
    typedef PackLinuxElf32x86 super;
671
public:
672
    PackNetBSDElf32x86(InputFile *f);
673
    virtual ~PackNetBSDElf32x86();
674
22.8k
    virtual int getFormat() const override { return UPX_F_BSD_ELF_i386; }
675
0
    virtual const char *getName() const override { return "netbsd/i386"; }
676
0
    virtual const char *getFullName(const options_t *) const override { return "i386-netbsd.elf"; }
677
protected:
678
    virtual void buildLoader(const Filter *ft) override;
679
    virtual void generateElfHdr(
680
        OutputFile *,
681
        void const *proto,
682
        unsigned const brka
683
    ) override;
684
};
685
686
class PackOpenBSDElf32x86 : public PackBSDElf32x86
687
{
688
    typedef PackBSDElf32x86 super;
689
public:
690
    PackOpenBSDElf32x86(InputFile *f);
691
    virtual ~PackOpenBSDElf32x86();
692
22.8k
    virtual int getFormat() const override { return UPX_F_BSD_ELF_i386; }
693
0
    virtual const char *getName() const override { return "openbsd/i386"; }
694
0
    virtual const char *getFullName(const options_t *) const override { return "i386-openbsd.elf"; }
695
696
protected:
697
    virtual void buildLoader(const Filter *ft) override;
698
    virtual void generateElfHdr(
699
        OutputFile *,
700
        void const *proto,
701
        unsigned const brka
702
    ) override;
703
};
704
705
706
/*************************************************************************
707
// linux/elfarm
708
**************************************************************************/
709
710
class PackLinuxElf32armLe : public PackLinuxElf32Le
711
{
712
    typedef PackLinuxElf32Le super;
713
public:
714
    PackLinuxElf32armLe(InputFile *f);
715
    virtual ~PackLinuxElf32armLe();
716
18.5k
    virtual int getFormat() const override { return UPX_F_LINUX_ELF32_ARM; }
717
2
    virtual const char *getName() const override { return "linux/arm"; }
718
0
    virtual const char *getFullName(const options_t *) const override { return "arm-linux.elf"; }
719
    virtual const int *getFilters() const override;
720
721
protected:
722
    virtual const int *getCompressionMethods(int method, int level) const override;
723
    virtual Linker* newLinker() const override;
724
    virtual void pack1(OutputFile *, Filter &) override;  // generate executable header
725
    virtual void buildLoader(const Filter *) override;
726
    virtual void updateLoader(OutputFile *) override;
727
    virtual void defineSymbols(Filter const *) override;
728
};
729
730
class PackLinuxElf32armBe : public PackLinuxElf32Be
731
{
732
    typedef PackLinuxElf32Be super;
733
public:
734
    PackLinuxElf32armBe(InputFile *f);
735
    virtual ~PackLinuxElf32armBe();
736
16.7k
    virtual int getFormat() const override { return UPX_F_LINUX_ELF32_ARMEB; }
737
4
    virtual const char *getName() const override { return "linux/armeb"; }
738
0
    virtual const char *getFullName(const options_t *) const override { return "armeb-linux.elf"; }
739
    virtual const int *getFilters() const override;
740
741
protected:
742
    virtual const int *getCompressionMethods(int method, int level) const override;
743
    virtual Linker* newLinker() const override;
744
    virtual void pack1(OutputFile *, Filter &) override;  // generate executable header
745
    virtual void buildLoader(const Filter *) override;
746
    virtual void updateLoader(OutputFile *) override;
747
    virtual void defineSymbols(Filter const *) override;
748
};
749
750
class PackLinuxElf32mipseb : public PackLinuxElf32Be
751
{
752
    typedef PackLinuxElf32Be super;
753
public:
754
    PackLinuxElf32mipseb(InputFile *f);
755
    virtual ~PackLinuxElf32mipseb();
756
14.1k
    virtual int getFormat() const override { return UPX_F_LINUX_ELF32_MIPS; }
757
3
    virtual const char *getName() const override { return "linux/mips"; }
758
0
    virtual const char *getFullName(const options_t *) const override { return "mips-linux.elf"; }
759
    virtual const int *getFilters() const override;
760
761
protected:
762
    virtual Linker* newLinker() const override;
763
    virtual void pack1(OutputFile *, Filter &) override;  // generate executable header
764
    virtual void buildLoader(const Filter *) override;
765
    virtual void updateLoader(OutputFile *) override;
766
    virtual void defineSymbols(Filter const *) override;
767
};
768
769
class PackLinuxElf32mipsel : public PackLinuxElf32Le
770
{
771
    typedef PackLinuxElf32Le super;
772
public:
773
    PackLinuxElf32mipsel(InputFile *f);
774
    virtual ~PackLinuxElf32mipsel();
775
14.2k
    virtual int getFormat() const override { return UPX_F_LINUX_ELF32_MIPSEL; }
776
5
    virtual const char *getName() const override { return "linux/mipsel"; }
777
0
    virtual const char *getFullName(const options_t *) const override { return "mipsel-linux.elf"; }
778
    virtual const int *getFilters() const override;
779
780
protected:
781
    virtual Linker* newLinker() const override;
782
    virtual void pack1(OutputFile *, Filter &) override;  // generate executable header
783
    virtual void buildLoader(const Filter *) override;
784
    virtual void updateLoader(OutputFile *) override;
785
    virtual void defineSymbols(Filter const *) override;
786
};
787
788
789
#endif /*} already included */
790
791
/* vim:set ts=4 sw=4 et: */