From owner-freebsd-hackers@FreeBSD.ORG Wed Jul 16 21:23:56 2014 Return-Path: Delivered-To: hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id BD5A6408 for ; Wed, 16 Jul 2014 21:23:56 +0000 (UTC) Received: from mho-02-ewr.mailhop.org (mho-02-ewr.mailhop.org [204.13.248.72]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7DE44255A for ; Wed, 16 Jul 2014 21:23:56 +0000 (UTC) Received: from c-50-155-136-3.hsd1.co.comcast.net ([50.155.136.3] helo=ilsoft.org) by mho-02-ewr.mailhop.org with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.72) (envelope-from ) id 1X7Wg6-000Cim-VD for hackers@freebsd.org; Wed, 16 Jul 2014 21:23:55 +0000 Received: from [172.22.42.240] (revolution.hippie.lan [172.22.42.240]) by ilsoft.org (8.14.9/8.14.9) with ESMTP id s6GLNrqD015637 for ; Wed, 16 Jul 2014 15:23:53 -0600 (MDT) (envelope-from ian@FreeBSD.org) X-Mail-Handler: Dyn Standard SMTP by Dyn X-Originating-IP: 50.155.136.3 X-Report-Abuse-To: abuse@dyndns.com (see http://www.dyndns.com/services/sendlabs/outbound_abuse.html for abuse reporting information) X-MHO-User: U2FsdGVkX19dHW1liLNvkT8CqR35sGOd X-Authentication-Warning: paranoia.hippie.lan: Host revolution.hippie.lan [172.22.42.240] claimed to be [172.22.42.240] Subject: [CFR] Adding a function to rtld-elf.so, how to handle Symbol.map? From: Ian Lepore To: hackers@freebsd.org Content-Type: multipart/mixed; boundary="=-8Dlxw1wOsZ9cQfa0wi9b" Date: Wed, 16 Jul 2014 15:23:53 -0600 Message-ID: <1405545833.1312.84.camel@revolution.hippie.lan> Mime-Version: 1.0 X-Mailer: Evolution 2.32.1 FreeBSD GNOME Team Port X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Jul 2014 21:23:56 -0000 --=-8Dlxw1wOsZ9cQfa0wi9b Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit I need to add an ARM-specific function to rtld-elf.so to help locate exception unwind info in shared objects. I'm confused about how to add the function to Symbol.map... do I have to add a 1.4 section because it was first added in FreeBSD 11, or does it go into an existing section because it doesn't introduce changes to an existing ABI? -- Ian --=-8Dlxw1wOsZ9cQfa0wi9b Content-Disposition: inline; filename="find_exidx2.diff" Content-Type: text/x-patch; name="find_exidx2.diff"; charset="us-ascii" Content-Transfer-Encoding: 7bit diff -r 63a383d5fd3e libexec/rtld-elf/Symbol.map --- libexec/rtld-elf/Symbol.map Thu May 01 08:14:39 2014 -0600 +++ libexec/rtld-elf/Symbol.map Wed Jul 16 15:06:30 2014 -0600 @@ -20,6 +20,7 @@ FBSD_1.0 { FBSD_1.3 { fdlopen; + __gnu_Unwind_Find_exidx; }; FBSDprivate_1.0 { diff -r 63a383d5fd3e libexec/rtld-elf/arm/Makefile.inc --- libexec/rtld-elf/arm/Makefile.inc Thu May 01 08:14:39 2014 -0600 +++ libexec/rtld-elf/arm/Makefile.inc Wed Jul 16 15:06:30 2014 -0600 @@ -1,1 +1,5 @@ # $FreeBSD: head/libexec/rtld-elf/arm/Makefile.inc 130646 2004-06-17 17:53:16Z cognet $ + +SRCS+= find_exidx.c +CFLAGS+= -I${TOPSRCDIR}/contrib/libexecinfo + diff -r 63a383d5fd3e libexec/rtld-elf/arm/find_exidx.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ libexec/rtld-elf/arm/find_exidx.c Wed Jul 16 15:06:30 2014 -0600 @@ -0,0 +1,103 @@ +/*- + * Copyright (c) 2014 Ian Lepore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include /* This is contrib/libexecinfo/unwind.h */ + +/* + * ARM EABI unwind helper for dynamically linked code. + * + * This code iterates all shared objects that have been loaded, looking for one + * whose in-memory text address range contains the given PC. It returns the + * address of the exidx section in that shared object along with the number of + * entries in that section, or NULL if it wasn't found. This overrides a + * weak-linkage default implementation in the unwinder library that only works + * for a static-linked application. + */ + +struct cbdata { + _Unwind_Ptr pc; + _Unwind_Ptr exptr; + int excount; +}; + +static int +findexcb(struct dl_phdr_info *info, size_t size, void *data) +{ + struct cbdata * cbd; + const Elf_Phdr *hdr; + Elf_Addr exptr, pc, vaddr; + Elf_Word len; + int i, exlen, found; + const int FOUND_PC = 0x01; + const int FOUND_EX = 0x02; + const int SIZEOF_EIT_ENTRY = 8; /* Not available in a header file. */ + + cbd = data; + found = 0; + pc = (Elf_Addr)cbd->pc; + for (i = 0, hdr = info->dlpi_phdr; i < info->dlpi_phnum; i++, hdr++) { + vaddr = info->dlpi_addr + hdr->p_vaddr; + len = hdr->p_memsz; + if (hdr->p_type == PT_LOAD && (hdr->p_flags & PF_X) != 0 && + pc >= vaddr && pc < vaddr + len) { + found |= FOUND_PC; + } else if (hdr->p_type == PT_ARM_EXIDX) { + found |= FOUND_EX; + exptr = vaddr; + exlen = len; + } + if (found == (FOUND_PC | FOUND_EX)) { + cbd->exptr = (_Unwind_Ptr)(exptr); + cbd->excount = exlen / SIZEOF_EIT_ENTRY; + return (1); /* Stop iterating. */ + } + } + return (0); /* Continue iterating with next object. */ + +} + +_Unwind_Ptr +__gnu_Unwind_Find_exidx(_Unwind_Ptr pc, int * pcount) +{ + struct cbdata cbd; + + cbd.pc = pc; + cbd.exptr = NULL; + cbd.excount = 0; + dl_iterate_phdr(findexcb, &cbd); + if (cbd.exptr != NULL) + *pcount = cbd.excount; + return (cbd.exptr); +} + diff -r 63a383d5fd3e sys/arm/include/elf.h --- a/sys/arm/include/elf.h Thu May 01 08:14:39 2014 -0600 +++ b/sys/arm/include/elf.h Wed Jul 16 15:06:30 2014 -0600 @@ -55,6 +55,9 @@ typedef struct { /* Auxiliary vec #define ELF_MACHINE_OK(x) ((x) == EM_ARM) +/* Unwind info section type */ +#define PT_ARM_EXIDX (PT_LOPROC + 1) + /* * Relocation types. */ --=-8Dlxw1wOsZ9cQfa0wi9b--