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) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
27 * Processing of SHF_ORDERED sections.
37 * Section Ordering History/Background:
39 * There are two forms of section ordering, SHF_ORDERED, and SHF_LINK_ORDER.
41 * SHF_ORDERED was invented at Sun in order to support the PowerPC port
42 * of Solaris 2.6, which used it for sorting tag words which describe
43 * the state of callee saves registers for given PC ranges. It was defined
44 * in the OS specific ELF section flag range. Some other values were defined
46 * SHF_EXCLUDE - Section is to be excluded from executables or shared
47 * objects, and only kept in relocatable object output.
48 * SHN_BEFORE/SHN_AFTER - Sections are placed before/after all other
49 * sections, in the order they are encountered by the linker.
50 * Although initially conceived to support the PowerPC, the functionality
51 * was implemented for all platforms, and was later used to manage C++
52 * exceptions and stack unwinding. The PowerPC port was discontinued after
53 * one release, but SHF_ORDERED lives on.
55 * SHF_LINK_ORDER was invented later by the wider ELF community, and is
56 * therefore assigned a value in the generic ELF section flag range. It is
57 * essentially a simpler version of SHF_ORDERED, dispensing with some
58 * unnecessary features. The Solaris implementation of SHF_LINK_ORDER uses
59 * SHF_EXCLUDE, and SHF_BEFORE/SHN_AFTER as well, but it appears that these
60 * are still Solaris-only extensions not used by other implementations.
61 * SHF_LINK_ORDER has superseded SHF_ORDERED. The older mechanism is
62 * supported for the benefit of old pre-existing objects.
66 * SHF_ORDERED offers two distinct and separate abilities:
68 * (1) To specify the output section
69 * (2) To optionally be sorted relative to other sorted sections,
70 * using a non-sorted section as a sort key.
72 * To do this, it uses both the sh_link, and sh_info fields:
75 * Specifies the output section to receive this input section.
76 * The sh_link field of an SHF_ORDERED section forms a linked list of
77 * sections, all of which must have identical section header flags
78 * (including SHF_ORDERED). The list is terminated by a final section
79 * with a sh_link that points at itself. All input sections in this list
80 * are assigned to the output section of the final section in the list.
81 * Hence, if a section points at itself, the effect is that it gets
82 * assigned to an output section in the usual default manner (i.e. an
83 * output section with the same name as the input). However, it can
84 * point at any arbitrary other section. This is a way to put a section
85 * with one name into an output section with a different name. It should
86 * be noted that this is of little value overall, because the link-editor
87 * already supports a more general feature for directing input sections
88 * to output sections: An input section named .text%foo will be sent to
89 * an output section named ".text", and this works for all sections,
90 * not just ordered ones.
93 * If sh_info is in the range (1 <= value < shnum), then this input section
94 * is added to the group of sorted sections. The section referenced by
95 * sh_info must be unsorted, and is used as the sort key.
97 * If sh_info is SHN_BEFORE or SHN_AFTER, it is put in the pre/post group,
98 * in the order it arrives (the before/after classes are not sorted).
100 * If sh_info is "invalid" (typically 0), then this section is added to
101 * the group of non-sorted sections, and goes into the output file in the
102 * order it arrives. This is not a valuable feature, as the same effect
103 * can be achieved more simply by not setting SHF_ORDERED at all.
105 * SHF_LINK_ORDER is a simplification of SHF_ORDERED. It uses sh_link to specify
106 * the section to use as a sort key and sh_info is set to 0. The standard
107 * ".text%foo" mechanism is used to direct input sections to output sections,
108 * and unordered sections indicate that by not setting SHF_LINK_ORDER.
113 * A "keyshndx" is the section index for the unordered section that should
114 * be used as a sort key for a ordered section. Verify that the given
118 * Returns 0 if the keyshndx is valid. A non-zero DBG_ORDER_ code is
119 * returned if the keyshndx is not valid to describe the problem.
122 is_keyshndx_ok(Ifl_desc
*ifl
, Word keyshndx
)
124 if ((keyshndx
== SHN_BEFORE
) || (keyshndx
== SHN_AFTER
))
128 * Validate the key range.
130 if ((keyshndx
== 0) || (keyshndx
>= ifl
->ifl_shnum
))
131 return (DBG_ORDER_LINK_OUTRANGE
);
134 * The section pointed to by keyshndx should not be an ordered section.
135 * Strictly speaking, we could test for SHF_ORDERED here instead of
136 * ALL_SHF_ORDER as the two ordering flags are not supposed to be
137 * mixed. Using ALL_SHF_ORDER costs the same and ensures that such
138 * mixing doesn't go undetected.
140 if (ifl
->ifl_isdesc
[keyshndx
]->is_shdr
->sh_flags
& ALL_SHF_ORDER
)
141 return (DBG_ORDER_INFO_ORDER
);
147 * The sh_link field of an SHF_ORDERED section forms a linked list of
148 * sections. The list is terminated by a final section with a sh_link
149 * that points at itself. Given the index of an SHF_ORDERED section, find
150 * the index of the final section in the list.
153 * ofl - Output file descriptor
154 * ifl - Input file descriptor
155 * ndx - Section index of SHF_ORDERED section
156 * alt_os_name - Address of pointer to string. If the final section
157 * name is different than the section given by ndx, *alt_os_name
158 * will be updated with the name of the final section. The caller
159 * should initialize *alt_os_name to NULL before calling
163 * On success: If the final section is different than the section
164 * given by ndx, then *alt_os_name is set to its name. TRUE is returned.
166 * On failure, FALSE is returned.
169 validate_shf_ordered_dest(Ofl_desc
*ofl
, Ifl_desc
*ifl
, Word ndx
,
170 const char **alt_os_name
)
172 Word shnum
= ifl
->ifl_shnum
;
173 Word isp1_ndx
, isp2_ndx
;
174 Is_desc
*isp1
, *isp2
;
179 * Traverse the list until we find the termination, or encounter
180 * an invalid condition in the object that prevents ordering.
183 isp1
= ifl
->ifl_isdesc
[ndx
];
186 * Obtain index of next section in list. Ensure it is in range.
188 isp2_ndx
= isp1
->is_shdr
->sh_link
;
189 if ((isp2_ndx
== 0) || (isp2_ndx
>= shnum
)) {
190 error
= DBG_ORDER_LINK_OUTRANGE
;
193 isp2
= ifl
->ifl_isdesc
[isp2_ndx
];
195 /* The section flags must match exactly */
196 if (isp1
->is_shdr
->sh_flags
!= isp2
->is_shdr
->sh_flags
) {
198 * The case where the next section in the list does
199 * not have the same ordered flag set as the original
200 * ordered section gets a unique error code. This
201 * provides more accurate/useful debugging diagnostics.
203 error
= ((isp2
->is_flags
& FLG_IS_ORDERED
) == 0) ?
204 DBG_ORDER_LINK_ERROR
: DBG_ORDER_FLAGS
;
209 * The sh_info field specifies the section index of an
210 * unorderd section which will be used as a sort key.
211 * Ensure it is in range. If not, we terminate the list
212 * at the current node instead of continuing on.
214 if ((error
= is_keyshndx_ok(ifl
, isp2
->is_shdr
->sh_info
)) != 0)
217 /* If the section points at itself, it terminates the list */
218 if (isp1_ndx
== isp2_ndx
)
222 * Advance to next section in list
228 * If we loop more times than the input file has sections,
229 * we have encountered a malformed object in which the list
230 * of SHF_ORDERED sections has a cycle. This can only happen
231 * if the compiler generating the object has a bad bug.
233 if (++iter
>= shnum
) {
234 error
= DBG_ORDER_CYCLIC
;
237 /* CONSTANTCONDITION */
241 * If we have found a problem, issue a debug diagnostic and map
242 * the output section to 0. This indicates that the section should
243 * remove the ordering flag and treat it as a standard section.
247 DBG_CALL(Dbg_sec_order_error(ofl
->ofl_lml
, ifl
, ndx
, error
));
253 * If the destination section is different than the input
254 * section, then set *alt_os_name to the destination name.
257 *alt_os_name
= ifl
->ifl_isdesc
[isp2_ndx
]->is_name
;
261 /* If we get here, there is no valid destination */
266 * Called when an ordered section has a problem that prevents ordering.
267 * The order flag is removed, and then the section is placed as an
271 place_unordered(Ofl_desc
*ofl
, Is_desc
*isp
, Place_path_info
*path_info
)
273 isp
->is_flags
&= ~FLG_IS_ORDERED
;
274 if (isp
->is_osdesc
== NULL
)
275 return ((uintptr_t)ld_place_section(ofl
, isp
, path_info
,
276 isp
->is_keyident
, NULL
));
277 return ((uintptr_t)isp
->is_osdesc
);
281 * Process ordered input section. Called from process_elf() after
282 * all the non-ordered sections have been placed.
285 * ofl - Output file descriptor
286 * ifl - Input file descriptor
287 * ndx - Section index of SHF_ORDERED section
292 ld_process_ordered(Ofl_desc
*ofl
, Ifl_desc
*ifl
, Place_path_info
*path_info
,
295 Is_desc
*isp2
, *isp
= ifl
->ifl_isdesc
[ndx
];
296 Xword shflags
= isp
->is_shdr
->sh_flags
;
297 const char *alt_os_name
= NULL
;
303 * Obtain the sort key section index for this ordered section.
304 * SHF_ORDERED uses sh_info, while SHF_LINK_ORDER uses sh_link.
305 * In order for this function to be called, one of SHF_ORDERED
306 * or SHF_LINK_ORDER must be set. Testing for one implies the
307 * state of the other.
309 keyshndx
= (shflags
& SHF_ORDERED
) ?
310 isp
->is_shdr
->sh_info
: isp
->is_shdr
->sh_link
;
313 * Validate the sort key section index. If something is wrong,
314 * fall back to treating it as a non-ordered section.
316 if ((error
= is_keyshndx_ok(ifl
, keyshndx
)) != 0) {
317 DBG_CALL(Dbg_sec_order_error(ofl
->ofl_lml
, ifl
, ndx
, error
));
318 return (place_unordered(ofl
, isp
, path_info
));
322 * If SHF_ORDERED is in effect, validate the destination section
323 * name given by sh_link, and set alt_os_name to the name of the
324 * destination if it differs from the section being processed.
326 if ((shflags
& SHF_ORDERED
) &&
327 (validate_shf_ordered_dest(ofl
, ifl
, ndx
, &alt_os_name
) == FALSE
))
328 return (place_unordered(ofl
, isp
, path_info
));
331 * Place the section into its output section. It's possible that this
332 * section is discarded (possibly because it's defined COMDAT), in
333 * which case we're done.
335 if ((osp
= isp
->is_osdesc
) == NULL
) {
336 osp
= ld_place_section(ofl
, isp
, path_info
, isp
->is_keyident
,
338 if ((osp
== (Os_desc
*)S_ERROR
) || (osp
== NULL
))
339 return ((uintptr_t)osp
);
343 * If the output section is not yet on the ordered list, place it on
346 if (aplist_test(&ofl
->ofl_ordered
, osp
, AL_CNT_OFL_ORDERED
) ==
348 return ((uintptr_t)S_ERROR
);
351 * Output section has been found - set up its sorting information.
353 if ((keyshndx
!= SHN_BEFORE
) && (keyshndx
!= SHN_AFTER
)) {
356 isp2
= ifl
->ifl_isdesc
[keyshndx
];
357 if (isp2
->is_flags
& FLG_IS_DISCARD
) {
358 ld_eprintf(ofl
, ERR_FATAL
, MSG_INTL(MSG_FIL_BADORDREF
),
359 ifl
->ifl_name
, EC_WORD(isp
->is_scnndx
),
360 isp
->is_name
, EC_WORD(isp2
->is_scnndx
),
366 * Indicate that this ordered input section will require a
367 * sort key. Propagate the key requirement through to the
368 * associated output section, segment and file, to trigger
369 * the sort key creation. See ld_sec_validate();
371 isp2
->is_flags
|= FLG_IS_KEY
;
373 osp2
= isp2
->is_osdesc
;
374 osp2
->os_flags
|= FLG_OS_KEY
;
375 osp2
->os_sgdesc
->sg_flags
|= FLG_SG_KEY
;
377 ofl
->ofl_flags
|= FLG_OF_KEY
;
380 return ((uintptr_t)osp
);
384 * Traverse all segments looking for section ordering information that hasn't
385 * been used. If found give a warning message to the user. Also, check if
386 * there are any ordered key sections, and if so set up sort key values.
389 ld_sec_validate(Ofl_desc
*ofl
)
395 for (APLIST_TRAVERSE(ofl
->ofl_segs
, idx1
, sgp
)) {
400 for (ALIST_TRAVERSE(sgp
->sg_os_order
, idx2
, scop
)) {
401 if ((scop
->sco_flags
& FLG_SGO_USED
) == 0) {
402 ld_eprintf(ofl
, ERR_WARNING
,
403 MSG_INTL(MSG_MAP_SECORDER
),
404 sgp
->sg_name
, scop
->sco_secname
);
407 if ((sgp
->sg_flags
& FLG_SG_KEY
) == 0)
410 for (APLIST_TRAVERSE(sgp
->sg_osdescs
, idx2
, osp
)) {
414 if ((osp
->os_flags
& FLG_OS_KEY
) == 0)
418 * The input sections used as sort keys are required
419 * to be unordered, so we only have to look at the
420 * DEFAULT list of input sections.
422 for (APLIST_TRAVERSE(osp
->os_isdescs
[OS_ISD_DEFAULT
],
424 if (isp
->is_flags
& FLG_IS_KEY
)
425 isp
->is_keyident
= key
++;
432 comp(const void *ss1
, const void *ss2
)
434 Is_desc
*s1
= *((Is_desc
**)ss1
);
435 Is_desc
*s2
= *((Is_desc
**)ss2
);
439 if (s1
->is_shdr
->sh_flags
& SHF_ORDERED
)
440 ndx1
= s1
->is_shdr
->sh_info
;
442 ndx1
= s1
->is_shdr
->sh_link
;
444 if (s2
->is_shdr
->sh_flags
& SHF_ORDERED
)
445 ndx2
= s2
->is_shdr
->sh_info
;
447 ndx2
= s2
->is_shdr
->sh_link
;
449 i1
= s1
->is_file
->ifl_isdesc
[ndx1
];
450 i2
= s2
->is_file
->ifl_isdesc
[ndx2
];
452 if (i1
->is_keyident
> i2
->is_keyident
)
454 if (i1
->is_keyident
< i2
->is_keyident
)
460 * Sort ordered input sections
463 ld_sort_ordered(Ofl_desc
*ofl
)
468 DBG_CALL(Dbg_sec_order_list(ofl
, 0));
470 for (APLIST_TRAVERSE(ofl
->ofl_ordered
, idx1
, osp
)) {
471 APlist
*ap_list
= osp
->os_isdescs
[OS_ISD_ORDERED
];
472 Aliste apl_nitems
= aplist_nitems(ap_list
);
475 * If this output section has a non-empty list of ordered
476 * input sections, sort their APlist in place into their
480 qsort((char *)ap_list
->apl_data
, apl_nitems
,
481 sizeof (Is_desc
*), comp
);
483 DBG_CALL(Dbg_sec_order_list(ofl
, 1));