am 560aacee: Merge "Fix unit tests, and extend for other architectures"
* commit '560aacee84ecfd1aa8983d0ab58b81fbbe34911d': Fix unit tests, and extend for other architectures
This commit is contained in:
commit
6fbb7cf4a9
@ -95,3 +95,9 @@ $(eval $(call copy-test-library,elf_file_unittest_relocs_arm32.so))
|
|||||||
$(eval $(call copy-test-library,elf_file_unittest_relocs_arm32_packed.so))
|
$(eval $(call copy-test-library,elf_file_unittest_relocs_arm32_packed.so))
|
||||||
$(eval $(call copy-test-library,elf_file_unittest_relocs_arm64.so))
|
$(eval $(call copy-test-library,elf_file_unittest_relocs_arm64.so))
|
||||||
$(eval $(call copy-test-library,elf_file_unittest_relocs_arm64_packed.so))
|
$(eval $(call copy-test-library,elf_file_unittest_relocs_arm64_packed.so))
|
||||||
|
$(eval $(call copy-test-library,elf_file_unittest_relocs_ia32.so))
|
||||||
|
$(eval $(call copy-test-library,elf_file_unittest_relocs_ia32_packed.so))
|
||||||
|
$(eval $(call copy-test-library,elf_file_unittest_relocs_x64.so))
|
||||||
|
$(eval $(call copy-test-library,elf_file_unittest_relocs_x64_packed.so))
|
||||||
|
$(eval $(call copy-test-library,elf_file_unittest_relocs_mips32.so))
|
||||||
|
$(eval $(call copy-test-library,elf_file_unittest_relocs_mips32_packed.so))
|
||||||
|
@ -302,13 +302,75 @@ static void AdjustSectionHeadersForHole(Elf* elf,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper for ResizeSection(). Adjust the offsets of any program headers
|
// Helpers for ResizeSection(). On packing, reduce p_align for LOAD segments
|
||||||
// that have offsets currently beyond the hole start.
|
// to 4kb if larger. On unpacking, restore p_align for LOAD segments if
|
||||||
|
// packing reduced it to 4kb. Return true if p_align was changed.
|
||||||
template <typename ELF>
|
template <typename ELF>
|
||||||
static void AdjustProgramHeaderOffsets(typename ELF::Phdr* program_headers,
|
static bool ClampLoadSegmentAlignment(typename ELF::Phdr* program_header) {
|
||||||
|
CHECK(program_header->p_type == PT_LOAD);
|
||||||
|
|
||||||
|
// If large, reduce p_align for a LOAD segment to page size on packing.
|
||||||
|
if (program_header->p_align > kPageSize) {
|
||||||
|
program_header->p_align = kPageSize;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ELF>
|
||||||
|
static bool RestoreLoadSegmentAlignment(typename ELF::Phdr* program_headers,
|
||||||
|
size_t count,
|
||||||
|
typename ELF::Phdr* program_header) {
|
||||||
|
CHECK(program_header->p_type == PT_LOAD);
|
||||||
|
|
||||||
|
// If p_align was reduced on packing, restore it to its previous value
|
||||||
|
// on unpacking. We do this by searching for a different LOAD segment
|
||||||
|
// and setting p_align to that of the other LOAD segment found.
|
||||||
|
//
|
||||||
|
// Relies on the following observations:
|
||||||
|
// - a packable ELF executable has more than one LOAD segment;
|
||||||
|
// - before packing all LOAD segments have the same p_align;
|
||||||
|
// - on packing we reduce only one LOAD segment's p_align.
|
||||||
|
if (program_header->p_align == kPageSize) {
|
||||||
|
for (size_t i = 0; i < count; ++i) {
|
||||||
|
typename ELF::Phdr* other_header = &program_headers[i];
|
||||||
|
if (other_header->p_type == PT_LOAD && other_header != program_header) {
|
||||||
|
program_header->p_align = other_header->p_align;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG(WARNING) << "Cannot find a LOAD segment from which to restore p_align";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename ELF>
|
||||||
|
static bool AdjustLoadSegmentAlignment(typename ELF::Phdr* program_headers,
|
||||||
size_t count,
|
size_t count,
|
||||||
typename ELF::Off hole_start,
|
typename ELF::Phdr* program_header,
|
||||||
ssize_t hole_size) {
|
ssize_t hole_size) {
|
||||||
|
CHECK(program_header->p_type == PT_LOAD);
|
||||||
|
|
||||||
|
bool status = false;
|
||||||
|
if (hole_size < 0) {
|
||||||
|
status = ClampLoadSegmentAlignment<ELF>(program_header);
|
||||||
|
} else if (hole_size > 0) {
|
||||||
|
status = RestoreLoadSegmentAlignment<ELF>(program_headers,
|
||||||
|
count,
|
||||||
|
program_header);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper for ResizeSection(). Adjust the offsets of any program headers
|
||||||
|
// that have offsets currently beyond the hole start, and adjust the
|
||||||
|
// virtual and physical addrs (and perhaps alignment) of the others.
|
||||||
|
template <typename ELF>
|
||||||
|
static void AdjustProgramHeaderFields(typename ELF::Phdr* program_headers,
|
||||||
|
size_t count,
|
||||||
|
typename ELF::Off hole_start,
|
||||||
|
ssize_t hole_size) {
|
||||||
|
int alignment_changes = 0;
|
||||||
for (size_t i = 0; i < count; ++i) {
|
for (size_t i = 0; i < count; ++i) {
|
||||||
typename ELF::Phdr* program_header = &program_headers[i];
|
typename ELF::Phdr* program_header = &program_headers[i];
|
||||||
|
|
||||||
@ -327,9 +389,20 @@ static void AdjustProgramHeaderOffsets(typename ELF::Phdr* program_headers,
|
|||||||
} else {
|
} else {
|
||||||
program_header->p_vaddr -= hole_size;
|
program_header->p_vaddr -= hole_size;
|
||||||
program_header->p_paddr -= hole_size;
|
program_header->p_paddr -= hole_size;
|
||||||
if (program_header->p_align > kPageSize) {
|
|
||||||
program_header->p_align = kPageSize;
|
// If packing, clamp LOAD segment alignment to 4kb to prevent strip
|
||||||
|
// from adjusting it unnecessarily if run on a packed file. If
|
||||||
|
// unpacking, attempt to restore a reduced alignment to its previous
|
||||||
|
// value. Ensure that we do this on at most one LOAD segment.
|
||||||
|
if (program_header->p_type == PT_LOAD) {
|
||||||
|
alignment_changes += AdjustLoadSegmentAlignment<ELF>(program_headers,
|
||||||
|
count,
|
||||||
|
program_header,
|
||||||
|
hole_size);
|
||||||
|
LOG_IF(FATAL, alignment_changes > 1)
|
||||||
|
<< "Changed p_align on more than one LOAD segment";
|
||||||
}
|
}
|
||||||
|
|
||||||
VLOG(1) << "phdr[" << i
|
VLOG(1) << "phdr[" << i
|
||||||
<< "] p_vaddr adjusted to "<< program_header->p_vaddr
|
<< "] p_vaddr adjusted to "<< program_header->p_vaddr
|
||||||
<< "; p_paddr adjusted to "<< program_header->p_paddr
|
<< "; p_paddr adjusted to "<< program_header->p_paddr
|
||||||
@ -383,10 +456,10 @@ static void RewriteProgramHeadersForHole(Elf* elf,
|
|||||||
target_load_header->p_memsz += hole_size;
|
target_load_header->p_memsz += hole_size;
|
||||||
|
|
||||||
// Adjust the offsets and p_vaddrs
|
// Adjust the offsets and p_vaddrs
|
||||||
AdjustProgramHeaderOffsets<ELF>(elf_program_header,
|
AdjustProgramHeaderFields<ELF>(elf_program_header,
|
||||||
program_header_count,
|
program_header_count,
|
||||||
hole_start,
|
hole_start,
|
||||||
hole_size);
|
hole_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper for ResizeSection(). Locate and return the dynamic section.
|
// Helper for ResizeSection(). Locate and return the dynamic section.
|
||||||
|
@ -183,6 +183,18 @@ TEST(ElfFile, PackRelocationsArm64) {
|
|||||||
RunPackRelocationsTestFor("arm64");
|
RunPackRelocationsTestFor("arm64");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ElfFile, PackRelocationsMips32) {
|
||||||
|
RunPackRelocationsTestFor("mips32");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ElfFile, PackRelocationsIa32) {
|
||||||
|
RunPackRelocationsTestFor("ia32");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ElfFile, PackRelocationsX64) {
|
||||||
|
RunPackRelocationsTestFor("x64");
|
||||||
|
}
|
||||||
|
|
||||||
TEST(ElfFile, UnpackRelocationsArm32) {
|
TEST(ElfFile, UnpackRelocationsArm32) {
|
||||||
RunUnpackRelocationsTestFor("arm32");
|
RunUnpackRelocationsTestFor("arm32");
|
||||||
}
|
}
|
||||||
@ -191,4 +203,16 @@ TEST(ElfFile, UnpackRelocationsArm64) {
|
|||||||
RunUnpackRelocationsTestFor("arm64");
|
RunUnpackRelocationsTestFor("arm64");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ElfFile, UnpackRelocationsMips32) {
|
||||||
|
RunUnpackRelocationsTestFor("mips32");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ElfFile, UnpackRelocationsIa32) {
|
||||||
|
RunUnpackRelocationsTestFor("ia32");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ElfFile, UnpackRelocationsX64) {
|
||||||
|
RunUnpackRelocationsTestFor("x64");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace relocation_packer
|
} // namespace relocation_packer
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32.so
Executable file
BIN
tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32.so
Executable file
Binary file not shown.
BIN
tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32_packed.so
Executable file
BIN
tools/relocation_packer/test_data/elf_file_unittest_relocs_ia32_packed.so
Executable file
Binary file not shown.
BIN
tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32.so
Executable file
BIN
tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32.so
Executable file
Binary file not shown.
BIN
tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32_packed.so
Executable file
BIN
tools/relocation_packer/test_data/elf_file_unittest_relocs_mips32_packed.so
Executable file
Binary file not shown.
BIN
tools/relocation_packer/test_data/elf_file_unittest_relocs_x64.so
Executable file
BIN
tools/relocation_packer/test_data/elf_file_unittest_relocs_x64.so
Executable file
Binary file not shown.
BIN
tools/relocation_packer/test_data/elf_file_unittest_relocs_x64_packed.so
Executable file
BIN
tools/relocation_packer/test_data/elf_file_unittest_relocs_x64_packed.so
Executable file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user