Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Jul 2014 15:23:53 -0600
From:      Ian Lepore <ian@FreeBSD.org>
To:        hackers@freebsd.org
Subject:   [CFR] Adding a function to rtld-elf.so, how to handle Symbol.map?
Message-ID:  <1405545833.1312.84.camel@revolution.hippie.lan>

next in thread | raw e-mail | index | archive | help

--=-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 <ian@freebsd.org>
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/elf_common.h>
+#include <sys/link_elf.h>
+#include <machine/elf.h>
+#include <stddef.h>
+#include <unwind.h>	/* 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--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1405545833.1312.84.camel>