mirror of
https://github.com/upx/upx.git
synced 2025-02-23 01:21:15 +00:00
WIP: handling shared library
modified: p_lx_elf.cpp modified: p_unix.cpp modified: p_unix.h
This commit is contained in:
parent
ef5b55b4d1
commit
d5263a56ce
@ -599,7 +599,8 @@ off_t PackLinuxElf64::pack3(OutputFile *fo, Filter &ft)
|
||||
fo->rewrite(&file_image[off2], 2*sizeof(word));
|
||||
}
|
||||
}
|
||||
else if (xct_off < ioff) { // Slide subsequent PT_LOAD.
|
||||
else if (j && (Elf64_Phdr::PF_W & get_te64(&phdr->p_flags))
|
||||
&& xct_off < ioff) { // Slide subsequent PT_LOAD.
|
||||
// AMD64 chip supports page sizes of 4KiB, 2MiB, and 1GiB;
|
||||
// the operating system chooses one. .p_align typically
|
||||
// is a forward-looking 2MiB. In 2009 Linux chooses 4KiB.
|
||||
@ -3711,12 +3712,14 @@ void PackLinuxElf64::pack1(OutputFile *fo, Filter & /*ft*/)
|
||||
|
||||
progid = 0; // getRandomId(); not useful, so do not clutter
|
||||
sz_elf_hdrs = sizeof(ehdri) + sz_phdrs;
|
||||
if (0!=xct_off) { // shared library
|
||||
sz_elf_hdrs = xct_off;
|
||||
if (0!=xct_off) { // shared library
|
||||
lowmem.alloc(xct_off + (!opt->o_unix.android_shlib
|
||||
? 0
|
||||
: e_shnum * sizeof(Elf64_Shdr)));
|
||||
memcpy(lowmem, file_image, xct_off); // android omits Shdr here
|
||||
}
|
||||
if (0!=xct_off && opt->o_unix.android_shlib) { // Android shared library
|
||||
sz_elf_hdrs = xct_off;
|
||||
fo->write(lowmem, xct_off); // < SHF_EXECINSTR (typ: in .plt or .init)
|
||||
if (opt->o_unix.android_shlib) {
|
||||
// In order to pacify the runtime linker on Android "O" ("Oreo"),
|
||||
@ -4225,9 +4228,39 @@ int PackLinuxElf64::pack2(OutputFile *fo, Filter &ft)
|
||||
}
|
||||
x.offset = get_te64(&phdri[k].p_offset);
|
||||
x.size = get_te64(&phdri[k].p_filesz);
|
||||
if (!is_shlib || hdr_u_len < (u64_t)x.size) {
|
||||
if (is_shlib) {
|
||||
if (x.offset <= xct_off) {
|
||||
unsigned const len = umin(x.size, xct_off - x.offset);
|
||||
if (len) {
|
||||
fi->seek(x.offset, SEEK_SET);
|
||||
fi->readx(ibuf, x.size);
|
||||
total_in += len;
|
||||
|
||||
fo->seek(x.offset, SEEK_SET);
|
||||
fo->write(ibuf, len);
|
||||
total_out += len;
|
||||
}
|
||||
if (len != x.size) {
|
||||
x.offset = 0;
|
||||
x.size = sz_elf_hdrs;
|
||||
packExtent(x, nullptr, fo, 0, 0, true);
|
||||
total_in -= sz_elf_hdrs;
|
||||
|
||||
x.offset = xct_off;
|
||||
x.size = get_te64(&phdri[k].p_filesz) - len;
|
||||
packExtent(x, &ft, fo, 0, 0, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!(Elf64_Phdr::PF_W & get_te64(&phdri[k].p_flags))) {
|
||||
packExtent(x, &ft, fo, 0, 0, true);
|
||||
}
|
||||
// else wait until slide
|
||||
}
|
||||
}
|
||||
else if (hdr_u_len < (u64_t)x.size) {
|
||||
if (0 == nx) { // 1st PT_LOAD64 must cover Ehdr at 0==p_offset
|
||||
unsigned const delta = (is_shlib ? xct_off : hdr_u_len);
|
||||
unsigned const delta = hdr_u_len;
|
||||
if (ft.id < 0x40) {
|
||||
// FIXME: ?? ft.addvalue += asl_delta;
|
||||
}
|
||||
@ -4247,7 +4280,7 @@ int PackLinuxElf64::pack2(OutputFile *fo, Filter &ft)
|
||||
// sometimes marks as PF_X anyway. So filter only first segment.
|
||||
if (k == nk_f || !is_shlib) {
|
||||
packExtent(x,
|
||||
(k==nk_f ? &ft : nullptr ), fo, hdr_u_len);
|
||||
(k==nk_f ? &ft : nullptr ), fo, hdr_u_len, 0, true);
|
||||
}
|
||||
else {
|
||||
total_in += x.size;
|
||||
|
@ -321,7 +321,8 @@ void PackUnix::packExtent(
|
||||
Filter *ft,
|
||||
OutputFile *fo,
|
||||
unsigned hdr_u_len,
|
||||
unsigned b_extra
|
||||
unsigned b_extra,
|
||||
bool inhibit_compression_check
|
||||
)
|
||||
{
|
||||
unsigned const init_u_adler = ph.u_adler;
|
||||
@ -363,7 +364,7 @@ void PackUnix::packExtent(
|
||||
ft->cto = 0;
|
||||
|
||||
compressWithFilters(ft, OVERHEAD, NULL_cconf, filter_strategy,
|
||||
0, 0, 0, hdr_ibuf, hdr_u_len);
|
||||
0, 0, 0, hdr_ibuf, hdr_u_len, inhibit_compression_check);
|
||||
}
|
||||
else {
|
||||
(void) compress(ibuf, ph.u_len, obuf); // ignore return value
|
||||
|
@ -74,7 +74,8 @@ protected:
|
||||
};
|
||||
virtual void packExtent(const Extent &x,
|
||||
Filter *, OutputFile *,
|
||||
unsigned hdr_len = 0, unsigned b_extra = 0);
|
||||
unsigned hdr_len = 0, unsigned b_extra = 0 ,
|
||||
bool inhibit_compression_check = false);
|
||||
virtual void unpackExtent(unsigned wanted, OutputFile *fo,
|
||||
unsigned &c_adler, unsigned &u_adler,
|
||||
bool first_PF_X, unsigned szb_info, bool is_rewrite = false);
|
||||
|
Loading…
x
Reference in New Issue
Block a user