diff options
Diffstat (limited to 'cpukit/libdl/rtl-elf.c')
-rw-r--r-- | cpukit/libdl/rtl-elf.c | 95 |
1 files changed, 69 insertions, 26 deletions
diff --git a/cpukit/libdl/rtl-elf.c b/cpukit/libdl/rtl-elf.c index 75b3d9c953..dd6d8617bb 100644 --- a/cpukit/libdl/rtl-elf.c +++ b/cpukit/libdl/rtl-elf.c @@ -1,10 +1,5 @@ -/* - * COPYRIGHT (c) 2012-2019 Chris Johns <chrisj@rtems.org> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ +/* SPDX-License-Identifier: BSD-2-Clause */ + /** * @file * @@ -15,6 +10,31 @@ * This is the RTL implementation. */ +/* + * COPYRIGHT (c) 2012-2019 Chris Johns <chrisj@rtems.org> + * + * 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -158,12 +178,19 @@ rtems_rtl_elf_find_symbol (rtems_rtl_obj* obj, /* * If the symbol type is STT_NOTYPE the symbol references a global - * symbol. The gobal symbol table is searched to find it and that value + * symbol. The global symbol table is searched to find it and that value * returned. If the symbol is local to the object module the section for the * symbol is located and it's base added to the symbol's value giving an * absolute location. + * + * If the symbols type of TLS return the symbols value. It is the + * offset from the thread's TLS area base. The offset is set by the + * linker for the base image and by the TLS allocator for loaded + * modules. There is no section and no absolute base. */ - if (ELF_ST_TYPE(sym->st_info) == STT_NOTYPE || sym->st_shndx == SHN_COMMON) + if (ELF_ST_TYPE (sym->st_info) == STT_NOTYPE || + sym->st_shndx == SHN_COMMON || + ELF_ST_TYPE (sym->st_info) == STT_TLS) { /* * Search the object file then the global table for the symbol. @@ -172,7 +199,7 @@ rtems_rtl_elf_find_symbol (rtems_rtl_obj* obj, if (!*symbol) return false; - *value = (Elf_Addr) (*symbol)->value; + *value = (Elf_Addr)(uintptr_t) (*symbol)->value; return true; } @@ -182,7 +209,7 @@ rtems_rtl_elf_find_symbol (rtems_rtl_obj* obj, if (!sect) return false; - *value = sym->st_value + (Elf_Addr) sect->base; + *value = sym->st_value + (Elf_Addr)(uintptr_t) sect->base; return true; } @@ -227,6 +254,13 @@ rtems_rtl_elf_reloc_parser (rtems_rtl_obj* obj, rtems_rtl_elf_rel_status rs; /* + * TLS are not parsed. + */ + if (ELF_ST_TYPE (sym->st_info) == STT_TLS) { + return true; + } + + /* * Check the reloc record to see if a trampoline is needed. */ if (is_rela) @@ -282,7 +316,7 @@ rtems_rtl_elf_reloc_parser (rtems_rtl_obj* obj, * Find the symbol's object file. It cannot be NULL so ignore that result * if returned, it means something is corrupted. We are in an iterator. */ - rtems_rtl_obj* sobj = rtems_rtl_find_obj_with_symbol (symbol); + rtems_rtl_obj* sobj = rtems_rtl_find_obj_with_symbol (symbol); if (sobj != NULL) { /* @@ -771,7 +805,7 @@ rtems_rtl_elf_tramp_resolve_reloc (rtems_rtl_unresolv_rec* rec, } if (unresolved || rs == rtems_rtl_elf_rel_tramp_add) - tramp->obj->tramps_size += tramp->obj->tramp_size; + ++tramp->obj->tramp_slots; if (rs == rtems_rtl_elf_rel_failure) { *failure = true; @@ -784,7 +818,7 @@ rtems_rtl_elf_tramp_resolve_reloc (rtems_rtl_unresolv_rec* rec, } static bool -rtems_rtl_elf_alloc_trampoline (rtems_rtl_obj* obj, size_t unresolved) +rtems_rtl_elf_find_trampolines (rtems_rtl_obj* obj, size_t unresolved) { rtems_rtl_tramp_data td = { 0 }; td.obj = obj; @@ -795,21 +829,20 @@ rtems_rtl_elf_alloc_trampoline (rtems_rtl_obj* obj, size_t unresolved) if (td.failure) return false; rtems_rtl_trampoline_remove (obj); - obj->tramp_relocs = obj->tramp_size == 0 ? 0 : obj->tramps_size / obj->tramp_size; + obj->tramp_relocs = obj->tramp_slots; if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) - printf ("rtl: tramp:elf: tramps: %zu count:%zu total:%zu\n", + printf ("rtl: tramp:elf: tramps: slots:%zu count:%zu total:%zu\n", obj->tramp_relocs, td.count, td.total); /* * Add on enough space to handle the unresolved externals that need to be * resolved at some point in time. They could all require fixups and * trampolines. */ - obj->tramps_size += obj->tramp_size * unresolved; + obj->tramp_slots += unresolved; if (rtems_rtl_trace (RTEMS_RTL_TRACE_RELOC)) - printf ("rtl: tramp:elf: slots: %zu (%zu)\n", - obj->tramp_size == 0 ? 0 : obj->tramps_size / obj->tramp_size, - obj->tramps_size); - return rtems_rtl_obj_alloc_trampoline (obj); + printf ("rtl: tramp:elf: slots:%zu (%zu)\n", + obj->tramp_slots, obj->tramp_slots * obj->tramp_slot_size); + return true; } static bool @@ -1151,7 +1184,7 @@ rtems_rtl_elf_symbols_load (rtems_rtl_obj* obj, rtems_chain_set_off_chain (&osym->node); memcpy (string, name, strlen (name) + 1); osym->name = string; - osym->value = (uint8_t*) value; + osym->value = (void*) (intptr_t) value; osym->data = symbol.st_shndx; if (rtems_rtl_trace (RTEMS_RTL_TRACE_SYMBOL)) @@ -1696,7 +1729,7 @@ rtems_rtl_elf_file_load (rtems_rtl_obj* obj, int fd) /* * Set the format's architecture's maximum tramp size. */ - obj->tramp_size = rtems_rtl_elf_relocate_tramp_max_size (); + obj->tramp_slot_size = rtems_rtl_elf_relocate_tramp_max_size (); /* * Parse the section information first so we have the memory map of the object @@ -1745,13 +1778,23 @@ rtems_rtl_elf_file_load (rtems_rtl_obj* obj, int fd) if (!rtems_rtl_obj_alloc_sections (obj, fd, rtems_rtl_elf_arch_alloc, &ehdr)) return false; - if (!rtems_rtl_obj_load_symbols (obj, fd, rtems_rtl_elf_symbols_locate, &ehdr)) + if (!rtems_rtl_elf_dependents (obj, &relocs)) return false; - if (!rtems_rtl_elf_dependents (obj, &relocs)) + if (!rtems_rtl_elf_find_trampolines (obj, relocs.unresolved)) return false; - if (!rtems_rtl_elf_alloc_trampoline (obj, relocs.unresolved)) + /* + * Resize the sections to allocate the trampoline memory as part of + * the text section. + */ + if (rtems_rtl_obj_has_trampolines (obj)) + { + if (!rtems_rtl_obj_resize_sections (obj)) + return false; + } + + if (!rtems_rtl_obj_load_symbols (obj, fd, rtems_rtl_elf_symbols_locate, &ehdr)) return false; /* |