Back to index

glibc  2.9
ldsodefs.h
Go to the documentation of this file.
00001 /* Run-time dynamic linker data structures for loaded ELF shared objects.
00002    Copyright (C) 2005, 2006 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #ifndef       _LDSODEFS_H
00021 
00022 /* Get the real definitions.  */
00023 #include_next <ldsodefs.h>
00024 
00025 /* Now define our stuff.  */
00026 
00027 static __always_inline bool
00028 _dl_ppc64_is_opd_sym (const struct link_map *l, const ElfW(Sym) *sym)
00029 {
00030   return (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC
00031          && l->l_addr + sym->st_value >= (ElfW(Addr)) l->l_ld
00032          && l->l_addr + sym->st_value < l->l_map_end
00033          && sym->st_size != 0);
00034 }
00035 
00036 static __always_inline bool
00037 _dl_ppc64_addr_sym_match (const struct link_map *l, const ElfW(Sym) *sym,
00038                        const ElfW(Sym) *matchsym, ElfW(Addr) addr)
00039 {
00040   ElfW(Addr) value = l->l_addr + sym->st_value;
00041   if (_dl_ppc64_is_opd_sym (l, sym))
00042     {
00043       if (addr < value || addr >= value + 24)
00044        {
00045          value = *(ElfW(Addr) *) value;
00046          if (addr < value || addr >= value + sym->st_size)
00047            return false;
00048        }
00049     }
00050   else if (sym->st_shndx == SHN_UNDEF || sym->st_size == 0)
00051     {
00052       if (addr != value)
00053        return false;
00054     }
00055   else if (addr < value || addr >= value + sym->st_size)
00056     return false;
00057 
00058   if (matchsym == NULL)
00059     return true;
00060 
00061   ElfW(Addr) matchvalue = l->l_addr + matchsym->st_value;
00062   if (_dl_ppc64_is_opd_sym (l, matchsym)
00063       && (addr < matchvalue || addr > matchvalue + 24))
00064     matchvalue = *(ElfW(Addr) *) matchvalue;
00065 
00066   return matchvalue < value;
00067 }
00068 
00069 /* If this is a function symbol defined past the end of our dynamic
00070    section, then it must be a function descriptor.  Allow these symbols
00071    to match their associated function code range as well as the
00072    descriptor addresses.  */
00073 #undef DL_ADDR_SYM_MATCH
00074 #define DL_ADDR_SYM_MATCH(L, SYM, MATCHSYM, ADDR) \
00075   _dl_ppc64_addr_sym_match (L, SYM, MATCHSYM, ADDR)
00076 
00077 #endif /* ldsodefs.h */