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) 1988 AT&T
26 * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
29 #define ELF_TARGET_AMD64
38 * The link-editor uses a segment descriptor list to describe the program
39 * headers, and related output segments, it can potentially create. This
40 * list is initially seeded using the templates contained in the sg_desc
41 * array below. Additional segments may be added using a mapfile.
43 * The entries in sg_desc must be put in the order defined by the
46 * The entries in sg_desc are initialized using the SG_DESC_INIT macro
49 * 1) The first field of the Sg_desc struct is a program header
50 * entry. ELF32_Phdr and ELF64_Phdr have the same fields,
51 * but their order is different. Use of a macro allows us
52 * to handle this transparently.
53 * 2) Most of the fields in the Sg_desc entries are set to 0.
54 * Use of a macro allows us to hide the clutter.
56 * If a given program header can be referenced via an entrance criteria
57 * (i.e. can serve as a segment), then it must be given a unique sg_name.
58 * Program headers that cannot be a segment (PHDR, INTERP, DYNAMIC, etc)
59 * must have a NULL sg_name --- their program header type identifies them.
62 #define SG_DESC_INIT(id, p_type, p_flags, sg_name, sg_flags) \
63 { id, { p_type, p_flags, 0, 0, 0, 0, 0, 0}, \
64 sg_name, 0, 0, NULL, NULL, NULL, sg_flags, NULL, 0, NULL}
66 #define SG_DESC_INIT(id, p_type, p_flags, sg_name, sg_flags) \
67 { id, { p_type, 0, 0, 0, 0, 0, p_flags, 0}, \
68 sg_name, 0, 0, NULL, NULL, NULL, sg_flags, NULL, 0, NULL}
72 * Predefined segment descriptors:
74 * The C language guarantees that a structure containing only fields of
75 * identical type is indistinguishable from a simple array containing
76 * the same number of items of the same type. They will have the same
77 * size, alignment, and internal layout:
79 * - A pointer to one is equivalent to a pointer to the other, and you
80 * can cast safely between them.
82 * - You can put both into a union, and access the elements within
83 * either way (by index, or by name).
85 * We use this fact here to create an "array" of predefined segment
86 * descriptors, assigning each one a mnemonic name that can be used to point
87 * at it from a predefined entrance criteria descriptor (below). These
88 * segments are positioned in the default order that will result in the
89 * output object, unless a mapfile alters things.
99 Sg_desc psg_lrodata
; /* (amd64-only) */
100 Sg_desc psg_ldata
; /* (amd64-only) */
103 Sg_desc psg_sunwdtrace
;
106 Sg_desc psg_sunwstack
;
111 static const size_t predef_seg_nelts
=
112 (sizeof (predef_seg_t
) / sizeof (Sg_desc
));
114 static predef_seg_t sg_desc
= {
116 SG_DESC_INIT(SGID_PHDR
, PT_PHDR
, PF_R
+ PF_X
, NULL
,
117 (FLG_SG_P_TYPE
| FLG_SG_P_FLAGS
)),
120 SG_DESC_INIT(SGID_INTERP
, PT_INTERP
, PF_R
, NULL
,
121 (FLG_SG_P_TYPE
| FLG_SG_P_FLAGS
)),
124 SG_DESC_INIT(SGID_SUNWCAP
, PT_SUNWCAP
, PF_R
, NULL
,
125 (FLG_SG_P_TYPE
| FLG_SG_P_FLAGS
)),
128 SG_DESC_INIT(SGID_TEXT
, PT_LOAD
, PF_R
+ PF_X
, MSG_ORIG(MSG_ENT_TEXT
),
129 (FLG_SG_P_TYPE
| FLG_SG_P_FLAGS
)),
132 SG_DESC_INIT(SGID_DATA
, PT_LOAD
, 0, MSG_ORIG(MSG_ENT_DATA
),
133 (FLG_SG_P_TYPE
| FLG_SG_P_FLAGS
)),
136 SG_DESC_INIT(SGID_BSS
, PT_LOAD
, 0, MSG_ORIG(MSG_ENT_BSS
),
137 (FLG_SG_P_TYPE
| FLG_SG_P_FLAGS
| FLG_SG_DISABLED
)),
140 /* psg_lrodata (amd64-only ) */
141 SG_DESC_INIT(SGID_LRODATA
, PT_LOAD
, PF_R
, MSG_ORIG(MSG_ENT_LRODATA
),
142 (FLG_SG_P_TYPE
| FLG_SG_P_FLAGS
)),
144 /* psg_ldata (amd64-only ) */
145 SG_DESC_INIT(SGID_LDATA
, PT_LOAD
, 0, MSG_ORIG(MSG_ENT_LDATA
),
146 (FLG_SG_P_TYPE
| FLG_SG_P_FLAGS
)),
149 SG_DESC_INIT(SGID_DYN
, PT_DYNAMIC
, 0, NULL
,
150 (FLG_SG_P_TYPE
| FLG_SG_P_FLAGS
)),
153 SG_DESC_INIT(SGID_DTRACE
, PT_SUNWDTRACE
, 0, NULL
,
154 (FLG_SG_P_TYPE
| FLG_SG_P_FLAGS
)),
157 SG_DESC_INIT(SGID_TLS
, PT_TLS
, PF_R
, NULL
,
158 (FLG_SG_P_TYPE
| FLG_SG_P_FLAGS
)),
161 SG_DESC_INIT(SGID_UNWIND
, PT_SUNW_UNWIND
, PF_R
, NULL
,
162 (FLG_SG_P_TYPE
| FLG_SG_P_FLAGS
)),
165 SG_DESC_INIT(SGID_SUNWSTACK
, PT_SUNWSTACK
, 0, NULL
,
166 (FLG_SG_P_TYPE
| FLG_SG_P_FLAGS
| FLG_SG_DISABLED
)),
169 SG_DESC_INIT(SGID_NOTE
, PT_NOTE
, 0, MSG_ORIG(MSG_ENT_NOTE
),
175 * This segment is referenced by the final entrance criteria descriptor
176 * to catch any segment not otherwise placed. It cannot be disabled
179 SG_DESC_INIT(SGID_EXTRA
, PT_NULL
, 0, MSG_ORIG(MSG_ENT_EXTRA
),
180 (FLG_SG_P_TYPE
| FLG_SG_NODISABLE
))
185 * The processing of input files by the link-editor involves matching the
186 * input file sections against an ordered list of entrance criteria
187 * descriptors. The following template defines the built in entrance criteria
188 * list. This list can be augmented using a mapfile. Each entrance criteria
189 * is associated with a segment descriptor, providing the means for mapping
190 * input sections to output segments.
192 * As with the segment descriptors, the EC_DESC_INIT macro is used
193 * to reduce boilerplate clutter.
195 #define EC_DESC_INIT(ec_is_name, ec_type, ec_attrmask, ec_attrbits, \
196 _seg_field, ec_flags) \
197 { NULL, NULL, ec_is_name, ec_type, ec_attrmask, ec_attrbits, \
198 &sg_desc.psg_ ## _seg_field, 0, FLG_EC_BUILTIN | ec_flags }
200 static const Ent_desc ent_desc
[] = {
201 EC_DESC_INIT(NULL
, SHT_NOTE
, 0, 0, note
, 0),
203 #if defined(_ELF64) /* (amd64-only) */
204 EC_DESC_INIT(NULL
, 0, SHF_ALLOC
+ SHF_WRITE
+ SHF_AMD64_LARGE
,
205 SHF_ALLOC
+ SHF_AMD64_LARGE
, lrodata
, 0),
207 EC_DESC_INIT(NULL
, 0, SHF_ALLOC
+ SHF_WRITE
, SHF_ALLOC
, text
, 0),
210 * Explicitly assign the .tdata section to bss. The design of TLS
211 * provides for initialized data being assigned to a .tdata section,
212 * and uninitialized data being assigned to a .tbss section. These
213 * sections should be laid out adjacent to each other, with little or
214 * no gap between them. A PT_TLS program header is created that
215 * defines the address range of the two sections. This header is
216 * passed to libc to instantiate the appropriate thread allocation.
218 * By default a separate bss segment is disabled, however users can
219 * trigger the creation of a bss segment with a mapfile. By default,
220 * all bss sections are assigned to the data segment, and the section
221 * identifiers of .tdata and .tbss ensure that these two sections are
222 * adjacent to each other.
224 * However, if a bss segment is enabled, the adjacency of the .tdata
225 * and .tbss sections can only be retained by having an explicit .tdata
228 EC_DESC_INIT(MSG_ORIG(MSG_SCN_TDATA
), 0, SHF_ALLOC
+ SHF_WRITE
,
229 SHF_ALLOC
+ SHF_WRITE
, bss
, 0),
231 EC_DESC_INIT(NULL
, SHT_NOBITS
, SHF_ALLOC
+ SHF_WRITE
,
232 SHF_ALLOC
+ SHF_WRITE
, bss
, 0),
234 #if defined(_ELF64) /* (amd64-only) */
235 EC_DESC_INIT(NULL
, SHT_NOBITS
, SHF_ALLOC
+ SHF_WRITE
+ SHF_AMD64_LARGE
,
236 SHF_ALLOC
+ SHF_WRITE
+ SHF_AMD64_LARGE
, data
, 0),
238 EC_DESC_INIT(NULL
, 0, SHF_ALLOC
+ SHF_WRITE
+ SHF_AMD64_LARGE
,
239 SHF_ALLOC
+ SHF_WRITE
+ SHF_AMD64_LARGE
, ldata
, 0),
241 EC_DESC_INIT(NULL
, 0, SHF_ALLOC
+ SHF_WRITE
, SHF_ALLOC
+ SHF_WRITE
,
245 * Final catchall rule sends remaining sections to "extra"
246 * NULL segment, which has been tagged as FLG_SG_NODISABLE,
247 * and which will therefore always accept them.
249 EC_DESC_INIT(NULL
, 0, 0, 0, extra
, FLG_EC_CATCHALL
)
254 * AVL comparison function for Sg_desc items in ofl_segs_avl.
257 * n1, n2 - pointers to nodes to be compared
260 * Returns -1 if (n1 < n2), 0 if they are equal, and 1 if (n1 > n2)
263 ofl_segs_avl_cmp(const void *n1
, const void *n2
)
267 rc
= strcmp(((Sg_desc
*)n1
)->sg_name
, ((Sg_desc
*)n2
)->sg_name
);
277 * AVL comparison function for Ent_desc items in ofl_ents_avl.
280 * n1, n2 - pointers to nodes to be compared
283 * Returns -1 if (n1 < n2), 0 if they are equal, and 1 if (n1 > n2)
286 ofl_ents_avl_cmp(const void *n1
, const void *n2
)
291 * There are entrance criteria nodes with NULL pointer names,
292 * but they are never entered into the AVL tree. Hence, we can
293 * assume that both nodes have names.
295 rc
= strcmp(((Ent_desc
*)n1
)->ec_name
, ((Ent_desc
*)n2
)->ec_name
);
305 * Lookup a segment descriptor by name.
308 * ofl - Output descriptor
309 * name - Name of desired segment
312 * On success, returns pointer to descriptor. On failure, returns NULL.
315 ld_seg_lookup(Ofl_desc
*ofl
, const char *name
, avl_index_t
*where
)
320 return (avl_find(&ofl
->ofl_segs_avl
, &sg
, where
));
325 * Look up an entrance criteria record by name
328 * mf - Mapfile descriptor
329 * name - Name of entrance criteria to locate
332 * On success, a pointer to the entrace criteria record is
333 * returned. On failure, NULL is returned.
336 * Entrance criteria are not required to have names. Only
337 * named entrance criteria can be looked up via this method.
340 ld_ent_lookup(Ofl_desc
*ofl
, const char *name
, avl_index_t
*where
)
345 return (avl_find(&ofl
->ofl_ents_avl
, &en
, where
));
349 * Initialize new entrance and segment descriptors and add them as lists to
350 * the output file descriptor.
353 ld_ent_setup(Ofl_desc
*ofl
, Xword segalign
)
361 * Initialize the elf library.
363 if (elf_version(EV_CURRENT
) == EV_NONE
) {
364 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_ELF_LIBELF
),
370 * Initialize internal Global Symbol Table AVL tree
372 avl_create(&ofl
->ofl_symavl
, &ld_sym_avl_comp
, sizeof (Sym_avlnode
),
373 SGSOFFSETOF(Sym_avlnode
, sav_node
));
375 /* Initialize segment AVL tree */
376 avl_create(&ofl
->ofl_segs_avl
, ofl_segs_avl_cmp
,
377 sizeof (Sg_desc
), SGSOFFSETOF(Sg_desc
, sg_avlnode
));
379 /* Initialize entrance criteria AVL tree */
380 avl_create(&ofl
->ofl_ents_avl
, ofl_ents_avl_cmp
, sizeof (Ent_desc
),
381 SGSOFFSETOF(Ent_desc
, ec_avlnode
));
385 * Allocate and initialize writable copies of both the entrance and
386 * segment descriptors.
388 * Note that on non-amd64 targets, this allocates a few more
389 * elements than are needed. For now, we are willing to overallocate
390 * a small amount to simplify the code.
392 if ((psegs
= libld_malloc(sizeof (sg_desc
))) == NULL
)
394 (void) memcpy(psegs
, &sg_desc
, sizeof (sg_desc
));
395 sgp
= (Sg_desc
*) psegs
;
398 * The data segment and stack permissions can differ:
400 * - Architectural/ABI per-platform differences
401 * - Whether the object is built statically or dynamically
403 * Those segments so affected have their program header flags
404 * set here at runtime, rather than in the sg_desc templates above.
406 psegs
->psg_data
.sg_phdr
.p_flags
= ld_targ
.t_m
.m_dataseg_perm
;
407 psegs
->psg_bss
.sg_phdr
.p_flags
= ld_targ
.t_m
.m_dataseg_perm
;
408 psegs
->psg_dynamic
.sg_phdr
.p_flags
= ld_targ
.t_m
.m_dataseg_perm
;
409 psegs
->psg_sunwdtrace
.sg_phdr
.p_flags
= ld_targ
.t_m
.m_dataseg_perm
;
411 psegs
->psg_ldata
.sg_phdr
.p_flags
= ld_targ
.t_m
.m_dataseg_perm
;
412 psegs
->psg_sunwdtrace
.sg_phdr
.p_flags
|= PF_X
;
414 psegs
->psg_sunwstack
.sg_phdr
.p_flags
= ld_targ
.t_m
.m_stack_perm
;
415 if ((ofl
->ofl_flags
& FLG_OF_DYNAMIC
) == 0)
416 psegs
->psg_data
.sg_phdr
.p_flags
|= PF_X
;
419 * Traverse the new entrance descriptor list converting the segment
420 * pointer entries to the absolute address within the new segment
421 * descriptor list. Add each entrance descriptor to the output file
424 if ((enp
= libld_malloc(sizeof (ent_desc
))) == NULL
)
426 (void) memcpy(enp
, ent_desc
, sizeof (ent_desc
));
427 for (idx
= 0; idx
< (sizeof (ent_desc
) / sizeof (ent_desc
[0])); idx
++,
431 /* Don't use the amd64 entry conditions for non-amd64 targets */
432 if ((enp
->ec_attrmask
& SHF_AMD64_LARGE
) &&
433 (ld_targ
.t_m
.m_mach
!= EM_AMD64
))
436 if (aplist_append(&ofl
->ofl_ents
, enp
,
437 AL_CNT_OFL_ENTRANCE
) == NULL
)
441 * The segment pointer is currently pointing at a template
442 * segment descriptor in sg_desc. Compute its array index,
443 * and then use that index to compute the address of the
444 * corresponding descriptor in the writable copy.
447 &sgp
[(enp
->ec_segment
- (Sg_desc
*) &sg_desc
)];
451 * Add each segment descriptor to the segment descriptor list. The
452 * ones with non-NULL sg_name are also entered into the AVL tree.
453 * For each loadable segment initialize a default alignment. Note
454 * that ld(1) and ld.so.1 initialize this differently.
456 for (idx
= 0; idx
< predef_seg_nelts
; idx
++, sgp
++) {
457 Phdr
*phdr
= &(sgp
->sg_phdr
);
460 /* Ignore amd64 segment templates for non-amd64 targets */
461 switch (sgp
->sg_id
) {
464 if ((ld_targ
.t_m
.m_mach
!= EM_AMD64
))
468 if (phdr
->p_type
== PT_LOAD
)
469 phdr
->p_align
= segalign
;
471 if ((aplist_append(&ofl
->ofl_segs
, sgp
,
472 AL_CNT_SEGMENTS
)) == NULL
)
475 #ifdef NDEBUG /* assert() is enabled */
477 * Enforce the segment name rule: Any segment that can
478 * be referenced by an entrance descriptor must have
479 * a name. Any segment that cannot, must have a NULL
482 switch (phdr
->p_type
) {
486 assert(sgp
->sg_name
!= NULL
);
489 assert(sgp
->sg_name
== NULL
);
495 * Add named segment descriptors to the AVL tree to
496 * provide O(logN) lookups.
498 if (sgp
->sg_name
!= NULL
)
499 avl_add(&ofl
->ofl_segs_avl
, sgp
);