8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sgs / libld / common / map.c
blobc54db636968d215f90e5ad554230fc0b014cf3b2
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 1988 AT&T
24 * All Rights Reserved
26 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
31 * Map file parsing (Original SysV syntax).
33 #include <string.h>
34 #include <strings.h>
35 #include <stdio.h>
36 #include <unistd.h>
37 #include <errno.h>
38 #include <limits.h>
39 #include <ctype.h>
40 #include <elfcap.h>
41 #include <debug.h>
42 #include "msg.h"
43 #include "_libld.h"
44 #include "_map.h"
47 * Process a hardware/software capabilities segment declaration definition.
48 * hwcap_1 = val,... [ OVERRIDE ]
49 * sfcap_1 = val,... [ OVERRIDE ]
50 * hwcap_2 = val,... [ OVERRIDE ]
51 * platcap = name,... [ OVERRIDE ]
52 * machcap = name,... [ OVERRIDE ]
54 * The values can be defined as a list of machine specify tokens, or numerics.
55 * Tokens are representations of the sys/auxv_$MACH.h capabilities, for example:
57 * #define AV_386_FPU 0x0001 is represented as FPU
58 * #define AV_386_TSC 0x0002 " " " " TSC
60 * Or, the above two capabilities could be represented as V0x3. Note, the
61 * OVERRIDE flag is used to ensure that only those values provided via this
62 * mapfile entry are recorded in the final image, ie. this overrides any
63 * hardware capabilities that may be defined in the objects read as part of
64 * this link-edit. Specifying:
66 * V0x0 OVERRIDE
68 * effectively removes any capabilities information from the final image.
70 static Boolean
71 map_cap(Mapfile *mf, Word type, Capmask *capmask)
73 Token tok; /* Current token. */
74 Xword number;
75 int used = 0;
76 Ofl_desc *ofl = mf->mf_ofl;
77 ld_map_tkval_t tkv; /* Value of token */
78 elfcap_mask_t value = 0;
80 if (DBG_ENABLED) {
81 Dbg_cap_mapfile_title(ofl->ofl_lml, mf->mf_lineno);
82 Dbg_cap_val_entry(ofl->ofl_lml, DBG_STATE_CURRENT, CA_SUNW_HW_1,
83 capmask->cm_val, ld_targ.t_m.m_mach);
86 while ((tok = ld_map_gettoken(mf, TK_F_STRLC, &tkv)) !=
87 TK_SEMICOLON) {
88 if (tok != TK_STRING) {
89 if (tok != TK_ERROR)
90 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGATT));
91 return (FALSE);
95 * First, determine if the token represents the reserved
96 * OVERRIDE keyword.
98 if (strncmp(tkv.tkv_str, MSG_ORIG(MSG_MAP_OVERRIDE),
99 MSG_MAP_OVERRIDE_SIZE) == 0) {
100 ld_map_cap_set_ovflag(mf, type);
101 used++;
102 continue;
105 /* Is the token a symbolic capability name? */
106 if ((number = (Xword)elfcap_tag_from_str(ELFCAP_STYLE_LC,
107 type, tkv.tkv_str, ld_targ.t_m.m_mach)) != 0) {
108 value |= number;
109 used++;
110 continue;
114 * Is the token a numeric value?
116 if (tkv.tkv_str[0] == 'v') {
117 if (ld_map_strtoxword(&tkv.tkv_str[1], NULL,
118 &number) != STRTOXWORD_OK) {
119 mf_fatal(mf, MSG_INTL(MSG_MAP_BADCAPVAL),
120 tkv.tkv_str);
121 return (FALSE);
123 value |= number;
124 used++;
125 continue;
129 * We have an unknown token.
131 used++;
132 mf_fatal(mf, MSG_INTL(MSG_MAP_UNKCAPATTR), tkv.tkv_str);
133 return (FALSE);
136 /* Catch empty declarations */
137 if (used == 0) {
138 mf_warn0(mf, MSG_INTL(MSG_MAP_EMPTYCAP));
139 return (TRUE);
142 DBG_CALL(Dbg_cap_val_entry(ofl->ofl_lml, DBG_STATE_NEW, type, value,
143 ld_targ.t_m.m_mach));
144 capmask->cm_val |= value;
146 /* Sanity check the resulting bits */
147 if (!ld_map_cap_sanitize(mf, type, capmask))
148 return (FALSE);
150 return (TRUE);
154 * Parse the flags for a segment definition. Called by map_equal().
156 * entry:
157 * mf - Mapfile descriptor
158 * sgp - Segment being defined
159 * b_flags - Address of b_flags variable from map_equal().
160 * *bflags is TRUE if flags have already been seen in, the
161 * current segment definition directive, and FALSE otherwise.
162 * flag_tok - Flags string, starting with the '?' character.
164 * exit:
165 * On success, the flags have been parsed and the segment updated,
166 * *b_flags is set to TRUE, and TRUE is returned. On error, FALSE
167 * is returned.
169 static Boolean
170 map_equal_flags(Mapfile *mf, Sg_desc *sgp, Boolean *b_flags,
171 const char *flag_tok)
173 Word tmp_flags = 0;
175 if (*b_flags) {
176 mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE),
177 MSG_INTL(MSG_MAP_SEGFLAG));
178 return (FALSE);
181 /* Skip over the leading '?' character */
182 flag_tok++;
185 * If ? has nothing following leave the flags cleared,
186 * otherwise OR in any flags specified.
188 while (*flag_tok) {
189 switch (*flag_tok) {
190 case 'r':
191 tmp_flags |= PF_R;
192 break;
193 case 'w':
194 tmp_flags |= PF_W;
195 break;
196 case 'x':
197 tmp_flags |= PF_X;
198 break;
199 case 'e':
200 sgp->sg_flags |= FLG_SG_EMPTY;
201 break;
202 case 'o':
204 * The version 1 ?O option is incompatible with
205 * the version 2 SEGMENT IS_ORDER attribute.
207 if (aplist_nitems(sgp->sg_is_order) > 0) {
208 mf_fatal(mf, MSG_INTL(MSG_MAP_ISORDVER),
209 sgp->sg_name);
210 return (FALSE);
214 * Set FLG_SG_IS_ORDER to indicate that segment has
215 * had the ?O flag set by a version 1 mapfile.
217 sgp->sg_flags |= FLG_SG_IS_ORDER;
218 break;
219 case 'n':
221 * If segment ends up as the first loadable segment,
222 * it will not include the the ELF and program headers.
224 sgp->sg_flags |= FLG_SG_NOHDR;
225 break;
226 default:
227 mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSEGFLG), *flag_tok);
228 return (FALSE);
230 flag_tok++;
234 * Warn when changing flags except when we're adding or removing "X"
235 * from a RW PT_LOAD segment.
237 if ((sgp->sg_flags & FLG_SG_P_FLAGS) &&
238 (sgp->sg_phdr.p_flags != tmp_flags) &&
239 !(sgp->sg_phdr.p_type == PT_LOAD &&
240 (tmp_flags & (PF_R|PF_W)) == (PF_R|PF_W) &&
241 (tmp_flags ^ sgp->sg_phdr.p_flags) == PF_X))
242 mf_warn(mf, MSG_INTL(MSG_MAP_REDEFATT),
243 MSG_INTL(MSG_MAP_SEGFLAG), sgp->sg_name);
245 sgp->sg_flags |= FLG_SG_P_FLAGS;
246 sgp->sg_phdr.p_flags = tmp_flags;
247 *b_flags = TRUE;
249 return (TRUE);
253 * Read an address (value) or size Xword from a TK_STRING token value
254 * where the first letter of the string is a letter ('v', 'l', 's', ...)
255 * followed by the numeric value.
257 * entry:
258 * mf - Mapfile descriptor
259 * tkv - TK_STRING token to parse
260 * value - Address of variable to receive the resulting value.
262 * exit:
263 * Returns TRUE for success. On failure, issues an error message
264 * and returns FALSE.
266 static Boolean
267 valuetoxword(Mapfile *mf, ld_map_tkval_t *tkv, Xword *value)
269 switch (ld_map_strtoxword(&tkv->tkv_str[1], NULL, value)) {
270 case STRTOXWORD_OK:
271 return (TRUE);
273 case STRTOXWORD_TOOBIG:
274 mf_fatal(mf, MSG_INTL(MSG_MAP_SEGADDR), tkv->tkv_str,
275 MSG_INTL(MSG_MAP_EXCLIMIT));
276 break;
277 default:
278 mf_fatal(mf, MSG_INTL(MSG_MAP_SEGADDR), tkv->tkv_str,
279 MSG_INTL(MSG_MAP_NOBADFRM));
280 break;
283 return (FALSE);
287 * Process a mapfile segment declaration definition.
288 * segment_name = segment_attribute;
289 * segment_attribute : segment_type segment_flags virtual_addr
290 * physical_addr length alignment
292 static Boolean
293 map_equal(Mapfile *mf, Sg_desc *sgp)
296 * Segment type. Users are permitted to define PT_LOAD,
297 * PT_NOTE, PT_SUNWSTACK and PT_NULL segments. Other segment
298 * types are only defined in seg_desc[].
300 typedef struct {
301 const char *name; /* Name for segment type */
302 Word p_type; /* PT_ constant corresponding to name */
303 sg_flags_t sg_flags; /* Seg descriptor flags to apply */
304 } seg_types_t;
306 static seg_types_t seg_type_arr[] = {
307 { MSG_ORIG(MSG_MAP_LOAD), PT_LOAD, FLG_SG_P_TYPE },
308 { MSG_ORIG(MSG_MAP_STACK), PT_SUNWSTACK,
309 FLG_SG_P_TYPE | FLG_SG_EMPTY },
310 { MSG_ORIG(MSG_MAP_NULL), PT_NULL, FLG_SG_P_TYPE },
311 { MSG_ORIG(MSG_MAP_NOTE), PT_NOTE, FLG_SG_P_TYPE },
313 /* Array must be NULL terminated */
314 { NULL }
318 seg_types_t *seg_type;
319 Token tok; /* Current token. */
320 ld_map_tkval_t tkv; /* Value of token */
321 Boolean b_type = FALSE; /* True if seg types found. */
322 Boolean b_flags = FALSE; /* True if seg flags found. */
323 Boolean b_len = FALSE; /* True if seg length found. */
324 Boolean b_round = FALSE; /* True if seg rounding found. */
325 Boolean b_vaddr = FALSE; /* True if seg virtual addr found. */
326 Boolean b_paddr = FALSE; /* True if seg physical addr found. */
327 Boolean b_align = FALSE; /* True if seg alignment found. */
329 while ((tok = ld_map_gettoken(mf, TK_F_STRLC, &tkv)) !=
330 TK_SEMICOLON) {
331 if (tok != TK_STRING) {
332 if (tok != TK_ERROR)
333 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGATT));
334 return (FALSE);
338 * If it is the name of a segment type, set the type
339 * and flags fields in the descriptor.
341 for (seg_type = seg_type_arr; seg_type->name; seg_type++) {
342 if (strcmp(tkv.tkv_str, seg_type->name) == 0) {
343 if (b_type) {
344 mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE),
345 MSG_INTL(MSG_MAP_SEGTYP));
346 return (FALSE);
348 if ((sgp->sg_flags & FLG_SG_P_TYPE) &&
349 (sgp->sg_phdr.p_type != seg_type->p_type)) {
350 mf_warn(mf, MSG_INTL(MSG_MAP_REDEFATT),
351 MSG_INTL(MSG_MAP_SEGTYP),
352 sgp->sg_name);
355 sgp->sg_phdr.p_type = seg_type->p_type;
356 sgp->sg_flags |= seg_type->sg_flags;
357 break;
360 if (seg_type->name != NULL) /* Matched segment type */
361 continue; /* next token */
363 /* Segment Flags */
364 if (*tkv.tkv_str == '?') {
365 if (!map_equal_flags(mf, sgp, &b_flags, tkv.tkv_str))
366 return (FALSE);
367 continue; /* next token */
371 /* Segment address, length, alignment or rounding number */
372 if ((tkv.tkv_str[0] == 'l') || (tkv.tkv_str[0] == 'v') ||
373 (tkv.tkv_str[0] == 'a') || (tkv.tkv_str[0] == 'p') ||
374 (tkv.tkv_str[0] == 'r')) {
375 Xword number;
377 if (!valuetoxword(mf, &tkv, &number))
378 return (FALSE);
380 switch (*tkv.tkv_str) {
381 case 'l':
382 if (b_len) {
383 mf_fatal(mf,
384 MSG_INTL(MSG_MAP_MOREONCE),
385 MSG_INTL(MSG_MAP_SEGLEN));
386 return (FALSE);
388 if ((sgp->sg_flags & FLG_SG_LENGTH) &&
389 (sgp->sg_length != number))
390 mf_warn(mf,
391 MSG_INTL(MSG_MAP_REDEFATT),
392 MSG_INTL(MSG_MAP_SEGLEN),
393 sgp->sg_name);
394 sgp->sg_length = number;
395 sgp->sg_flags |= FLG_SG_LENGTH;
396 b_len = TRUE;
397 break;
398 case 'r':
399 if (b_round) {
400 mf_fatal(mf,
401 MSG_INTL(MSG_MAP_MOREONCE),
402 MSG_INTL(MSG_MAP_SEGROUND));
403 return (FALSE);
405 if ((sgp->sg_flags & FLG_SG_ROUND) &&
406 (sgp->sg_round != number))
407 mf_warn(mf,
408 MSG_INTL(MSG_MAP_REDEFATT),
409 MSG_INTL(MSG_MAP_SEGROUND),
410 sgp->sg_name);
411 sgp->sg_round = number;
412 sgp->sg_flags |= FLG_SG_ROUND;
413 b_round = TRUE;
414 break;
415 case 'v':
416 if (b_vaddr) {
417 mf_fatal(mf,
418 MSG_INTL(MSG_MAP_MOREONCE),
419 MSG_INTL(MSG_MAP_SEGVADDR));
420 return (FALSE);
422 if ((sgp->sg_flags & FLG_SG_P_VADDR) &&
423 (sgp->sg_phdr.p_vaddr != number))
424 mf_warn(mf,
425 MSG_INTL(MSG_MAP_REDEFATT),
426 MSG_INTL(MSG_MAP_SEGVADDR),
427 sgp->sg_name);
428 /* LINTED */
429 sgp->sg_phdr.p_vaddr = (Addr)number;
430 sgp->sg_flags |= FLG_SG_P_VADDR;
431 b_vaddr = TRUE;
432 break;
433 case 'p':
434 if (b_paddr) {
435 mf_fatal(mf,
436 MSG_INTL(MSG_MAP_MOREONCE),
437 MSG_INTL(MSG_MAP_SEGPHYS));
438 return (FALSE);
440 if ((sgp->sg_flags & FLG_SG_P_PADDR) &&
441 (sgp->sg_phdr.p_paddr != number))
442 mf_warn(mf,
443 MSG_INTL(MSG_MAP_REDEFATT),
444 MSG_INTL(MSG_MAP_SEGPHYS),
445 sgp->sg_name);
446 /* LINTED */
447 sgp->sg_phdr.p_paddr = (Addr)number;
448 sgp->sg_flags |= FLG_SG_P_PADDR;
449 b_paddr = TRUE;
450 break;
451 case 'a':
452 if (b_align) {
453 mf_fatal(mf,
454 MSG_INTL(MSG_MAP_MOREONCE),
455 MSG_INTL(MSG_MAP_SEGALIGN));
456 return (FALSE);
458 if ((sgp->sg_flags & FLG_SG_P_ALIGN) &&
459 (sgp->sg_phdr.p_align != number))
460 mf_warn(mf,
461 MSG_INTL(MSG_MAP_REDEFATT),
462 MSG_INTL(MSG_MAP_SEGALIGN),
463 sgp->sg_name);
464 /* LINTED */
465 sgp->sg_phdr.p_align = (Xword)number;
466 sgp->sg_flags |= FLG_SG_P_ALIGN;
467 b_align = TRUE;
468 break;
471 continue; /* next token */
475 * If we reach the bottom of this loop, we have an
476 * unrecognized token.
478 mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSEGATT), tkv.tkv_str);
479 return (FALSE);
483 * Empty segments can be used to define PT_LOAD segment reservations, or
484 * to reserve PT_NULL program headers.
486 * PT_LOAD reservations are only allowed within executables, as the
487 * reservation must be established through exec() as part of initial
488 * process loading. In addition, PT_LOAD reservations must have an
489 * associated address and size. Note: This is an obsolete feature,
490 * not supported by the newer mapfile syntax.
492 * PT_NULL program headers are established for later use by applications
493 * such as the post-optimizer. PT_NULL headers should have no other
494 * attributes assigned.
496 if ((sgp->sg_flags & FLG_SG_EMPTY) &&
497 (sgp->sg_phdr.p_type != PT_SUNWSTACK)) {
500 * Any style of empty segment should have no permissions.
502 if (sgp->sg_phdr.p_flags != 0) {
503 mf_fatal(mf, MSG_INTL(MSG_MAP_SEGEMNOPERM),
504 EC_WORD(sgp->sg_phdr.p_flags));
505 return (FALSE);
508 if (sgp->sg_phdr.p_type == PT_LOAD) {
509 if ((mf->mf_ofl->ofl_flags & FLG_OF_EXEC) == 0) {
510 mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPEXE));
511 return (FALSE);
513 if ((sgp->sg_flags &
514 (FLG_SG_LENGTH | FLG_SG_P_VADDR)) !=
515 (FLG_SG_LENGTH | FLG_SG_P_VADDR)) {
516 mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPATT));
517 return (FALSE);
519 } else if (sgp->sg_phdr.p_type == PT_NULL) {
520 if ((sgp->sg_flags &
521 (FLG_SG_LENGTH | FLG_SG_P_VADDR)) &&
522 ((sgp->sg_length != 0) ||
523 (sgp->sg_phdr.p_vaddr != 0))) {
524 mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPNOATT));
525 return (FALSE);
527 } else {
528 mf_warn0(mf, MSG_INTL(MSG_MAP_SEGEMPLOAD));
529 sgp->sg_phdr.p_type = PT_LOAD;
534 * All segment attributes have now been scanned. Certain flags do not
535 * make sense if this is not a loadable segment, fix if necessary.
536 * Note, if the segment is of type PT_NULL it must be new, and any
537 * defaults will be applied by ld_map_seg_insert(). When clearing an
538 * attribute leave the flag set as an indicator for later entries
539 * re-specifying the same segment.
541 if ((sgp->sg_phdr.p_type != PT_NULL) &&
542 (sgp->sg_phdr.p_type != PT_LOAD)) {
543 const char *fmt;
545 if (sgp->sg_phdr.p_type == PT_SUNWSTACK)
546 fmt = MSG_INTL(MSG_MAP_NOSTACK1);
547 else
548 fmt = MSG_INTL(MSG_MAP_NONLOAD);
550 if ((sgp->sg_flags & FLG_SG_P_FLAGS) &&
551 (sgp->sg_phdr.p_type != PT_SUNWSTACK)) {
552 if (sgp->sg_phdr.p_flags != 0) {
553 mf_warn(mf, MSG_INTL(MSG_MAP_NONLOAD),
554 MSG_INTL(MSG_MAP_SEGFLAG));
555 sgp->sg_phdr.p_flags = 0;
558 if (sgp->sg_flags & FLG_SG_LENGTH)
559 if (sgp->sg_length != 0) {
560 mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGLEN));
561 sgp->sg_length = 0;
563 if (sgp->sg_flags & FLG_SG_ROUND)
564 if (sgp->sg_round != 0) {
565 mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGROUND));
566 sgp->sg_round = 0;
568 if (sgp->sg_flags & FLG_SG_P_VADDR) {
569 if (sgp->sg_phdr.p_vaddr != 0) {
570 mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGVADDR));
571 sgp->sg_phdr.p_vaddr = 0;
574 if (sgp->sg_flags & FLG_SG_P_PADDR)
575 if (sgp->sg_phdr.p_paddr != 0) {
576 mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGPHYS));
577 sgp->sg_phdr.p_paddr = 0;
579 if (sgp->sg_flags & FLG_SG_P_ALIGN)
580 if (sgp->sg_phdr.p_align != 0) {
581 mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGALIGN));
582 sgp->sg_phdr.p_align = 0;
585 return (TRUE);
590 * Process a mapfile mapping directives definition.
592 * segment_name : section_attribute [ : file_name ]
594 * Where segment_attribute is one of: section_name section_type section_flags;
596 static Boolean
597 map_colon(Mapfile *mf, Ent_desc *enp)
599 Token tok;
600 ld_map_tkval_t tkv;
601 Boolean b_name = FALSE;
602 Boolean b_type = FALSE;
603 Boolean b_attr = FALSE;
604 Boolean b_bang = FALSE;
608 * Start out assuming that this entrance criteria will be empty,
609 * and therefore match anything. We clear the CATCHALL flag below
610 * if this turns out not to be the case.
612 enp->ec_flags |= FLG_EC_CATCHALL;
614 while (((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_COLON) &&
615 (tok != TK_SEMICOLON)) {
616 if (tok == TK_ERROR)
617 return (FALSE);
618 if (tok != TK_STRING) {
619 mf_fatal0(mf, MSG_INTL(MSG_MAP_MALFORM));
620 return (FALSE);
623 /* Segment type. */
625 if (*tkv.tkv_str == '$') {
626 if (b_type) {
627 mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE),
628 MSG_INTL(MSG_MAP_SECTYP));
629 return (FALSE);
631 b_type = TRUE;
632 tkv.tkv_str++;
633 ld_map_lowercase(tkv.tkv_str);
634 if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_PROGBITS)) ==
636 enp->ec_type = SHT_PROGBITS;
637 else if (strcmp(tkv.tkv_str,
638 MSG_ORIG(MSG_STR_SYMTAB)) == 0)
639 enp->ec_type = SHT_SYMTAB;
640 else if (strcmp(tkv.tkv_str,
641 MSG_ORIG(MSG_STR_DYNSYM)) == 0)
642 enp->ec_type = SHT_DYNSYM;
643 else if (strcmp(tkv.tkv_str,
644 MSG_ORIG(MSG_STR_STRTAB)) == 0)
645 enp->ec_type = SHT_STRTAB;
646 else if ((strcmp(tkv.tkv_str,
647 MSG_ORIG(MSG_STR_REL)) == 0) ||
648 (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_RELA)) == 0))
649 enp->ec_type = ld_targ.t_m.m_rel_sht_type;
650 else if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_HASH)) ==
652 enp->ec_type = SHT_HASH;
653 else if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_LIB)) ==
655 enp->ec_type = SHT_SHLIB;
656 else if (strcmp(tkv.tkv_str,
657 MSG_ORIG(MSG_STR_LD_DYNAMIC)) == 0)
658 enp->ec_type = SHT_DYNAMIC;
659 else if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_NOTE)) ==
661 enp->ec_type = SHT_NOTE;
662 else if (strcmp(tkv.tkv_str,
663 MSG_ORIG(MSG_STR_NOBITS)) == 0)
664 enp->ec_type = SHT_NOBITS;
665 else {
666 mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSECTYP),
667 tkv.tkv_str);
668 return (FALSE);
671 enp->ec_flags &= ~FLG_EC_CATCHALL;
674 * Segment flags.
675 * If a segment flag is specified then the appropriate bit is
676 * set in the ec_attrmask, the ec_attrbits fields determine
677 * whether the attrmask fields must be tested true or false
678 * ie. for ?A the attrmask is set and the attrbit is set,
679 * for ?!A the attrmask is set and the attrbit is clear.
681 } else if (*tkv.tkv_str == '?') {
682 if (b_attr) {
683 mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE),
684 MSG_INTL(MSG_MAP_SECFLAG));
685 return (FALSE);
687 b_attr = TRUE;
688 b_bang = FALSE;
689 tkv.tkv_str++;
690 ld_map_lowercase(tkv.tkv_str);
691 for (; *tkv.tkv_str != '\0'; tkv.tkv_str++)
692 switch (*tkv.tkv_str) {
693 case '!':
694 if (b_bang) {
695 mf_fatal(mf,
696 MSG_INTL(MSG_MAP_BADFLAG),
697 tkv.tkv_str);
698 return (FALSE);
700 b_bang = TRUE;
701 break;
702 case 'a':
703 if (enp->ec_attrmask & SHF_ALLOC) {
704 mf_fatal(mf,
705 MSG_INTL(MSG_MAP_BADFLAG),
706 tkv.tkv_str);
707 return (FALSE);
709 enp->ec_attrmask |= SHF_ALLOC;
710 if (!b_bang)
711 enp->ec_attrbits |= SHF_ALLOC;
712 b_bang = FALSE;
713 break;
714 case 'w':
715 if (enp->ec_attrmask & SHF_WRITE) {
716 mf_fatal(mf,
717 MSG_INTL(MSG_MAP_BADFLAG),
718 tkv.tkv_str);
719 return (FALSE);
721 enp->ec_attrmask |= SHF_WRITE;
722 if (!b_bang)
723 enp->ec_attrbits |= SHF_WRITE;
724 b_bang = FALSE;
725 break;
726 case 'x':
727 if (enp->ec_attrmask & SHF_EXECINSTR) {
728 mf_fatal(mf,
729 MSG_INTL(MSG_MAP_BADFLAG),
730 tkv.tkv_str);
731 return (FALSE);
733 enp->ec_attrmask |= SHF_EXECINSTR;
734 if (!b_bang)
735 enp->ec_attrbits |=
736 SHF_EXECINSTR;
737 b_bang = FALSE;
738 break;
739 default:
740 mf_fatal(mf,
741 MSG_INTL(MSG_MAP_BADFLAG),
742 tkv.tkv_str);
743 return (FALSE);
745 if (enp->ec_attrmask != 0)
746 enp->ec_flags &= ~FLG_EC_CATCHALL;
749 * Section name.
751 } else {
752 if (b_name) {
753 mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE),
754 MSG_INTL(MSG_MAP_SECNAME));
755 return (FALSE);
757 b_name = TRUE;
758 enp->ec_is_name = tkv.tkv_str;
759 enp->ec_flags &= ~FLG_EC_CATCHALL;
762 if (tok == TK_COLON) {
764 * File names.
766 while ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_SEMICOLON) {
767 Word ecf_type;
769 if (tok != TK_STRING) {
770 if (tok != TK_ERROR)
771 mf_fatal0(mf,
772 MSG_INTL(MSG_MAP_MALFORM));
773 return (FALSE);
777 * A leading '*' means that this should be a basename
778 * comparison rather than a full path. It's not a glob
779 * wildcard, although it looks like one.
781 if (tkv.tkv_str[0] == '*') {
782 ecf_type = TYP_ECF_BASENAME;
783 tkv.tkv_str++;
784 } else {
785 ecf_type = TYP_ECF_PATH;
787 if (!ld_map_seg_ent_files(mf, enp, ecf_type,
788 tkv.tkv_str))
789 return (FALSE);
790 enp->ec_flags &= ~FLG_EC_CATCHALL;
793 return (TRUE);
797 * Process a mapfile size symbol definition.
798 * segment_name @ symbol_name;
800 static Boolean
801 map_atsign(Mapfile *mf, Sg_desc *sgp)
803 Token tok; /* Current token. */
804 ld_map_tkval_t tkv; /* Value of token */
806 if ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_STRING) {
807 if (tok != TK_ERROR)
808 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSYM_1));
809 return (FALSE);
812 /* Add the symbol to the segment */
813 if (!ld_map_seg_size_symbol(mf, sgp, TK_PLUSEQ, tkv.tkv_str))
814 return (FALSE);
817 if (ld_map_gettoken(mf, 0, &tkv) != TK_SEMICOLON) {
818 if (tok != TK_ERROR)
819 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSCOL));
820 return (FALSE);
823 return (TRUE);
827 static Boolean
828 map_pipe(Mapfile *mf, Sg_desc *sgp)
830 Token tok; /* current token. */
831 ld_map_tkval_t tkv; /* Value of token */
833 if ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_STRING) {
834 if (tok != TK_ERROR)
835 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEC));
836 return (FALSE);
839 if (!ld_map_seg_os_order_add(mf, sgp, tkv.tkv_str))
840 return (FALSE);
842 if ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_SEMICOLON) {
843 if (tok != TK_ERROR)
844 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSCOL));
845 return (FALSE);
848 return (TRUE);
852 * Process a mapfile library specification definition.
853 * shared_object_name - shared object definition
854 * shared object definition : [ shared object type [ = SONAME ]]
855 * [ versions ];
857 static Boolean
858 map_dash(Mapfile *mf, char *name)
860 Token tok;
861 Sdf_desc *sdf;
862 ld_map_tkval_t tkv; /* Value of token */
863 enum {
864 MD_NONE = 0,
865 MD_ADDVERS,
866 } dolkey = MD_NONE;
868 /* Get descriptor for dependency */
869 if ((sdf = ld_map_dv(mf, name)) == NULL)
870 return (FALSE);
873 * Get the shared object descriptor string.
875 while ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_SEMICOLON) {
876 if ((tok != TK_STRING) && (tok != TK_EQUAL)) {
877 if (tok != TK_ERROR)
878 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSO));
879 return (FALSE);
883 * Determine if the library type is accompanied with a SONAME
884 * definition.
886 if (tok == TK_EQUAL) {
887 if ((tok = ld_map_gettoken(mf, 0, &tkv)) !=
888 TK_STRING) {
889 if (tok != TK_ERROR)
890 mf_fatal0(mf,
891 MSG_INTL(MSG_MAP_EXPSO));
892 return (FALSE);
894 switch (dolkey) {
895 case MD_ADDVERS:
896 if (!ld_map_dv_entry(mf, sdf, TRUE,
897 tkv.tkv_str))
898 return (FALSE);
899 break;
900 case MD_NONE:
901 mf_fatal(mf, MSG_INTL(MSG_MAP_UNEXTOK), '=');
902 return (FALSE);
904 dolkey = MD_NONE;
905 continue;
909 * A shared object type has been specified. This may also be
910 * accompanied by an SONAME redefinition (see above).
912 if (*tkv.tkv_str == '$') {
913 if (dolkey != MD_NONE) {
914 mf_fatal(mf, MSG_INTL(MSG_MAP_UNEXTOK), '$');
915 return (FALSE);
917 tkv.tkv_str++;
918 ld_map_lowercase(tkv.tkv_str);
919 if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_MAP_ADDVERS)) ==
920 0) {
921 dolkey = MD_ADDVERS;
922 } else {
923 mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSOTYP),
924 tkv.tkv_str);
925 return (FALSE);
927 continue;
931 * shared object version requirement.
933 if (!ld_map_dv_entry(mf, sdf, FALSE, tkv.tkv_str))
934 return (FALSE);
937 return (TRUE);
942 * Process a symbol definition. Historically, this originated from processing
943 * a version definition. However, this has evolved into a generic means of
944 * defining symbol references and definitions (see Defining Additional Symbols
945 * in the Linker and Libraries guide for the complete syntax).
947 * [ name ] {
948 * scope:
949 * symbol [ = [ type ] [ value ] [ size ] [ attribute ] ];
950 * } [ dependency ];
953 static Boolean
954 map_version(Mapfile *mf, char *name)
956 Token tok;
957 ld_map_tkval_t tkv; /* Value of token */
958 ld_map_ver_t mv;
959 ld_map_sym_t ms;
960 Ofl_desc *ofl = mf->mf_ofl;
962 /* Establish the version descriptor and related data */
963 if (!ld_map_sym_ver_init(mf, name, &mv))
964 return (FALSE);
967 * Scan the mapfile entry picking out scoping and symbol definitions.
969 while ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_RIGHTBKT) {
970 uint_t filter = 0;
972 if (tok != TK_STRING) {
973 if (tok == TK_ERROR) {
974 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSYM_2));
975 return (FALSE);
977 mv.mv_errcnt++;
978 continue;
981 /* The default value for all the symbol attributes is 0 */
982 (void) memset(&ms, 0, sizeof (ms));
983 ms.ms_name = tkv.tkv_str;
985 tok = ld_map_gettoken(mf, 0, &tkv);
986 if (tok == TK_ERROR) {
987 mv.mv_errcnt++;
988 continue;
992 * Turn off the WEAK flag to indicate that definitions are
993 * associated with this version. It would probably be more
994 * accurate to only remove this flag with the specification of
995 * global symbols, however setting it here allows enough slop
996 * to compensate for the various user inputs we've seen so far.
997 * Only if a closed version is specified (i.e., "SUNW_1.x {};")
998 * will a user get a weak version (which is how we document the
999 * creation of weak versions).
1001 mv.mv_vdp->vd_flags &= ~VER_FLG_WEAK;
1003 switch (tok) {
1004 case TK_COLON:
1005 ld_map_sym_scope(mf, ms.ms_name, &mv);
1006 continue;
1008 case TK_EQUAL:
1010 * A full blown symbol definition follows.
1011 * Determine the symbol type and any virtual address or
1012 * alignment specified and then fall through to process
1013 * the entire symbols information.
1015 while ((tok = ld_map_gettoken(mf, 0, &tkv)) !=
1016 TK_SEMICOLON) {
1017 if (tok == TK_ERROR)
1018 return (FALSE);
1019 if (tok != TK_STRING) {
1020 mf_fatal0(mf,
1021 MSG_INTL(MSG_MAP_MALFORM));
1022 return (FALSE);
1026 * If we had previously seen AUX or FILTER,
1027 * the next string is the filtee itself.
1028 * Add it, and clear the filter flag.
1030 if (filter) {
1031 ld_map_sym_filtee(mf, &mv, &ms,
1032 filter, tkv.tkv_str);
1033 filter = 0;
1034 continue;
1038 * Determine any Value or Size attributes.
1040 ld_map_lowercase(tkv.tkv_str);
1042 if (tkv.tkv_str[0] == 'v' ||
1043 tkv.tkv_str[0] == 's') {
1044 Xword number;
1046 if (!valuetoxword(mf, &tkv, &number)) {
1047 mv.mv_errcnt++;
1048 return (FALSE);
1051 switch (*tkv.tkv_str) {
1052 case 'v':
1053 /* BEGIN CSTYLED */
1054 if (ms.ms_value) {
1055 mf_fatal(mf,
1056 MSG_INTL(MSG_MAP_MOREONCE),
1057 MSG_INTL(MSG_MAP_SYMVAL));
1058 mv.mv_errcnt++;
1059 continue;
1061 /* LINTED */
1062 ms.ms_value = (Addr)number;
1063 ms.ms_value_set = TRUE;
1064 break;
1065 /* END CSTYLED */
1066 case 's':
1067 /* BEGIN CSTYLED */
1068 if (ms.ms_size) {
1069 mf_fatal(mf,
1070 MSG_INTL(MSG_MAP_MOREONCE),
1071 MSG_INTL(MSG_MAP_SYMSIZE));
1072 mv.mv_errcnt++;
1073 continue;
1075 /* LINTED */
1076 ms.ms_size = (Addr)number;
1077 break;
1078 /* END CSTYLED */
1081 } else if (strcmp(tkv.tkv_str,
1082 MSG_ORIG(MSG_MAP_FUNCTION)) == 0) {
1083 ms.ms_shndx = SHN_ABS;
1084 ms.ms_sdflags |= FLG_SY_SPECSEC;
1085 ms.ms_type = STT_FUNC;
1086 } else if (strcmp(tkv.tkv_str,
1087 MSG_ORIG(MSG_MAP_DATA)) == 0) {
1088 ms.ms_shndx = SHN_ABS;
1089 ms.ms_sdflags |= FLG_SY_SPECSEC;
1090 ms.ms_type = STT_OBJECT;
1091 } else if (strcmp(tkv.tkv_str,
1092 MSG_ORIG(MSG_MAP_COMMON)) == 0) {
1093 ms.ms_shndx = SHN_COMMON;
1094 ms.ms_sdflags |= FLG_SY_SPECSEC;
1095 ms.ms_type = STT_OBJECT;
1096 } else if (strcmp(tkv.tkv_str,
1097 MSG_ORIG(MSG_MAP_PARENT)) == 0) {
1098 ms.ms_sdflags |= FLG_SY_PARENT;
1099 ofl->ofl_flags |= FLG_OF_SYMINFO;
1100 } else if (strcmp(tkv.tkv_str,
1101 MSG_ORIG(MSG_MAP_EXTERN)) == 0) {
1102 ms.ms_sdflags |= FLG_SY_EXTERN;
1103 ofl->ofl_flags |= FLG_OF_SYMINFO;
1104 } else if (strcmp(tkv.tkv_str,
1105 MSG_ORIG(MSG_MAP_DIRECT)) == 0) {
1106 ms.ms_sdflags |= FLG_SY_DIR;
1107 ofl->ofl_flags |= FLG_OF_SYMINFO;
1108 } else if (strcmp(tkv.tkv_str,
1109 MSG_ORIG(MSG_MAP_NODIRECT)) == 0) {
1110 ms.ms_sdflags |= FLG_SY_NDIR;
1111 ofl->ofl_flags |= FLG_OF_SYMINFO;
1112 ofl->ofl_flags1 |=
1113 (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR);
1114 } else if (strcmp(tkv.tkv_str,
1115 MSG_ORIG(MSG_MAP_FILTER)) == 0) {
1116 /* Next token is the filtee */
1117 filter = FLG_SY_STDFLTR;
1118 continue;
1119 } else if (strcmp(tkv.tkv_str,
1120 MSG_ORIG(MSG_MAP_AUXILIARY)) == 0) {
1121 /* Next token is the filtee */
1122 filter = FLG_SY_AUXFLTR;
1123 continue;
1124 } else if (strcmp(tkv.tkv_str,
1125 MSG_ORIG(MSG_MAP_INTERPOSE)) == 0) {
1126 /* BEGIN CSTYLED */
1127 if (!(ofl->ofl_flags & FLG_OF_EXEC)) {
1128 mf_fatal0(mf,
1129 MSG_INTL(MSG_MAP_NOINTPOSE));
1130 mv.mv_errcnt++;
1131 break;
1133 /* END CSTYLED */
1134 ms.ms_sdflags |= FLG_SY_INTPOSE;
1135 ofl->ofl_flags |= FLG_OF_SYMINFO;
1136 ofl->ofl_dtflags_1 |= DF_1_SYMINTPOSE;
1137 continue;
1138 } else if (strcmp(tkv.tkv_str,
1139 MSG_ORIG(MSG_MAP_DYNSORT)) == 0) {
1140 ms.ms_sdflags |= FLG_SY_DYNSORT;
1141 ms.ms_sdflags &= ~FLG_SY_NODYNSORT;
1142 continue;
1143 } else if (strcmp(tkv.tkv_str,
1144 MSG_ORIG(MSG_MAP_NODYNSORT)) == 0) {
1145 ms.ms_sdflags &= ~FLG_SY_DYNSORT;
1146 ms.ms_sdflags |= FLG_SY_NODYNSORT;
1147 continue;
1148 } else {
1149 mf_fatal(mf,
1150 MSG_INTL(MSG_MAP_UNKSYMDEF),
1151 tkv.tkv_str);
1152 mv.mv_errcnt++;
1153 continue;
1156 /* FALLTHROUGH */
1158 case TK_SEMICOLON:
1159 /* Auto-reduction directive ('*')? */
1160 if (*ms.ms_name == '*') {
1161 ld_map_sym_autoreduce(mf, &mv);
1162 continue;
1166 * Catch the error where the AUX or FILTER keyword
1167 * was used, but the filtee wasn't supplied.
1169 if (filter && (ms.ms_filtee == NULL)) {
1170 mf_fatal(mf, MSG_INTL(MSG_MAP_NOFILTER),
1171 ms.ms_name);
1172 mv.mv_errcnt++;
1173 continue;
1177 * Add the new symbol. It should be noted that all
1178 * symbols added by the mapfile start out with global
1179 * scope, thus they will fall through the normal symbol
1180 * resolution process. Symbols defined as locals will
1181 * be reduced in scope after all input file processing.
1183 if (!ld_map_sym_enter(mf, &mv, &ms))
1184 return (FALSE);
1185 break;
1187 default:
1188 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSCOL));
1189 mv.mv_errcnt++;
1190 continue;
1194 if (mv.mv_errcnt)
1195 return (FALSE);
1198 * Determine if any version references are provided after the close
1199 * bracket, parsing up to the terminating ';'.
1201 if (!ld_map_sym_ver_fini(mf, &mv))
1202 return (FALSE);
1204 return (TRUE);
1208 * Parse the mapfile --- Sysv syntax
1210 Boolean
1211 ld_map_parse_v1(Mapfile *mf)
1213 Sg_desc *sgp1; /* seg descriptor being manipulated */
1214 Ent_desc *enp; /* segment entrance criteria. */
1215 Token tok; /* current token. */
1216 Boolean new_segment; /* If true, defines new segment */
1217 char *name;
1218 Ofl_desc *ofl = mf->mf_ofl;
1219 ld_map_tkval_t tkv; /* Value of token */
1220 avl_index_t where;
1223 * We now parse the mapfile until the gettoken routine returns EOF.
1225 while ((tok = ld_map_gettoken(mf, TK_F_EOFOK, &tkv)) != TK_EOF) {
1226 Xword ndx;
1229 * At this point we are at the beginning of a line, and the
1230 * variable tkv.tkv_str points to the first string on the line.
1231 * All mapfile entries start with some string token except it
1232 * is possible for a scoping definition to start with `{'.
1234 if (tok == TK_LEFTBKT) {
1235 if (!map_version(mf, NULL))
1236 return (FALSE);
1237 continue;
1239 if (tok != TK_STRING) {
1240 if (tok != TK_ERROR)
1241 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGNAM));
1242 return (FALSE);
1246 * Save the initial token.
1248 name = tkv.tkv_str;
1251 * Now check the second character on the line. The special `-'
1252 * and `{' characters do not involve any segment manipulation so
1253 * we handle them first.
1255 tok = ld_map_gettoken(mf, 0, &tkv);
1256 if (tok == TK_ERROR)
1257 return (FALSE);
1258 if (tok == TK_DASH) {
1259 if (!map_dash(mf, name))
1260 return (FALSE);
1261 continue;
1263 if (tok == TK_LEFTBKT) {
1264 if (!map_version(mf, name))
1265 return (FALSE);
1266 continue;
1270 * If we're here we need to interpret the first string as a
1271 * segment name. Is this an already known segment?
1273 sgp1 = ld_seg_lookup(mf->mf_ofl, name, &where);
1274 new_segment = sgp1 == NULL;
1275 if (!new_segment)
1276 sgp1->sg_flags &= ~FLG_SG_DISABLED;
1279 * If the second token is a '|' then we had better have found a
1280 * segment. It is illegal to perform section within segment
1281 * ordering before the segment has been declared.
1283 if (tok == TK_PIPE) {
1284 if (sgp1 == NULL) {
1285 mf_fatal(mf, MSG_INTL(MSG_MAP_SECINSEG),
1286 name);
1287 return (FALSE);
1289 if (!map_pipe(mf, sgp1))
1290 return (FALSE);
1291 continue;
1295 * If segment does not exist, allocate a descriptor with
1296 * its values set to 0 so that map_equal() can detect
1297 * changing attributes.
1299 if (new_segment &&
1300 ((sgp1 = ld_map_seg_alloc(name, PT_NULL, 0)) == NULL))
1301 return (FALSE);
1304 * Now check the second token from the input line.
1306 switch (tok) {
1307 case TK_EQUAL: /* Create/modify segment */
1309 * We use the same syntax for hardware/software
1310 * capabilities as we do for segments. If the
1311 * "segment name" matches one of these, then
1312 * process the capabilities instead of treating it
1313 * as a segment. Note that no dynamic memory has
1314 * been allocated for the segment descriptor yet,
1315 * so we can bail without leaking memory.
1317 if (strcmp(sgp1->sg_name,
1318 MSG_ORIG(MSG_STR_HWCAP_1)) == 0) {
1319 if (!map_cap(mf, CA_SUNW_HW_1,
1320 &ofl->ofl_ocapset.oc_hw_1))
1321 return (FALSE);
1322 continue;
1324 if (strcmp(sgp1->sg_name,
1325 MSG_ORIG(MSG_STR_SFCAP_1)) == 0) {
1326 if (!map_cap(mf, CA_SUNW_SF_1,
1327 &ofl->ofl_ocapset.oc_sf_1))
1328 return (FALSE);
1329 continue;
1333 * If not a new segment, show the initial value
1334 * before modifying it.
1336 if (!new_segment && DBG_ENABLED) {
1337 ndx = ld_map_seg_index(mf, sgp1);
1338 Dbg_map_seg(ofl, DBG_STATE_MOD_BEFORE,
1339 ndx, sgp1, mf->mf_lineno);
1342 /* Process the segment */
1343 if (!map_equal(mf, sgp1))
1344 return (FALSE);
1347 * Special case for STACK "segments":
1349 * The ability to modify the stack flags was added
1350 * long after this sysv syntax was designed. It was
1351 * fit into the existing syntax by treating it as a
1352 * segment. However, there can only be one stack program
1353 * header, while segment syntax requires user to supply
1354 * a name. This is confusing, and it allows the user to
1355 * attempt to create more than one stack segment. The
1356 * original implementation had a test to catch this.
1358 * If this is a stack segment, locate the real stack
1359 * descriptor and transfer the flags to it. We then
1360 * free the allocated descriptor without inserting it.
1361 * The end result is that all stack segments simply
1362 * alter the one stack descriptor, and the segment
1363 * name is ignored.
1365 if (sgp1->sg_phdr.p_type == PT_SUNWSTACK) {
1366 Sg_desc *stack = ld_map_seg_stack(mf);
1368 if (sgp1->sg_flags & FLG_SG_P_FLAGS)
1369 stack->sg_phdr.p_flags =
1370 sgp1->sg_phdr.p_flags;
1371 free(sgp1);
1373 DBG_CALL(Dbg_map_seg(ofl,
1374 DBG_STATE_MOD_AFTER, ndx, sgp1,
1375 mf->mf_lineno));
1376 break;
1380 * If this is a new segment, finish its initialization
1381 * and insert it into the segment list.
1383 if (new_segment) {
1384 switch (ld_map_seg_insert(mf, DBG_STATE_NEW,
1385 sgp1, where)) {
1386 case SEG_INS_SKIP:
1387 continue;
1388 case SEG_INS_FAIL:
1389 return (FALSE);
1391 } else {
1392 /* Not new. Show what's changed */
1393 DBG_CALL(Dbg_map_seg(ofl,
1394 DBG_STATE_MOD_AFTER, ndx, sgp1,
1395 mf->mf_lineno));
1397 break;
1399 case TK_COLON: /* Section to segment mapping */
1401 * If this is a new segment, finish its initialization
1402 * and insert it into the segment list.
1404 * If it is not a new segment, ensure that it is
1405 * not an empty segment reservation, as sections
1406 * cannot be assigned to those.
1408 if (new_segment) {
1409 switch (ld_map_seg_insert(mf,
1410 DBG_STATE_NEW_IMPLICIT, sgp1, where)) {
1411 case SEG_INS_SKIP:
1412 continue;
1413 case SEG_INS_FAIL:
1414 return (FALSE);
1416 } else if (sgp1->sg_flags & FLG_SG_EMPTY) {
1417 mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPSEC));
1418 return (FALSE);
1422 * Create new entrance criteria descriptor, and
1423 * process the mapping directive.
1425 enp = ld_map_seg_ent_add(mf, sgp1, NULL);
1426 if ((enp == NULL) || !map_colon(mf, enp))
1427 return (FALSE);
1428 DBG_CALL(Dbg_map_ent(ofl->ofl_lml, enp, ofl,
1429 mf->mf_lineno));
1430 break;
1432 case TK_ATSIGN: /* Section size symbol */
1434 * If this is a new segment, finish its initialization
1435 * and insert it into the segment list.
1437 if (new_segment) {
1438 switch (ld_map_seg_insert(mf,
1439 DBG_STATE_NEW_IMPLICIT, sgp1, where)) {
1440 case SEG_INS_SKIP:
1441 continue;
1442 case SEG_INS_FAIL:
1443 return (FALSE);
1446 if (!map_atsign(mf, sgp1))
1447 return (FALSE);
1448 break;
1450 case TK_ERROR:
1451 return (FALSE); /* Error was already issued */
1453 default:
1454 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPEQU));
1455 return (FALSE);
1459 return (TRUE);