mirror of
https://github.com/upx/upx
synced 2025-10-05 19:20:23 +08: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));
|
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;
|
// AMD64 chip supports page sizes of 4KiB, 2MiB, and 1GiB;
|
||||||
// the operating system chooses one. .p_align typically
|
// the operating system chooses one. .p_align typically
|
||||||
// is a forward-looking 2MiB. In 2009 Linux chooses 4KiB.
|
// is a forward-looking 2MiB. In 2009 Linux chooses 4KiB.
|
||||||
|
@ -3712,11 +3713,13 @@ void PackLinuxElf64::pack1(OutputFile *fo, Filter & /*ft*/)
|
||||||
progid = 0; // getRandomId(); not useful, so do not clutter
|
progid = 0; // getRandomId(); not useful, so do not clutter
|
||||||
sz_elf_hdrs = sizeof(ehdri) + sz_phdrs;
|
sz_elf_hdrs = sizeof(ehdri) + sz_phdrs;
|
||||||
if (0!=xct_off) { // shared library
|
if (0!=xct_off) { // shared library
|
||||||
sz_elf_hdrs = xct_off;
|
|
||||||
lowmem.alloc(xct_off + (!opt->o_unix.android_shlib
|
lowmem.alloc(xct_off + (!opt->o_unix.android_shlib
|
||||||
? 0
|
? 0
|
||||||
: e_shnum * sizeof(Elf64_Shdr)));
|
: e_shnum * sizeof(Elf64_Shdr)));
|
||||||
memcpy(lowmem, file_image, xct_off); // android omits Shdr here
|
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)
|
fo->write(lowmem, xct_off); // < SHF_EXECINSTR (typ: in .plt or .init)
|
||||||
if (opt->o_unix.android_shlib) {
|
if (opt->o_unix.android_shlib) {
|
||||||
// In order to pacify the runtime linker on Android "O" ("Oreo"),
|
// 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.offset = get_te64(&phdri[k].p_offset);
|
||||||
x.size = get_te64(&phdri[k].p_filesz);
|
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
|
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) {
|
if (ft.id < 0x40) {
|
||||||
// FIXME: ?? ft.addvalue += asl_delta;
|
// 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.
|
// sometimes marks as PF_X anyway. So filter only first segment.
|
||||||
if (k == nk_f || !is_shlib) {
|
if (k == nk_f || !is_shlib) {
|
||||||
packExtent(x,
|
packExtent(x,
|
||||||
(k==nk_f ? &ft : nullptr ), fo, hdr_u_len);
|
(k==nk_f ? &ft : nullptr ), fo, hdr_u_len, 0, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
total_in += x.size;
|
total_in += x.size;
|
||||||
|
|
|
@ -321,7 +321,8 @@ void PackUnix::packExtent(
|
||||||
Filter *ft,
|
Filter *ft,
|
||||||
OutputFile *fo,
|
OutputFile *fo,
|
||||||
unsigned hdr_u_len,
|
unsigned hdr_u_len,
|
||||||
unsigned b_extra
|
unsigned b_extra,
|
||||||
|
bool inhibit_compression_check
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned const init_u_adler = ph.u_adler;
|
unsigned const init_u_adler = ph.u_adler;
|
||||||
|
@ -363,7 +364,7 @@ void PackUnix::packExtent(
|
||||||
ft->cto = 0;
|
ft->cto = 0;
|
||||||
|
|
||||||
compressWithFilters(ft, OVERHEAD, NULL_cconf, filter_strategy,
|
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 {
|
else {
|
||||||
(void) compress(ibuf, ph.u_len, obuf); // ignore return value
|
(void) compress(ibuf, ph.u_len, obuf); // ignore return value
|
||||||
|
|
|
@ -74,7 +74,8 @@ protected:
|
||||||
};
|
};
|
||||||
virtual void packExtent(const Extent &x,
|
virtual void packExtent(const Extent &x,
|
||||||
Filter *, OutputFile *,
|
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,
|
virtual void unpackExtent(unsigned wanted, OutputFile *fo,
|
||||||
unsigned &c_adler, unsigned &u_adler,
|
unsigned &c_adler, unsigned &u_adler,
|
||||||
bool first_PF_X, unsigned szb_info, bool is_rewrite = false);
|
bool first_PF_X, unsigned szb_info, bool is_rewrite = false);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user