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