MIPS: Fix MIPS linker VDSO issues
This patch resolves two issues: (1) AOSP MIPS linker crash with SIGSEGV while relocating VDSO GOT (2) Missing of MIPS_ABI_FP_ANY flag while ckecking & adjusting MIPS FP modes (1): AOSP MIPS linker crash with SIGSEGV while relocating VDSO GOT During bringup and testing of the kernel VDSO support on the emulator we encountered an issue where all userspace processes were crashing due to linker crash with SIGSEGV during VDSO GOT relocation. The mentioned scenario will trigger SIGSEGV in the linker only if the kernel code base contains VDSO implementation introduced with the following commits: a7f4df4 MIPS: VDSO: Add implementations of gettimeofday() and clock_gettime() c0a9f72 irqchip: irq-mips-gic: Provide function to map GIC user section ebb5e78 MIPS: Initial implementation of a VDSO Another prerequisite is that the linker contains the following commit from AOSP: https://android-review.googlesource.com/#/c/264857/ The above commit introduces auxvec.h header containing definition of AT_SYSINFO_EHDR in: https://android.googlesource.com/platform/bionic/+/master/libc/kernel/uapi/asm-mips/asm/auxvec.h, which in turn activates VDSO GOT relocations in mips_relocate_got(): https://android.googlesource.com/platform/bionic/+/master/linker/linker_mips.cpp#149 Since VDSO is mapped as a RO region, writing anything to its page will result in SIGSEGV. Removing this 0xdeadbeef cookies writes to the got[0]/got[1] solved SIGSEGV issue. We also compared with the glibc linker code and we haven't seen anything similar like writing some cookie values into GOT entries. (2): Missing of MIPS_ABI_FP_ANY flag while checking & adjusting MIPS FP modes This issue was found during testing of the patch: https://android-review.googlesource.com/#/c/platform/bionic/+/494440/ This patch adds a bionic dlfcn.dlopen_vdso test which tries to open "linux-vdso.so.1" (virtual ELF shared library) and expects to succeed. dlopen fails in the mips linker part due to the following error: "Unsupported MIPS32 FloatPt ABI 0 found in linux.vdso.so.1" According to: https://dmz-portal.imgtec.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking#A.2._O32_FPXX_code_calling_FPXX, ABI 0 is: Val_GNU_MIPS_ABI_FP_ANY = 0 /* Not tagged or not using any ABIs affected by the differences. */ The issue appeared because MIPS_ABI_FP_ANY is not supposed to be checked as a possible FP ABI-variant compatibility flag. This patch adds logic to MIPS linker to handle this case appropriately, after which dlfcn.dlopen_vdso test passes. Test: * bionic-unit-tests --gtest_filter=dlfcn.dlopen_vdso * Boot android in emulator with kernel which supports VDSO optimizations Change-Id: Icbcd9879beea1b38fbe8d97b3b205058eaa861f4 Signed-off-by: Goran Ferenc <goran.ferenc@imgtec.com>
This commit is contained in:
parent
ddd6436df2
commit
e8c76b7a30
1 changed files with 5 additions and 4 deletions
|
@ -142,13 +142,12 @@ bool soinfo::mips_relocate_got(const VersionTracker& version_tracker,
|
|||
|
||||
// got[0] is the address of the lazy resolver function.
|
||||
// got[1] may be used for a GNU extension.
|
||||
// Set it to a recognizable address in case someone calls it (should be _rtld_bind_start).
|
||||
// FIXME: maybe this should be in a separate routine?
|
||||
if ((flags_ & FLAG_LINKER) == 0) {
|
||||
size_t g = 0;
|
||||
got[g++] = reinterpret_cast<ElfW(Addr)*>(0xdeadbeef);
|
||||
size_t g = 1;
|
||||
// Check for the high bit to determine whether to skip got[1]
|
||||
if (reinterpret_cast<intptr_t>(got[g]) < 0) {
|
||||
got[g++] = reinterpret_cast<ElfW(Addr)*>(0xdeadfeed);
|
||||
g++;
|
||||
}
|
||||
// Relocate the local GOT entries.
|
||||
for (; g < mips_local_gotno_; g++) {
|
||||
|
@ -231,6 +230,7 @@ struct mips_elf_abiflags_v0 {
|
|||
#define MIPS_AFL_FLAGS1_ODDSPREG 1 // Uses odd-numbered single-prec fp regs
|
||||
|
||||
// Some values of fp_abi: via compiler flag:
|
||||
#define MIPS_ABI_FP_ANY 0 // Not tagged or not using any ABIs affected by the differences.
|
||||
#define MIPS_ABI_FP_DOUBLE 1 // -mdouble-float
|
||||
#define MIPS_ABI_FP_XX 5 // -mfpxx
|
||||
#define MIPS_ABI_FP_64A 7 // -mips32r* -mfp64 -mno-odd-spreg
|
||||
|
@ -277,6 +277,7 @@ bool soinfo::mips_check_and_adjust_fp_modes() {
|
|||
#if __mips_isa_rev >= 5
|
||||
mips_fpabi == MIPS_ABI_FP_64A ||
|
||||
#endif
|
||||
mips_fpabi == MIPS_ABI_FP_ANY ||
|
||||
mips_fpabi == MIPS_ABI_FP_XX )) {
|
||||
DL_ERR("Unsupported MIPS32 FloatPt ABI %d found in \"%s\"",
|
||||
mips_fpabi, get_realpath());
|
||||
|
|
Loading…
Reference in a new issue