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) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
27 * Object file dependent suport for ELF objects.
42 static Rt_map
*olmp
= NULL
;
43 static Alist
*mpalp
= NULL
;
45 static Ehdr dehdr
= { { ELFMAG0
, ELFMAG1
, ELFMAG2
, ELFMAG3
,
46 M_CLASS
, M_DATA
}, 0, M_MACH
, EV_CURRENT
};
49 * Process a relocatable object. The static object link map pointer is used as
50 * a flag to determine whether a concatenation is already in progress (ie. an
51 * LD_PRELOAD may specify a list of objects). The link map returned simply
52 * specifies an `object' flag which the caller can interpret and thus call
53 * elf_obj_fini() to complete the concatenation.
56 elf_obj_init(Lm_list
*lml
, Aliste lmco
, const char *oname
)
63 * Allocate the name of this object, as the original name may be
64 * associated with a data buffer that can be reused to load the
65 * dependencies needed to processes this object.
67 if ((name
= stravl_insert(oname
, 0, 0, 0)) == NULL
)
71 * Initialize an output file descriptor and the entrance criteria.
73 if ((ofl
= calloc(sizeof (Ofl_desc
), 1)) == NULL
)
76 ofl
->ofl_dehdr
= &dehdr
;
78 ofl
->ofl_flags
= (FLG_OF_DYNAMIC
| FLG_OF_SHAROBJ
| FLG_OF_STRIP
);
79 ofl
->ofl_flags1
= (FLG_OF1_RELDYN
| FLG_OF1_TEXTOFF
| FLG_OF1_MEMORY
);
83 * As ent_setup() will effectively lazy load the necessary support
84 * libraries, make sure ld.so.1 is initialized for plt relocations.
85 * Then configure libld.so to process objects of the desired target
86 * type (this is the first call to libld.so, which will effectively
89 if ((elf_rtld_load() == 0) || (ld_init_target(lml
, M_MACH
) != 0)) {
95 * Obtain a generic set of entrance criteria, and generate a link map
96 * place holder and use the ELFPRV() element to maintain the output
99 lmsz
= S_DROUND(sizeof (Rt_map
)) + sizeof (Rt_elfp
);
100 if ((ld_ent_setup(ofl
, syspagsz
) == S_ERROR
) ||
101 ((olmp
= calloc(lmsz
, 1)) == NULL
)) {
106 DBG_CALL(Dbg_file_elf(lml
, name
, 0, 0, lml
->lm_lmidstr
, lmco
));
107 FLAGS(olmp
) |= FLG_RT_OBJECT
;
108 ELFPRV(olmp
) = (void *)ofl
;
111 * Initialize string tables.
113 if (ld_init_strings(ofl
) == S_ERROR
) {
121 * Assign the output file name to be the initial object that got us
122 * here. This name is being used for diagnostic purposes only as we
123 * don't actually generate an output file unless debugging is enabled.
125 ofl
->ofl_name
= name
;
126 NAME(olmp
) = (char *)name
;
129 lm_append(lml
, lmco
, olmp
);
134 * Define a structure to retain the mapping information of the original
135 * relocatable object. Typically, mmapobj(2) maps a relocatable object into one
136 * mapping. However, if padding has been enabled by a debugger, then additional
137 * padding segments may have been added. elf_obj_file() needs to know which
138 * segment is the relocatable objects data, and retain the initial segment and
139 * the associated segment number for unmapping this object later (see
140 * elf_obj_fini()). Note, even if padding is enabled, the final shared object
141 * that is created by the link-editor for this relocatable object will have no
142 * associated padding, as ld(1) has no capabilities to provide padding.
145 mmapobj_result_t
*md_mpp
;
150 * Initial processing of a relocatable object. If this is the first object
151 * encountered we need to initialize some structures, then simply call the
152 * link-edit functionality to provide the initial processing of the file (ie.
153 * reads in sections and symbols, performs symbol resolution if more that one
154 * object file have been specified, and assigns input sections to output
158 elf_obj_file(Lm_list
*lml
, Aliste lmco
, Rt_map
*clmp
, const char *name
,
159 mmapobj_result_t
*hmpp
, mmapobj_result_t
*mpp
, uint_t mnum
)
165 * If this is the first relocatable object (LD_PRELOAD could provide a
166 * list of objects), initialize an input file descriptor and a link map.
168 if ((olmp
== NULL
) && ((olmp
= elf_obj_init(lml
, lmco
, name
)) == NULL
))
171 DBG_CALL(Dbg_util_nl(lml
, DBG_NL_STD
));
174 * Keep track of the input image, as this must be free'd after all ELF
175 * processing is completed.
179 if (alist_append(&mpalp
, &md
, sizeof (Mmap_desc
),
180 AL_CNT_MPOBJS
) == NULL
) {
181 remove_so(lml
, olmp
, clmp
);
186 * Pass the object mapping to the link-editor to commence processing the
189 if (ld_process_mem(name
, name
, hmpp
->mr_addr
, hmpp
->mr_msize
,
190 (Ofl_desc
*)ELFPRV(olmp
), &rej
) == (Ifl_desc
*)S_ERROR
) {
191 remove_so(lml
, olmp
, clmp
);
199 * Ensure any platform or machine capability names are valid.
202 check_plat_names(Syscapset
*scapset
, Alist
*caps
, Rej_desc
*rej
)
207 for (ALIST_TRAVERSE(caps
, idx
, capstr
)) {
208 if (platcap_check(scapset
, capstr
->cs_str
, rej
) == 1)
215 check_mach_names(Syscapset
*scapset
, Alist
*caps
, Rej_desc
*rej
)
220 for (ALIST_TRAVERSE(caps
, idx
, capstr
)) {
221 if (machcap_check(scapset
, capstr
->cs_str
, rej
) == 1)
228 * Finish relocatable object processing. Having already initially processed one
229 * or more objects, complete the generation of a shared object image by calling
230 * the appropriate link-edit functionality (refer to sgs/ld/common/main.c).
233 elf_obj_fini(Lm_list
*lml
, Rt_map
*lmp
, Rt_map
*clmp
, int *in_nfavl
)
235 Ofl_desc
*ofl
= (Ofl_desc
*)ELFPRV(lmp
);
239 mmapobj_result_t
*mpp
, *hmpp
;
247 Rej_desc rej
= { 0 };
252 DBG_CALL(Dbg_util_nl(lml
, DBG_NL_STD
));
254 if (ld_reloc_init(ofl
) == S_ERROR
)
256 if (ld_sym_validate(ofl
) == S_ERROR
)
260 * At this point, all input section processing is complete. If any
261 * capabilities have been established, ensure that they are appropriate
264 if (pnavl_recorded(&capavl
, ofl
->ofl_name
, 0, NULL
))
265 scapset
= alt_scapset
;
267 scapset
= org_scapset
;
269 if ((((omsk
= ofl
->ofl_ocapset
.oc_hw_1
.cm_val
) != 0) &&
270 (hwcap1_check(scapset
, omsk
, &rej
) == 0)) ||
271 (((omsk
= ofl
->ofl_ocapset
.oc_sf_1
.cm_val
) != 0) &&
272 (sfcap1_check(scapset
, omsk
, &rej
) == 0)) ||
273 (((omsk
= ofl
->ofl_ocapset
.oc_hw_2
.cm_val
) != 0) &&
274 (hwcap2_check(scapset
, omsk
, &rej
) == 0)) ||
275 (((oalp
= ofl
->ofl_ocapset
.oc_plat
.cl_val
) != NULL
) &&
276 (check_plat_names(scapset
, oalp
, &rej
) == 0)) ||
277 (((oalp
= ofl
->ofl_ocapset
.oc_mach
.cl_val
) != NULL
) &&
278 (check_mach_names(scapset
, oalp
, &rej
) == 0))) {
279 if ((lml_main
.lm_flags
& LML_FLG_TRC_LDDSTUB
) && lmp
&&
280 (FLAGS1(lmp
) & FL1_RT_LDDSTUB
) && (NEXT(lmp
) == NULL
)) {
282 (void) printf(MSG_INTL(ldd_reject
[rej
.rej_type
]),
283 ofl
->ofl_name
, rej
.rej_str
);
289 * Finish creating the output file.
291 if (ld_make_sections(ofl
) == S_ERROR
)
293 if (ld_create_outfile(ofl
) == S_ERROR
)
295 if (ld_update_outfile(ofl
) == S_ERROR
)
297 if (ld_reloc_process(ofl
) == S_ERROR
)
301 * At this point we have a memory image of the shared object. The link
302 * editor would normally simply write this to the required output file.
303 * If we're debugging generate a standard temporary output file.
305 DBG_CALL(Dbg_file_output(ofl
));
308 * Allocate a mapping array to retain mapped segment information.
310 ehdr
= ofl
->ofl_nehdr
;
311 phdr
= ofl
->ofl_phdr
;
313 if ((mpp
= hmpp
= calloc(ehdr
->e_phnum
,
314 sizeof (mmapobj_result_t
))) == NULL
)
316 for (mnum
= 0, phnum
= 0; phnum
< ehdr
->e_phnum
; phnum
++) {
317 if (phdr
[phnum
].p_type
!= PT_LOAD
)
320 mpp
[mnum
].mr_addr
= (caddr_t
)((uintptr_t)phdr
[phnum
].p_vaddr
+
322 mpp
[mnum
].mr_msize
= phdr
[phnum
].p_memsz
;
323 mpp
[mnum
].mr_fsize
= phdr
[phnum
].p_filesz
;
324 mpp
[mnum
].mr_prot
= (PROT_READ
| PROT_WRITE
| PROT_EXEC
);
329 * Generate a new link map representing the memory image created.
331 fd
.fd_nname
= ofl
->ofl_name
;
332 if ((nlmp
= elf_new_lmp(lml
, CNTL(olmp
), &fd
, (Addr
)hmpp
->mr_addr
,
333 ofl
->ofl_size
, NULL
, clmp
, in_nfavl
)) == NULL
)
337 MMAPCNT(nlmp
) = mnum
;
338 PADSTART(nlmp
) = (ulong_t
)hmpp
->mr_addr
;
339 PADIMLEN(nlmp
) = mpp
->mr_addr
+ mpp
->mr_msize
- hmpp
->mr_addr
;
342 * Replace the original (temporary) link map with the new link map.
345 lmc
= (Lm_cntl
*)alist_item_by_offset(lml
->lm_lists
, CNTL(nlmp
));
348 if ((tlmp
= PREV_RT_MAP(nlmp
)) == olmp
)
352 NEXT(PREV_RT_MAP(olmp
)) = (Link_map
*)nlmp
;
353 PREV(nlmp
) = PREV(olmp
);
357 if (CNTL(nlmp
) == ALIST_OFF_DATA
)
361 if (NEXT(olmp
) != (Link_map
*)nlmp
) {
362 NEXT(nlmp
) = NEXT(olmp
);
363 PREV(NEXT_RT_MAP(olmp
)) = (Link_map
*)nlmp
;
369 if (CNTL(nlmp
) == ALIST_OFF_DATA
)
372 HANDLES(nlmp
) = HANDLES(olmp
);
373 GROUPS(nlmp
) = GROUPS(olmp
);
374 STDEV(nlmp
) = STDEV(olmp
);
375 STINO(nlmp
) = STINO(olmp
);
377 FLAGS(nlmp
) |= ((FLAGS(olmp
) & ~FLG_RT_OBJECT
) | FLG_RT_IMGALLOC
);
378 FLAGS1(nlmp
) |= FLAGS1(olmp
);
379 MODE(nlmp
) |= MODE(olmp
);
381 NAME(nlmp
) = NAME(olmp
);
384 * Reassign any original handles to the new link-map.
386 for (APLIST_TRAVERSE(HANDLES(nlmp
), idx1
, ghp
)) {
390 ghp
->gh_ownlmp
= nlmp
;
392 for (ALIST_TRAVERSE(ghp
->gh_depends
, idx2
, gdp
)) {
393 if (gdp
->gd_depend
== olmp
) {
394 gdp
->gd_depend
= nlmp
;
406 * Unmap the original relocatable object.
408 for (ALIST_TRAVERSE(mpalp
, idx1
, mdp
)) {
409 unmap_obj(mdp
->md_mpp
, mdp
->md_mnum
);
416 * Now that we've allocated our permanent link map structure, expand the
417 * PATHNAME() and insert this path name into the FullPathNode AVL tree.
419 (void) fullpath(nlmp
, 0);
420 if (fpavl_insert(lml
, nlmp
, PATHNAME(nlmp
), 0) == 0)
424 * If we're being audited tell the audit library of the file we've just
427 if ((lml
->lm_tflags
| AFLAGS(nlmp
)) & LML_TFLG_AUD_MASK
) {
428 if (audit_objopen(nlmp
, nlmp
) == 0)