xref: /titanic_50/usr/src/cmd/sgs/libld/common/place.c (revision 03831d35f7499c87d51205817c93e9a8d42c4bae)
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 	 * Setup the masks to flagout when matching sections
309 	 */
310 	shflagmask = ALL_SHF_ORDER;
311 	if ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0)
312 		shflagmask = ALL_SHF_IGNORE;
313 
314 	/*
315 	 * Traverse the input section list for the output section we have been
316 	 * assigned.  If we find a matching section simply add this new section.
317 	 */
318 	off2 = 0;
319 	for (ALIST_TRAVERSE(sgp->sg_osdescs, off1, ospp)) {
320 		Shdr	*_shdr;
321 
322 		osp = *ospp;
323 		_shdr = osp->os_shdr;
324 
325 		if ((ident == osp->os_scnsymndx) && (ident != M_ID_REL) &&
326 		    (isp->is_namehash == osp->os_namehash) &&
327 		    (shdr->sh_type != SHT_GROUP) &&
328 		    (shdr->sh_type != SHT_SUNW_dof) &&
329 		    ((shdr->sh_type == _shdr->sh_type) ||
330 		    ((shdr->sh_type == SHT_SUNW_COMDAT) &&
331 		    (_shdr->sh_type == SHT_PROGBITS))) &&
332 		    ((shflags & ~shflagmask) ==
333 		    (_shdr->sh_flags & ~shflagmask)) &&
334 		    (strcmp(isp->is_name, osp->os_name) == 0)) {
335 			/*
336 			 * If this is a COMDAT section, determine if this
337 			 * section is a keeper, and/or if it is to be discarded.
338 			 */
339 			if (shdr->sh_type == SHT_SUNW_COMDAT) {
340 				Listnode *	clist;
341 				Is_desc *	cisp;
342 
343 				for (LIST_TRAVERSE(&(osp->os_comdats),
344 				    clist, cisp)) {
345 					if (strcmp(isp->is_basename,
346 					    cisp->is_basename))
347 						continue;
348 
349 					isp->is_flags |= FLG_IS_DISCARD;
350 					DBG_CALL(Dbg_sec_discarded(ofl->ofl_lml,
351 					    isp, cisp));
352 					return (0);
353 				}
354 
355 				/*
356 				 * This is a new COMDAT section - so keep it.
357 				 */
358 				if (list_appendc(&(osp->os_comdats), isp) == 0)
359 					return ((Os_desc *)S_ERROR);
360 			}
361 
362 			/*
363 			 * Set alignment
364 			 */
365 			set_addralign(ofl, osp, isp);
366 
367 			/*
368 			 * If this section is a non-empty TLS section indicate
369 			 * that a PT_TLS program header is required.
370 			 */
371 			if ((shflags & SHF_TLS) && shdr->sh_size &&
372 			    ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0))
373 				ofl->ofl_flags |= FLG_OF_TLSPHDR;
374 
375 			/*
376 			 * If is_txtndx is 0 then this section was not
377 			 * seen in mapfile, so put it at the end.
378 			 * If is_txtndx is not 0 and ?O is turned on
379 			 * then check to see where this section should
380 			 * be inserted.
381 			 */
382 			if ((sgp->sg_flags & FLG_SG_ORDER) && isp->is_txtndx) {
383 				Listnode *	tlist;
384 
385 				tlist = list_where(&(osp->os_isdescs),
386 				    isp->is_txtndx);
387 				if (tlist != NULL) {
388 					if (list_insertc(&(osp->os_isdescs),
389 					    isp, tlist) == 0)
390 						return ((Os_desc *)S_ERROR);
391 				} else {
392 					if (list_prependc(&(osp->os_isdescs),
393 					    isp) == 0)
394 						return ((Os_desc *)S_ERROR);
395 				}
396 			} else
397 				if (list_appendc(&(osp->os_isdescs), isp) == 0)
398 					return ((Os_desc *)S_ERROR);
399 
400 			isp->is_osdesc = osp;
401 
402 			/*
403 			 * If this input section and file is associated to an
404 			 * artificially referenced output section, make sure
405 			 * they are marked as referenced also. This insures this
406 			 * input section and file isn't eliminated when -zignore
407 			 * is in effect.
408 			 * See -zignore comments when creating a new output
409 			 * section below.
410 			 */
411 			if (((ifl &&
412 			    (ifl->ifl_flags & FLG_IF_IGNORE)) || DBG_ENABLED) &&
413 			    (osp->os_flags & FLG_OS_SECTREF)) {
414 				isp->is_flags |= FLG_IS_SECTREF;
415 				if (ifl)
416 					ifl->ifl_flags |= FLG_IF_FILEREF;
417 			}
418 
419 			DBG_CALL(Dbg_sec_added(ofl->ofl_lml, osp, sgp));
420 			return (osp);
421 		}
422 
423 		/*
424 		 * Do we need to worry about section ordering?
425 		 */
426 		if (os_ndx) {
427 			if (osp->os_txtndx) {
428 				if (os_ndx < osp->os_txtndx)
429 					/* insert section here. */
430 					break;
431 				else {
432 					off2 = off1;
433 					continue;
434 				}
435 			} else {
436 				/* insert section here. */
437 				break;
438 			}
439 		} else if (osp->os_txtndx) {
440 			off2 = off1;
441 			continue;
442 		}
443 
444 		/*
445 		 * If the new sections identifier is less than that of the
446 		 * present input section we need to insert the new section
447 		 * at this point.
448 		 */
449 		if (ident < osp->os_scnsymndx)
450 			break;
451 
452 		off2 = off1;
453 	}
454 
455 	/*
456 	 * We are adding a new output section.  Update the section header
457 	 * count and associated string size.
458 	 */
459 	ofl->ofl_shdrcnt++;
460 	if (st_insert(ofl->ofl_shdrsttab, isp->is_name) == -1)
461 		return ((Os_desc *)S_ERROR);
462 
463 	/*
464 	 * Create a new output section descriptor.
465 	 */
466 	if ((osp = libld_calloc(sizeof (Os_desc), 1)) == 0)
467 		return ((Os_desc *)S_ERROR);
468 	if ((osp->os_shdr = libld_calloc(sizeof (Shdr), 1)) == 0)
469 		return ((Os_desc *)S_ERROR);
470 
471 	/*
472 	 * We convert COMDAT sections to PROGBITS if this is the first
473 	 * section of a output section.
474 	 */
475 	if (shdr->sh_type == SHT_SUNW_COMDAT) {
476 		Shdr *	tshdr;
477 
478 		if ((tshdr = libld_malloc(sizeof (Shdr))) == 0)
479 			return ((Os_desc *)S_ERROR);
480 		*tshdr = *shdr;
481 		isp->is_shdr = shdr = tshdr;
482 		shdr->sh_type = SHT_PROGBITS;
483 		if (list_appendc(&(osp->os_comdats), isp) == 0)
484 			return ((Os_desc *)S_ERROR);
485 	}
486 
487 	osp->os_shdr->sh_type = shdr->sh_type;
488 	osp->os_shdr->sh_flags = shdr->sh_flags;
489 	osp->os_shdr->sh_entsize = shdr->sh_entsize;
490 	osp->os_name = isp->is_name;
491 	osp->os_namehash = isp->is_namehash;
492 	osp->os_txtndx = os_ndx;
493 	osp->os_sgdesc = sgp;
494 
495 	if (ifl && (shdr->sh_type == SHT_PROGBITS)) {
496 		/*
497 		 * Try to preserve the intended meaning of sh_link/sh_info.
498 		 * See the translate_link() in update.c.
499 		 */
500 		osp->os_shdr->sh_link = shdr->sh_link;
501 		if (shdr->sh_flags & SHF_INFO_LINK)
502 			osp->os_shdr->sh_info = shdr->sh_info;
503 	}
504 
505 	/*
506 	 * When -zignore is in effect, user supplied sections and files that are
507 	 * not referenced from other sections, are eliminated from the object
508 	 * being produced.  Some sections, although unreferenced, are special,
509 	 * and must not be eliminated.  Determine if this new output section is
510 	 * one of those special sections, and if so mark it artificially as
511 	 * referenced.  Any input section and file associated to this output
512 	 * section is also be marked as referenced, and thus won't be eliminated
513 	 * from the final output.
514 	 */
515 	if (ifl && ((ofl->ofl_flags1 & FLG_OF1_IGNPRC) || DBG_ENABLED)) {
516 		const Msg	*refsec;
517 
518 		for (refsec = RefSecs; *refsec; refsec++) {
519 			if (strcmp(osp->os_name, MSG_ORIG(*refsec)) == 0) {
520 				osp->os_flags |= FLG_OS_SECTREF;
521 
522 				if ((ifl->ifl_flags & FLG_IF_IGNORE) ||
523 				    DBG_ENABLED) {
524 					isp->is_flags |= FLG_IS_SECTREF;
525 					ifl->ifl_flags |= FLG_IF_FILEREF;
526 				}
527 				break;
528 			}
529 		}
530 	}
531 
532 	/*
533 	 * Setions of SHT_GROUP are added to the ofl->ofl_osgroups
534 	 * list - so that they can be updated as a group later.
535 	 */
536 	if (shdr->sh_type == SHT_GROUP) {
537 		if (list_appendc(&ofl->ofl_osgroups, osp) == 0)
538 			return ((Os_desc *)S_ERROR);
539 	}
540 
541 	/*
542 	 * If this section is a non-empty TLS section indicate that a PT_TLS
543 	 * program header is required.
544 	 */
545 	if ((shflags & SHF_TLS) && shdr->sh_size &&
546 	    ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0))
547 		ofl->ofl_flags |= FLG_OF_TLSPHDR;
548 
549 	/*
550 	 * If a non-allocatable section is going to be put into a loadable
551 	 * segment then turn on the allocate bit for this section and warn the
552 	 * user that we have done so.  This could only happen through the use
553 	 * of a mapfile.
554 	 */
555 	if ((sgp->sg_phdr.p_type == PT_LOAD) &&
556 	    ((osp->os_shdr->sh_flags & SHF_ALLOC) == 0)) {
557 		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SCN_NONALLOC),
558 		    ofl->ofl_name, osp->os_name);
559 		osp->os_shdr->sh_flags |= SHF_ALLOC;
560 	}
561 
562 	/*
563 	 * Retain this sections identifier for future comparisons when placing
564 	 * a section (after all sections have been processed this variable will
565 	 * be used to hold the sections symbol index as we don't need to retain
566 	 * the identifier any more).
567 	 */
568 	osp->os_scnsymndx = ident;
569 
570 	/*
571 	 * Set alignment
572 	 */
573 	set_addralign(ofl, osp, isp);
574 
575 	if (list_appendc(&(osp->os_isdescs), isp) == 0)
576 		return ((Os_desc *)S_ERROR);
577 
578 	DBG_CALL(Dbg_sec_created(ofl->ofl_lml, osp, sgp));
579 	isp->is_osdesc = osp;
580 
581 	if (off2) {
582 		/*
583 		 * Insert the new section after the section identified by off2.
584 		 */
585 		off2 += sizeof (Os_desc *);
586 		if (alist_insert(&(sgp->sg_osdescs), &osp,
587 		    sizeof (Os_desc *), AL_CNT_OSDESC, off2) == 0)
588 			return ((Os_desc *)S_ERROR);
589 	} else {
590 		/*
591 		 * Prepend this section to the section list.
592 		 */
593 		if (alist_insert(&(sgp->sg_osdescs), &osp,
594 		    sizeof (Os_desc *), AL_CNT_OSDESC, ALO_DATA) == 0)
595 			return ((Os_desc *)S_ERROR);
596 	}
597 	return (osp);
598 }
599