--- zzzz-none-000/linux-3.10.107/arch/tile/mm/elf.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/tile/mm/elf.c 2021-02-04 17:41:59.000000000 +0000 @@ -17,11 +17,13 @@ #include #include #include +#include #include #include #include #include -#include +#include +#include /* Notify a running simulator, if any, that an exec just occurred. */ static void sim_notify_exec(const char *binary_name) @@ -38,21 +40,65 @@ static int notify_exec(struct mm_struct *mm) { - int retval = 0; /* failure */ + int ret = 0; + char *buf, *path; + struct vm_area_struct *vma; + struct file *exe_file; + + if (!sim_is_simulator()) + return 1; + + buf = (char *) __get_free_page(GFP_KERNEL); + if (buf == NULL) + return 0; + + exe_file = get_mm_exe_file(mm); + if (exe_file == NULL) + goto done_free; + + path = file_path(exe_file, buf, PAGE_SIZE); + if (IS_ERR(path)) + goto done_put; + + down_read(&mm->mmap_sem); + for (vma = current->mm->mmap; ; vma = vma->vm_next) { + if (vma == NULL) { + up_read(&mm->mmap_sem); + goto done_put; + } + if (vma->vm_file == exe_file) + break; + } - if (mm->exe_file) { - char *buf = (char *) __get_free_page(GFP_KERNEL); - if (buf) { - char *path = d_path(&mm->exe_file->f_path, - buf, PAGE_SIZE); - if (!IS_ERR(path)) { - sim_notify_exec(path); - retval = 1; + /* + * Notify simulator of an ET_DYN object so we know the load address. + * The somewhat cryptic overuse of SIM_CONTROL_DLOPEN allows us + * to be backward-compatible with older simulator releases. + */ + if (vma->vm_start == (ELF_ET_DYN_BASE & PAGE_MASK)) { + char buf[64]; + int i; + + snprintf(buf, sizeof(buf), "0x%lx:@", vma->vm_start); + for (i = 0; ; ++i) { + char c = buf[i]; + __insn_mtspr(SPR_SIM_CONTROL, + (SIM_CONTROL_DLOPEN + | (c << _SIM_CONTROL_OPERATOR_BITS))); + if (c == '\0') { + ret = 1; /* success */ + break; } - free_page((unsigned long)buf); } } - return retval; + up_read(&mm->mmap_sem); + + sim_notify_exec(path); +done_put: + fput(exe_file); +done_free: + free_page((unsigned long)buf); + return ret; } /* Notify a running simulator, if any, that we loaded an interpreter. */ @@ -68,41 +114,12 @@ } -/* Kernel address of page used to map read-only kernel data into userspace. */ -static void *vdso_page; - -/* One-entry array used for install_special_mapping. */ -static struct page *vdso_pages[1]; - -static int __init vdso_setup(void) -{ - vdso_page = (void *)get_zeroed_page(GFP_ATOMIC); - memcpy(vdso_page, __rt_sigreturn, __rt_sigreturn_end - __rt_sigreturn); - vdso_pages[0] = virt_to_page(vdso_page); - return 0; -} -device_initcall(vdso_setup); - -const char *arch_vma_name(struct vm_area_struct *vma) -{ - if (vma->vm_private_data == vdso_pages) - return "[vdso]"; -#ifndef __tilegx__ - if (vma->vm_start == MEM_USER_INTRPT) - return "[intrpt]"; -#endif - return NULL; -} - int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack) { struct mm_struct *mm = current->mm; - unsigned long vdso_base; int retval = 0; - down_write(&mm->mmap_sem); - /* * Notify the simulator that an exec just occurred. * If we can't find the filename of the mapping, just use @@ -111,14 +128,9 @@ if (!notify_exec(mm)) sim_notify_exec(bprm->filename); - /* - * MAYWRITE to allow gdb to COW and set breakpoints - */ - vdso_base = VDSO_BASE; - retval = install_special_mapping(mm, vdso_base, PAGE_SIZE, - VM_READ|VM_EXEC| - VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, - vdso_pages); + down_write(&mm->mmap_sem); + + retval = setup_vdso_pages(); #ifndef __tilegx__ /*