1 /* Copyright (C) 2011-2013 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Chris Metcalf <cmetcalf@tilera.com>, 2011.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the 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 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library. If not, see
17 <http://www.gnu.org/licenses/>. */
19 /* Like x86_64, we pass the index of the relocation and not its offset.
20 In _dl_profile_fixup and _dl_call_pltexit we also use the index.
21 Therefore it is wasteful to compute the offset in the trampoline
22 just to reverse the operation immediately afterwards. */
23 #define reloc_offset reloc_arg * sizeof (PLTREL)
24 #define reloc_index reloc_arg
26 #include <elf/dl-runtime.c>
31 /* Like realpath(), but simplified: no dynamic memory use, no lstat(),
32 no set_errno(), no valid "rpath" on error, etc. This handles some
33 simple cases where the simulator might not have a valid entry for
34 a loaded Elf object, in particular dlopen() with a relative path.
35 For this relatively rare case, one could also imagine using
36 link_map.l_origin to avoid the getcwd() here, but the simpler code
37 here seems like a better solution. */
39 dl_realpath (const char *name
, char *rpath
)
42 const char *start
, *end
;
46 if (!__getcwd (rpath
, PATH_MAX
))
48 dest
= __rawmemchr (rpath
, '\0');
56 for (start
= end
= name
; *start
; start
= end
)
58 /* Skip sequence of multiple path-separators. */
62 /* Find end of path component. */
63 for (end
= start
; *end
&& *end
!= '/'; ++end
)
68 else if (end
- start
== 1 && start
[0] == '.')
70 else if (end
- start
== 2 && start
[0] == '.' && start
[1] == '.')
72 /* Back up to previous component, ignore if at root already. */
74 while ((--dest
)[-1] != '/');
81 if (dest
+ (end
- start
) >= rpath
+ PATH_MAX
)
84 dest
= __mempcpy (dest
, start
, end
- start
);
88 if (dest
> rpath
+ 1 && dest
[-1] == '/')
95 /* Support notifying the simulator about new objects. */
96 void internal_function
97 _dl_after_load (struct link_map
*l
)
100 char pathbuf
[PATH_MAX
];
103 /* Don't bother if not in the simulator. */
104 if (__insn_mfspr (SPR_SIM_CONTROL
) == 0)
107 #define DLPUTC(c) __insn_mtspr (SPR_SIM_CONTROL, \
108 (SIM_CONTROL_DLOPEN \
109 | ((c) << _SIM_CONTROL_OPERATOR_BITS)))
111 /* Write the library address in hex. */
114 for (shift
= (int) sizeof (unsigned long) * 8 - 4; shift
>= 0; shift
-= 4)
115 DLPUTC ("0123456789abcdef"[(l
->l_map_start
>> shift
) & 0xF]);
118 /* Write the library path, including the terminating '\0'. */
119 path
= dl_realpath (l
->l_name
, pathbuf
) ?: l
->l_name
;
120 for (size_t i
= 0;; i
++)
129 /* Support notifying the simulator about removed objects prior to munmap(). */
130 void internal_function
131 _dl_unmap (struct link_map
*l
)
135 /* Don't bother if not in the simulator. */
136 if (__insn_mfspr (SPR_SIM_CONTROL
) == 0)
139 #define DLPUTC(c) __insn_mtspr (SPR_SIM_CONTROL, \
140 (SIM_CONTROL_DLCLOSE \
141 | ((c) << _SIM_CONTROL_OPERATOR_BITS)))
143 /* Write the library address in hex. */
146 for (shift
= (int) sizeof (unsigned long) * 8 - 4; shift
>= 0; shift
-= 4)
147 DLPUTC ("0123456789abcdef"[(l
->l_map_start
>> shift
) & 0xF]);
151 __munmap ((void *) l
->l_map_start
, l
->l_map_end
- l
->l_map_start
);