1211706Skib/* 2211706Skib * Copyright (c) 2010 Konstantin Belousov <kib@freebsd.org> 3211706Skib * All rights reserved. 4211706Skib * 5211706Skib * Redistribution and use in source and binary forms, with or without 6211706Skib * modification, are permitted provided that the following conditions 7211706Skib * are met: 8211706Skib * 1. Redistributions of source code must retain the above copyright 9211706Skib * notice, this list of conditions and the following disclaimer. 10211706Skib * 2. Neither the name of the author nor the names of any co-contributors 11211706Skib * may be used to endorse or promote products derived from this software 12211706Skib * without specific prior written permission. 13211706Skib * 14211706Skib * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15211706Skib * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16211706Skib * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17211706Skib * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18211706Skib * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19211706Skib * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20211706Skib * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21211706Skib * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22211706Skib * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23211706Skib * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24211706Skib * SUCH DAMAGE. 25211706Skib * 26211706Skib * $FreeBSD$ 27211706Skib */ 28211706Skib 29217154Skib#include <sys/types.h> 30217154Skib#include <sys/mman.h> 31217154Skib#include <sys/resource.h> 32217154Skib#include <sys/sysctl.h> 33211706Skib#include <link.h> 34217154Skib#include <stddef.h> 35211706Skib 36211706Skibint 37211706Skib__elf_phdr_match_addr(struct dl_phdr_info *phdr_info, void *addr) 38211706Skib{ 39211706Skib const Elf_Phdr *ph; 40211706Skib int i; 41211706Skib 42211706Skib for (i = 0; i < phdr_info->dlpi_phnum; i++) { 43211706Skib ph = &phdr_info->dlpi_phdr[i]; 44211706Skib if (ph->p_type != PT_LOAD || (ph->p_flags & PF_X) == 0) 45211706Skib continue; 46211706Skib if (phdr_info->dlpi_addr + ph->p_vaddr <= (uintptr_t)addr && 47211706Skib (uintptr_t)addr + sizeof(addr) < phdr_info->dlpi_addr + 48211706Skib ph->p_vaddr + ph->p_memsz) 49211706Skib break; 50211706Skib } 51211706Skib return (i != phdr_info->dlpi_phnum); 52211706Skib} 53217154Skib 54217154Skib#pragma weak __pthread_map_stacks_exec 55217154Skibvoid 56217154Skib__pthread_map_stacks_exec(void) 57217154Skib{ 58217154Skib int mib[2]; 59217154Skib struct rlimit rlim; 60217154Skib u_long usrstack; 61217154Skib size_t len; 62217154Skib 63217154Skib mib[0] = CTL_KERN; 64217154Skib mib[1] = KERN_USRSTACK; 65217154Skib len = sizeof(usrstack); 66217154Skib if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &usrstack, &len, NULL, 0) 67217154Skib == -1) 68217154Skib return; 69217154Skib if (getrlimit(RLIMIT_STACK, &rlim) == -1) 70217154Skib return; 71217154Skib mprotect((void *)(uintptr_t)(usrstack - rlim.rlim_cur), 72217154Skib rlim.rlim_cur, _rtld_get_stack_prot()); 73217154Skib} 74217154Skib 75