Path: blob/main/lib/libc/arm/aeabi/aeabi_unwind_exidx.c
39536 views
/*-1* Copyright (c) 2014 Ian Lepore <[email protected]>2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND14* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE15* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE16* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE17* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS19* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)20* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT21* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY22* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF23* SUCH DAMAGE.24*/2526#include <sys/types.h>27#include <machine/elf.h>28#include <link.h>29#include <stddef.h>3031/*32* ARM EABI unwind helper.33*34* This finds the exidx section address and size associated with a given code35* address. There are separate implementations for static and dynamic code.36*37* GCC expects this function to exist as __gnu_Unwind_Find_exidx(), clang and38* BSD tools expect it to be dl_unwind_find_exidx(). Both have the same API, so39* we set up an alias for GCC.40*/41__strong_reference(dl_unwind_find_exidx, __gnu_Unwind_Find_exidx);4243/*44* Each entry in the exidx section is a pair of 32-bit words. We don't45* interpret the contents of the entries here; this typedef is just a local46* convenience for using sizeof() and doing pointer math.47*/48typedef struct exidx_entry {49uint32_t data[2];50} exidx_entry;5152#ifdef __PIC__5354/*55* Unwind helper for dynamically linked code.56*57* This finds the shared object that contains the given address, and returns the58* address of the exidx section in that shared object along with the number of59* entries in that section, or NULL if it wasn't found.60*/61void *62dl_unwind_find_exidx(const void *pc, int *pcount)63{64const Elf_Phdr *hdr;65struct dl_phdr_info info;66int i;6768if (_rtld_addr_phdr(pc, &info)) {69hdr = info.dlpi_phdr;70for (i = 0; i < info.dlpi_phnum; i++, hdr++) {71if (hdr->p_type == PT_ARM_EXIDX) {72*pcount = hdr->p_memsz / sizeof(exidx_entry);73return ((void *)(info.dlpi_addr + hdr->p_vaddr));74}75}76}77return (NULL);78}7980#else /* !__PIC__ */8182/*83* Unwind helper for statically linked code.84*85* In a statically linked program, the linker populates a pair of symbols with86* the addresses of the start and end of the exidx table, so returning the87* address and count of elements is pretty straighforward.88*/89void *90dl_unwind_find_exidx(const void *pc, int *pcount)91{92extern struct exidx_entry __exidx_start;93extern struct exidx_entry __exidx_end;9495*pcount = (int)(&__exidx_end - &__exidx_start);96return (&__exidx_start);97}9899#endif /* __PIC__ */100101102103