xref: /illumos-gate/usr/src/cmd/sgs/libld/common/place.c (revision 09295472)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  *	Copyright (c) 1988 AT&T
24  *	  All Rights Reserved
25  *
26  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
27  * Use is subject to license terms.
28  */
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 /*
32  * Map file parsing and input section to output segment mapping.
33  */
34 #include	<stdio.h>
35 #include	<string.h>
36 #include	<debug.h>
37 #include	"msg.h"
38 #include	"_libld.h"
39 
40 /*
41  * Each time a section is placed, the function set_addralign()
42  * is called.  This function performs:
43  *
44  *  .	if the section is from an external file, check if this is empty or not.
45  *	If not, we know the segment this section will belong needs a program
46  *	header. (Of course, the program is needed only if this section falls
47  *	into a loadable segment.)
48  *  .	compute the Least Common Multiplier for setting the segment alignment.
49  */
50 static void
51 set_addralign(Ofl_desc *ofl, Os_desc *osp, Is_desc *isp)
52 {
53 	Shdr *		shdr = isp->is_shdr;
54 
55 	/*
56 	 * If this section has data or will be assigned data
57 	 * later, mark this segment not-empty.
58 	 */
59 	if ((shdr->sh_size != 0) ||
60 	    ((isp->is_flags & FLG_IS_EXTERNAL) == 0))
61 		osp->os_sgdesc->sg_flags |= FLG_SG_PHREQ;
62 
63 	if ((ofl->ofl_dtflags_1 & DF_1_NOHDR) &&
64 	    (osp->os_sgdesc->sg_phdr).p_type != PT_LOAD)
65 		return;
66 
67 	osp->os_sgdesc->sg_addralign =
68 	    ld_lcm(osp->os_sgdesc->sg_addralign, shdr->sh_addralign);
69 }
70 
71 /*
72  * Place a section into the appropriate segment.
73  */
74 Os_desc *
75 ld_place_section(Ofl_desc * ofl, Is_desc * isp, int ident, Word link)
76 {
77 	Listnode *	lnp1, * lnp2;
78 	Ent_desc *	enp;
79 	Sg_desc	*	sgp;
80 	Os_desc		**ospp, *osp;
81 	Aliste		off1, off2;
82 	int		os_ndx;
83 	Shdr *		shdr = isp->is_shdr;
84 	Xword		shflagmask, shflags = shdr->sh_flags;
85 	Ifl_desc *	ifl = isp->is_file;
86 
87 	/*
88 	 * Define any sections that must be thought of as referenced.  These
89 	 * sections may not be referenced externaly in a manner ld(1) can
90 	 * discover, but they must be retained (ie. not removed by -zignore).
91 	 */
92 	static const Msg RefSecs[] = {
93 		MSG_SCN_INIT,		/* MSG_ORIG(MSG_SCN_INIT) */
94 		MSG_SCN_FINI,		/* MSG_ORIG(MSG_SCN_FINI) */
95 		MSG_SCN_EX_RANGES,	/* MSG_ORIG(MSG_SCN_EX_RANGES) */
96 		MSG_SCN_EX_SHARED,	/* MSG_ORIG(MSG_SCN_EX_SHARED) */
97 		MSG_SCN_CTORS,		/* MSG_ORIG(MSG_SCN_CTORS) */
98 		MSG_SCN_DTORS,		/* MSG_ORIG(MSG_SCN_DTORS) */
99 		MSG_SCN_EHFRAME,	/* MSG_ORIG(MSG_SCN_EHFRAME) */
100 		MSG_SCN_EHFRAME_HDR,	/* MSG_ORIG(MSG_SCN_EHFRAME_HDR) */
101 		MSG_SCN_JCR,		/* MSG_ORIG(MSG_SCN_JCR) */
102 		0
103 	};
104 
105 	DBG_CALL(Dbg_sec_in(ofl->ofl_lml, isp));
106 
107 	if ((shflags & SHF_GROUP) || (shdr->sh_type == SHT_GROUP)) {
108 		Group_desc *	gdesc;
109 
110 		if ((gdesc = ld_get_group(ofl, isp)) == (Group_desc *)S_ERROR)
111 			return ((Os_desc *)S_ERROR);
112 
113 		if (gdesc) {
114 			DBG_CALL(Dbg_sec_group(ofl->ofl_lml, isp, gdesc));
115 
116 			/*
117 			 * If this group is marked as discarded, then this
118 			 * section needs to be discarded.
119 			 */
120 			if (gdesc->gd_flags & GRP_FLG_DISCARD) {
121 				isp->is_flags |= FLG_IS_DISCARD;
122 				return ((Os_desc *)0);
123 			}
124 		}
125 
126 		/*
127 		 * SHT_GROUP sections can only be included into relocatable
128 		 * objects.
129 		 */
130 		if (shdr->sh_type == SHT_GROUP) {
131 			if ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) {
132 				isp->is_flags |= FLG_IS_DISCARD;
133 				return ((Os_desc *)0);
134 			}
135 		}
136 	}
137 
138 	/*
139 	 * Always assign SHF_TLS sections to the DATA segment (and then the
140 	 * PT_TLS embedded inside of there).
141 	 */
142 	if (shflags & SHF_TLS)
143 		shflags |= SHF_WRITE;
144 
145 	/*
146 	 * Traverse the entrance criteria list searching for a segment that
147 	 * matches the input section we have.  If an entrance criterion is set
148 	 * then there must be an exact match.  If we complete the loop without
149 	 * finding a segment, then sgp will be NULL.
150 	 */
151 	sgp = NULL;
152 	for (LIST_TRAVERSE(&ofl->ofl_ents, lnp1, enp)) {
153 		if (enp->ec_segment &&
154 		    (enp->ec_segment->sg_flags & FLG_SG_DISABLED))
155 			continue;
156 		if (enp->ec_type && (enp->ec_type != shdr->sh_type))
157 			continue;
158 		if (enp->ec_attrmask &&
159 		    /* LINTED */
160 		    (enp->ec_attrmask & enp->ec_attrbits) !=
161 		    (enp->ec_attrmask & shflags))
162 			continue;
163 		if (enp->ec_name && (strcmp(enp->ec_name, isp->is_name) != 0))
164 			continue;
165 		if (enp->ec_files.head) {
166 			char	*file;
167 			int	found = 0;
168 
169 			if (isp->is_file == 0)
170 				continue;
171 
172 			for (LIST_TRAVERSE(&(enp->ec_files), lnp2, file)) {
173 				const char	*name = isp->is_file->ifl_name;
174 
175 				if (file[0] == '*') {
176 					const char	*basename;
177 
178 					basename = strrchr(name, '/');
179 					if (basename == NULL)
180 						basename = name;
181 					else if (basename[1] != '\0')
182 						basename++;
183 
184 					if (strcmp(&file[1], basename) == 0) {
185 						found++;
186 						break;
187 					}
188 				} else {
189 					if (strcmp(file, name) == 0) {
190 						found++;
191 						break;
192 					}
193 				}
194 			}
195 			if (!found)
196 				continue;
197 		}
198 		break;
199 	}
200 
201 	if ((sgp = enp->ec_segment) == 0)
202 		sgp = ((Ent_desc *)(ofl->ofl_ents.tail->data))->ec_segment;
203 
204 	isp->is_basename = isp->is_name;
205 
206 	/*
207 	 * Strip out the % from the section name in all cases except when '-r'
208 	 * is used without '-M', and '-r' is used with '-M' without
209 	 * the ?O flag.
210 	 */
211 	if (((ofl->ofl_flags & FLG_OF_RELOBJ) &&
212 	    (sgp->sg_flags & FLG_SG_ORDER)) ||
213 	    !(ofl->ofl_flags & FLG_OF_RELOBJ)) {
214 		char	*cp;
215 
216 		if ((cp = strchr(isp->is_name, '%')) != NULL) {
217 			char	*name;
218 			size_t	size = (size_t)(cp - isp->is_name);
219 
220 			if ((name = libld_malloc(size + 1)) == 0)
221 				return ((Os_desc *)S_ERROR);
222 			(void) strncpy(name, isp->is_name, size);
223 			cp = name + size;
224 			*cp = '\0';
225 			isp->is_name = name;
226 		}
227 		isp->is_txtndx = enp->ec_ndx;
228 	}
229 
230 	/*
231 	 * Assign a hash value now that the section name has been finalized.
232 	 */
233 	isp->is_namehash = sgs_str_hash(isp->is_name);
234 
235 	if (sgp->sg_flags & FLG_SG_ORDER)
236 		enp->ec_flags |= FLG_EC_USED;
237 
238 	/*
239 	 * If the link is not 0, then the input section is going to be appended
240 	 * to the output section.  The append occurs at the input section
241 	 * pointed to by the link.
242 	 */
243 	if (link != 0) {
244 		osp = isp->is_file->ifl_isdesc[link]->is_osdesc;
245 
246 		/*
247 		 * If this is a COMDAT section, then see if this
248 		 * section is a keeper and/or if it is to be discarded.
249 		 */
250 		if (shdr->sh_type == SHT_SUNW_COMDAT) {
251 			Listnode *	clist;
252 			Is_desc *	cisp;
253 
254 			for (LIST_TRAVERSE(&(osp->os_comdats), clist, cisp)) {
255 				if (strcmp(isp->is_basename, cisp->is_basename))
256 					continue;
257 
258 				isp->is_flags |= FLG_IS_DISCARD;
259 				DBG_CALL(Dbg_sec_discarded(ofl->ofl_lml,
260 				    isp, cisp));
261 				return (0);
262 			}
263 
264 			/*
265 			 * This is a new COMDAT section - so keep it.
266 			 */
267 			if (list_appendc(&(osp->os_comdats), isp) == 0)
268 				return ((Os_desc *)S_ERROR);
269 		}
270 
271 		/*
272 		 * Set alignment
273 		 */
274 		set_addralign(ofl, osp, isp);
275 
276 		if (list_appendc(&(osp->os_isdescs), isp) == 0)
277 			return ((Os_desc *)S_ERROR);
278 
279 		isp->is_osdesc = osp;
280 		sgp = osp->os_sgdesc;
281 
282 		DBG_CALL(Dbg_sec_added(ofl->ofl_lml, osp, sgp));
283 		return (osp);
284 	}
285 
286 	/*
287 	 * Determine if section ordering is turned on.  If so, return the
288 	 * appropriate os_txtndx.  This information is derived from the
289 	 * Sg_desc->sg_segorder list that was built up from the Mapfile.
290 	 */
291 	os_ndx = 0;
292 	if (sgp->sg_secorder) {
293 		Aliste		off;
294 		Sec_order	**scopp;
295 
296 		for (ALIST_TRAVERSE(sgp->sg_secorder, off, scopp)) {
297 			Sec_order	*scop = *scopp;
298 
299 			if (strcmp(scop->sco_secname, isp->is_name) == 0) {
300 				scop->sco_flags |= FLG_SGO_USED;
301 				os_ndx = scop->sco_index;
302 				break;
303 			}
304 		}
305 	}
306 
307 	/*
308 	 * Mask of section header flags to ignore when
309 	 * matching sections. We are more strict with
310 	 * relocatable objects, ignoring only the order
311 	 * flags, and keeping sections apart if they differ
312 	 * otherwise. This follows the policy that sections
313 	 * in a relative object should only be merged if their
314 	 * flags are the same, and avoids destroying information
315 	 * prematurely. For final products however, we ignore all
316 	 * flags that do not prevent a merge.
317 	 */
318 	shflagmask = (ofl->ofl_flags & FLG_OF_RELOBJ)
319 		? ALL_SHF_ORDER : ALL_SHF_IGNORE;
320 
321 	/*
322 	 * Traverse the input section list for the output section we have been
323 	 * assigned. If we find a matching section simply add this new section.
324 	 */
325 	off2 = 0;
326 	for (ALIST_TRAVERSE(sgp->sg_osdescs, off1, ospp)) {
327 		Shdr	*_shdr;
328 
329 		osp = *ospp;
330 		_shdr = osp->os_shdr;
331 
332 		if ((ident == osp->os_scnsymndx) && (ident != M_ID_REL) &&
333 		    (isp->is_namehash == osp->os_namehash) &&
334 		    (shdr->sh_type != SHT_GROUP) &&
335 		    (shdr->sh_type != SHT_SUNW_dof) &&
336 		    ((shdr->sh_type == _shdr->sh_type) ||
337 		    ((shdr->sh_type == SHT_SUNW_COMDAT) &&
338 		    (_shdr->sh_type == SHT_PROGBITS))) &&
339 		    ((shflags & ~shflagmask) ==
340 		    (_shdr->sh_flags & ~shflagmask)) &&
341 		    (strcmp(isp->is_name, osp->os_name) == 0)) {
342 			/*
343 			 * If this is a COMDAT section, determine if this
344 			 * section is a keeper, and/or if it is to be discarded.
345 			 */
346 			if (shdr->sh_type == SHT_SUNW_COMDAT) {
347 				Listnode *	clist;
348 				Is_desc *	cisp;
349 
350 				for (LIST_TRAVERSE(&(osp->os_comdats),
351 				    clist, cisp)) {
352 					if (strcmp(isp->is_basename,
353 					    cisp->is_basename))
354 						continue;
355 
356 					isp->is_flags |= FLG_IS_DISCARD;
357 					DBG_CALL(Dbg_sec_discarded(ofl->ofl_lml,
358 					    isp, cisp));
359 					return (0);
360 				}
361 
362 				/*
363 				 * This is a new COMDAT section - so keep it.
364 				 */
365 				if (list_appendc(&(osp->os_comdats), isp) == 0)
366 					return ((Os_desc *)S_ERROR);
367 			}
368 
369 			/*
370 			 * Set alignment
371 			 */
372 			set_addralign(ofl, osp, isp);
373 
374 			/*
375 			 * If this section is a non-empty TLS section indicate
376 			 * that a PT_TLS program header is required.
377 			 */
378 			if ((shflags & SHF_TLS) && shdr->sh_size &&
379 			    ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0))
380 				ofl->ofl_flags |= FLG_OF_TLSPHDR;
381 
382 			/*
383 			 * If is_txtndx is 0 then this section was not
384 			 * seen in mapfile, so put it at the end.
385 			 * If is_txtndx is not 0 and ?O is turned on
386 			 * then check to see where this section should
387 			 * be inserted.
388 			 */
389 			if ((sgp->sg_flags & FLG_SG_ORDER) && isp->is_txtndx) {
390 				Listnode *	tlist;
391 
392 				tlist = list_where(&(osp->os_isdescs),
393 				    isp->is_txtndx);
394 				if (tlist != NULL) {
395 					if (list_insertc(&(osp->os_isdescs),
396 					    isp, tlist) == 0)
397 						return ((Os_desc *)S_ERROR);
398 				} else {
399 					if (list_prependc(&(osp->os_isdescs),
400 					    isp) == 0)
401 						return ((Os_desc *)S_ERROR);
402 				}
403 			} else
404 				if (list_appendc(&(osp->os_isdescs), isp) == 0)
405 					return ((Os_desc *)S_ERROR);
406 
407 			isp->is_osdesc = osp;
408 
409 			/*
410 			 * If this input section and file is associated to an
411 			 * artificially referenced output section, make sure
412 			 * they are marked as referenced also. This insures this
413 			 * input section and file isn't eliminated when -zignore
414 			 * is in effect.
415 			 * See -zignore comments when creating a new output
416 			 * section below.
417 			 */
418 			if (((ifl &&
419 			    (ifl->ifl_flags & FLG_IF_IGNORE)) || DBG_ENABLED) &&
420 			    (osp->os_flags & FLG_OS_SECTREF)) {
421 				isp->is_flags |= FLG_IS_SECTREF;
422 				if (ifl)
423 					ifl->ifl_flags |= FLG_IF_FILEREF;
424 			}
425 
426 			DBG_CALL(Dbg_sec_added(ofl->ofl_lml, osp, sgp));
427 			return (osp);
428 		}
429 
430 		/*
431 		 * Do we need to worry about section ordering?
432 		 */
433 		if (os_ndx) {
434 			if (osp->os_txtndx) {
435 				if (os_ndx < osp->os_txtndx)
436 					/* insert section here. */
437 					break;
438 				else {
439 					off2 = off1;
440 					continue;
441 				}
442 			} else {
443 				/* insert section here. */
444 				break;
445 			}
446 		} else if (osp->os_txtndx) {
447 			off2 = off1;
448 			continue;
449 		}
450 
451 		/*
452 		 * If the new sections identifier is less than that of the
453 		 * present input section we need to insert the new section
454 		 * at this point.
455 		 */
456 		if (ident < osp->os_scnsymndx)
457 			break;
458 
459 		off2 = off1;
460 	}
461 
462 	/*
463 	 * We are adding a new output section.  Update the section header
464 	 * count and associated string size.
465 	 */
466 	ofl->ofl_shdrcnt++;
467 	if (st_insert(ofl->ofl_shdrsttab, isp->is_name) == -1)
468 		return ((Os_desc *)S_ERROR);
469 
470 	/*
471 	 * Create a new output section descriptor.
472 	 */
473 	if ((osp = libld_calloc(sizeof (Os_desc), 1)) == 0)
474 		return ((Os_desc *)S_ERROR);
475 	if ((osp->os_shdr = libld_calloc(sizeof (Shdr), 1)) == 0)
476 		return ((Os_desc *)S_ERROR);
477 
478 	/*
479 	 * We convert COMDAT sections to PROGBITS if this is the first
480 	 * section of a output section.
481 	 */
482 	if (shdr->sh_type == SHT_SUNW_COMDAT) {
483 		Shdr *	tshdr;
484 
485 		if ((tshdr = libld_malloc(sizeof (Shdr))) == 0)
486 			return ((Os_desc *)S_ERROR);
487 		*tshdr = *shdr;
488 		isp->is_shdr = shdr = tshdr;
489 		shdr->sh_type = SHT_PROGBITS;
490 		if (list_appendc(&(osp->os_comdats), isp) == 0)
491 			return ((Os_desc *)S_ERROR);
492 	}
493 
494 	osp->os_shdr->sh_type = shdr->sh_type;
495 	osp->os_shdr->sh_flags = shdr->sh_flags;
496 	osp->os_shdr->sh_entsize = shdr->sh_entsize;
497 	osp->os_name = isp->is_name;
498 	osp->os_namehash = isp->is_namehash;
499 	osp->os_txtndx = os_ndx;
500 	osp->os_sgdesc = sgp;
501 
502 	if (ifl && (shdr->sh_type == SHT_PROGBITS)) {
503 		/*
504 		 * Try to preserve the intended meaning of sh_link/sh_info.
505 		 * See the translate_link() in update.c.
506 		 */
507 		osp->os_shdr->sh_link = shdr->sh_link;
508 		if (shdr->sh_flags & SHF_INFO_LINK)
509 			osp->os_shdr->sh_info = shdr->sh_info;
510 	}
511 
512 	/*
513 	 * When -zignore is in effect, user supplied sections and files that are
514 	 * not referenced from other sections, are eliminated from the object
515 	 * being produced.  Some sections, although unreferenced, are special,
516 	 * and must not be eliminated.  Determine if this new output section is
517 	 * one of those special sections, and if so mark it artificially as
518 	 * referenced.  Any input section and file associated to this output
519 	 * section is also be marked as referenced, and thus won't be eliminated
520 	 * from the final output.
521 	 */
522 	if (ifl && ((ofl->ofl_flags1 & FLG_OF1_IGNPRC) || DBG_ENABLED)) {
523 		const Msg	*refsec;
524 
525 		for (refsec = RefSecs; *refsec; refsec++) {
526 			if (strcmp(osp->os_name, MSG_ORIG(*refsec)) == 0) {
527 				osp->os_flags |= FLG_OS_SECTREF;
528 
529 				if ((ifl->ifl_flags & FLG_IF_IGNORE) ||
530 				    DBG_ENABLED) {
531 					isp->is_flags |= FLG_IS_SECTREF;
532 					ifl->ifl_flags |= FLG_IF_FILEREF;
533 				}
534 				break;
535 			}
536 		}
537 	}
538 
539 	/*
540 	 * Setions of SHT_GROUP are added to the ofl->ofl_osgroups
541 	 * list - so that they can be updated as a group later.
542 	 */
543 	if (shdr->sh_type == SHT_GROUP) {
544 		if (list_appendc(&ofl->ofl_osgroups, osp) == 0)
545 			return ((Os_desc *)S_ERROR);
546 	}
547 
548 	/*
549 	 * If this section is a non-empty TLS section indicate that a PT_TLS
550 	 * program header is required.
551 	 */
552 	if ((shflags & SHF_TLS) && shdr->sh_size &&
553 	    ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0))
554 		ofl->ofl_flags |= FLG_OF_TLSPHDR;
555 
556 	/*
557 	 * If a non-allocatable section is going to be put into a loadable
558 	 * segment then turn on the allocate bit for this section and warn the
559 	 * user that we have done so.  This could only happen through the use
560 	 * of a mapfile.
561 	 */
562 	if ((sgp->sg_phdr.p_type == PT_LOAD) &&
563 	    ((osp->os_shdr->sh_flags & SHF_ALLOC) == 0)) {
564 		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SCN_NONALLOC),
565 		    ofl->ofl_name, osp->os_name);
566 		osp->os_shdr->sh_flags |= SHF_ALLOC;
567 	}
568 
569 	/*
570 	 * Retain this sections identifier for future comparisons when placing
571 	 * a section (after all sections have been processed this variable will
572 	 * be used to hold the sections symbol index as we don't need to retain
573 	 * the identifier any more).
574 	 */
575 	osp->os_scnsymndx = ident;
576 
577 	/*
578 	 * Set alignment
579 	 */
580 	set_addralign(ofl, osp, isp);
581 
582 	if (list_appendc(&(osp->os_isdescs), isp) == 0)
583 		return ((Os_desc *)S_ERROR);
584 
585 	DBG_CALL(Dbg_sec_created(ofl->ofl_lml, osp, sgp));
586 	isp->is_osdesc = osp;
587 
588 	if (off2) {
589 		/*
590 		 * Insert the new section after the section identified by off2.
591 		 */
592 		off2 += sizeof (Os_desc *);
593 		if (alist_insert(&(sgp->sg_osdescs), &osp,
594 		    sizeof (Os_desc *), AL_CNT_OSDESC, off2) == 0)
595 			return ((Os_desc *)S_ERROR);
596 	} else {
597 		/*
598 		 * Prepend this section to the section list.
599 		 */
600 		if (alist_insert(&(sgp->sg_osdescs), &osp,
601 		    sizeof (Os_desc *), AL_CNT_OSDESC, ALO_DATA) == 0)
602 			return ((Os_desc *)S_ERROR);
603 	}
604 	return (osp);
605 }
606