mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-10-30 10:45:40 +03:00 
			
		
		
		
	1999-12-18 Ulrich Drepper <drepper@cygnus.com> * sysdeps/unix/sysv/linux/i386/setrlimit.c: Declare local variable result if necessary. * sysdeps/unix/sysv/linux/i386/bits/resource.h: Don't depend on the unreliable kernel headers. * sysdeps/unix/sysv/linux/bits/resource.h: Likewise. * sysdeps/unix/sysv/linux/sparc/bits/resource.h: Likewise. * sysdeps/unix/sysv/linux/alpha/bits/resource.h: New file. * sysdeps/unix/sysv/linux/mips/bits/resource.h: New file. 1999-12-18 Andreas Jaeger <aj@suse.de> * config.make.in (datadir): Added. Closes PR libc/1491. Patch by dervishd@jazzfree.com. 1999-12-18 Andreas Jaeger <aj@suse.de> * sysdeps/unix/sysv/linux/ftruncate64.c (ftruncate64): Save and set errno. * sysdeps/unix/sysv/linux/truncate64.c (truncate64): Likewise. 1999-12-18 Andreas Jaeger <aj@suse.de> * sysdeps/unix/sysv/linux/fxstat64.c: Rewrite to use fstat64 syscall if available. * sysdeps/unix/sysv/linux/lxstat64.c: Likewise for lstat64. * sysdeps/unix/sysv/linux/xstat64.c: Likewise for stat64. * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_STAT64_SYSCALL): New. 1999-12-17 Scott Bambrough <scottb@netwinder.org> * sysdeps/arm/dl-machine.h (CLEAR_CACHE): New macro to force a cache flush. * elf/dl-reloc.c (_dl_relocate_object): Add call to flush cache after .text segment fixups. 1999-12-16 Andreas Jaeger <aj@suse.de> * rt/aio.h: Remove erroneous __restrict declarations. 1999-12-18 Ulrich Drepper <drepper@cygnus.com> * scripts/rellns-sh: Find pwd program also in /usr/bin and let shell do the job if it is there neither. Patch by David R. Conrad <drc@adni.net> (PR libc/1485). 1999-12-16 Andreas Jaeger <aj@suse.de> * sysdeps/ieee754/bits/nan.h (NAN): Rename union to avoid duplicate definition with function __nan. Closes PR libc/1487 reported by <diana@kai.com>. * string/bits/string2.h (__strsep): Help gcc optimizing string access.
		
			
				
	
	
		
			165 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			165 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* Relocate a shared object and resolve its references to other loaded objects.
 | |
|    Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
 | |
|    This file is part of the GNU C Library.
 | |
| 
 | |
|    The GNU C Library is free software; you can redistribute it and/or
 | |
|    modify it under the terms of the GNU Library General Public License as
 | |
|    published by the Free Software Foundation; either version 2 of the
 | |
|    License, or (at your option) any later version.
 | |
| 
 | |
|    The GNU C Library is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|    Library General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU Library General Public
 | |
|    License along with the GNU C Library; see the file COPYING.LIB.  If not,
 | |
|    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | |
|    Boston, MA 02111-1307, USA.  */
 | |
| 
 | |
| #include <errno.h>
 | |
| #include <stdlib.h>
 | |
| #include <unistd.h>
 | |
| #include <elf/ldsodefs.h>
 | |
| #include <sys/mman.h>
 | |
| #include <sys/types.h>
 | |
| #include "dynamic-link.h"
 | |
| 
 | |
| 
 | |
| void
 | |
| _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 | |
| 		     int lazy, int consider_profiling)
 | |
| {
 | |
|   if (l->l_relocated)
 | |
|     return;
 | |
| 
 | |
|   /* If DT_BIND_NOW is set relocate all references in this object.  We
 | |
|      do not do this if we are profiling, of course.  */
 | |
|   if (!consider_profiling && l->l_info[DT_BIND_NOW])
 | |
|     lazy = 0;
 | |
| 
 | |
|   if (_dl_debug_reloc)
 | |
|     _dl_debug_message (1, "\nrelocation processing: ",
 | |
| 		       l->l_name[0] ? l->l_name : _dl_argv[0],
 | |
| 		       lazy ? " (lazy)\n" : "\n", NULL);
 | |
| 
 | |
|   if (l->l_info[DT_TEXTREL])
 | |
|     {
 | |
|       /* Bletch.  We must make read-only segments writable
 | |
| 	 long enough to relocate them.  */
 | |
|       const ElfW(Phdr) *ph;
 | |
|       for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph)
 | |
| 	if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0)
 | |
| 	  {
 | |
| 	    caddr_t mapstart = ((caddr_t) l->l_addr +
 | |
| 				(ph->p_vaddr & ~(_dl_pagesize - 1)));
 | |
| 	    caddr_t mapend = ((caddr_t) l->l_addr +
 | |
| 			      ((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1)
 | |
| 			       & ~(_dl_pagesize - 1)));
 | |
| 	    if (__mprotect (mapstart, mapend - mapstart,
 | |
| 			    PROT_READ|PROT_WRITE) < 0)
 | |
| 	      _dl_signal_error (errno, l->l_name,
 | |
| 				"cannot make segment writable for relocation");
 | |
| 	  }
 | |
