vmlinux/i386: fix filters, 0x400000 start, integration with kernel build
This commit is contained in:
parent
b31b8cd7f0
commit
6891bc3da3
118
src/p_vmlinx.cpp
118
src/p_vmlinx.cpp
@ -65,11 +65,22 @@ const int *PackVmlinuxI386::getCompressionMethods(int method, int level) const
|
||||
const int *PackVmlinuxI386::getFilters() const
|
||||
{
|
||||
static const int filters[] = {
|
||||
0x49,
|
||||
0x49, 0x46,
|
||||
-1 };
|
||||
return filters;
|
||||
}
|
||||
|
||||
// copied from PackUnix 2006-10-13.
|
||||
int PackVmlinuxI386::getStrategy(Filter &/*ft*/)
|
||||
{
|
||||
// Called just before reading and compressing each block.
|
||||
// Might want to adjust blocksize, etc.
|
||||
|
||||
// If user specified the filter, then use it (-2==strategy).
|
||||
// Else try the first two filters, and pick the better (2==strategy).
|
||||
return (opt->no_filter ? -3 : ((opt->filter > 0) ? -2 : 2));
|
||||
}
|
||||
|
||||
static int __acc_cdecl_qsort
|
||||
compare_Phdr(void const *aa, void const *bb)
|
||||
{
|
||||
@ -102,6 +113,12 @@ compare_Phdr(void const *aa, void const *bb)
|
||||
// LOAD 0x249000 0x02348000 0x02348000 0x81800 0xcb0fc RWE 0x1000
|
||||
// STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4
|
||||
//
|
||||
//----- kernel-2.6.18-1.2778 Fedora Core 6 test 3
|
||||
//Program Headers(3)
|
||||
// Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
|
||||
// LOAD 0x001000 0xc0400000 0x00400000 0x279820 0x279820 R E 0x1000
|
||||
// LOAD 0x27b000 0xc067a000 0x0067a000 0x10ee64 0x1b07e8 RWE 0x1000
|
||||
// NOTE 0x000000 0x00000000 0x00000000 0x00000 0x00000 R 0x4
|
||||
|
||||
bool PackVmlinuxI386::canPack()
|
||||
{
|
||||
@ -121,7 +138,7 @@ bool PackVmlinuxI386::canPack()
|
||||
|| ehdri.e_phoff != sizeof(ehdri) // Phdrs not contiguous with Ehdr
|
||||
|| ehdri.e_phentsize!=sizeof(Elf32_Phdr)
|
||||
|| ehdri.e_type!=Elf32_Ehdr::ET_EXEC
|
||||
|| 0x00100000!=(0x001fffff & ehdri.e_entry) // entry not an odd 1MB
|
||||
|| 0!=(0x000fffff & ehdri.e_entry) // entry not on whole 1MB
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
@ -190,8 +207,10 @@ int PackVmlinuxI386::buildLoader(const Filter *ft)
|
||||
|
||||
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||
{
|
||||
if (ft->id == 0)
|
||||
if (ft->id == 0) {
|
||||
linker->defineSymbol("filter_length", 0);
|
||||
return false;
|
||||
}
|
||||
assert(ft->calls > 0);
|
||||
|
||||
linker->defineSymbol("filter_cto", ft->cto);
|
||||
@ -245,7 +264,7 @@ void PackVmlinuxI386::pack(OutputFile *fo)
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
// limit stack size needed for runtime decompression
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||
compressWithFilters(&ft, 512, 0, NULL, &cconf);
|
||||
compressWithFilters(&ft, 512, getStrategy(ft), getFilters(), &cconf);
|
||||
|
||||
const unsigned lsize = getLoaderSize();
|
||||
|
||||
@ -268,11 +287,23 @@ void PackVmlinuxI386::pack(OutputFile *fo)
|
||||
shdro[1].sh_size = 1+ 4+ ph.c_len + lsize;
|
||||
shdro[1].sh_addralign = 1;
|
||||
|
||||
unsigned char const call = 0xE8; // opcode for CALL d32
|
||||
fo->write(&call, 1); fo_off+=1;
|
||||
tmp_le32 = ph.c_len; fo->write(&tmp_le32, 4); fo_off += 4;
|
||||
fo->write(obuf, ph.c_len); fo_off += ph.c_len;
|
||||
fo->write(loader, lsize); fo_off += lsize;
|
||||
{
|
||||
static const
|
||||
#include "stub/i386-linux.kernel.head-vmlinux.h"
|
||||
|
||||
// ENTRY_POINT
|
||||
fo->write(&head_stack[0], sizeof(head_stack)-2*(1+ 4) +1);
|
||||
tmp_le32 = ehdri.e_entry; fo->write(&tmp_le32, 4);
|
||||
|
||||
// COMPRESSED_LENGTH
|
||||
fo->write(&head_stack[sizeof(head_stack)-(1+ 4)], 1);
|
||||
tmp_le32 = ph.c_len; fo->write(&tmp_le32, 4);
|
||||
|
||||
fo_off += sizeof(head_stack);
|
||||
|
||||
fo->write(obuf, ph.c_len); fo_off += ph.c_len;
|
||||
fo->write(loader, lsize); fo_off += lsize;
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("%-13s: compressed : %8u bytes\n", getName(), ph.c_len);
|
||||
@ -495,7 +526,7 @@ void PackVmlinuxI386::unpack(OutputFile *fo)
|
||||
}
|
||||
|
||||
//
|
||||
// Example usage within build system of Linux kernel-2.6.7:
|
||||
// Example usage within build system of Linux kernel-2.6.18:
|
||||
//
|
||||
//----- arch/i386/boot/compressed/Makefile
|
||||
//#
|
||||
@ -507,7 +538,6 @@ void PackVmlinuxI386::unpack(OutputFile *fo)
|
||||
//targets := vmlinux upx-head.o upx-piggy.o
|
||||
//
|
||||
//LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32
|
||||
//EXTRA_AFLAGS += -DIMAGE_OFFSET=$(IMAGE_OFFSET)
|
||||
//
|
||||
//$(obj)/vmlinux: $(obj)/upx-head.o $(obj)/upx-piggy.o FORCE
|
||||
// $(call if_changed,ld)
|
||||
@ -517,44 +547,42 @@ void PackVmlinuxI386::unpack(OutputFile *fo)
|
||||
// rm -f $@
|
||||
// upx --best -o $@ $<
|
||||
// touch $@
|
||||
//
|
||||
//#
|
||||
//# The ORIGINAL build sequence using gzip is:
|
||||
//# vmlinux Elf executable at top level in tree
|
||||
//# (in same directory as MAINTAINERS)
|
||||
//# In arch/i386:
|
||||
//# boot/compressed/vmlinux.bin by objcopy -O binary
|
||||
//# boot/compressed/vmlinux.bin.gz by gzip
|
||||
//# boot/compressed/piggy.o by ld --format binary --oformat elf32-i386
|
||||
//#
|
||||
//# The 3 steps above create a linkable
|
||||
//# compressed blob.
|
||||
//# In arch/i386:
|
||||
//# boot/compressed/vmlinux by ld head.o misc.o piggy.o
|
||||
//# boot/vmlinux.bin by objcopy
|
||||
//# boot/bzImage by arch/i386/boot/tools/build with
|
||||
//# bootsect and setup
|
||||
//#
|
||||
//#
|
||||
//# The MODIFIED build sequence using upx is:
|
||||
//# vmlinux Elf executable at top level in tree
|
||||
//# (in same directory as MAINTAINERS)
|
||||
//# In arch/i386:
|
||||
//# boot/compressed/upx-piggy.o by upx format vmlinux/386
|
||||
//#
|
||||
//# In arch/i386/boot:
|
||||
//# boot/compressed/vmlinux by ld upx-head.o upx-piggy.o
|
||||
//# boot/vmlinux.bin by objcopy
|
||||
//# boot/bzImage by arch/i386/boot/tools/build with
|
||||
//# bootsect and setup
|
||||
//#
|
||||
//-----
|
||||
//
|
||||
//----- arch/i386/boot/compressed/upx-head.S
|
||||
// .text
|
||||
//startup_32: .globl startup_32 # In: %esi=0x90000 setup data "real_mode pointer"
|
||||
// #cli # this must be true already
|
||||
//
|
||||
// /* The only facts about segments here, that are true for all kernels:
|
||||
// * %cs is a valid "flat" code segment; no other segment reg is valid;
|
||||
// * the next segment after %cs is a valid "flat" data segment, but
|
||||
// * no segment register designates it yet.
|
||||
// */
|
||||
// movl %cs,%eax; addl $1<<3,%eax # the next segment after %cs
|
||||
// movl %eax,%ds
|
||||
// movl %eax,%es
|
||||
// leal 0x9000(%esi),%ecx # 0x99000 typical
|
||||
// movl %ecx,-8(%ecx) # 32-bit offset for stack pointer
|
||||
// movl %eax,-4(%ecx) # segment for stack pointer
|
||||
// lss -8(%ecx),%esp # %ss:%esp= %ds:0x99000
|
||||
// /* Linux Documentation/i386/boot.txt "SAMPLE BOOT CONFIGURATION" says
|
||||
// 0x8000-0x8FFF Stack and heap [inside the "real mode segment",
|
||||
// just below the command line at offset 0x9000].
|
||||
//
|
||||
// arch/i386/boot/compressed/head.S "Do the decompression ..." says
|
||||
// %esi contains the "real mode pointer" [as a 32-bit addr].
|
||||
//
|
||||
// In any case, avoid EBDA (Extended BIOS Data Area) below 0xA0000.
|
||||
// boot.txt says 0x9A000 is the limit. LILO goes up to 0x9B000.
|
||||
// */
|
||||
//
|
||||
// pushl $0; popf # subsumes "cli; cld"; also clears NT for buggy BIOS
|
||||
//
|
||||
//#ifndef IMAGE_OFFSET /*{*/
|
||||
//#define IMAGE_OFFSET 0x100000
|
||||
//#endif /*}*/
|
||||
// movl $ IMAGE_OFFSET,%eax # destination of uncompression (and entry point)
|
||||
// push %cs
|
||||
/* Fall into .text of upx-compressed vmlinux. */
|
||||
// /* All code is in stub/src/i386-linux.kernel.head-vmlinux.S */
|
||||
//-----
|
||||
|
||||
// Approximate translation for Linux 2.4.x:
|
||||
|
||||
@ -46,6 +46,7 @@ public:
|
||||
virtual const char *getName() const { return "vmlinux/386"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
virtual int getStrategy(Filter &);
|
||||
|
||||
virtual void pack(OutputFile *fo);
|
||||
virtual void unpack(OutputFile *fo);
|
||||
|
||||
@ -70,7 +70,7 @@ STUBS += i386-linux.elf.interp-entry.h
|
||||
STUBS += i386-linux.elf.interp-fold.h
|
||||
STUBS += i386-linux.elf.shell-entry.h
|
||||
STUBS += i386-linux.elf.shell-fold.h
|
||||
STUBS += i386-linux.kernel.vmlinux.h
|
||||
STUBS += i386-linux.kernel.vmlinux.h i386-linux.kernel.head-vmlinux.h
|
||||
STUBS += i386-linux.kernel.vmlinuz.h
|
||||
STUBS += i386-win32.pe.h
|
||||
STUBS += m68k-atari.tos.h
|
||||
@ -581,6 +581,13 @@ i386-linux.kernel.vmlinu%.h : $(srcdir)/src/$$T.S
|
||||
$(call tc,f-embed_objinfo,tmp/$T.bin)
|
||||
$(call tc,bin2h) --ident=nrv_loader tmp/$T.bin $@
|
||||
|
||||
i386-linux.kernel.head-vmlinux.h : tc_list = arch-i386 default
|
||||
|
||||
i386-linux.kernel.head-vmlinux.h : $(srcdir)/src/$$T.S
|
||||
$(call tc,gcc) -c -x assembler-with-cpp $< -o tmp/$T.tmp
|
||||
$(call tc,objcopy) --output-target binary --only-section .text tmp/$T.tmp tmp/$T.bin
|
||||
$(call tc,bin2h) --ident=head_stack tmp/$T.bin $@
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // i386-win32.pe
|
||||
|
||||
38
src/stub/i386-linux.kernel.head-vmlinux.h
Normal file
38
src/stub/i386-linux.kernel.head-vmlinux.h
Normal file
@ -0,0 +1,38 @@
|
||||
/* i386-linux.kernel.head-vmlinux.h -- created from i386-linux.kernel.head-vmlinux.bin, 39 (0x27) bytes
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2000-2006 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#define HEAD_STACK_SIZE 39
|
||||
#define HEAD_STACK_ADLER32 0x7a591357
|
||||
#define HEAD_STACK_CRC32 0xf4f6740a
|
||||
|
||||
unsigned char head_stack[39] = {
|
||||
140,200,131,192, 8,142,216,142,192,141,142, 0,144, 0, 0,137, /* 0x 0 */
|
||||
73,248,137, 65,252, 15,178, 97,248,106, 0,157, 14,184, 0, 0, /* 0x 10 */
|
||||
0, 0,232,252,255,255,255 /* 0x 20 */
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user