4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
25 * Update any dynamic entry offsets. One issue with dynamic entries is that
26 * you only know whether they refer to a value or an offset if you know each
27 * type. Thus we check for all types we know about, it a type is found that
28 * we don't know about then return and error as we have no idea what to do.
39 update_dynamic(Cache
*cache
, Cache
*_cache
, Rt_map
*lmp
, int flags
,
40 Addr addr
, Off off
, const char *file
, Xword null
, Xword data
, Xword func
,
41 Xword entsize
, Xword checksum
)
43 Dyn
*dyn
= (Dyn
*)_cache
->c_data
->d_buf
, *posdyn
= 0;
48 * If we're dealing with an object that might have bound to an external
49 * dependency establish our string table for possible NEEDED processing.
51 if (flags
& RTLD_REL_DEPENDS
) {
52 __cache
= &cache
[_cache
->c_shdr
->sh_link
];
53 strs
= (const char *)__cache
->c_data
->d_buf
;
57 * Loop through the dynamic table updating all offsets.
59 while (dyn
->d_tag
!= DT_NULL
) {
62 switch ((Xword
)dyn
->d_tag
) {
68 * Determine whether this dependency has been loaded
69 * (this is the most generic way to check any alias
70 * names), and if it has been bound to, undo any
71 * lazy-loading or deferred position flag.
73 if (dlmp
= is_so_loaded(LIST(lmp
),
74 (strs
+ dyn
->d_un
.d_val
), NULL
)) {
78 for (APLIST_TRAVERSE(DEPENDS(lmp
), idx
, bdp
)) {
79 if (dlmp
!= bdp
->b_depend
)
83 ~(DF_P1_LAZYLOAD
| DF_P1_DEFERRED
);
103 case DT_DEPRECATED_SPARC_REGISTER
:
106 case DT_INIT_ARRAYSZ
:
107 case DT_FINI_ARRAYSZ
:
127 dyn
->d_un
.d_ptr
+= addr
;
131 * If the memory image is being used, this element would have
132 * been initialized to the runtime linkers internal link-map
140 * The number of relocations may have been reduced if
141 * relocations have been saved in the new image. Thus we
142 * compute the new relocation size and start.
146 dyn
->d_un
.d_val
= ((data
+ func
) * entsize
);
151 dyn
->d_un
.d_ptr
= (addr
+ off
+ (null
* entsize
));
155 * If relative relocations have been processed clear the count.
159 if (flags
& RTLD_REL_RELATIVE
)
164 dyn
->d_un
.d_val
= (func
* entsize
);
168 dyn
->d_un
.d_ptr
= (addr
+ off
+
169 ((null
+ data
) * entsize
));
173 * Recompute the images elf checksum.
176 dyn
->d_un
.d_val
= checksum
;
180 * If a flag entry is available, indicate if this image has
181 * been generated via the configuration process (crle(1)).
182 * Because we only started depositing DT_FLAGS_1 entries in all
183 * objects starting with Solaris 8, set a feature flag if it
184 * is present (these got added in Solaris 7).
185 * The runtime linker may use this flag to search for a local
186 * configuration file - this is only meaningful in executables
187 * but the flag has value for identifying images regardless.
189 * If this file is acting as a filter, and dependency
190 * relocations have been processed (a filter is thought of as a
191 * dependency in terms of symbol binding), we may have bound to
192 * the filtee, and hence carried out the relocation. Indicate
193 * that the filtee must be preloaded, as the .plt won't get
194 * exercised to cause its normal loading.
197 if (flags
& RTLD_CONFSET
)
198 dyn
->d_un
.d_val
|= DF_1_CONFALT
;
199 if ((flags
& RTLD_REL_DEPENDS
) &&
200 (FLAGS1(lmp
)) & MSK_RT_FILTER
)
201 dyn
->d_un
.d_val
|= DF_1_LOADFLTR
;
205 if (flags
& RTLD_CONFSET
)
206 dyn
->d_un
.d_val
|= DTF_1_CONFEXP
;
210 * If a position flag is available save it for possible update
211 * when processing the next NEEDED tag.
214 if (flags
& RTLD_REL_DEPENDS
) {
221 * Collect the defaults.
225 * If d_val is used, don't touch.
227 if ((dyn
->d_tag
>= DT_VALRNGLO
) &&
228 (dyn
->d_tag
<= DT_VALRNGHI
))
232 * If d_ptr is used, adjust. Note, some entries that
233 * fell into this range are offsets into the dynamic
234 * string table. Although these would need modifying
235 * if the section itself were resized, there is no
236 * resizing with dldump(). Entries that correspond to
237 * offsets are picked off in the initial DT_ loop
240 if ((dyn
->d_tag
>= DT_ADDRRNGLO
) &&
241 (dyn
->d_tag
<= DT_ADDRRNGHI
)) {
242 dyn
->d_un
.d_ptr
+= addr
;
247 * Check to see if this DT_ entry conforms
248 * to the DT_ENCODING rules.
250 if ((dyn
->d_tag
>= DT_ENCODING
) &&
251 (dyn
->d_tag
<= DT_HIOS
)) {
253 * Even tag values are ADDRESS encodings
255 if ((dyn
->d_tag
% 2) == 0) {
256 dyn
->d_un
.d_ptr
+= addr
;
260 eprintf(LIST(lmp
), ERR_WARNING
,
261 MSG_INTL(MSG_DT_UNKNOWN
), file
,
262 EC_XWORD(dyn
->d_tag
));