|     }
 | |
| 
 | |
|   {
 | |
|     /* Do the actual relocation of the object's GOT and other data.  */
 | |
| 
 | |
|     /* String table object symbols.  */
 | |
|     const char *strtab = (const void *) l->l_info[DT_STRTAB]->d_un.d_ptr;
 | |
| 
 | |
|     /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
 | |
| #define RESOLVE(ref, version, flags) \
 | |
|     (ELFW(ST_VISIBILITY) ((*ref)->st_other) != STV_PROTECTED		      \
 | |
|      ? ((version) != NULL && (version)->hash != 0			      \
 | |
| 	? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name, l, (ref),    \
 | |
| 				       scope, (version), (flags))	      \
 | |
| 	: _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref), scope,	      \
 | |
| 			     (flags)))					      \
 | |
|      : l->l_addr)
 | |
| 
 | |
| #include "dynamic-link.h"
 | |
|     ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling);
 | |
| 
 | |
|     if (_dl_profile != NULL)
 | |
|       {
 | |
| 	/* Allocate the array which will contain the already found
 | |
| 	   relocations.  */
 | |
| 	l->l_reloc_result =
 | |
| 	  (ElfW(Addr) *) calloc (sizeof (ElfW(Addr)),
 | |
| 				 l->l_info[DT_PLTRELSZ]->d_un.d_val);
 | |
| 	if (l->l_reloc_result == NULL)
 | |
| 	  _dl_sysdep_fatal (_dl_argv[0] ?: "<program name unknown>",
 | |
| 			    "cannot allocate memory for profiling", NULL);
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   /* Mark the object so we know this work has been done.  */
 | |
|   l->l_relocated = 1;
 | |
| 
 | |
|   /* DT_TEXTREL is now in level 2 and might phase out at some time.
 | |
|      But we rewrite the DT_FLAGS entry to make testing easier and
 | |
|      therefore it will be available at all time.  */
 | |
|   if (l->l_info[DT_TEXTREL])
 | |
|     {
 | |
|       /* Undo the protection change we made before relocating.  */
 | |
|       const ElfW(Phdr) *ph;
 | |
|       for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph)
 | |
| 	if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0)
 | |
| 	  {
 | |
| 	    caddr_t mapstart = ((caddr_t) l->l_addr +
 | |
| 				(ph->p_vaddr & ~(_dl_pagesize - 1)));
 | |
| 	    caddr_t mapend = ((caddr_t) l->l_addr +
 | |
| 			      ((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1)
 | |
| 			       & ~(_dl_pagesize - 1)));
 | |
| 	    extern unsigned char _dl_pf_to_prot[8];
 | |
| 	    int prot;
 | |
| 
 | |
| 	    if ((PF_R | PF_W | PF_X) == 7
 | |
| 		&& (PROT_READ | PROT_WRITE | PROT_EXEC) == 7)
 | |
| 	      prot = _dl_pf_to_prot[ph->p_flags & (PF_R | PF_X)];
 | |
| 	    else
 | |
| 	      {
 | |
| 		prot = 0;
 | |
| 		if (ph->p_flags & PF_R)
 | |
| 		  prot |= PROT_READ;
 | |
| 		if (ph->p_flags & PF_X)
 | |
| 		  prot |= PROT_EXEC;
 | |
| 	      }
 | |
| 
 | |
| 	    if (__mprotect (mapstart, mapend - mapstart, prot) < 0)
 | |
| 	      _dl_signal_error (errno, l->l_name,
 | |
| 				"can't restore segment prot after reloc");
 | |
| 
 | |
| #ifdef CLEAR_CACHE
 | |
| 	    CLEAR_CACHE (mapstart, mapend);
 | |
| #endif 
 | |
| 	  }
 | |
|     }
 | |
| }
 | |
| 
 | |
| #include "../stdio-common/_itoa.h"
 | |
| #define DIGIT(b)	_itoa_lower_digits[(b) & 0xf];
 | |
| 
 | |
| void
 | |
| internal_function
 | |
| _dl_reloc_bad_type (struct link_map *map, uint_fast8_t type, int plt)
 | |
| {
 | |
|   extern const char _itoa_lower_digits[];
 | |
|   if (plt)
 | |
|     {
 | |
|       char msg[] = "unexpected reloc type 0x??";
 | |
|       msg[sizeof msg - 2] = DIGIT(type >> 8);
 | |
|       msg[sizeof msg - 1] = DIGIT(type);
 | |
|       _dl_signal_error (0, map->l_name, msg);
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       char msg[] = "unexpected PLT reloc type 0x??";
 | |
|       msg[sizeof msg - 2] = DIGIT(type >> 8);
 | |
|       msg[sizeof msg - 1] = DIGIT(type);
 | |
|       _dl_signal_error (0, map->l_name, msg);
 | |
|     }
 | |
| }
 |