Fix "bad slide" on 32-bit ARM shared library
https://github.com/upx/upx/issues/944 modified: src/p_elf_enum.h modified: src/p_lx_elf.cpp
This commit is contained in:
parent
75325bf9ef
commit
70cb4aadda
@ -108,6 +108,7 @@ class Dummy {
|
|||||||
/* Register usage information. */ //
|
/* Register usage information. */ //
|
||||||
// PT_MIPS_RTPROC = 0x70000001, /* Runtime procedure table. */
|
// PT_MIPS_RTPROC = 0x70000001, /* Runtime procedure table. */
|
||||||
// PT_MIPS_OPTIONS = 0x70000002,
|
// PT_MIPS_OPTIONS = 0x70000002,
|
||||||
|
PT_ARM_EXIDX = (0x70000000 + 1), /* ARM unwind segment. */
|
||||||
PT_MIPS_ABIFLAGS = 0x70000003, /* FP mode requirement. */
|
PT_MIPS_ABIFLAGS = 0x70000003, /* FP mode requirement. */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -148,6 +149,7 @@ class Dummy {
|
|||||||
|
|
||||||
SHT_LOOS = 0x60000000, /* LOcal OS; SHT_ANDROID_REL{,A} is +1, +2 */
|
SHT_LOOS = 0x60000000, /* LOcal OS; SHT_ANDROID_REL{,A} is +1, +2 */
|
||||||
SHT_LOPROC = 0x70000000, /* Start of processor-specific */
|
SHT_LOPROC = 0x70000000, /* Start of processor-specific */
|
||||||
|
SHT_ARM_EXIDX = (SHT_LOPROC + 1), /* ARM unwind section. */
|
||||||
SHT_ARM_ATTRIBUTES = (SHT_LOPROC + 3), /* ARM attributes section. */
|
SHT_ARM_ATTRIBUTES = (SHT_LOPROC + 3), /* ARM attributes section. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
126
src/p_lx_elf.cpp
126
src/p_lx_elf.cpp
@ -487,17 +487,17 @@ PackLinuxElf32::slide_sh_offset(Elf32_Shdr *shdr)
|
|||||||
{
|
{
|
||||||
unsigned sh_offset = get_te32(&shdr->sh_offset);
|
unsigned sh_offset = get_te32(&shdr->sh_offset);
|
||||||
unsigned sh_addr = get_te32(&shdr->sh_addr);
|
unsigned sh_addr = get_te32(&shdr->sh_addr);
|
||||||
|
char const *sh_name = get_te32(&shdr->sh_name) + shstrtab;
|
||||||
|
(void)sh_name; // convenience for debug
|
||||||
if (Elf32_Shdr::SHF_WRITE & get_te32(&shdr->sh_flags)
|
if (Elf32_Shdr::SHF_WRITE & get_te32(&shdr->sh_flags)
|
||||||
|| (sh_offset && !sh_addr))
|
|| (sh_offset && !sh_addr))
|
||||||
{
|
{
|
||||||
unsigned newoff = so_slide + sh_offset + (is_asl ? asl_delta : 0);
|
unsigned newoff = so_slide + sh_offset + (is_asl ? asl_delta : 0);
|
||||||
if ((unsigned)this->file_size < newoff) {
|
if (sh_addr // only check "real memory"
|
||||||
|
&& (unsigned)this->file_size < newoff) {
|
||||||
throwInternalError("bad slide %p %#x", shdr, (unsigned)so_slide);
|
throwInternalError("bad slide %p %#x", shdr, (unsigned)so_slide);
|
||||||
}
|
}
|
||||||
set_te32(&shdr->sh_offset, newoff);
|
set_te32(&shdr->sh_offset, newoff);
|
||||||
if (sh_addr) // change only if non-zero
|
|
||||||
set_te32(&shdr->sh_addr,
|
|
||||||
so_slide + sh_addr + (is_asl ? asl_delta : 0));
|
|
||||||
return newoff;
|
return newoff;
|
||||||
}
|
}
|
||||||
return sh_offset;
|
return sh_offset;
|
||||||
@ -520,17 +520,17 @@ PackLinuxElf64::slide_sh_offset(Elf64_Shdr *shdr)
|
|||||||
{
|
{
|
||||||
unsigned sh_offset = get_te64(&shdr->sh_offset);
|
unsigned sh_offset = get_te64(&shdr->sh_offset);
|
||||||
unsigned sh_addr = get_te64(&shdr->sh_addr);
|
unsigned sh_addr = get_te64(&shdr->sh_addr);
|
||||||
|
char const *sh_name = get_te32(&shdr->sh_name) + shstrtab;
|
||||||
|
(void)sh_name; // convenience for debug
|
||||||
if (Elf64_Shdr::SHF_WRITE & get_te64(&shdr->sh_flags)
|
if (Elf64_Shdr::SHF_WRITE & get_te64(&shdr->sh_flags)
|
||||||
|| (sh_offset && !sh_addr))
|
|| (sh_offset && !sh_addr))
|
||||||
{
|
{
|
||||||
unsigned newoff = so_slide + sh_offset + (is_asl ? asl_delta : 0);
|
unsigned newoff = so_slide + sh_offset + (is_asl ? asl_delta : 0);
|
||||||
if ((unsigned)this->file_size < newoff) {
|
if (sh_addr // only check "real memory"
|
||||||
|
&& (unsigned)this->file_size < newoff) {
|
||||||
throwInternalError("bad slide %p %#x", shdr, (unsigned)so_slide);
|
throwInternalError("bad slide %p %#x", shdr, (unsigned)so_slide);
|
||||||
}
|
}
|
||||||
set_te64(&shdr->sh_offset, newoff);
|
set_te64(&shdr->sh_offset, newoff);
|
||||||
if (sh_addr) // change only if non-zero
|
|
||||||
set_te64(&shdr->sh_addr,
|
|
||||||
so_slide + sh_addr + (is_asl ? asl_delta : 0));
|
|
||||||
return newoff;
|
return newoff;
|
||||||
}
|
}
|
||||||
return sh_offset;
|
return sh_offset;
|
||||||
@ -641,25 +641,18 @@ off_t PackLinuxElf32::pack3(OutputFile *fo, Filter &ft)
|
|||||||
|
|
||||||
Elf32_Phdr *const phdr0 = (Elf32_Phdr *)lowmem.subref(
|
Elf32_Phdr *const phdr0 = (Elf32_Phdr *)lowmem.subref(
|
||||||
"bad e_phoff", e_phoff, e_phnum * sizeof(Elf32_Phdr));
|
"bad e_phoff", e_phoff, e_phnum * sizeof(Elf32_Phdr));
|
||||||
Elf32_Phdr *phdr = phdr0;
|
Elf32_Phdr *phdr = phdr0, *outp = phdr0;
|
||||||
upx_off_t off = fo->st_size(); // 64 bits
|
upx_off_t off = fo->st_size(); // 64 bits
|
||||||
so_slide = 0;
|
so_slide = 0;
|
||||||
for (unsigned j = 0; j < e_phnum; ++j, ++phdr) {
|
for (unsigned j = 0; j < e_phnum; ++j, ++phdr) {
|
||||||
// p_vaddr and p_paddr do not change!
|
// p_vaddr and p_paddr do not change!
|
||||||
unsigned const len = get_te32(&phdr->p_filesz);
|
|
||||||
unsigned const ioff = get_te32(&phdri[j].p_offset); // without asl_delta
|
unsigned const ioff = get_te32(&phdri[j].p_offset); // without asl_delta
|
||||||
unsigned align= get_te32(&phdr->p_align);
|
unsigned align= get_te32(&phdr->p_align);
|
||||||
unsigned const type = get_te32(&phdr->p_type);
|
unsigned const type = get_te32(&phdr->p_type);
|
||||||
if (Elf32_Phdr::PT_INTERP==type) {
|
unsigned const len = get_te32(&phdr->p_filesz);
|
||||||
// Rotate to highest position, so it can be lopped
|
if (Elf32_Phdr::PT_INTERP==type
|
||||||
// by decrementing e_phnum.
|
|| Elf32_Phdr::PT_ARM_EXIDX==type) {
|
||||||
memcpy((unsigned char *)ibuf, phdr, sizeof(*phdr)); // extract
|
/* OMIT */ continue; // OMIT: reference to compressed data
|
||||||
memmove(phdr, 1+phdr, (e_phnum - (1+ j))*sizeof(*phdr)); // overlapping
|
|
||||||
memcpy(&phdr[e_phnum - (1+ j)], (unsigned char *)ibuf, sizeof(*phdr)); // to top
|
|
||||||
--phdr; --e_phnum;
|
|
||||||
set_te16(&ehdri.e_phnum, e_phnum);
|
|
||||||
set_te16(&((Elf32_Ehdr *)(unsigned char *)lowmem)->e_phnum, e_phnum);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
if (PT_LOAD == type) {
|
if (PT_LOAD == type) {
|
||||||
if (!ioff) { // first PT_LOAD must contain everything written so far
|
if (!ioff) { // first PT_LOAD must contain everything written so far
|
||||||
@ -707,12 +700,21 @@ off_t PackLinuxElf32::pack3(OutputFile *fo, Filter &ft)
|
|||||||
fo->seek(0, SEEK_END);
|
fo->seek(0, SEEK_END);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue; // all done with this PT_LOAD
|
|
||||||
}
|
}
|
||||||
if (xct_off < ioff) {
|
else if (Elf32_Phdr::PT_DYNAMIC == type
|
||||||
set_te32(&phdr->p_offset, so_slide + (is_asl ? asl_delta : 0) + ioff);
|
|| Elf32_Phdr::PT_GNU_RELRO == type) {
|
||||||
|
unsigned delta = so_slide + (is_asl ? asl_delta : 0);
|
||||||
|
set_te32(&phdr->p_offset, delta + ioff);
|
||||||
|
// unsigned x = get_te32(&phdr->p_vaddr);
|
||||||
|
// set_te32(&phdr->p_vaddr, delta + x);
|
||||||
|
// unsigned y = get_te32(&phdr->p_paddr);
|
||||||
|
// set_te32(&phdr->p_paddr, delta + y);
|
||||||
}
|
}
|
||||||
|
*outp++ = *phdr; // propagate
|
||||||
} // end each Phdr
|
} // end each Phdr
|
||||||
|
e_phnum = outp - phdr0;
|
||||||
|
set_te16(&ehdri.e_phnum, e_phnum);
|
||||||
|
set_te16(&((Elf32_Ehdr *)(unsigned char *)lowmem)->e_phnum, e_phnum);
|
||||||
|
|
||||||
if (sec_arm_attr || is_asl) { // must update Shdr.sh_offset for so_slide
|
if (sec_arm_attr || is_asl) { // must update Shdr.sh_offset for so_slide
|
||||||
Elf32_Shdr *shdr = shdri;
|
Elf32_Shdr *shdr = shdri;
|
||||||
@ -769,6 +771,7 @@ off_t PackLinuxElf32::pack3(OutputFile *fo, Filter &ft)
|
|||||||
return total_out;
|
return total_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NYI 2025-12-10: should be updated from the Elf32::pack3 version
|
||||||
off_t PackLinuxElf64::pack3(OutputFile *fo, Filter &ft)
|
off_t PackLinuxElf64::pack3(OutputFile *fo, Filter &ft)
|
||||||
{
|
{
|
||||||
if (!overlay_offset) {
|
if (!overlay_offset) {
|
||||||
@ -835,7 +838,7 @@ off_t PackLinuxElf64::pack3(OutputFile *fo, Filter &ft)
|
|||||||
|
|
||||||
Elf64_Phdr *const phdr0 = (Elf64_Phdr *)lowmem.subref(
|
Elf64_Phdr *const phdr0 = (Elf64_Phdr *)lowmem.subref(
|
||||||
"bad e_phoff", e_phoff, e_phnum * sizeof(Elf64_Phdr));
|
"bad e_phoff", e_phoff, e_phnum * sizeof(Elf64_Phdr));
|
||||||
Elf64_Phdr *phdr = phdr0;
|
Elf64_Phdr *phdr = phdr0, *outp = phdr0;
|
||||||
upx_off_t off = fo->st_size(); // 64 bits
|
upx_off_t off = fo->st_size(); // 64 bits
|
||||||
so_slide = 0;
|
so_slide = 0;
|
||||||
for (unsigned j = 0; j < e_phnum; ++j, ++phdr) {
|
for (unsigned j = 0; j < e_phnum; ++j, ++phdr) {
|
||||||
@ -845,16 +848,9 @@ off_t PackLinuxElf64::pack3(OutputFile *fo, Filter &ft)
|
|||||||
u64_t align= get_te64(&phdr->p_align);
|
u64_t align= get_te64(&phdr->p_align);
|
||||||
unsigned const type = get_te32(&phdr->p_type);
|
unsigned const type = get_te32(&phdr->p_type);
|
||||||
if (Elf64_Phdr::PT_INTERP==type) {
|
if (Elf64_Phdr::PT_INTERP==type) {
|
||||||
// Rotate to highest position, so it can be lopped
|
continue; // OMIT
|
||||||
// by decrementing e_phnum.
|
|
||||||
memcpy((unsigned char *)ibuf, phdr, sizeof(*phdr)); // extract
|
|
||||||
memmove(phdr, 1+phdr, (e_phnum - (1+ j))*sizeof(*phdr)); // overlapping
|
|
||||||
memcpy(&phdr[e_phnum - (1+ j)], (unsigned char *)ibuf, sizeof(*phdr)); // to top
|
|
||||||
--phdr; --e_phnum;
|
|
||||||
set_te16(&ehdri.e_phnum, e_phnum);
|
|
||||||
set_te16(&((Elf64_Ehdr *)(unsigned char *)lowmem)->e_phnum, e_phnum);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
*outp++ = *phdr; // propagate
|
||||||
if (PT_LOAD == type) {
|
if (PT_LOAD == type) {
|
||||||
if (!ioff) { // first PT_LOAD must contain everything written so far
|
if (!ioff) { // first PT_LOAD must contain everything written so far
|
||||||
set_te64(&phdr->p_filesz, sz_pack2 + lsize); // is this correct?
|
set_te64(&phdr->p_filesz, sz_pack2 + lsize); // is this correct?
|
||||||
@ -903,6 +899,9 @@ off_t PackLinuxElf64::pack3(OutputFile *fo, Filter &ft)
|
|||||||
set_te64(&phdr->p_offset, so_slide + (is_asl ? asl_delta : 0) + ioff);
|
set_te64(&phdr->p_offset, so_slide + (is_asl ? asl_delta : 0) + ioff);
|
||||||
}
|
}
|
||||||
} // end each Phdr
|
} // end each Phdr
|
||||||
|
e_phnum = outp - phdr0;
|
||||||
|
set_te16(&ehdri.e_phnum, e_phnum);
|
||||||
|
set_te16(&((Elf64_Ehdr *)(unsigned char *)lowmem)->e_phnum, e_phnum);
|
||||||
|
|
||||||
if (sec_arm_attr || is_asl) { // must update Shdr.sh_offset for so_slide
|
if (sec_arm_attr || is_asl) { // must update Shdr.sh_offset for so_slide
|
||||||
// Update {DYNAMIC}.sh_offset by so_slide.
|
// Update {DYNAMIC}.sh_offset by so_slide.
|
||||||
@ -6107,6 +6106,8 @@ unsigned PackLinuxElf32::forward_Shdrs(OutputFile *fo, Elf32_Ehdr *const eho)
|
|||||||
// Keep _Shdr for SHF_WRITE.
|
// Keep _Shdr for SHF_WRITE.
|
||||||
// Discard _Shdr with (0==sh_addr), except _Shdr[0]
|
// Discard _Shdr with (0==sh_addr), except _Shdr[0]
|
||||||
// Keep ARM_ATTRIBUTES
|
// Keep ARM_ATTRIBUTES
|
||||||
|
// Remove .ARM.extab(PROGBITS) and .ARM.exidx(SHT_ARM_EXIDX)
|
||||||
|
// because they refer to compressed .text(PT_LOAD)
|
||||||
unsigned const want_types_mask = 0
|
unsigned const want_types_mask = 0
|
||||||
| 1u<<SHT_PROGBITS // see comment above, and special code below
|
| 1u<<SHT_PROGBITS // see comment above, and special code below
|
||||||
| 1u<<SHT_HASH
|
| 1u<<SHT_HASH
|
||||||
@ -6181,30 +6182,14 @@ unsigned PackLinuxElf32::forward_Shdrs(OutputFile *fo, Elf32_Ehdr *const eho)
|
|||||||
|| (Elf32_Shdr::SHT_ARM_ATTRIBUTES == sh_type)
|
|| (Elf32_Shdr::SHT_ARM_ATTRIBUTES == sh_type)
|
||||||
) {
|
) {
|
||||||
*sh_out = *sh_in; // *sh_in is a candidate for fowarding
|
*sh_out = *sh_in; // *sh_in is a candidate for fowarding
|
||||||
if (sh_offset > xct_off) { // may slide down: earlier compression
|
|
||||||
if (sh_offset >= xct_off_hi) { // easy: so_slide down
|
|
||||||
if (Elf32_Shdr::SHT_ARM_ATTRIBUTES != sh_type) {
|
|
||||||
slide_sh_offset(sh_out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { // somewhere in compressed; try proportional (aligned)
|
|
||||||
// But note that PROGBITS without SHF_ALLOC
|
|
||||||
// will be dropped below.
|
|
||||||
u32_t const slice = xct_off + (~0xFu & (unsigned)(
|
|
||||||
(sh_offset - xct_off) *
|
|
||||||
((sh_offset - xct_off) / (float)(xct_off_hi - xct_off))));
|
|
||||||
//set_te32(&sh_out->sh_addr, slice);
|
|
||||||
set_te32(&sh_out->sh_offset, slice);
|
|
||||||
}
|
|
||||||
u32_t const max_sz = total_out - get_te32(&sh_out->sh_offset);
|
|
||||||
if (sh_size > max_sz) { // avoid complaint "extends beyond EOF"
|
|
||||||
set_te32(&sh_out->sh_size, max_sz);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (j == e_shstrndx) { // changes Elf32_Ehdr itself
|
if (j == e_shstrndx) { // changes Elf32_Ehdr itself
|
||||||
set_te16(&eho->e_shstrndx, sh_out -
|
set_te16(&eho->e_shstrndx, sh_out -
|
||||||
(Elf32_Shdr *)mb_shdro.getVoidPtr());
|
(Elf32_Shdr *)mb_shdro.getVoidPtr());
|
||||||
}
|
}
|
||||||
|
if (Elf32_Shdr::SHT_ARM_EXIDX == sh_type
|
||||||
|
|| 0==strcmp(".ARM.extab", name)) {
|
||||||
|
/* OMIT */ continue; // OMIT: compressed contents
|
||||||
|
}
|
||||||
if (Elf32_Shdr::SHT_ARM_ATTRIBUTES == sh_type
|
if (Elf32_Shdr::SHT_ARM_ATTRIBUTES == sh_type
|
||||||
|| (SHT_NOTE == sh_type && xct_off < sh_offset)
|
|| (SHT_NOTE == sh_type && xct_off < sh_offset)
|
||||||
) { // append a copy
|
) { // append a copy
|
||||||
@ -6218,7 +6203,7 @@ unsigned PackLinuxElf32::forward_Shdrs(OutputFile *fo, Elf32_Ehdr *const eho)
|
|||||||
if (!(Elf32_Shdr::SHF_ALLOC & sh_flags)) {
|
if (!(Elf32_Shdr::SHF_ALLOC & sh_flags)) {
|
||||||
// .debug_*, .gnu_debuglink etc. Typically compressed
|
// .debug_*, .gnu_debuglink etc. Typically compressed
|
||||||
// but not in RAM, and gdb (BFD) gets confused.
|
// but not in RAM, and gdb (BFD) gets confused.
|
||||||
continue; // OMIT the commit: do not forward
|
/* OMIT */ continue; // OMIT the commit: do not forward
|
||||||
} else
|
} else
|
||||||
if (sh_offset <= xct_off
|
if (sh_offset <= xct_off
|
||||||
&& 0 == strcmp(".text", name) ) {
|
&& 0 == strcmp(".text", name) ) {
|
||||||
@ -6233,9 +6218,31 @@ unsigned PackLinuxElf32::forward_Shdrs(OutputFile *fo, Elf32_Ehdr *const eho)
|
|||||||
n_shstrsec = sh_out;
|
n_shstrsec = sh_out;
|
||||||
} else
|
} else
|
||||||
if (strcmp(".dynstr", name)) {
|
if (strcmp(".dynstr", name)) {
|
||||||
continue; // OMIT the commit of non-global symbol names
|
/* OMIT */ continue; // OMIT the commit of non-global symbol names
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (sh_offset > xct_off) { // may slide down: earlier compression
|
||||||
|
if (sh_offset >= xct_off_hi) { // easy: so_slide down
|
||||||
|
if (Elf32_Shdr::SHT_ARM_ATTRIBUTES != sh_type
|
||||||
|
// && Elf32_Shdr::SHT_ARM_EXIDX != sh_type
|
||||||
|
) {
|
||||||
|
slide_sh_offset(sh_out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // somewhere in compressed; try proportional (aligned)
|
||||||
|
// Note that PROGBITS without SHF_ALLOC is already omitted.
|
||||||
|
u32_t const slice = xct_off + (~0xFu & (unsigned)(
|
||||||
|
(sh_offset - xct_off) *
|
||||||
|
((sh_offset - xct_off) / (float)(xct_off_hi - xct_off))));
|
||||||
|
//set_te32(&sh_out->sh_addr, slice);
|
||||||
|
set_te32(&sh_out->sh_offset, slice);
|
||||||
|
}
|
||||||
|
u32_t const max_sz = total_out - get_te32(&sh_out->sh_offset);
|
||||||
|
if (sh_size > max_sz) { // avoid complaint "extends beyond EOF"
|
||||||
|
set_te32(&sh_out->sh_size, max_sz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Will be forwarded, but needs a name.
|
||||||
set_te32(&sh_out->sh_name, ptr_shstrings - (char *)mb_shstrings.getVoidPtr());
|
set_te32(&sh_out->sh_name, ptr_shstrings - (char *)mb_shstrings.getVoidPtr());
|
||||||
do { // stupid MSVC lacks stpcpy()
|
do { // stupid MSVC lacks stpcpy()
|
||||||
*ptr_shstrings++ = *name;
|
*ptr_shstrings++ = *name;
|
||||||
@ -6292,6 +6299,7 @@ unsigned PackLinuxElf32::forward_Shdrs(OutputFile *fo, Elf32_Ehdr *const eho)
|
|||||||
return penalty;
|
return penalty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NYI 2025-12-10: should be merged from Elf32::forward_Shdrs
|
||||||
unsigned PackLinuxElf64::forward_Shdrs(OutputFile *fo, Elf64_Ehdr *const eho)
|
unsigned PackLinuxElf64::forward_Shdrs(OutputFile *fo, Elf64_Ehdr *const eho)
|
||||||
{
|
{
|
||||||
if (!fo) {
|
if (!fo) {
|
||||||
@ -6303,7 +6311,9 @@ unsigned PackLinuxElf64::forward_Shdrs(OutputFile *fo, Elf64_Ehdr *const eho)
|
|||||||
// Keep _Shdr for rtld data (below xct_off).
|
// Keep _Shdr for rtld data (below xct_off).
|
||||||
// Discard _Shdr for compressed regions, except ".text" for gdb.
|
// Discard _Shdr for compressed regions, except ".text" for gdb.
|
||||||
// Keep _Shdr with SHF_WRITE.
|
// Keep _Shdr with SHF_WRITE.
|
||||||
// Keep ARM_ATTRIBUTES
|
// Keep ARM_ATTRIBUTES.
|
||||||
|
// Remove .ARM.extab(PROGBITS) and .ARM.exidx(ARM_EXIDX)
|
||||||
|
// because they refer to compressed .text.
|
||||||
// Discard _Shdr with (0==sh_addr), except _Shdr[0]
|
// Discard _Shdr with (0==sh_addr), except _Shdr[0]
|
||||||
unsigned const want_types_mask =
|
unsigned const want_types_mask =
|
||||||
1u<<SHT_SYMTAB
|
1u<<SHT_SYMTAB
|
||||||
@ -6351,7 +6361,6 @@ unsigned PackLinuxElf64::forward_Shdrs(OutputFile *fo, Elf64_Ehdr *const eho)
|
|||||||
|
|
||||||
for (unsigned j = 1; j < e_shnum; ++j, ++sh_in) {
|
for (unsigned j = 1; j < e_shnum; ++j, ++sh_in) {
|
||||||
char const *sh_name = &shstrtab[get_te32(&sh_in->sh_name)];
|
char const *sh_name = &shstrtab[get_te32(&sh_in->sh_name)];
|
||||||
(void)sh_name; // debugging
|
|
||||||
unsigned sh_type = get_te32(&sh_in->sh_type);
|
unsigned sh_type = get_te32(&sh_in->sh_type);
|
||||||
u64_t sh_flags = get_te64(&sh_in->sh_flags);
|
u64_t sh_flags = get_te64(&sh_in->sh_flags);
|
||||||
u64_t sh_addr = get_te64(&sh_in->sh_addr);
|
u64_t sh_addr = get_te64(&sh_in->sh_addr);
|
||||||
@ -6396,6 +6405,9 @@ unsigned PackLinuxElf64::forward_Shdrs(OutputFile *fo, Elf64_Ehdr *const eho)
|
|||||||
set_te16(&eho->e_shstrndx, sh_out -
|
set_te16(&eho->e_shstrndx, sh_out -
|
||||||
(Elf64_Shdr *)mb_shdro.getVoidPtr());
|
(Elf64_Shdr *)mb_shdro.getVoidPtr());
|
||||||
}
|
}
|
||||||
|
if (0==strcmp(".ARM.extab", sh_name)) {
|
||||||
|
/* OMIT */ continue; // OMIT: compressed contents
|
||||||
|
}
|
||||||
if (j == e_shstrndx
|
if (j == e_shstrndx
|
||||||
|| sec_arm_attr == sh_in
|
|| sec_arm_attr == sh_in
|
||||||
|| (SHT_NOTE == sh_type && xct_off < sh_offset)
|
|| (SHT_NOTE == sh_type && xct_off < sh_offset)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user