mirror of
https://github.com/upx/upx.git
synced 2024-11-24 05:10:07 +00:00
Documentation: UPX_F_VMLINUX_PPC32 changes to arch/powerpc/boot/main.c
This commit is contained in:
parent
f347458c53
commit
faa33d89a2
103
src/p_vmlinx.cpp
103
src/p_vmlinx.cpp
@ -331,6 +331,109 @@ void PackVmlinuxBase<T>::pack(OutputFile *fo)
|
||||
hdr_info.b_cto8 = ft.cto;
|
||||
fo->write(&hdr_info, sizeof(hdr_info)); fo_off += sizeof(hdr_info);
|
||||
ppc32_extra += sizeof(hdr_info);
|
||||
|
||||
#if 0 /*{ Documentation: changes to arch/powerpc/boot/main.c */
|
||||
struct b_info {
|
||||
unsigned sz_unc;
|
||||
unsigned sz_cpr;
|
||||
unsigned char b_method;
|
||||
unsigned char b_ftid;
|
||||
unsigned char b_cto8;
|
||||
unsigned char b_unused;
|
||||
};
|
||||
typedef int (*upx_f_unc)( /* uncompress */
|
||||
unsigned char const *src, unsigned src_len,
|
||||
unsigned char *dst, unsigned *dst_len,
|
||||
int method
|
||||
);
|
||||
typedef int (*upx_f_unf)( /* unfilter */
|
||||
unsigned char *buf,
|
||||
unsigned len,
|
||||
unsigned cto8,
|
||||
unsigned ftid
|
||||
);
|
||||
|
||||
unsigned char const *upx_expand( // return updated src [aligned, too]
|
||||
unsigned char const *src,
|
||||
unsigned char *dst,
|
||||
unsigned *const dst_len,
|
||||
upx_f_unc const f_unc
|
||||
)
|
||||
{
|
||||
if (0==*dst_len) {
|
||||
*dst_len = ((struct b_info const *)src)->sz_unc;
|
||||
}
|
||||
upx_f_unf const f_unf = (upx_f_unf)(sizeof(int) + (char *)f_unc);
|
||||
unsigned total_len = 0;
|
||||
unsigned need = *dst_len;
|
||||
while (0 < need) {
|
||||
struct b_info const *const b_hdr = (struct b_info const *)src;
|
||||
src = (unsigned char const *)(1+ b_hdr);
|
||||
unsigned blk_len = b_hdr->sz_unc;
|
||||
int const rv = (*f_unc)(src, b_hdr->sz_cpr, dst, &blk_len, b_hdr->b_method);
|
||||
if (0!=rv) {
|
||||
printf("decompress error %d\n\r", rv);
|
||||
exit();
|
||||
}
|
||||
if (b_hdr->b_ftid) {
|
||||
(*f_unf)(dst, b_hdr->sz_unc, b_hdr->b_cto8, b_hdr->b_ftid);
|
||||
}
|
||||
src += b_hdr->sz_cpr;
|
||||
src += (3& -(int)src); // 4-byte align
|
||||
dst += b_hdr->sz_unc;
|
||||
total_len += b_hdr->sz_unc;
|
||||
need -= b_hdr->sz_unc;
|
||||
}
|
||||
*dst_len = total_len;
|
||||
return src;
|
||||
}
|
||||
|
||||
void prep_kernel(unsigned long a1, unsigned long a2)
|
||||
{
|
||||
upx_f_unc f_unc = (upx_f_unc)0;
|
||||
|
||||
vmlinuz.addr = (unsigned long)_vmlinux_start;
|
||||
vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
|
||||
|
||||
if (0x55505821 == *(unsigned *)vmlinuz.addr) {
|
||||
/* was compressed by upx */
|
||||
/* Uncompress elfheader */
|
||||
unsigned const *const fwa = (unsigned *)vmlinuz.addr;
|
||||
f_unc = (upx_f_unc)((char *)&fwa[2] + fwa[1]);
|
||||
unsigned dst_len = 0;
|
||||
unsigned char const *src = (unsigned char const *)&fwa[2];
|
||||
src = upx_expand(src, (unsigned char *)elfheader, &dst_len, f_unc);
|
||||
unsigned const src_len = src - (unsigned char const *)&fwa[0];
|
||||
vmlinuz.addr += src_len;
|
||||
vmlinuz.size -= src_len;
|
||||
} else {
|
||||
memcpy(elfheader, (const void *)vmlinuz.addr,
|
||||
sizeof(elfheader));
|
||||
}
|
||||
=====
|
||||
/* Eventually gunzip the kernel */
|
||||
if (f_unc) {
|
||||
/* was compressed by upx */
|
||||
printf("upx_expand (0x%lx <- 0x%lx:0x%0lx)...",
|
||||
vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size);
|
||||
unsigned dst_len = vmlinux.size - elfoffset;
|
||||
upx_expand((unsigned char const *)vmlinuz.addr,
|
||||
(unsigned char *)vmlinux.addr, &dst_len, f_unc);
|
||||
printf("done 0x%lx bytes\n\r", len);
|
||||
} else {
|
||||
memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,
|
||||
vmlinuz.size);
|
||||
/* Skip over the ELF header */
|
||||
#ifdef DEBUG
|
||||
printf("... skipping 0x%lx bytes of ELF header\n\r",
|
||||
elfoffset);
|
||||
#endif
|
||||
vmlinux.addr += elfoffset;
|
||||
}
|
||||
=====
|
||||
}
|
||||
#endif /*}*/
|
||||
|
||||
}
|
||||
else {
|
||||
compressWithFilters(&ft, 512, &cconf, getStrategy(ft));
|
||||
|
Loading…
Reference in New Issue
Block a user