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
[-- Attachment #1 --]
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
[-- Attachment #2 --]
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.
*/
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1405545833.1312.84.camel>
