1 /* Unmap a loaded object. IA-64 version.
2 Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
22 #include <sys/param.h>
26 #include <elf/dynamic-link.h>
27 #include <dl-machine.h>
28 #ifdef _LIBC_REENTRANT
29 # include <pt-machine.h>
31 static int __ia64_fptr_lock
= 0;
34 /* Because ld.so is now versioned, these functions can be in their own
35 file; no relocations need to be done to call them. Of course, if
36 ld.so is not versioned... */
39 # error "This will not work with versioning turned off, sorry."
44 /* The fd is not examined when using MAP_ANON. */
47 extern int _dl_zerofd
;
48 #define ANONFD _dl_zerofd
52 /* ld.so currently has 14 FPTR relocs, we take 256 and use them for
53 the relocs for the dynamic app itself. */
54 struct ia64_fptr __boot_ldso_fptr
[IA64_BOOT_FPTR_SIZE
];
55 struct ia64_fptr
*__fptr_root
= NULL
;
56 struct ia64_fptr
*__fptr_next
= __boot_ldso_fptr
;
57 static struct ia64_fptr
*__fptr_free
= NULL
;
58 int __fptr_count
= IA64_BOOT_FPTR_SIZE
;
61 __ia64_make_fptr (const struct link_map
*sym_map
, Elf64_Addr value
,
62 struct ia64_fptr
**root
, struct ia64_fptr
*mem
)
64 struct ia64_fptr
**loc
;
67 #ifdef _LIBC_REENTRANT
68 /* Make sure we are alone. We don't need a lock during bootstrap. */
70 while (testandset (&__ia64_fptr_lock
));
73 /* Search the sorted linked list for an existing entry for this
77 while (f
!= NULL
&& f
->func
<= value
)
85 /* Not found. Create a new one. */
88 else if (__fptr_free
!= NULL
)
91 __fptr_free
= f
->next
;
95 if (__fptr_count
== 0)
101 _dl_zerofd
= _dl_sysdep_open_zero_fill ();
102 if (_dl_zerofd
== -1)
105 _dl_signal_error (errno
, NULL
,
106 "cannot open zero fill device");
111 __fptr_next
= __mmap (0, _dl_pagesize
, PROT_READ
| PROT_WRITE
,
112 MAP_ANON
| MAP_PRIVATE
, ANONFD
, 0);
113 if (__fptr_next
== MAP_FAILED
)
114 _dl_signal_error(errno
, NULL
, "cannot map page for fptr");
115 __fptr_count
= _dl_pagesize
/ sizeof (struct ia64_fptr
);
122 /* GOT has already been relocated in elf_get_dynamic_info - don't
123 try to relocate it again. */
124 f
->gp
= sym_map
->l_info
[DT_PLTGOT
]->d_un
.d_ptr
;
129 #ifdef _LIBC_REENTRANT
130 /* Release the lock. */
132 __ia64_fptr_lock
= 0;
135 return (Elf64_Addr
) f
;
139 _dl_unmap (struct link_map
*map
)
141 struct ia64_fptr
**floc
;
143 struct ia64_fptr
**lloc
;
146 __munmap ((void *) map
->l_map_start
, map
->l_map_end
- map
->l_map_start
);
148 #ifdef _LIBC_REENTRANT
149 /* Make sure we are alone. */
150 while (testandset (&__ia64_fptr_lock
));
153 /* Search the sorted linked list for the first entry for this object. */
156 while (f
!= NULL
&& f
->func
< map
->l_map_start
)
163 if (f
!= NULL
&& f
->func
< map
->l_map_end
)
165 /* Get the last entry. */
168 while (l
&& l
->func
< map
->l_map_end
)
177 /* Prepend them to the free list. */
182 #ifdef _LIBC_REENTRANT
183 /* Release the lock. */
184 __ia64_fptr_lock
= 0;
189 _dl_lookup_address (const void *address
)
191 Elf64_Addr addr
= (Elf64_Addr
) address
;
194 #ifdef _LIBC_REENTRANT
195 /* Make sure we are alone. */
196 while (testandset (&__ia64_fptr_lock
));
199 for (f
= __fptr_root
; f
!= NULL
; f
= f
->next
)
206 #ifdef _LIBC_REENTRANT
207 /* Release the lock. */
208 __ia64_fptr_lock
= 0;