mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
Try to appease Android runtime loader; _Shdr vs _Phdr offsets
JNI FalalError called: Unable to load library: [dlopen failed: "/lib/arm/libunity.so" .dynamic section has invalid offset: 0x6d3e58, expected to match PT_DYNAMIC offset: 0x441e58] https://github.com/upx/upx/issues/609 modified: p_elf_enum.h modified: p_lx_elf.cpp
This commit is contained in:
parent
b5d1eba4c1
commit
b361b91ec7
|
@ -127,9 +127,12 @@
|
|||
SHT_FINI_ARRAY = 15, /* Array of destructors */
|
||||
SHT_PREINIT_ARRAY = 16, /* Array of pre-constructors */
|
||||
SHT_GROUP = 17, /* Section group */
|
||||
SHT_SYMTAB_SHNDX = 18, /* Extended section indeces */
|
||||
SHT_SYMTAB_SHNDX = 18, /* Extended section indices */
|
||||
SHT_GNU_HASH = 0x6ffffff6, /* GNU-style hash table. */
|
||||
SHT_GNU_LIBLIST = 0x6ffffff7, /* Prelink library list */
|
||||
SHT_GNU_HASH = 0x6ffffff6, /* GNU-style hash table. */
|
||||
SHT_GNU_verdef = 0x6ffffffd, /* Version definition section. */
|
||||
SHT_GNU_verneed = 0x6ffffffe, /* Version needs section. */
|
||||
SHT_GNU_versym = 0x6fffffff, /* Version symbol table. */
|
||||
|
||||
SHT_LOOS = 0x60000000, /* LOcal OS; SHT_ANDROID_REL{,A} is +1, +2 */
|
||||
SHT_LOPROC = 0x70000000, /* Start of processor-specific */
|
||||
|
|
|
@ -1660,6 +1660,7 @@ static const
|
|||
|
||||
#define WANT_NHDR_ENUM
|
||||
#include "p_elf_enum.h"
|
||||
#undef WANT_NHDR_ENUM
|
||||
|
||||
void
|
||||
PackNetBSDElf32x86::buildLoader(const Filter *ft)
|
||||
|
@ -5477,6 +5478,10 @@ void PackLinuxElf32mipsel::defineSymbols(Filter const *ft)
|
|||
PackLinuxElf32::defineSymbols(ft);
|
||||
}
|
||||
|
||||
#define WANT_SHDR_ENUM
|
||||
#include "p_elf_enum.h"
|
||||
#undef WANT_SHDR_ENUM
|
||||
|
||||
void PackLinuxElf32::forward_Shdrs(OutputFile *fo)
|
||||
{
|
||||
if (saved_opt_android_shlib) { // Forward select _Shdr
|
||||
|
@ -5485,6 +5490,21 @@ void PackLinuxElf32::forward_Shdrs(OutputFile *fo)
|
|||
// Keep _Shdr for SHF_WRITE.
|
||||
// Discard _Shdr with (0==sh_addr), except _Shdr[0]
|
||||
// Keep ARM_ATTRIBUTES
|
||||
unsigned const want_types_mask =
|
||||
1<<SHT_SYMTAB
|
||||
| 1<<SHT_RELA
|
||||
| 1<<SHT_HASH
|
||||
| 1<<SHT_DYNAMIC
|
||||
| 1<<SHT_NOTE
|
||||
| 1<<SHT_REL
|
||||
| 1<<SHT_DYNSYM
|
||||
| 1<<SHT_INIT_ARRAY
|
||||
| 1<<SHT_FINI_ARRAY
|
||||
| 1<<SHT_PREINIT_ARRAY
|
||||
| 1<<(0x1f & SHT_GNU_versym)
|
||||
| 1<<(0x1f & SHT_GNU_verneed)
|
||||
| 1<<(0x1f & SHT_GNU_verdef)
|
||||
| 1<<(0x1f & SHT_GNU_HASH);
|
||||
Elf32_Ehdr *eho = (Elf32_Ehdr *)lowmem.getVoidPtr();
|
||||
MemBuffer mb_ask_for(e_shnum * sizeof(eho->e_shnum));
|
||||
memset(mb_ask_for, 0, mb_ask_for.getSize());
|
||||
|
@ -5501,7 +5521,8 @@ void PackLinuxElf32::forward_Shdrs(OutputFile *fo)
|
|||
for (unsigned j = 1; j < e_shnum; ++j, ++sh_in) {
|
||||
unsigned sh_offset = get_te32(&sh_in->sh_offset);
|
||||
unsigned sh_flags = get_te32(&sh_in->sh_flags);
|
||||
unsigned sh_info = get_te16(&sh_in->sh_info);
|
||||
unsigned sh_info = get_te32(&sh_in->sh_info);
|
||||
unsigned sh_type = get_te32(&sh_in->sh_type);
|
||||
if (ask_for[j]) { // Some previous _Shdr requested me
|
||||
// Tell them my new index
|
||||
set_te16(&sh_out0[ask_for[j]].sh_info, n_sh_out);
|
||||
|
@ -5511,6 +5532,7 @@ void PackLinuxElf32::forward_Shdrs(OutputFile *fo)
|
|||
|| (Elf32_Shdr::SHF_WRITE & sh_flags)
|
||||
|| (j == e_shstrndx)
|
||||
|| (sec_arm_attr == sh_in)
|
||||
|| (want_types_mask & (1<<(0x1f & sh_type)))
|
||||
) {
|
||||
*sh_out = *sh_in;
|
||||
if (sec_arm_attr == sh_in) {
|
||||
|
@ -5530,8 +5552,10 @@ void PackLinuxElf32::forward_Shdrs(OutputFile *fo)
|
|||
fo->write(ibuf, len);
|
||||
total_out += len;
|
||||
}
|
||||
if (Elf32_Shdr::SHF_WRITE & sh_flags) {
|
||||
set_te32(&sh_out->sh_offset, so_slide + get_te32(&sh_out->sh_offset));
|
||||
if (Elf32_Shdr::SHF_WRITE & sh_flags || SHT_NOTE == sh_type) {
|
||||
if (sh_offset > xct_off) {
|
||||
set_te32(&sh_out->sh_offset, so_slide + sh_offset);
|
||||
}
|
||||
}
|
||||
++sh_out; ++n_sh_out;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user