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 2010 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
28 */
29
30 /*
31 * Copyright 2019 Joyent, Inc.
32 */
33
34 /*
35 * Map file parsing (Shared Support Code).
36 */
37 #include <stdio.h>
38 #include <errno.h>
39 #include "msg.h"
40 #include "_libld.h"
41 #include "_map.h"
42
43 /*
44 * Given a NULL terminated array of structures of arbitrary type, where
45 * each struct contains (among other fields) a character pointer field
46 * giving that struct a unique name, return the address of the struct
47 * that matches the given name.
48 *
49 * entry:
50 * name - "Keyword" name to be found.
51 * array - Base address of array
52 * name_offset - Offset of the name field within the struct
53 * type used by this array, as generated via
54 * SGSOFFSETOF().
55 * elt_size - sizeof the basic array element type
56 *
57 * exit:
58 * Using a case insensitive comparison, name is compared to the
59 * name of each element of the array. The address of the first
60 * match found is returned. If the desired name is not found,
61 * NULL is returned.
62 *
63 * note:
64 * This routine is completely type-unsafe. The upside is that this
65 * single routine is able to search arrays of arbitrary type, leaving
66 * the caller free to structure their array in any way that is convenient
67 * to solve the problem at hand.
68 */
69 #ifndef _ELF64
70 void *
71 ld_map_kwfind(const char *name, void *array, size_t name_offset,
72 size_t elt_size)
73 {
74 for (; ; array = elt_size + (char *)array) {
75 /* LINTED E_BAD_PTR_CAST_ALIGN */
76 const char *arr_name = *((const char **)
77 (name_offset + (const char *) array));
78
79 if (arr_name == NULL)
80 return (NULL);
81
82 if (strcasecmp(name, arr_name) == 0)
83 return (array);
84 }
85
86 /*NOTREACHED*/
87 }
88 #endif
89
90 /*
91 * Given the same NULL terminated array accepted by ld_map_kwfind(), format
92 * the strings into a comma separated list of names.
93 *
94 * entry:
95 * array - Base address of array
96 * name_offset - Offset of the name field within the struct
97 * type used by this array, as generated via
98 * SGSOFFSETOF().
99 * elt_size - sizeof the basic array element type
100 * buf - Buffer to receive output
101 * bufsize - sizeof(buf)
102 *
103 * exit:
104 * As many of the names as will fit are formatted into buf. If all the
105 * names do not fit, the remainder are quietly clipped. The caller must
106 * ensure that there is sufficient room. buf is returned, for convenience
107 * in using this function as an argument for printing.
108 */
109 #ifndef _ELF64
110 char *
111 ld_map_kwnames(void *array, size_t name_offset, size_t elt_size, char *buf,
112 size_t bufsize)
113 {
114 size_t cnt = 0;
115 size_t len;
116 char *str = buf;
117
118 for (; bufsize > 1; array = elt_size + (char *)array, cnt++) {
119 /* LINTED E_BAD_PTR_CAST_ALIGN */
120 const char *arr_name = *((const char **)
121 (name_offset + (const char *) array));
122
123 if (arr_name == NULL)
124 break;
125
126 if (cnt > 0) {
127 if (bufsize < 3)
128 break;
129 *str++ = ',';
130 *str++ = ' ';
131 bufsize -= 2;
132 *(str + 1) = '\0';
133 }
134
135 len = strlcpy(str, arr_name, bufsize);
136 if (len >= bufsize)
137 break;
138 str += len;
139 bufsize -= len;
140 }
141
142 return (buf);
143 }
144 #endif
145
146 /*
147 * Create a pseudo input file descriptor to represent the specified Mapfile.
148 * An input descriptor is required any time a symbol is generated.
149 *
150 * entry:
151 * mf - Mapfile descriptor.
152 *
153 * exit:
154 * If an input descriptor was already created for this mapfile
155 * by a previous call, it is returned. Otherwise, a new descriptor
156 * is created, entered into the mapfile descriptor, and returned.
157 *
158 * Success is indicated by a non-NULL return value, failure by NULL.
159 */
160 Ifl_desc *
161 ld_map_ifl(Mapfile *mf)
162 {
163 Ifl_desc *ifl;
164
165 /*
166 * If we've already created a pseudo input descriptor for this
167 * mapfile, reuse it.
168 */
169 if (mf->mf_ifl != NULL)
170 return (mf->mf_ifl);
171
172 if ((ifl = libld_calloc(sizeof (Ifl_desc), 1)) == NULL)
173 return (NULL);
174 ifl->ifl_name = mf->mf_name;
175 ifl->ifl_flags = (FLG_IF_MAPFILE | FLG_IF_NEEDED | FLG_IF_FILEREF);
176 if ((ifl->ifl_ehdr = libld_calloc(sizeof (Ehdr), 1)) == NULL)
177 return (NULL);
178 ifl->ifl_ehdr->e_type = ET_REL;
179
180 if (aplist_append(&mf->mf_ofl->ofl_objs, ifl, AL_CNT_OFL_OBJS) == NULL)
181 return (NULL);
182
183 mf->mf_ifl = ifl;
184 return (mf->mf_ifl);
185 }
186
187 /*
188 * Given a capability tag type, set the override bit in the output descriptor.
189 * This prevents the use of capability values of that type from the input
190 * objects.
191 */
192 void
193 ld_map_cap_set_ovflag(Mapfile *mf, Word type)
194 {
195 /*
196 * Map capability tag to the corresponding output descriptor
197 * override flag.
198 */
199 static ofl_flag_t override_flag[CA_SUNW_NUM] = {
200 0, /* CA_SUNW_NULL */
201 FLG_OF1_OVHWCAP1, /* CA_SUNW_HW_1 */
202 FLG_OF1_OVSFCAP1, /* CA_SUNW_SF_1 */
203 FLG_OF1_OVHWCAP2, /* CA_SUNW_HW_2 */
204 FLG_OF1_OVPLATCAP, /* CA_SUNW_PLAT */
205 FLG_OF1_OVMACHCAP, /* CA_SUNW_MACH */
206 FLG_OF1_OVIDCAP /* CA_SUNW_ID */
207 };
208 #if CA_SUNW_NUM != (CA_SUNW_ID + 1)
209 #error "CA_SUNW_NUM has grown"
210 #endif
211 mf->mf_ofl->ofl_flags1 |= override_flag[type];
212 }
213
214 /*
215 * Sanity check the given capability bitmask.
216 */
217 Boolean
218 ld_map_cap_sanitize(Mapfile *mf, Word type, Capmask *capmask)
219 {
220 elfcap_mask_t mask;
221
222 switch (type) {
223 case CA_SUNW_SF_1:
224 /*
225 * Unlike hardware capabilities, we do not allow setting
226 * software capability bits that do not have known definitions.
227 * Software capability tokens have to be validated as a unit
228 * as the bits can affect each others meaning (see sf1_cap()
229 * in files.c).
230 */
231 if ((mask = (capmask->cm_val & ~SF1_SUNW_MASK)) != 0) {
232 mf_warn(mf, MSG_INTL(MSG_MAP_BADSF1),
233 EC_XWORD(mask));
234 capmask->cm_val &= SF1_SUNW_MASK;
235 }
236 if ((capmask->cm_val &
237 (SF1_SUNW_FPKNWN | SF1_SUNW_FPUSED)) == SF1_SUNW_FPUSED) {
238 mf_warn(mf, MSG_INTL(MSG_MAP_BADSF1),
239 EC_XWORD(SF1_SUNW_FPUSED));
240 capmask->cm_val &= ~SF1_SUNW_FPUSED;
241 }
242 #if !defined(_ELF64)
243 /*
244 * The SF1_SUNW_ADDR32 software capability is only meaningful
245 * when building a 64-bit object. Warn the user, and remove the
246 * setting, if we're building a 32-bit object.
247 */
248 if (capmask->cm_val & SF1_SUNW_ADDR32) {
249 mf_warn0(mf, MSG_INTL(MSG_MAP_INADDR32SF1));
250 capmask->cm_val &= ~SF1_SUNW_ADDR32;
251 }
252 #endif
253 }
254
255 return (TRUE);
256 }
257
258 /*
259 * Return the shared object control definition structure (ofl_socntl)
260 * for the specified object, creating one if necessary.
261 *
262 * entry:
263 * mf - Mapfile descriptor
264 * obj_name - Name of object
265 *
266 * exit:
267 * Returns the pointer to the definition structure, or NULL on error.
268 */
269 Sdf_desc *
270 ld_map_dv(Mapfile *mf, const char *obj_name)
271 {
272 Sdf_desc *sdf;
273
274 /*
275 * If a shared object definition for this file already exists use it,
276 * otherwise allocate a new descriptor.
277 */
278 if ((sdf = sdf_find(obj_name, mf->mf_ofl->ofl_socntl)) == NULL) {
279 if ((sdf = sdf_add(obj_name, &mf->mf_ofl->ofl_socntl)) ==
280 (Sdf_desc *)S_ERROR)
281 return (NULL);
282 sdf->sdf_rfile = mf->mf_name;
283 }
284
285 DBG_CALL(Dbg_map_dv(mf->mf_ofl->ofl_lml, sdf->sdf_name,
286 mf->mf_lineno));
287 return (sdf);
288 }
289
290
291 Boolean
292 ld_map_dv_entry(Mapfile *mf, Sdf_desc *sdf, Boolean require,
293 const char *version)
294 {
295 Sdv_desc sdv;
296
297 sdv.sdv_name = version;
298 sdv.sdv_ref = mf->mf_name;
299 sdv.sdv_flags = 0;
300
301
302 if (require) {
303 /*
304 * Add a VERNEED entry for the specified version
305 * from this object:
306 *
307 * MapfileVersion Syntax
308 * ----------------------------------------
309 * 1 obj - $ADDVERS=version;
310 * 2 DEPENDENCY obj { REQUIRE=version };
311 */
312 sdf->sdf_flags |= FLG_SDF_ADDVER;
313
314 if (alist_append(&sdf->sdf_verneed, &sdv, sizeof (Sdv_desc),
315 AL_CNT_SDF_VERSIONS) == NULL)
316 return (FALSE);
317 } else { /* Allow */
318 /*
319 * Allow linking to symbols found in this version, or
320 * from the versions it inherits from.
321 *
322 * MapfileVersion Syntax
323 * ----------------------------------------
324 * 1 obj - version;
325 * 2 DEPENDENCY obj { ALLOW=version };
326 */
327 sdf->sdf_flags |= FLG_SDF_SELECT;
328
329 if (alist_append(&sdf->sdf_vers, &sdv, sizeof (Sdv_desc),
330 AL_CNT_SDF_VERSIONS) == NULL)
331 return (FALSE);
332 }
333
334 DBG_CALL(Dbg_map_dv_entry(mf->mf_ofl->ofl_lml, mf->mf_lineno,
335 require, version));
336
337 return (TRUE);
338 }
339
340 /*
341 * Given a segment descriptor, return its index.
342 *
343 * entry:
344 * mf - Mapfile descriptor
345 * sgp - Segment for which index is desired
346 *
347 * exit:
348 * Index of segment is returned.
349 */
350 Xword
351 ld_map_seg_index(Mapfile *mf, Sg_desc *sgp)
352 {
353 Aliste idx;
354 Sg_desc *sgp2;
355 Ofl_desc *ofl = mf->mf_ofl;
356
357 for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp2))
358 if (sgp == sgp2)
359 break;
360
361 return (idx);
362 }
363
364 /*
365 * Add a section name to the output section sort list for the given
366 * segment.
367 *
368 * entry:
369 * mf - Mapfile descriptor
370 * sgp - Segment in question
371 * sec_name - Name of section to be added.
372 *
373 * exit:
374 * Returns TRUE for success, FALSE for failure.
375 */
376 Boolean
377 ld_map_seg_os_order_add(Mapfile *mf, Sg_desc *sgp, const char *sec_name)
378 {
379 Aliste idx;
380 Sec_order *scop;
381
382 /*
383 * Make sure it's not already on the list
384 */
385 for (ALIST_TRAVERSE(sgp->sg_os_order, idx, scop))
386 if (strcmp(scop->sco_secname, sec_name) == 0) {
387 mf_fatal(mf, MSG_INTL(MSG_MAP_DUP_OS_ORD), sec_name);
388 return (FALSE);
389 }
390
391
392 scop = alist_append(&sgp->sg_os_order, NULL, sizeof (Sec_order),
393 AL_CNT_SG_SECORDER);
394 if (scop == NULL)
395 return (FALSE);
396
397 scop->sco_secname = sec_name;
398
399 DBG_CALL(Dbg_map_seg_os_order(mf->mf_ofl->ofl_lml, sgp, sec_name,
400 alist_nitems(sgp->sg_os_order), mf->mf_lineno));
401
402 /*
403 * Output section ordering is a relatively expensive operation,
404 * and one that is generally not used. In order to avoid needless
405 * work, the FLG_OF_OS_ORDER must be set when it will be needed.
406 * The section we just added needs this flag to be set. However,
407 * it is possible that a subsequent mapfile directive may come
408 * along and clear the order list, making it unnecessary.
409 *
410 * Instead of setting it here, we do a final pass over the segments
411 * in ld_map_finalize() and set it there if a segment with sorting
412 * requirements is seen.
413 */
414
415 return (TRUE);
416 }
417
418 /*
419 * Add a size symbol to a segment
420 *
421 * entry:
422 * mf - Mapfile descriptor
423 * sgp - Segment descriptor
424 * eq_tol - Type of assignment: TK_EQUAL, or TK_PLUSEQ
425 * symname - Name of symbol. Must be in stable static storage
426 * that can be retained.
427 *
428 * exit:
429 * On success, the symbol has been added and TRUE is returned.
430 * Otherwise an error is reported and FALSE is returned.
431 */
432 Boolean
433 ld_map_seg_size_symbol(Mapfile *mf, Sg_desc *sgp, Token eq_tok,
434 const char *symname)
435 {
436 Sym *sym; /* New symbol pointer */
437 Sym_desc *sdp; /* New symbol node pointer */
438 Ifl_desc *ifl; /* Dummy input file structure */
439 avl_index_t where;
440 Ofl_desc *ofl = mf->mf_ofl;
441
442 /*
443 * We don't allow resetting the list of size symbols, so if the
444 * operator is TK_EQUAL and the list is not empty, issue an error.
445 *
446 * If we want to lift this restriction, we would have to save the
447 * size symbols and enter them from ld_map_post_process(). Doing that
448 * well would require a significant overhead in saved error reporting
449 * state, and interactions with the same symbols created by symbol
450 * directives. As size symbols are of little practical use, and are
451 * maintained primarily for backward compatibility with SysV, we have
452 * decided not to do that, but to create the symbols as the mapfiles
453 * are processed, and to disallow later attempts to remove them.
454 */
455 if ((eq_tok == TK_EQUAL) && (aplist_nitems(sgp->sg_sizesym) > 0)) {
456 mf_fatal(mf, MSG_INTL(MSG_MAP_SEGSIZE), sgp->sg_name);
457 return (FALSE);
458 }
459
460 /*
461 * Make sure we have a pseudo file descriptor to associate to the
462 * symbol.
463 */
464 if ((ifl = ld_map_ifl(mf)) == NULL)
465 return (FALSE);
466
467 /*
468 * Make sure the symbol doesn't already exist. It is possible that the
469 * symbol has been scoped or versioned, in which case it does exist
470 * but we can freely update it here.
471 */
472 if ((sdp = ld_sym_find(symname, SYM_NOHASH, &where, ofl)) == NULL) {
473 Word hval;
474
475 if ((sym = libld_calloc(sizeof (Sym), 1)) == NULL)
476 return (FALSE);
477 sym->st_shndx = SHN_ABS;
478 sym->st_size = 0;
479 sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT);
480
481 DBG_CALL(Dbg_map_size_new(ofl->ofl_lml, symname,
482 sgp->sg_name, mf->mf_lineno));
483 /* LINTED */
484 hval = (Word)elf_hash(symname);
485 if ((sdp = ld_sym_enter(symname, sym, hval, ifl, ofl, 0,
486 SHN_ABS, (FLG_SY_SPECSEC | FLG_SY_GLOBREF), &where)) ==
487 (Sym_desc *)S_ERROR)
488 return (FALSE);
489 sdp->sd_flags &= ~FLG_SY_CLEAN;
490 DBG_CALL(Dbg_map_symbol(ofl, sdp));
491 } else {
492 sym = sdp->sd_sym;
493
494 if (sym->st_shndx == SHN_UNDEF) {
495 sdp->sd_shndx = sym->st_shndx = SHN_ABS;
496 sdp->sd_flags |= FLG_SY_SPECSEC;
497 sym->st_size = 0;
498 sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT);
499
500 sdp->sd_flags &= ~FLG_SY_MAPREF;
501
502 DBG_CALL(Dbg_map_size_old(ofl, sdp,
503 sgp->sg_name, mf->mf_lineno));
504 } else {
505 mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF1),
506 demangle(sdp->sd_name), sdp->sd_file->ifl_name,
507 MSG_INTL(MSG_MAP_DIFF_SYMMUL));
508 return (FALSE);
509 }
510 }
511
512 /*
513 * Assign the symbol to the segment.
514 */
515 if (aplist_append(&sgp->sg_sizesym, sdp, AL_CNT_SG_SIZESYM) == NULL)
516 return (FALSE);
517
518 return (TRUE);
519 }
520
521 /*
522 * Allocate a zeroed segment descriptor.
523 *
524 * exit:
525 * Returns pointer to the descriptor on success, NULL on failure.
526 * The contents of the returned descriptor have been zeroed.
527 * The returned descriptor is not added to the segment list
528 * (ofl_segs). That is done using ld_map_seg_insert().
529 */
530 Sg_desc *
531 ld_map_seg_alloc(const char *name, Word p_type, sg_flags_t sg_flags)
532 {
533 Sg_desc *sgp;
534
535 if ((sgp = libld_calloc(sizeof (Sg_desc), 1)) == NULL)
536 return (NULL);
537 sgp->sg_phdr.p_type = p_type;
538 sgp->sg_name = name;
539 sgp->sg_flags = sg_flags;
540
541 return (sgp);
542 }
543
544 /*
545 * Return the PT_SUNWSTACK segment descriptor from the ofl_segs list.
546 * This segment is part of the default set and cannot be removed, so
547 * this routine will always succeed.
548 *
549 * exit:
550 * The descriptor is located, a DBG_STATE_MOD_BEFORE debug
551 * message issued, the FLG_SG_DISABLED flag is cleared, and the
552 * descriptor pointer returned.
553 */
554 Sg_desc *
555 ld_map_seg_stack(Mapfile *mf)
556 {
557 Ofl_desc *ofl = mf->mf_ofl;
558 Sg_desc *sgp;
559 Aliste idx;
560
561 /*
562 * The stack is established by exec(), using the executable's program
563 * headers, before any sharable objects are loaded. If there is a
564 * PT_SUNWSTACK program header, exec() will act on it. As such, stack
565 * program headers are normally only applicable to executables.
566 *
567 * However, ELF allows a sharable object with an interpreter to
568 * be executed directly, and in this extremely rare case, the
569 * PT_SUNWSTACK program header would have meaning. Rather than
570 * second guess user intent, we simply create it on demand for any
571 * dynamic object, trusting that the user has a good reason for it.
572 */
573 for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp))
574 if (sgp->sg_phdr.p_type == PT_SUNWSTACK) {
575 DBG_CALL(Dbg_map_seg(mf->mf_ofl, DBG_STATE_MOD_BEFORE,
576 idx, sgp, mf->mf_lineno));
577 sgp->sg_flags &= ~FLG_SG_DISABLED;
578 return (sgp);
579 }
580
581 /*NOTREACHED*/
582 return (NULL);
583 }
584
585 /*
586 * Finish the initialization of a new segment descriptor allocated by
587 * ld_map_seg_alloc(), and enter it into the segment list.
588 *
589 * entry:
590 * mf - Mapfile descriptor
591 * seg_type - One of DBG_SEG_NEW or DBG_SEG_NEW_IMPLICIT
592 * ins_head - If TRUE, the new segment goes at the front of
593 * others of its type. If FALSE, it goes at the end.
594 * sgp - Segment descriptor to enter.
595 * where - Insertion point, initialized by a previous (failed) call to
596 * ld_seg_lookup(). Ignored if the segment has a NULL sg_name.
597 *
598 * exit:
599 * On success, returns SEG_INS_OK. A non-fatal error is indicated with
600 * a return value of SEG_INS_SKIP, in which case the descriptor is
601 * not entered, but the user is expected to discard it and continue
602 * running. On failure, returns SEG_INS_FAIL.
603 *
604 * note:
605 * This routine will modify the contents of the descriptor referenced
606 * by sgp_tmpl before allocating the new descriptor. The caller must
607 * not expect it to be unmodified.
608 */
609 ld_map_seg_ins_t
610 ld_map_seg_insert(Mapfile *mf, dbg_state_t dbg_state, Sg_desc *sgp,
611 avl_index_t where)
612 {
613 Ofl_desc *ofl = mf->mf_ofl;
614 Aliste idx;
615 Sg_desc *sgp2; /* temp segment descriptor pointer */
616 int ins_head;
617 Xword sg_ndx;
618
619 /*
620 * If specific fields have not been supplied via
621 * map_equal(), make sure defaults are supplied.
622 */
623 if (((sgp->sg_flags & FLG_SG_P_TYPE) == 0) &&
624 (sgp->sg_phdr.p_type == PT_NULL)) {
625 /*
626 * Default to a loadable segment.
627 */
628 sgp->sg_phdr.p_type = PT_LOAD;
629 sgp->sg_flags |= FLG_SG_P_TYPE;
630 }
631 if (sgp->sg_phdr.p_type == PT_LOAD) {
632 if ((sgp->sg_flags & FLG_SG_P_FLAGS) == 0) {
633 /*
634 * Default to read/write and execute.
635 */
636 sgp->sg_phdr.p_flags = PF_R + PF_W + PF_X;
637 sgp->sg_flags |= FLG_SG_P_FLAGS;
638 }
639 if ((sgp->sg_flags & FLG_SG_P_ALIGN) == 0) {
640 /*
641 * Default to segment alignment
642 */
643 sgp->sg_phdr.p_align = ld_targ.t_m.m_segm_align;
644 sgp->sg_flags |= FLG_SG_P_ALIGN;
645 }
646 }
647
648 /*
649 * Determine where the new item should be inserted in
650 * the segment descriptor list.
651 */
652 switch (sgp->sg_phdr.p_type) {
653 case PT_LOAD:
654 if (sgp->sg_flags & FLG_SG_EMPTY)
655 sgp->sg_id = SGID_TEXT_EMPTY;
656 else
657 sgp->sg_id = SGID_TEXT;
658 break;
659 case PT_NULL:
660 if (sgp->sg_flags & FLG_SG_EMPTY)
661 sgp->sg_id = SGID_NULL_EMPTY;
662 else
663 sgp->sg_id = SGID_NULL;
664 break;
665 case PT_NOTE:
666 sgp->sg_id = SGID_NOTE;
667 break;
668 default:
669 mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSEGTYP),
670 EC_WORD(sgp->sg_phdr.p_type));
671 return (SEG_INS_FAIL);
672 }
673
674 /*
675 * Add the descriptor to the segment list. In the v1 syntax,
676 * new sections are added at the head of their type, while in
677 * the newer syntax, they go at the end of their type.
678 */
679 sg_ndx = 0;
680 ins_head = (mf->mf_version == MFV_SYSV);
681 for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp2)) {
682 if (ins_head) { /* Insert before the others of its type */
683 if (sgp->sg_id > sgp2->sg_id) {
684 sg_ndx++;
685 continue;
686 }
687 } else { /* Insert after the others of its type */
688 if (sgp->sg_id >= sgp2->sg_id) {
689 sg_ndx++;
690 continue;
691 }
692 }
693 break;
694 }
695 if (aplist_insert(&ofl->ofl_segs, sgp, AL_CNT_SEGMENTS, idx) == NULL)
696 return (SEG_INS_FAIL);
697 if (sgp->sg_name != NULL)
698 avl_insert(&ofl->ofl_segs_avl, sgp, where);
699
700 DBG_CALL(Dbg_map_seg(ofl, dbg_state, sg_ndx, sgp, mf->mf_lineno));
701 return (SEG_INS_OK);
702 }
703
704 /*
705 * Add an entrance criteria record for the specified segment
706 *
707 * entry:
708 * mf - Mapfile descriptor
709 * sgp - Segment for which a new entrance criteria record is needed
710 * name - NULL, or name by which the entrance criteria can be referenced.
711 *
712 * exit:
713 * On success, a pointer to the new entrace criteria record is
714 * returned, the contents of which have been zeroed. On failure,
715 * NULL is returned.
716 */
717 Ent_desc *
718 ld_map_seg_ent_add(Mapfile *mf, Sg_desc *sgp, const char *name)
719 {
720 Ent_desc *enp;
721 avl_index_t where;
722 Ofl_desc *ofl = mf->mf_ofl;
723
724 if ((name != NULL) &&
725 (ld_ent_lookup(mf->mf_ofl, name, &where) != NULL)) {
726 mf_fatal(mf, MSG_INTL(MSG_MAP_DUPNAMENT), name);
727 return (NULL);
728 }
729
730 /* Allocate and initialize the entrace criteria descriptor */
731 if ((enp = libld_calloc(1, sizeof (*enp))) == NULL)
732 return (NULL);
733 enp->ec_name = name;
734 enp->ec_segment = sgp; /* Tie criteria to segment */
735
736
737 /*
738 * Insert into the APlist. The mf_ec_insndx field for each mapfile
739 * starts at 0, and is incremented with each insertion. This means
740 * that the entrance criteria for each mapfile go to the head of
741 * the list, but that within a single mapfile, they are inserted in
742 * the order they are seen.
743 */
744 if (aplist_insert(&ofl->ofl_ents, enp, AL_CNT_OFL_ENTRANCE,
745 mf->mf_ec_insndx) == NULL)
746 return (NULL);
747 mf->mf_ec_insndx++;
748
749 /*
750 * If the entrance criteria is named insert it into the AVL tree
751 * as well. This provides O(logN) lookups by name.
752 */
753 if (name != NULL)
754 avl_insert(&ofl->ofl_ents_avl, enp, where);
755
756 return (enp);
757 }
758
759 Boolean
760 ld_map_seg_ent_files(Mapfile *mf, Ent_desc *enp, Word ecf_type, const char *str)
761 {
762 Ent_desc_file edf;
763
764 /*
765 * The v1 sysv syntax can let an empty string get in, consisting of
766 * just a '*' where the '*' is interpreted as 'basename'.
767 */
768 if (str[0] == '\0') {
769 mf_fatal0(mf, MSG_INTL(MSG_MAP_MALFORM));
770 return (FALSE);
771 }
772
773 /* Basename or objname string must not contain a path separator (/) */
774 if ((ecf_type != TYP_ECF_PATH) && (strchr(str, '/') != NULL)) {
775 const char *msg = (ecf_type == TYP_ECF_BASENAME) ?
776 MSG_INTL(MSG_MAP_BADBNAME) : MSG_INTL(MSG_MAP_BADONAME);
777
778 mf_fatal(mf, msg, str);
779 return (FALSE);
780 }
781
782 edf.edf_flags = ecf_type;
783 edf.edf_name = str;
784 edf.edf_name_len = strlen(edf.edf_name);
785
786 /* Does it have an archive member suffix? */
787 if ((edf.edf_name[edf.edf_name_len - 1] == ')') &&
788 (strrchr(edf.edf_name, '(') != NULL))
789 edf.edf_flags |= FLG_ECF_ARMEMBER;
790
791 if (alist_append(&enp->ec_files, &edf, sizeof (edf),
792 AL_CNT_EC_FILES) == NULL)
793 return (FALSE);
794
795 /*
796 * Note that an entrance criteria requiring file name matching exists
797 * in the system. This is used by ld_place_path_info_init() to
798 * skip Place_pathinfo initialization in cases where there are
799 * no entrance criteria that will use the results.
800 */
801 mf->mf_ofl->ofl_flags |= FLG_OF_EC_FILES;
802
803 return (TRUE);
804 }
805
806 /*
807 * Prepare an ld_map_ver_t structure for a new mapfile defined version.
808 *
809 * exit:
810 * Returns TRUE for success, FALSE for failure.
811 */
812 Boolean
813 ld_map_sym_ver_init(Mapfile *mf, char *name, ld_map_ver_t *mv)
814 {
815 Word hash;
816 Ofl_desc *ofl = mf->mf_ofl;
817
818 mv->mv_name = name;
819 mv->mv_scope = FLG_SCOPE_DFLT;
820 mv->mv_errcnt = 0;
821
822 /*
823 * If we're generating segments within the image then any symbol
824 * reductions will be processed (ie. applied to relocations and symbol
825 * table entries). Otherwise (when creating a relocatable object) any
826 * versioning information is simply recorded for use in a later
827 * (segment generating) link-edit.
828 */
829 if (ofl->ofl_flags & FLG_OF_RELOBJ)
830 ofl->ofl_flags |= FLG_OF_VERDEF;
831
832 /*
833 * If no version descriptors have yet been set up, initialize a base
834 * version to represent the output file itself. This `base' version
835 * catches any internally generated symbols (_end, _etext, etc.) and
836 * serves to initialize the output version descriptor count.
837 */
838 if (ofl->ofl_vercnt == 0) {
839 if (ld_vers_base(ofl) == (Ver_desc *)S_ERROR)
840 return (FALSE);
841 }
842
843 /*
844 * If this definition has an associated version name then generate a
845 * new version descriptor and an associated version symbol index table.
846 */
847 if (name) {
848 ofl->ofl_flags |= FLG_OF_VERDEF;
849
850 /*
851 * Traverse the present version descriptor list to see if there
852 * is already one of the same name, otherwise create a new one.
853 */
854 /* LINTED */
855 hash = (Word)elf_hash(name);
856 if (((mv->mv_vdp = ld_vers_find(name, hash,
857 ofl->ofl_verdesc)) == NULL) &&
858 ((mv->mv_vdp = ld_vers_desc(name, hash,
859 &ofl->ofl_verdesc)) == (Ver_desc *)S_ERROR))
860 return (FALSE);
861
862 /*
863 * Initialize any new version with an index, the file from
864 * which it was first referenced, and a WEAK flag (indicates
865 * that there are no symbols assigned to it yet).
866 */
867 if (mv->mv_vdp->vd_ndx == 0) {
868 /* LINTED */
869 mv->mv_vdp->vd_ndx = (Half)++ofl->ofl_vercnt;
870 mv->mv_vdp->vd_file = ld_map_ifl(mf);
871 mv->mv_vdp->vd_flags = VER_FLG_WEAK;
872 }
873 } else {
874 /*
875 * If a version definition hasn't been specified assign any
876 * symbols to the base version.
877 */
878 mv->mv_vdp = (Ver_desc *)ofl->ofl_verdesc->apl_data[0];
879 }
880
881 return (TRUE);
882 }
883
884 /*
885 * Change the current scope for the given version.
886 *
887 * entry:
888 * mf - Mapfile descriptor
889 * scope_name - Name for new scope
890 * mv - Information related to version being defined
891 *
892 * exit:
893 * On success, mv is updated to change the current scope.
894 * On failure, mv->errcnt is incremented, and mv is otherwise unaltered.
895 */
896 void
897 ld_map_sym_scope(Mapfile *mf, const char *scope_name, ld_map_ver_t *mv)
898 {
899 typedef struct {
900 const char *name; /* scope keyword string */
901 ld_map_scope_t type; /* Resulting type */
902 ofl_flag_t ofl_flags; /* 0, or ofl flags to add */
903 } scope_t;
904
905 /*
906 * Valid symbol scope keywords
907 *
908 * All symbols added by a mapfile are actually global entries, and
909 * are assigned the scope that is presently in effect.
910 *
911 * If a protected/symbolic scope is detected, remember this. If
912 * a protected/symbolic scope is the only scope defined in this
913 * (or any other mapfiles), then the mode -Bsymbolic is established.
914 */
915 static scope_t scope_list[] = {
916 { MSG_ORIG(MSG_MAPKW_DEFAULT), FLG_SCOPE_DFLT, FLG_OF_MAPGLOB },
917 { MSG_ORIG(MSG_MAPKW_ELIMINATE), FLG_SCOPE_ELIM, 0 },
918 { MSG_ORIG(MSG_MAPKW_EXPORTED), FLG_SCOPE_EXPT, 0 },
919 { MSG_ORIG(MSG_MAPKW_HIDDEN), FLG_SCOPE_HIDD, 0 },
920 { MSG_ORIG(MSG_MAPKW_GLOBAL), FLG_SCOPE_DFLT, FLG_OF_MAPGLOB },
921 { MSG_ORIG(MSG_MAPKW_LOCAL), FLG_SCOPE_HIDD, 0 },
922 { MSG_ORIG(MSG_MAPKW_PROTECTED),
923 FLG_SCOPE_PROT, FLG_OF_MAPSYMB },
924 { MSG_ORIG(MSG_MAPKW_SINGLETON),
925 FLG_SCOPE_SNGL, FLG_OF_MAPGLOB },
926 { MSG_ORIG(MSG_MAPKW_SYMBOLIC),
927 FLG_SCOPE_PROT, FLG_OF_MAPSYMB },
928
929 /* List must be null terminated */
930 { 0 }
931 };
932
933 /*
934 * Size of buffer needed to format the names in scope_list[]. Must
935 * be kept in sync with scope_list.
936 */
937 static size_t scope_list_bufsize =
938 KW_NAME_SIZE(MSG_MAPKW_DEFAULT) +
939 KW_NAME_SIZE(MSG_MAPKW_ELIMINATE) +
940 KW_NAME_SIZE(MSG_MAPKW_EXPORTED) +
941 KW_NAME_SIZE(MSG_MAPKW_HIDDEN) +
942 KW_NAME_SIZE(MSG_MAPKW_GLOBAL) +
943 KW_NAME_SIZE(MSG_MAPKW_LOCAL) +
944 KW_NAME_SIZE(MSG_MAPKW_PROTECTED) +
945 KW_NAME_SIZE(MSG_MAPKW_SINGLETON) +
946 KW_NAME_SIZE(MSG_MAPKW_SYMBOLIC);
947
948 scope_t *scope;
949
950 scope = ld_map_kwfind(scope_name, scope_list,
951 SGSOFFSETOF(scope_t, name), sizeof (scope_list[0]));
952 if (scope == NULL) {
953 char buf[VLA_SIZE(scope_list_bufsize)];
954
955 mf_fatal(mf, MSG_INTL(MSG_MAP_EXP_SYMSCOPE),
956 ld_map_kwnames(scope_list, SGSOFFSETOF(scope_t, name),
957 sizeof (scope[0]), buf, scope_list_bufsize), scope_name);
958 mv->mv_errcnt++;
959 return;
960 }
961
962 mv->mv_scope = scope->type;
963 mf->mf_ofl->ofl_flags |= scope->ofl_flags;
964 }
965
966 /*
967 * Process the special auto-reduction directive ('*'). It can be specified
968 * in hidden/local, and eliminate scope. This directive indicates that all
969 * symbols processed that are not explicitly defined to be global are to be
970 * reduced to hidden/local scope in, or eliminated from, the output image.
971 *
972 * An auto-reduction directive also implies that a version definition must
973 * be created, as the user has effectively defined an interface.
974 */
975 void
976 ld_map_sym_autoreduce(Mapfile *mf, ld_map_ver_t *mv)
977 {
978 switch (mv->mv_scope) {
979 case FLG_SCOPE_HIDD:
980 mf->mf_ofl->ofl_flags |= (FLG_OF_VERDEF | FLG_OF_AUTOLCL);
981 break;
982 case FLG_SCOPE_ELIM:
983 mf->mf_ofl->ofl_flags |= (FLG_OF_VERDEF | FLG_OF_AUTOELM);
984 break;
985 default:
986 /*
987 * Auto reduction has been applied to a scope that doesn't
988 * support it. This should be a fatal error, but we limit
989 * it to a warning for version 1 mapfiles. For years, we
990 * quietly ignored this case, so there may be mapfiles in
991 * production use that we do not wish to break.
992 */
993 if (mf->mf_version == 1) {
994 mf_warn0(mf, MSG_INTL(MSG_MAP_BADAUTORED));
995 } else {
996 mf_fatal0(mf, MSG_INTL(MSG_MAP_BADAUTORED));
997 mv->mv_errcnt++;
998 }
999 }
1000 }
1001
1002 /*
1003 * Add a standard or auxiliary filter to the given symbol
1004 *
1005 * entry:
1006 * mf - Mapfile descriptor
1007 * mv - Information related to version being defined
1008 * ms - Information related to symbol being defined
1009 * dft_flag - One of FLG_SY_STDFLTR or FLG_SY_AUXFLTR,
1010 * specifying the type of filter.
1011 * filtee - String giving filtee to be added
1012 *
1013 * exit:
1014 * On success, the filtee is added. On failure, mv->errcnt is
1015 * incremented, and mv/ms are otherwise unaltered.
1016 */
1017 void
1018 ld_map_sym_filtee(Mapfile *mf, ld_map_ver_t *mv, ld_map_sym_t *ms,
1019 Word dft_flag, const char *filtee)
1020 {
1021 /*
1022 * A given symbol can only be tied to a single filter, be it
1023 * a standard filter, or auxiliary.
1024 */
1025 if (ms->ms_filtee) {
1026 mf_fatal0(mf, MSG_INTL(MSG_MAP_MULTFILTEE));
1027 mv->mv_errcnt++;
1028 return;
1029 }
1030
1031 /* Symbol filtering is only for sharable objects */
1032 if (!(mf->mf_ofl->ofl_flags & FLG_OF_SHAROBJ)) {
1033 mf_fatal0(mf, MSG_INTL(MSG_MAP_FLTR_ONLYAVL));
1034 mv->mv_errcnt++;
1035 return;
1036 }
1037
1038 ms->ms_filtee = filtee;
1039 ms->ms_dft_flag = dft_flag;
1040 ms->ms_sdflags |= dft_flag;
1041 mf->mf_ofl->ofl_flags |= FLG_OF_SYMINFO;
1042 }
1043
1044 /*
1045 * Enter a mapfile defined symbol into the given version
1046 *
1047 * entry:
1048 * mf - Mapfile descriptor
1049 * ms - Information related to symbol being added to version
1050 *
1051 * exit:
1052 * On success, returns TRUE. On failure that requires an immediate
1053 * halt, returns FALSE.
1054 *
1055 * On failure that requires eventual halt, but for which it would
1056 * be OK to continue parsing in hopes of flushing out additional
1057 * problems, increments mv->mv_errcnt, and returns TRUE.
1058 */
1059 Boolean
1060 ld_map_sym_enter(Mapfile *mf, ld_map_ver_t *mv, ld_map_sym_t *ms)
1061 {
1062 Ofl_desc *ofl = mf->mf_ofl;
1063 Word hash;
1064 avl_index_t where;
1065 Sym *sym;
1066 Sym_desc *sdp;
1067 const char *conflict;
1068
1069 /*
1070 * Add the new symbol. It should be noted that all
1071 * symbols added by the mapfile start out with global
1072 * scope, thus they will fall through the normal symbol
1073 * resolution process. Symbols defined as locals will
1074 * be reduced in scope after all input file processing.
1075 */
1076 /* LINTED */
1077 hash = (Word)elf_hash(ms->ms_name);
1078 DBG_CALL(Dbg_map_version(ofl->ofl_lml, mv->mv_name, ms->ms_name,
1079 mv->mv_scope));
1080
1081 /*
1082 * Make sure that any parent or external declarations fall back to
1083 * references.
1084 */
1085 if (ms->ms_sdflags & (FLG_SY_PARENT | FLG_SY_EXTERN)) {
1086 /*
1087 * Turn it into a reference by setting the section index
1088 * to UNDEF.
1089 */
1090 ms->ms_shndx = SHN_UNDEF;
1091
1092 /*
1093 * It is wrong to specify size or value for an external symbol.
1094 */
1095 if (ms->ms_value_set || (ms->ms_size != 0)) {
1096 mf_fatal0(mf, MSG_INTL(MSG_MAP_NOEXVLSZ));
1097 mv->mv_errcnt++;
1098 return (TRUE);
1099 }
1100 }
1101
1102 if ((sdp = ld_sym_find(ms->ms_name, hash, &where, ofl)) == NULL) {
1103 if ((sym = libld_calloc(sizeof (Sym), 1)) == NULL)
1104 return (FALSE);
1105
1106 sym->st_shndx = (Half)ms->ms_shndx;
1107 sym->st_value = ms->ms_value;
1108 sym->st_size = ms->ms_size;
1109 sym->st_info = ELF_ST_INFO(STB_GLOBAL, ms->ms_type);
1110
1111 if ((sdp = ld_sym_enter(ms->ms_name, sym, hash,
1112 ld_map_ifl(mf), ofl, 0, ms->ms_shndx, ms->ms_sdflags,
1113 &where)) == (Sym_desc *)S_ERROR)
1114 return (FALSE);
1115
1116 sdp->sd_flags &= ~FLG_SY_CLEAN;
1117
1118 /*
1119 * Identify any references. FLG_SY_MAPREF is
1120 * turned off once a relocatable object with
1121 * the same symbol is found, thus the existence
1122 * of FLG_SY_MAPREF at symbol validation is
1123 * used to flag undefined/misspelled entries.
1124 */
1125 if (sym->st_shndx == SHN_UNDEF)
1126 sdp->sd_flags |= (FLG_SY_MAPREF | FLG_SY_GLOBREF);
1127
1128 } else {
1129 conflict = NULL;
1130 sym = sdp->sd_sym;
1131
1132 /*
1133 * If this symbol already exists, make sure this
1134 * definition doesn't conflict with the former.
1135 * Provided it doesn't, multiple definitions
1136 * from different mapfiles can augment each
1137 * other.
1138 */
1139 if (sym->st_value) {
1140 if (ms->ms_value && (sym->st_value != ms->ms_value))
1141 conflict = MSG_INTL(MSG_MAP_DIFF_SYMVAL);
1142 } else {
1143 sym->st_value = ms->ms_value;
1144 }
1145 if (sym->st_size) {
1146 if (ms->ms_size && (sym->st_size != ms->ms_size))
1147 conflict = MSG_INTL(MSG_MAP_DIFF_SYMSZ);
1148 } else {
1149 sym->st_size = ms->ms_size;
1150 }
1151 if (ELF_ST_TYPE(sym->st_info) != STT_NOTYPE) {
1152 if ((ms->ms_type != STT_NOTYPE) &&
1153 (ELF_ST_TYPE(sym->st_info) != ms->ms_type))
1154 conflict = MSG_INTL(MSG_MAP_DIFF_SYMTYP);
1155 } else {
1156 sym->st_info = ELF_ST_INFO(STB_GLOBAL, ms->ms_type);
1157 }
1158 if (sym->st_shndx != SHN_UNDEF) {
1159 if ((ms->ms_shndx != SHN_UNDEF) &&
1160 (sym->st_shndx != ms->ms_shndx))
1161 conflict = MSG_INTL(MSG_MAP_DIFF_SYMNDX);
1162 } else {
1163 sym->st_shndx = sdp->sd_shndx = ms->ms_shndx;
1164 }
1165
1166 if ((sdp->sd_flags & MSK_SY_GLOBAL) &&
1167 (sdp->sd_aux->sa_overndx != VER_NDX_GLOBAL) &&
1168 (mv->mv_vdp->vd_ndx != VER_NDX_GLOBAL) &&
1169 (sdp->sd_aux->sa_overndx != mv->mv_vdp->vd_ndx)) {
1170 conflict = MSG_INTL(MSG_MAP_DIFF_SYMVER);
1171 }
1172
1173 if (conflict) {
1174 mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF1),
1175 demangle(ms->ms_name),
1176 sdp->sd_file->ifl_name, conflict);
1177 mv->mv_errcnt++;
1178 return (TRUE);
1179 }
1180
1181 /*
1182 * If this mapfile entry supplies a definition,
1183 * indicate that the symbol is now used.
1184 */
1185 if (ms->ms_shndx != SHN_UNDEF)
1186 sdp->sd_flags |= FLG_SY_MAPUSED;
1187 }
1188
1189 /*
1190 * A symbol declaration that defines a size but no
1191 * value is processed as a request to create an
1192 * associated backing section. The intent behind this
1193 * functionality is to provide OBJT definitions within
1194 * filters that are not ABS. ABS symbols don't allow
1195 * copy-relocations to be established to filter OBJT
1196 * definitions.
1197 */
1198 if ((ms->ms_shndx == SHN_ABS) && ms->ms_size && !ms->ms_value_set) {
1199 /* Create backing section if not there */
1200 if (sdp->sd_isc == NULL) {
1201 Is_desc *isp;
1202
1203 if (ms->ms_type == STT_OBJECT) {
1204 if ((isp = ld_make_data(ofl, ms->ms_size)) ==
1205 (Is_desc *)S_ERROR)
1206 return (FALSE);
1207 } else {
1208 if ((isp = ld_make_text(ofl, ms->ms_size)) ==
1209 (Is_desc *)S_ERROR)
1210 return (FALSE);
1211 }
1212
1213 sdp->sd_isc = isp;
1214 isp->is_file = ld_map_ifl(mf);
1215 }
1216
1217 /*
1218 * Now that backing storage has been created,
1219 * associate the symbol descriptor. Remove the
1220 * symbols special section tag so that it will
1221 * be assigned the correct section index as part
1222 * of update symbol processing.
1223 */
1224 sdp->sd_flags &= ~FLG_SY_SPECSEC;
1225 ms->ms_sdflags &= ~FLG_SY_SPECSEC;
1226 }
1227
1228 /*
1229 * Indicate the new symbols scope. Although the
1230 * symbols st_other field will eventually be updated as
1231 * part of writing out the final symbol, update the
1232 * st_other field here to trigger better diagnostics
1233 * during symbol validation (for example, undefined
1234 * references that are defined symbolic in a mapfile).
1235 */
1236 if (mv->mv_scope == FLG_SCOPE_HIDD) {
1237 /*
1238 * This symbol needs to be reduced to local.
1239 */
1240 if (ofl->ofl_flags & FLG_OF_REDLSYM) {
1241 sdp->sd_flags |= (FLG_SY_HIDDEN | FLG_SY_ELIM);
1242 sdp->sd_sym->st_other = STV_ELIMINATE;
1243 } else {
1244 sdp->sd_flags |= FLG_SY_HIDDEN;
1245 sdp->sd_sym->st_other = STV_HIDDEN;
1246 }
1247 } else if (mv->mv_scope == FLG_SCOPE_ELIM) {
1248 /*
1249 * This symbol needs to be eliminated. Note,
1250 * the symbol is also tagged as local to trigger
1251 * any necessary relocation processing prior
1252 * to the symbol being eliminated.
1253 */
1254 sdp->sd_flags |= (FLG_SY_HIDDEN | FLG_SY_ELIM);
1255 sdp->sd_sym->st_other = STV_ELIMINATE;
1256
1257 } else {
1258 /*
1259 * This symbol is explicitly defined to remain
1260 * global.
1261 */
1262 sdp->sd_flags |= ms->ms_sdflags;
1263
1264 /*
1265 * Qualify any global scope.
1266 */
1267 if (mv->mv_scope == FLG_SCOPE_SNGL) {
1268 sdp->sd_flags |= (FLG_SY_SINGLE | FLG_SY_NDIR);
1269 sdp->sd_sym->st_other = STV_SINGLETON;
1270 } else if (mv->mv_scope == FLG_SCOPE_PROT) {
1271 sdp->sd_flags |= FLG_SY_PROTECT;
1272 sdp->sd_sym->st_other = STV_PROTECTED;
1273 } else if (mv->mv_scope == FLG_SCOPE_EXPT) {
1274 sdp->sd_flags |= FLG_SY_EXPORT;
1275 sdp->sd_sym->st_other = STV_EXPORTED;
1276 } else
1277 sdp->sd_flags |= FLG_SY_DEFAULT;
1278
1279 /*
1280 * Record the present version index for later
1281 * potential versioning.
1282 */
1283 if ((sdp->sd_aux->sa_overndx == 0) ||
1284 (sdp->sd_aux->sa_overndx == VER_NDX_GLOBAL))
1285 sdp->sd_aux->sa_overndx = mv->mv_vdp->vd_ndx;
1286 mv->mv_vdp->vd_flags |= FLG_VER_REFER;
1287 }
1288
1289 conflict = NULL;
1290
1291 /*
1292 * Carry out some validity checks to ensure incompatible
1293 * symbol characteristics have not been defined.
1294 * These checks are carried out after symbols are added
1295 * or resolved, to catch single instance, and
1296 * multi-instance definition inconsistencies.
1297 */
1298 if ((sdp->sd_flags & (FLG_SY_HIDDEN | FLG_SY_ELIM)) &&
1299 ((mv->mv_scope != FLG_SCOPE_HIDD) &&
1300 (mv->mv_scope != FLG_SCOPE_ELIM))) {
1301 conflict = MSG_INTL(MSG_MAP_DIFF_SYMLCL);
1302
1303 } else if ((sdp->sd_flags &
1304 (FLG_SY_SINGLE | FLG_SY_EXPORT)) &&
1305 ((mv->mv_scope != FLG_SCOPE_DFLT) &&
1306 (mv->mv_scope != FLG_SCOPE_EXPT) &&
1307 (mv->mv_scope != FLG_SCOPE_SNGL))) {
1308 conflict = MSG_INTL(MSG_MAP_DIFF_SYMGLOB);
1309
1310 } else if ((sdp->sd_flags & FLG_SY_PROTECT) &&
1311 ((mv->mv_scope != FLG_SCOPE_DFLT) &&
1312 (mv->mv_scope != FLG_SCOPE_PROT))) {
1313 conflict = MSG_INTL(MSG_MAP_DIFF_SYMPROT);
1314
1315 } else if ((sdp->sd_flags & FLG_SY_NDIR) &&
1316 (mv->mv_scope == FLG_SCOPE_PROT)) {
1317 conflict = MSG_INTL(MSG_MAP_DIFF_PROTNDIR);
1318
1319 } else if ((sdp->sd_flags & FLG_SY_DIR) &&
1320 (mv->mv_scope == FLG_SCOPE_SNGL)) {
1321 conflict = MSG_INTL(MSG_MAP_DIFF_SNGLDIR);
1322 }
1323
1324 if (conflict) {
1325 /*
1326 * Select the conflict message from either a
1327 * single instance or multi-instance definition.
1328 */
1329 if (sdp->sd_file->ifl_name == mf->mf_name) {
1330 mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF2),
1331 demangle(ms->ms_name), conflict);
1332 } else {
1333 mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF1),
1334 demangle(ms->ms_name),
1335 sdp->sd_file->ifl_name, conflict);
1336 }
1337 mv->mv_errcnt++;
1338 return (TRUE);
1339 }
1340
1341 /*
1342 * Indicate that this symbol has been explicitly
1343 * contributed from a mapfile.
1344 */
1345 sdp->sd_flags |= (FLG_SY_MAPFILE | FLG_SY_EXPDEF);
1346
1347 /*
1348 * If we've encountered a symbol definition simulate
1349 * that an input file has been processed - this allows
1350 * things like filters to be created purely from a
1351 * mapfile.
1352 */
1353 if (ms->ms_type != STT_NOTYPE)
1354 ofl->ofl_objscnt++;
1355 DBG_CALL(Dbg_map_symbol(ofl, sdp));
1356
1357 /*
1358 * If this symbol has an associated filtee, record the
1359 * filtee string and associate the string index with the
1360 * symbol. This is used later to associate the syminfo
1361 * information with the necessary .dynamic entry.
1362 */
1363 if (ms->ms_filtee) {
1364 Dfltr_desc * dftp;
1365 Sfltr_desc sft;
1366 Aliste idx, _idx, nitems;
1367
1368 /*
1369 * Make sure we don't duplicate any filtee
1370 * strings, and create a new descriptor if
1371 * necessary.
1372 */
1373 idx = nitems = alist_nitems(ofl->ofl_dtsfltrs);
1374 for (ALIST_TRAVERSE(ofl->ofl_dtsfltrs, _idx, dftp)) {
1375 if ((ms->ms_dft_flag != dftp->dft_flag) ||
1376 (strcmp(dftp->dft_str, ms->ms_filtee)))
1377 continue;
1378 idx = _idx;
1379 break;
1380 }
1381 if (idx == nitems) {
1382 Dfltr_desc dft;
1383
1384 dft.dft_str = ms->ms_filtee;
1385 dft.dft_flag = ms->ms_dft_flag;
1386 dft.dft_ndx = 0;
1387
1388 /*
1389 * The following append puts the new
1390 * item at the offset contained in
1391 * idx, because we know idx contains
1392 * the index of the next available slot.
1393 */
1394 if (alist_append(&ofl->ofl_dtsfltrs, &dft,
1395 sizeof (Dfltr_desc), AL_CNT_OFL_DTSFLTRS) == NULL)
1396 return (FALSE);
1397 }
1398
1399 /*
1400 * Create a new filter descriptor for this
1401 * symbol.
1402 */
1403 sft.sft_sdp = sdp;
1404 sft.sft_idx = idx;
1405
1406 if (alist_append(&ofl->ofl_symfltrs, &sft, sizeof (Sfltr_desc),
1407 AL_CNT_OFL_SYMFLTRS) == NULL)
1408 return (FALSE);
1409 }
1410
1411 return (TRUE);
1412 }
1413
1414 /*
1415 * In both the version 1 and version 2 syntaxes, a version definition
1416 * can have 0 or more inherited versions following the closing '}',
1417 * terminated by a ';'.
1418 *
1419 * Add the inherited names, and return when the terminator is seen.
1420 */
1421 Boolean
1422 ld_map_sym_ver_fini(Mapfile *mf, ld_map_ver_t *mv)
1423 {
1424 Token tok;
1425 ld_map_tkval_t tkv; /* Value of token */
1426 Boolean done = FALSE;
1427 Conv_inv_buf_t inv_buf;
1428 const char *name;
1429 Ver_desc *vdp;
1430 Word hash;
1431
1432 /*
1433 * Read version names until we encounter the ';' terminator.
1434 */
1435 while (!done) {
1436 switch (tok = ld_map_gettoken(mf, 0, &tkv)) {
1437 case TK_ERROR:
1438 return (FALSE);
1439
1440 case TK_STRING:
1441 name = tkv.tkv_str;
1442
1443 /* The unnamed global scope can't inherit */
1444 if (mv->mv_vdp->vd_ndx == VER_NDX_GLOBAL) {
1445 mf_fatal(mf, MSG_INTL(MSG_MAP_UNEXINHERIT),
1446 name);
1447 return (FALSE);
1448 }
1449
1450 /*
1451 * Generate a new version descriptor if it doesn't
1452 * already exist.
1453 */
1454 /* LINTED */
1455 hash = (Word)elf_hash(name);
1456 vdp = ld_vers_find(name, hash, mf->mf_ofl->ofl_verdesc);
1457 if ((vdp == NULL) && ((vdp = ld_vers_desc(name, hash,
1458 &mf->mf_ofl->ofl_verdesc)) == (Ver_desc *)S_ERROR))
1459 return (FALSE);
1460
1461 /*
1462 * Add the new version descriptor to the parent version
1463 * descriptors reference list. Indicate the version
1464 * descriptors first reference (used for error diags
1465 * if undefined version dependencies remain).
1466 */
1467 if (ld_vers_find(name, hash, mv->mv_vdp->vd_deps) ==
1468 NULL)
1469 if (aplist_append(&mv->mv_vdp->vd_deps, vdp,
1470 AL_CNT_VERDESCS) == NULL)
1471 return (FALSE);
1472
1473 if (vdp->vd_ref == NULL)
1474 vdp->vd_ref = mv->mv_vdp;
1475 break;
1476
1477 case TK_SEMICOLON:
1478 done = TRUE;
1479 break;
1480
1481 default:
1482 mf_fatal(mf, MSG_INTL(MSG_MAP_EXP_SYMEND),
1483 ld_map_tokenstr(tok, &tkv, &inv_buf));
1484 return (FALSE);
1485 }
1486 }
1487
1488 return (TRUE);
1489 }