17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
55aefb655Srie * Common Development and Distribution License (the "License").
65aefb655Srie * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
215aefb655Srie
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate * Copyright (c) 1988 AT&T
247c478bd9Sstevel@tonic-gate * All Rights Reserved
257c478bd9Sstevel@tonic-gate *
2669112eddSAli Bahrami * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
277c478bd9Sstevel@tonic-gate * Use is subject to license terms.
287c478bd9Sstevel@tonic-gate */
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate /*
3169112eddSAli Bahrami * Map file parsing (Original SysV syntax).
327c478bd9Sstevel@tonic-gate */
337c478bd9Sstevel@tonic-gate #include <string.h>
3469112eddSAli Bahrami #include <strings.h>
357c478bd9Sstevel@tonic-gate #include <stdio.h>
367c478bd9Sstevel@tonic-gate #include <unistd.h>
377c478bd9Sstevel@tonic-gate #include <errno.h>
387c478bd9Sstevel@tonic-gate #include <limits.h>
397c478bd9Sstevel@tonic-gate #include <ctype.h>
407c478bd9Sstevel@tonic-gate #include <elfcap.h>
415aefb655Srie #include <debug.h>
427c478bd9Sstevel@tonic-gate #include "msg.h"
437c478bd9Sstevel@tonic-gate #include "_libld.h"
4469112eddSAli Bahrami #include "_map.h"
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate /*
477c478bd9Sstevel@tonic-gate * Process a hardware/software capabilities segment declaration definition.
487c478bd9Sstevel@tonic-gate * hwcap_1 = val,... [ OVERRIDE ]
497c478bd9Sstevel@tonic-gate * sfcap_1 = val,... [ OVERRIDE ]
5008278a5eSRod Evans * hwcap_2 = val,... [ OVERRIDE ]
5108278a5eSRod Evans * platcap = name,... [ OVERRIDE ]
5208278a5eSRod Evans * machcap = name,... [ OVERRIDE ]
537c478bd9Sstevel@tonic-gate *
547c478bd9Sstevel@tonic-gate * The values can be defined as a list of machine specify tokens, or numerics.
557c478bd9Sstevel@tonic-gate * Tokens are representations of the sys/auxv_$MACH.h capabilities, for example:
567c478bd9Sstevel@tonic-gate *
577c478bd9Sstevel@tonic-gate * #define AV_386_FPU 0x0001 is represented as FPU
588222814eSRichard Lowe * #define AV_386_TSC 0x0002 " " " " TSC
597c478bd9Sstevel@tonic-gate *
607c478bd9Sstevel@tonic-gate * Or, the above two capabilities could be represented as V0x3. Note, the
61635216b6SRod Evans * OVERRIDE flag is used to ensure that only those values provided via this
627c478bd9Sstevel@tonic-gate * mapfile entry are recorded in the final image, ie. this overrides any
6308278a5eSRod Evans * hardware capabilities that may be defined in the objects read as part of
6408278a5eSRod Evans * this link-edit. Specifying:
657c478bd9Sstevel@tonic-gate *
667c478bd9Sstevel@tonic-gate * V0x0 OVERRIDE
677c478bd9Sstevel@tonic-gate *
687c478bd9Sstevel@tonic-gate * effectively removes any capabilities information from the final image.
697c478bd9Sstevel@tonic-gate */
7069112eddSAli Bahrami static Boolean
map_cap(Mapfile * mf,Word type,Capmask * capmask)7108278a5eSRod Evans map_cap(Mapfile *mf, Word type, Capmask *capmask)
727c478bd9Sstevel@tonic-gate {
7369112eddSAli Bahrami Token tok; /* Current token. */
7469112eddSAli Bahrami Xword number;
7569112eddSAli Bahrami int used = 0;
7669112eddSAli Bahrami Ofl_desc *ofl = mf->mf_ofl;
7769112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */
7869112eddSAli Bahrami elfcap_mask_t value = 0;
7969112eddSAli Bahrami
8069112eddSAli Bahrami if (DBG_ENABLED) {
8169112eddSAli Bahrami Dbg_cap_mapfile_title(ofl->ofl_lml, mf->mf_lineno);
8208278a5eSRod Evans Dbg_cap_val_entry(ofl->ofl_lml, DBG_STATE_CURRENT, CA_SUNW_HW_1,
8308278a5eSRod Evans capmask->cm_val, ld_targ.t_m.m_mach);
8469112eddSAli Bahrami }
857c478bd9Sstevel@tonic-gate
8669112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, TK_F_STRLC, &tkv)) !=
8769112eddSAli Bahrami TK_SEMICOLON) {
887c478bd9Sstevel@tonic-gate if (tok != TK_STRING) {
8971ae4d73Sab if (tok != TK_ERROR)
9069112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGATT));
9169112eddSAli Bahrami return (FALSE);
927c478bd9Sstevel@tonic-gate }
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate /*
957c478bd9Sstevel@tonic-gate * First, determine if the token represents the reserved
967c478bd9Sstevel@tonic-gate * OVERRIDE keyword.
977c478bd9Sstevel@tonic-gate */
9869112eddSAli Bahrami if (strncmp(tkv.tkv_str, MSG_ORIG(MSG_MAP_OVERRIDE),
997c478bd9Sstevel@tonic-gate MSG_MAP_OVERRIDE_SIZE) == 0) {
10069112eddSAli Bahrami ld_map_cap_set_ovflag(mf, type);
1017c478bd9Sstevel@tonic-gate used++;
1027c478bd9Sstevel@tonic-gate continue;
1037c478bd9Sstevel@tonic-gate }
1047c478bd9Sstevel@tonic-gate
10569112eddSAli Bahrami /* Is the token a symbolic capability name? */
10669112eddSAli Bahrami if ((number = (Xword)elfcap_tag_from_str(ELFCAP_STYLE_LC,
10769112eddSAli Bahrami type, tkv.tkv_str, ld_targ.t_m.m_mach)) != 0) {
10869112eddSAli Bahrami value |= number;
10969112eddSAli Bahrami used++;
11069112eddSAli Bahrami continue;
1117c478bd9Sstevel@tonic-gate }
1127c478bd9Sstevel@tonic-gate
1137c478bd9Sstevel@tonic-gate /*
11469112eddSAli Bahrami * Is the token a numeric value?
1157c478bd9Sstevel@tonic-gate */
11669112eddSAli Bahrami if (tkv.tkv_str[0] == 'v') {
11769112eddSAli Bahrami if (ld_map_strtoxword(&tkv.tkv_str[1], NULL,
11869112eddSAli Bahrami &number) != STRTOXWORD_OK) {
11969112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_BADCAPVAL),
12069112eddSAli Bahrami tkv.tkv_str);
12169112eddSAli Bahrami return (FALSE);
1227c478bd9Sstevel@tonic-gate }
12369112eddSAli Bahrami value |= number;
1247c478bd9Sstevel@tonic-gate used++;
1257c478bd9Sstevel@tonic-gate continue;
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate /*
1297c478bd9Sstevel@tonic-gate * We have an unknown token.
1307c478bd9Sstevel@tonic-gate */
1317c478bd9Sstevel@tonic-gate used++;
13269112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_UNKCAPATTR), tkv.tkv_str);
13369112eddSAli Bahrami return (FALSE);
1347c478bd9Sstevel@tonic-gate }
1357c478bd9Sstevel@tonic-gate
13669112eddSAli Bahrami /* Catch empty declarations */
1377c478bd9Sstevel@tonic-gate if (used == 0) {
13869112eddSAli Bahrami mf_warn0(mf, MSG_INTL(MSG_MAP_EMPTYCAP));
13969112eddSAli Bahrami return (TRUE);
1407c478bd9Sstevel@tonic-gate }
14169112eddSAli Bahrami
14208278a5eSRod Evans DBG_CALL(Dbg_cap_val_entry(ofl->ofl_lml, DBG_STATE_NEW, type, value,
14308278a5eSRod Evans ld_targ.t_m.m_mach));
14408278a5eSRod Evans capmask->cm_val |= value;
14569112eddSAli Bahrami
14669112eddSAli Bahrami /* Sanity check the resulting bits */
14769112eddSAli Bahrami if (!ld_map_cap_sanitize(mf, type, capmask))
14869112eddSAli Bahrami return (FALSE);
14969112eddSAli Bahrami
15069112eddSAli Bahrami return (TRUE);
1517c478bd9Sstevel@tonic-gate }
1527c478bd9Sstevel@tonic-gate
153d1827f25Srie /*
15469112eddSAli Bahrami * Parse the flags for a segment definition. Called by map_equal().
15569112eddSAli Bahrami *
15669112eddSAli Bahrami * entry:
15769112eddSAli Bahrami * mf - Mapfile descriptor
15869112eddSAli Bahrami * sgp - Segment being defined
15969112eddSAli Bahrami * b_flags - Address of b_flags variable from map_equal().
16069112eddSAli Bahrami * *bflags is TRUE if flags have already been seen in, the
16169112eddSAli Bahrami * current segment definition directive, and FALSE otherwise.
16269112eddSAli Bahrami * flag_tok - Flags string, starting with the '?' character.
16369112eddSAli Bahrami *
16469112eddSAli Bahrami * exit:
16569112eddSAli Bahrami * On success, the flags have been parsed and the segment updated,
16669112eddSAli Bahrami * *b_flags is set to TRUE, and TRUE is returned. On error, FALSE
16769112eddSAli Bahrami * is returned.
168d1827f25Srie */
169d1827f25Srie static Boolean
map_equal_flags(Mapfile * mf,Sg_desc * sgp,Boolean * b_flags,const char * flag_tok)17069112eddSAli Bahrami map_equal_flags(Mapfile *mf, Sg_desc *sgp, Boolean *b_flags,
17169112eddSAli Bahrami const char *flag_tok)
172d1827f25Srie {
17369112eddSAli Bahrami Word tmp_flags = 0;
17469112eddSAli Bahrami
17569112eddSAli Bahrami if (*b_flags) {
17669112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE),
17769112eddSAli Bahrami MSG_INTL(MSG_MAP_SEGFLAG));
178d1827f25Srie return (FALSE);
179d1827f25Srie }
18069112eddSAli Bahrami
18169112eddSAli Bahrami /* Skip over the leading '?' character */
18269112eddSAli Bahrami flag_tok++;
18369112eddSAli Bahrami
18469112eddSAli Bahrami /*
18569112eddSAli Bahrami * If ? has nothing following leave the flags cleared,
18669112eddSAli Bahrami * otherwise OR in any flags specified.
18769112eddSAli Bahrami */
18869112eddSAli Bahrami while (*flag_tok) {
18969112eddSAli Bahrami switch (*flag_tok) {
19069112eddSAli Bahrami case 'r':
19169112eddSAli Bahrami tmp_flags |= PF_R;
19269112eddSAli Bahrami break;
19369112eddSAli Bahrami case 'w':
19469112eddSAli Bahrami tmp_flags |= PF_W;
19569112eddSAli Bahrami break;
19669112eddSAli Bahrami case 'x':
19769112eddSAli Bahrami tmp_flags |= PF_X;
19869112eddSAli Bahrami break;
19969112eddSAli Bahrami case 'e':
20069112eddSAli Bahrami sgp->sg_flags |= FLG_SG_EMPTY;
20169112eddSAli Bahrami break;
20269112eddSAli Bahrami case 'o':
20369112eddSAli Bahrami /*
20469112eddSAli Bahrami * The version 1 ?O option is incompatible with
20569112eddSAli Bahrami * the version 2 SEGMENT IS_ORDER attribute.
20669112eddSAli Bahrami */
20769112eddSAli Bahrami if (aplist_nitems(sgp->sg_is_order) > 0) {
20869112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_ISORDVER),
20969112eddSAli Bahrami sgp->sg_name);
21069112eddSAli Bahrami return (FALSE);
21169112eddSAli Bahrami }
21269112eddSAli Bahrami
21369112eddSAli Bahrami /*
21469112eddSAli Bahrami * Set FLG_SG_IS_ORDER to indicate that segment has
21569112eddSAli Bahrami * had the ?O flag set by a version 1 mapfile.
21669112eddSAli Bahrami */
21769112eddSAli Bahrami sgp->sg_flags |= FLG_SG_IS_ORDER;
21869112eddSAli Bahrami break;
21969112eddSAli Bahrami case 'n':
22069112eddSAli Bahrami /*
22169112eddSAli Bahrami * If segment ends up as the first loadable segment,
22269112eddSAli Bahrami * it will not include the the ELF and program headers.
22369112eddSAli Bahrami */
22469112eddSAli Bahrami sgp->sg_flags |= FLG_SG_NOHDR;
22569112eddSAli Bahrami break;
22669112eddSAli Bahrami default:
22769112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSEGFLG), *flag_tok);
22869112eddSAli Bahrami return (FALSE);
22969112eddSAli Bahrami }
23069112eddSAli Bahrami flag_tok++;
231d1827f25Srie }
23269112eddSAli Bahrami
23369112eddSAli Bahrami /*
23469112eddSAli Bahrami * Warn when changing flags except when we're adding or removing "X"
23569112eddSAli Bahrami * from a RW PT_LOAD segment.
23669112eddSAli Bahrami */
23769112eddSAli Bahrami if ((sgp->sg_flags & FLG_SG_P_FLAGS) &&
23869112eddSAli Bahrami (sgp->sg_phdr.p_flags != tmp_flags) &&
23969112eddSAli Bahrami !(sgp->sg_phdr.p_type == PT_LOAD &&
24069112eddSAli Bahrami (tmp_flags & (PF_R|PF_W)) == (PF_R|PF_W) &&
24169112eddSAli Bahrami (tmp_flags ^ sgp->sg_phdr.p_flags) == PF_X))
24269112eddSAli Bahrami mf_warn(mf, MSG_INTL(MSG_MAP_REDEFATT),
24369112eddSAli Bahrami MSG_INTL(MSG_MAP_SEGFLAG), sgp->sg_name);
24469112eddSAli Bahrami
24569112eddSAli Bahrami sgp->sg_flags |= FLG_SG_P_FLAGS;
24669112eddSAli Bahrami sgp->sg_phdr.p_flags = tmp_flags;
24769112eddSAli Bahrami *b_flags = TRUE;
24869112eddSAli Bahrami
249d1827f25Srie return (TRUE);
250d1827f25Srie }
251d1827f25Srie
25269112eddSAli Bahrami /*
25369112eddSAli Bahrami * Read an address (value) or size Xword from a TK_STRING token value
25469112eddSAli Bahrami * where the first letter of the string is a letter ('v', 'l', 's', ...)
25569112eddSAli Bahrami * followed by the numeric value.
25669112eddSAli Bahrami *
25769112eddSAli Bahrami * entry:
25869112eddSAli Bahrami * mf - Mapfile descriptor
25969112eddSAli Bahrami * tkv - TK_STRING token to parse
26069112eddSAli Bahrami * value - Address of variable to receive the resulting value.
26169112eddSAli Bahrami *
26269112eddSAli Bahrami * exit:
26369112eddSAli Bahrami * Returns TRUE for success. On failure, issues an error message
26469112eddSAli Bahrami * and returns FALSE.
26569112eddSAli Bahrami */
26669112eddSAli Bahrami static Boolean
valuetoxword(Mapfile * mf,ld_map_tkval_t * tkv,Xword * value)26769112eddSAli Bahrami valuetoxword(Mapfile *mf, ld_map_tkval_t *tkv, Xword *value)
26869112eddSAli Bahrami {
26969112eddSAli Bahrami switch (ld_map_strtoxword(&tkv->tkv_str[1], NULL, value)) {
27069112eddSAli Bahrami case STRTOXWORD_OK:
27169112eddSAli Bahrami return (TRUE);
27269112eddSAli Bahrami
27369112eddSAli Bahrami case STRTOXWORD_TOOBIG:
27469112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_SEGADDR), tkv->tkv_str,
27569112eddSAli Bahrami MSG_INTL(MSG_MAP_EXCLIMIT));
27669112eddSAli Bahrami break;
27769112eddSAli Bahrami default:
27869112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_SEGADDR), tkv->tkv_str,
27969112eddSAli Bahrami MSG_INTL(MSG_MAP_NOBADFRM));
28069112eddSAli Bahrami break;
28169112eddSAli Bahrami }
28269112eddSAli Bahrami
28369112eddSAli Bahrami return (FALSE);
28469112eddSAli Bahrami }
28569112eddSAli Bahrami
2867c478bd9Sstevel@tonic-gate /*
2877c478bd9Sstevel@tonic-gate * Process a mapfile segment declaration definition.
2887c478bd9Sstevel@tonic-gate * segment_name = segment_attribute;
2898222814eSRichard Lowe * segment_attribute : segment_type segment_flags virtual_addr
2907c478bd9Sstevel@tonic-gate * physical_addr length alignment
2917c478bd9Sstevel@tonic-gate */
29269112eddSAli Bahrami static Boolean
map_equal(Mapfile * mf,Sg_desc * sgp)29369112eddSAli Bahrami map_equal(Mapfile *mf, Sg_desc *sgp)
2947c478bd9Sstevel@tonic-gate {
29569112eddSAli Bahrami /*
29669112eddSAli Bahrami * Segment type. Users are permitted to define PT_LOAD,
29769112eddSAli Bahrami * PT_NOTE, PT_SUNWSTACK and PT_NULL segments. Other segment
29869112eddSAli Bahrami * types are only defined in seg_desc[].
29969112eddSAli Bahrami */
30069112eddSAli Bahrami typedef struct {
30169112eddSAli Bahrami const char *name; /* Name for segment type */
30269112eddSAli Bahrami Word p_type; /* PT_ constant corresponding to name */
30369112eddSAli Bahrami sg_flags_t sg_flags; /* Seg descriptor flags to apply */
30469112eddSAli Bahrami } seg_types_t;
30569112eddSAli Bahrami
30669112eddSAli Bahrami static seg_types_t seg_type_arr[] = {
30769112eddSAli Bahrami { MSG_ORIG(MSG_MAP_LOAD), PT_LOAD, FLG_SG_P_TYPE },
30869112eddSAli Bahrami { MSG_ORIG(MSG_MAP_STACK), PT_SUNWSTACK,
30969112eddSAli Bahrami FLG_SG_P_TYPE | FLG_SG_EMPTY },
31069112eddSAli Bahrami { MSG_ORIG(MSG_MAP_NULL), PT_NULL, FLG_SG_P_TYPE },
31169112eddSAli Bahrami { MSG_ORIG(MSG_MAP_NOTE), PT_NOTE, FLG_SG_P_TYPE },
31269112eddSAli Bahrami
31369112eddSAli Bahrami /* Array must be NULL terminated */
31469112eddSAli Bahrami { NULL }
31569112eddSAli Bahrami };
31669112eddSAli Bahrami
31769112eddSAli Bahrami
31869112eddSAli Bahrami seg_types_t *seg_type;
3197c478bd9Sstevel@tonic-gate Token tok; /* Current token. */
32069112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */
3217c478bd9Sstevel@tonic-gate Boolean b_type = FALSE; /* True if seg types found. */
3227c478bd9Sstevel@tonic-gate Boolean b_flags = FALSE; /* True if seg flags found. */
3237c478bd9Sstevel@tonic-gate Boolean b_len = FALSE; /* True if seg length found. */
3247c478bd9Sstevel@tonic-gate Boolean b_round = FALSE; /* True if seg rounding found. */
3257c478bd9Sstevel@tonic-gate Boolean b_vaddr = FALSE; /* True if seg virtual addr found. */
3267c478bd9Sstevel@tonic-gate Boolean b_paddr = FALSE; /* True if seg physical addr found. */
3277c478bd9Sstevel@tonic-gate Boolean b_align = FALSE; /* True if seg alignment found. */
3287c478bd9Sstevel@tonic-gate
32969112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, TK_F_STRLC, &tkv)) !=
33069112eddSAli Bahrami TK_SEMICOLON) {
3317c478bd9Sstevel@tonic-gate if (tok != TK_STRING) {
33271ae4d73Sab if (tok != TK_ERROR)
33369112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGATT));
33469112eddSAli Bahrami return (FALSE);
3357c478bd9Sstevel@tonic-gate }
3367c478bd9Sstevel@tonic-gate
3377c478bd9Sstevel@tonic-gate /*
33869112eddSAli Bahrami * If it is the name of a segment type, set the type
33969112eddSAli Bahrami * and flags fields in the descriptor.
3407c478bd9Sstevel@tonic-gate */
34169112eddSAli Bahrami for (seg_type = seg_type_arr; seg_type->name; seg_type++) {
34269112eddSAli Bahrami if (strcmp(tkv.tkv_str, seg_type->name) == 0) {
34369112eddSAli Bahrami if (b_type) {
34469112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE),
34569112eddSAli Bahrami MSG_INTL(MSG_MAP_SEGTYP));
34669112eddSAli Bahrami return (FALSE);
3477c478bd9Sstevel@tonic-gate }
34869112eddSAli Bahrami if ((sgp->sg_flags & FLG_SG_P_TYPE) &&
34969112eddSAli Bahrami (sgp->sg_phdr.p_type != seg_type->p_type)) {
35069112eddSAli Bahrami mf_warn(mf, MSG_INTL(MSG_MAP_REDEFATT),
35169112eddSAli Bahrami MSG_INTL(MSG_MAP_SEGTYP),
35269112eddSAli Bahrami sgp->sg_name);
35369112eddSAli Bahrami }
35469112eddSAli Bahrami
35569112eddSAli Bahrami sgp->sg_phdr.p_type = seg_type->p_type;
35669112eddSAli Bahrami sgp->sg_flags |= seg_type->sg_flags;
35769112eddSAli Bahrami break;
3587c478bd9Sstevel@tonic-gate }
35969112eddSAli Bahrami }
36069112eddSAli Bahrami if (seg_type->name != NULL) /* Matched segment type */
36169112eddSAli Bahrami continue; /* next token */
36269112eddSAli Bahrami
36369112eddSAli Bahrami /* Segment Flags */
36469112eddSAli Bahrami if (*tkv.tkv_str == '?') {
36569112eddSAli Bahrami if (!map_equal_flags(mf, sgp, &b_flags, tkv.tkv_str))
36669112eddSAli Bahrami return (FALSE);
36769112eddSAli Bahrami continue; /* next token */
3687c478bd9Sstevel@tonic-gate }
3697c478bd9Sstevel@tonic-gate
3707c478bd9Sstevel@tonic-gate
37169112eddSAli Bahrami /* Segment address, length, alignment or rounding number */
37269112eddSAli Bahrami if ((tkv.tkv_str[0] == 'l') || (tkv.tkv_str[0] == 'v') ||
37369112eddSAli Bahrami (tkv.tkv_str[0] == 'a') || (tkv.tkv_str[0] == 'p') ||
37469112eddSAli Bahrami (tkv.tkv_str[0] == 'r')) {
37569112eddSAli Bahrami Xword number;
3767c478bd9Sstevel@tonic-gate
37769112eddSAli Bahrami if (!valuetoxword(mf, &tkv, &number))
37869112eddSAli Bahrami return (FALSE);
3797c478bd9Sstevel@tonic-gate
38069112eddSAli Bahrami switch (*tkv.tkv_str) {
3817c478bd9Sstevel@tonic-gate case 'l':
3827c478bd9Sstevel@tonic-gate if (b_len) {
38369112eddSAli Bahrami mf_fatal(mf,
3847c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_MOREONCE),
3857c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGLEN));
38669112eddSAli Bahrami return (FALSE);
3877c478bd9Sstevel@tonic-gate }
3887c478bd9Sstevel@tonic-gate if ((sgp->sg_flags & FLG_SG_LENGTH) &&
3897c478bd9Sstevel@tonic-gate (sgp->sg_length != number))
39069112eddSAli Bahrami mf_warn(mf,
3917c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_REDEFATT),
3927c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGLEN),
3937c478bd9Sstevel@tonic-gate sgp->sg_name);
3947c478bd9Sstevel@tonic-gate sgp->sg_length = number;
3957c478bd9Sstevel@tonic-gate sgp->sg_flags |= FLG_SG_LENGTH;
3967c478bd9Sstevel@tonic-gate b_len = TRUE;
3977c478bd9Sstevel@tonic-gate break;
3987c478bd9Sstevel@tonic-gate case 'r':
3997c478bd9Sstevel@tonic-gate if (b_round) {
40069112eddSAli Bahrami mf_fatal(mf,
4017c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_MOREONCE),
4027c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGROUND));
40369112eddSAli Bahrami return (FALSE);
4047c478bd9Sstevel@tonic-gate }
4057c478bd9Sstevel@tonic-gate if ((sgp->sg_flags & FLG_SG_ROUND) &&
4067c478bd9Sstevel@tonic-gate (sgp->sg_round != number))
40769112eddSAli Bahrami mf_warn(mf,
4087c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_REDEFATT),
4097c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGROUND),
4107c478bd9Sstevel@tonic-gate sgp->sg_name);
4117c478bd9Sstevel@tonic-gate sgp->sg_round = number;
4127c478bd9Sstevel@tonic-gate sgp->sg_flags |= FLG_SG_ROUND;
4137c478bd9Sstevel@tonic-gate b_round = TRUE;
4147c478bd9Sstevel@tonic-gate break;
4157c478bd9Sstevel@tonic-gate case 'v':
4167c478bd9Sstevel@tonic-gate if (b_vaddr) {
41769112eddSAli Bahrami mf_fatal(mf,
4187c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_MOREONCE),
4197c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGVADDR));
42069112eddSAli Bahrami return (FALSE);
4217c478bd9Sstevel@tonic-gate }
42269112eddSAli Bahrami if ((sgp->sg_flags & FLG_SG_P_VADDR) &&
4237c478bd9Sstevel@tonic-gate (sgp->sg_phdr.p_vaddr != number))
42469112eddSAli Bahrami mf_warn(mf,
4257c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_REDEFATT),
4267c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGVADDR),
4277c478bd9Sstevel@tonic-gate sgp->sg_name);
4287c478bd9Sstevel@tonic-gate /* LINTED */
4297c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_vaddr = (Addr)number;
43069112eddSAli Bahrami sgp->sg_flags |= FLG_SG_P_VADDR;
4317c478bd9Sstevel@tonic-gate b_vaddr = TRUE;
4327c478bd9Sstevel@tonic-gate break;
4337c478bd9Sstevel@tonic-gate case 'p':
4347c478bd9Sstevel@tonic-gate if (b_paddr) {
43569112eddSAli Bahrami mf_fatal(mf,
4367c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_MOREONCE),
4377c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGPHYS));
43869112eddSAli Bahrami return (FALSE);
4397c478bd9Sstevel@tonic-gate }
44069112eddSAli Bahrami if ((sgp->sg_flags & FLG_SG_P_PADDR) &&
4417c478bd9Sstevel@tonic-gate (sgp->sg_phdr.p_paddr != number))
44269112eddSAli Bahrami mf_warn(mf,
4437c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_REDEFATT),
4447c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGPHYS),
4457c478bd9Sstevel@tonic-gate sgp->sg_name);
4467c478bd9Sstevel@tonic-gate /* LINTED */
4477c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_paddr = (Addr)number;
44869112eddSAli Bahrami sgp->sg_flags |= FLG_SG_P_PADDR;
4497c478bd9Sstevel@tonic-gate b_paddr = TRUE;
4507c478bd9Sstevel@tonic-gate break;
4517c478bd9Sstevel@tonic-gate case 'a':
4527c478bd9Sstevel@tonic-gate if (b_align) {
45369112eddSAli Bahrami mf_fatal(mf,
4547c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_MOREONCE),
4557c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGALIGN));
45669112eddSAli Bahrami return (FALSE);
4577c478bd9Sstevel@tonic-gate }
45869112eddSAli Bahrami if ((sgp->sg_flags & FLG_SG_P_ALIGN) &&
4597c478bd9Sstevel@tonic-gate (sgp->sg_phdr.p_align != number))
46069112eddSAli Bahrami mf_warn(mf,
4617c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_REDEFATT),
4627c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGALIGN),
4637c478bd9Sstevel@tonic-gate sgp->sg_name);
4647c478bd9Sstevel@tonic-gate /* LINTED */
4657c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_align = (Xword)number;
46669112eddSAli Bahrami sgp->sg_flags |= FLG_SG_P_ALIGN;
4677c478bd9Sstevel@tonic-gate b_align = TRUE;
4687c478bd9Sstevel@tonic-gate break;
4697c478bd9Sstevel@tonic-gate }
47069112eddSAli Bahrami
47169112eddSAli Bahrami continue; /* next token */
4727c478bd9Sstevel@tonic-gate }
47369112eddSAli Bahrami
47469112eddSAli Bahrami /*
47569112eddSAli Bahrami * If we reach the bottom of this loop, we have an
47669112eddSAli Bahrami * unrecognized token.
47769112eddSAli Bahrami */
47869112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSEGATT), tkv.tkv_str);
47969112eddSAli Bahrami return (FALSE);
4807c478bd9Sstevel@tonic-gate }
4817c478bd9Sstevel@tonic-gate
4827c478bd9Sstevel@tonic-gate /*
483d1827f25Srie * Empty segments can be used to define PT_LOAD segment reservations, or
484d1827f25Srie * to reserve PT_NULL program headers.
485d1827f25Srie *
486d1827f25Srie * PT_LOAD reservations are only allowed within executables, as the
487d1827f25Srie * reservation must be established through exec() as part of initial
488d1827f25Srie * process loading. In addition, PT_LOAD reservations must have an
48969112eddSAli Bahrami * associated address and size. Note: This is an obsolete feature,
49069112eddSAli Bahrami * not supported by the newer mapfile syntax.
491d1827f25Srie *
492d1827f25Srie * PT_NULL program headers are established for later use by applications
493d1827f25Srie * such as the post-optimizer. PT_NULL headers should have no other
494d1827f25Srie * attributes assigned.
4957c478bd9Sstevel@tonic-gate */
4967c478bd9Sstevel@tonic-gate if ((sgp->sg_flags & FLG_SG_EMPTY) &&
4977c478bd9Sstevel@tonic-gate (sgp->sg_phdr.p_type != PT_SUNWSTACK)) {
498d1827f25Srie
499d1827f25Srie /*
500d1827f25Srie * Any style of empty segment should have no permissions.
501d1827f25Srie */
5027c478bd9Sstevel@tonic-gate if (sgp->sg_phdr.p_flags != 0) {
50369112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_SEGEMNOPERM),
504d1827f25Srie EC_WORD(sgp->sg_phdr.p_flags));
50569112eddSAli Bahrami return (FALSE);
50613b387e7Sdm }
507d1827f25Srie
508d1827f25Srie if (sgp->sg_phdr.p_type == PT_LOAD) {
50969112eddSAli Bahrami if ((mf->mf_ofl->ofl_flags & FLG_OF_EXEC) == 0) {
51069112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPEXE));
51169112eddSAli Bahrami return (FALSE);
512d1827f25Srie }
51369112eddSAli Bahrami if ((sgp->sg_flags &
51469112eddSAli Bahrami (FLG_SG_LENGTH | FLG_SG_P_VADDR)) !=
51569112eddSAli Bahrami (FLG_SG_LENGTH | FLG_SG_P_VADDR)) {
51669112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPATT));
51769112eddSAli Bahrami return (FALSE);
518d1827f25Srie }
519d1827f25Srie } else if (sgp->sg_phdr.p_type == PT_NULL) {
52069112eddSAli Bahrami if ((sgp->sg_flags &
52169112eddSAli Bahrami (FLG_SG_LENGTH | FLG_SG_P_VADDR)) &&
522d1827f25Srie ((sgp->sg_length != 0) ||
523d1827f25Srie (sgp->sg_phdr.p_vaddr != 0))) {
52469112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPNOATT));
52569112eddSAli Bahrami return (FALSE);
526d1827f25Srie }
527d1827f25Srie } else {
52869112eddSAli Bahrami mf_warn0(mf, MSG_INTL(MSG_MAP_SEGEMPLOAD));
5297c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_type = PT_LOAD;
5307c478bd9Sstevel@tonic-gate }
5317c478bd9Sstevel@tonic-gate }
5327c478bd9Sstevel@tonic-gate
5337c478bd9Sstevel@tonic-gate /*
5347c478bd9Sstevel@tonic-gate * All segment attributes have now been scanned. Certain flags do not
5357c478bd9Sstevel@tonic-gate * make sense if this is not a loadable segment, fix if necessary.
5367c478bd9Sstevel@tonic-gate * Note, if the segment is of type PT_NULL it must be new, and any
53769112eddSAli Bahrami * defaults will be applied by ld_map_seg_insert(). When clearing an
53869112eddSAli Bahrami * attribute leave the flag set as an indicator for later entries
53969112eddSAli Bahrami * re-specifying the same segment.
5407c478bd9Sstevel@tonic-gate */
541d1827f25Srie if ((sgp->sg_phdr.p_type != PT_NULL) &&
542d1827f25Srie (sgp->sg_phdr.p_type != PT_LOAD)) {
543d1827f25Srie const char *fmt;
5447c478bd9Sstevel@tonic-gate
5457c478bd9Sstevel@tonic-gate if (sgp->sg_phdr.p_type == PT_SUNWSTACK)
5467c478bd9Sstevel@tonic-gate fmt = MSG_INTL(MSG_MAP_NOSTACK1);
5477c478bd9Sstevel@tonic-gate else
5487c478bd9Sstevel@tonic-gate fmt = MSG_INTL(MSG_MAP_NONLOAD);
5497c478bd9Sstevel@tonic-gate
55069112eddSAli Bahrami if ((sgp->sg_flags & FLG_SG_P_FLAGS) &&
5517c478bd9Sstevel@tonic-gate (sgp->sg_phdr.p_type != PT_SUNWSTACK)) {
5527c478bd9Sstevel@tonic-gate if (sgp->sg_phdr.p_flags != 0) {
55369112eddSAli Bahrami mf_warn(mf, MSG_INTL(MSG_MAP_NONLOAD),
5547c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGFLAG));
5557c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_flags = 0;
5567c478bd9Sstevel@tonic-gate }
5577c478bd9Sstevel@tonic-gate }
5587c478bd9Sstevel@tonic-gate if (sgp->sg_flags & FLG_SG_LENGTH)
5597c478bd9Sstevel@tonic-gate if (sgp->sg_length != 0) {
56069112eddSAli Bahrami mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGLEN));
5617c478bd9Sstevel@tonic-gate sgp->sg_length = 0;
5627c478bd9Sstevel@tonic-gate }
5637c478bd9Sstevel@tonic-gate if (sgp->sg_flags & FLG_SG_ROUND)
5647c478bd9Sstevel@tonic-gate if (sgp->sg_round != 0) {
56569112eddSAli Bahrami mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGROUND));
5667c478bd9Sstevel@tonic-gate sgp->sg_round = 0;
5677c478bd9Sstevel@tonic-gate }
56869112eddSAli Bahrami if (sgp->sg_flags & FLG_SG_P_VADDR) {
5697c478bd9Sstevel@tonic-gate if (sgp->sg_phdr.p_vaddr != 0) {
57069112eddSAli Bahrami mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGVADDR));
5717c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_vaddr = 0;
5727c478bd9Sstevel@tonic-gate }
5737c478bd9Sstevel@tonic-gate }
57469112eddSAli Bahrami if (sgp->sg_flags & FLG_SG_P_PADDR)
5757c478bd9Sstevel@tonic-gate if (sgp->sg_phdr.p_paddr != 0) {
57669112eddSAli Bahrami mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGPHYS));
5777c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_paddr = 0;
5787c478bd9Sstevel@tonic-gate }
57969112eddSAli Bahrami if (sgp->sg_flags & FLG_SG_P_ALIGN)
5807c478bd9Sstevel@tonic-gate if (sgp->sg_phdr.p_align != 0) {
58169112eddSAli Bahrami mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGALIGN));
5827c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_align = 0;
5837c478bd9Sstevel@tonic-gate }
5847c478bd9Sstevel@tonic-gate }
58569112eddSAli Bahrami return (TRUE);
5867c478bd9Sstevel@tonic-gate }
5877c478bd9Sstevel@tonic-gate
5887c478bd9Sstevel@tonic-gate
5897c478bd9Sstevel@tonic-gate /*
5907c478bd9Sstevel@tonic-gate * Process a mapfile mapping directives definition.
59169112eddSAli Bahrami *
5928222814eSRichard Lowe * segment_name : section_attribute [ : file_name ]
59369112eddSAli Bahrami *
59469112eddSAli Bahrami * Where segment_attribute is one of: section_name section_type section_flags;
5957c478bd9Sstevel@tonic-gate */
59669112eddSAli Bahrami static Boolean
map_colon(Mapfile * mf,Ent_desc * enp)59769112eddSAli Bahrami map_colon(Mapfile *mf, Ent_desc *enp)
5987c478bd9Sstevel@tonic-gate {
59969112eddSAli Bahrami Token tok;
60069112eddSAli Bahrami ld_map_tkval_t tkv;
6017c478bd9Sstevel@tonic-gate Boolean b_name = FALSE;
6027c478bd9Sstevel@tonic-gate Boolean b_type = FALSE;
6037c478bd9Sstevel@tonic-gate Boolean b_attr = FALSE;
6047c478bd9Sstevel@tonic-gate Boolean b_bang = FALSE;
6057c478bd9Sstevel@tonic-gate
6067c478bd9Sstevel@tonic-gate
60769112eddSAli Bahrami /*
60869112eddSAli Bahrami * Start out assuming that this entrance criteria will be empty,
60969112eddSAli Bahrami * and therefore match anything. We clear the CATCHALL flag below
61069112eddSAli Bahrami * if this turns out not to be the case.
61169112eddSAli Bahrami */
61269112eddSAli Bahrami enp->ec_flags |= FLG_EC_CATCHALL;
61369112eddSAli Bahrami
61469112eddSAli Bahrami while (((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_COLON) &&
6155aefb655Srie (tok != TK_SEMICOLON)) {
61669112eddSAli Bahrami if (tok == TK_ERROR)
61769112eddSAli Bahrami return (FALSE);
61869112eddSAli Bahrami if (tok != TK_STRING) {
61969112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_MALFORM));
62069112eddSAli Bahrami return (FALSE);
62169112eddSAli Bahrami }
6227c478bd9Sstevel@tonic-gate
6237c478bd9Sstevel@tonic-gate /* Segment type. */
6247c478bd9Sstevel@tonic-gate
62569112eddSAli Bahrami if (*tkv.tkv_str == '$') {
6267c478bd9Sstevel@tonic-gate if (b_type) {
62769112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE),
6287c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SECTYP));
62969112eddSAli Bahrami return (FALSE);
6307c478bd9Sstevel@tonic-gate }
6317c478bd9Sstevel@tonic-gate b_type = TRUE;
63269112eddSAli Bahrami tkv.tkv_str++;
63369112eddSAli Bahrami ld_map_lowercase(tkv.tkv_str);
63469112eddSAli Bahrami if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_PROGBITS)) ==
63569112eddSAli Bahrami 0)
6367c478bd9Sstevel@tonic-gate enp->ec_type = SHT_PROGBITS;
63769112eddSAli Bahrami else if (strcmp(tkv.tkv_str,
6387c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_SYMTAB)) == 0)
6397c478bd9Sstevel@tonic-gate enp->ec_type = SHT_SYMTAB;
64069112eddSAli Bahrami else if (strcmp(tkv.tkv_str,
6417c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_DYNSYM)) == 0)
6427c478bd9Sstevel@tonic-gate enp->ec_type = SHT_DYNSYM;
64369112eddSAli Bahrami else if (strcmp(tkv.tkv_str,
6447c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_STRTAB)) == 0)
6457c478bd9Sstevel@tonic-gate enp->ec_type = SHT_STRTAB;
64669112eddSAli Bahrami else if ((strcmp(tkv.tkv_str,
6477c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_REL)) == 0) ||
64869112eddSAli Bahrami (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_RELA)) == 0))
649ba2be530Sab enp->ec_type = ld_targ.t_m.m_rel_sht_type;
65069112eddSAli Bahrami else if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_HASH)) ==
65169112eddSAli Bahrami 0)
6527c478bd9Sstevel@tonic-gate enp->ec_type = SHT_HASH;
65369112eddSAli Bahrami else if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_LIB)) ==
65469112eddSAli Bahrami 0)
6557c478bd9Sstevel@tonic-gate enp->ec_type = SHT_SHLIB;
65669112eddSAli Bahrami else if (strcmp(tkv.tkv_str,
6577c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_LD_DYNAMIC)) == 0)
6587c478bd9Sstevel@tonic-gate enp->ec_type = SHT_DYNAMIC;
65969112eddSAli Bahrami else if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_NOTE)) ==
66069112eddSAli Bahrami 0)
6617c478bd9Sstevel@tonic-gate enp->ec_type = SHT_NOTE;
66269112eddSAli Bahrami else if (strcmp(tkv.tkv_str,
6637c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_NOBITS)) == 0)
6647c478bd9Sstevel@tonic-gate enp->ec_type = SHT_NOBITS;
6657c478bd9Sstevel@tonic-gate else {
66669112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSECTYP),
66769112eddSAli Bahrami tkv.tkv_str);
66869112eddSAli Bahrami return (FALSE);
6697c478bd9Sstevel@tonic-gate }
6707c478bd9Sstevel@tonic-gate
67169112eddSAli Bahrami enp->ec_flags &= ~FLG_EC_CATCHALL;
67269112eddSAli Bahrami
6737c478bd9Sstevel@tonic-gate /*
6747c478bd9Sstevel@tonic-gate * Segment flags.
6757c478bd9Sstevel@tonic-gate * If a segment flag is specified then the appropriate bit is
6767c478bd9Sstevel@tonic-gate * set in the ec_attrmask, the ec_attrbits fields determine
6777c478bd9Sstevel@tonic-gate * whether the attrmask fields must be tested true or false
6787c478bd9Sstevel@tonic-gate * ie. for ?A the attrmask is set and the attrbit is set,
6797c478bd9Sstevel@tonic-gate * for ?!A the attrmask is set and the attrbit is clear.
6807c478bd9Sstevel@tonic-gate */
68169112eddSAli Bahrami } else if (*tkv.tkv_str == '?') {
6827c478bd9Sstevel@tonic-gate if (b_attr) {
68369112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE),
6847c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SECFLAG));
68569112eddSAli Bahrami return (FALSE);
6867c478bd9Sstevel@tonic-gate }
6877c478bd9Sstevel@tonic-gate b_attr = TRUE;
6887c478bd9Sstevel@tonic-gate b_bang = FALSE;
68969112eddSAli Bahrami tkv.tkv_str++;
69069112eddSAli Bahrami ld_map_lowercase(tkv.tkv_str);
69169112eddSAli Bahrami for (; *tkv.tkv_str != '\0'; tkv.tkv_str++)
69269112eddSAli Bahrami switch (*tkv.tkv_str) {
6937c478bd9Sstevel@tonic-gate case '!':
6947c478bd9Sstevel@tonic-gate if (b_bang) {
69569112eddSAli Bahrami mf_fatal(mf,
6967c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_BADFLAG),
69769112eddSAli Bahrami tkv.tkv_str);
69869112eddSAli Bahrami return (FALSE);
6997c478bd9Sstevel@tonic-gate }
7007c478bd9Sstevel@tonic-gate b_bang = TRUE;
7017c478bd9Sstevel@tonic-gate break;
7027c478bd9Sstevel@tonic-gate case 'a':
7037c478bd9Sstevel@tonic-gate if (enp->ec_attrmask & SHF_ALLOC) {
70469112eddSAli Bahrami mf_fatal(mf,
7057c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_BADFLAG),
70669112eddSAli Bahrami tkv.tkv_str);
70769112eddSAli Bahrami return (FALSE);
7087c478bd9Sstevel@tonic-gate }
7097c478bd9Sstevel@tonic-gate enp->ec_attrmask |= SHF_ALLOC;
7107c478bd9Sstevel@tonic-gate if (!b_bang)
7117c478bd9Sstevel@tonic-gate enp->ec_attrbits |= SHF_ALLOC;
7127c478bd9Sstevel@tonic-gate b_bang = FALSE;
7137c478bd9Sstevel@tonic-gate break;
7147c478bd9Sstevel@tonic-gate case 'w':
7157c478bd9Sstevel@tonic-gate if (enp->ec_attrmask & SHF_WRITE) {
71669112eddSAli Bahrami mf_fatal(mf,
7177c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_BADFLAG),
71869112eddSAli Bahrami tkv.tkv_str);
71969112eddSAli Bahrami return (FALSE);
7207c478bd9Sstevel@tonic-gate }
7217c478bd9Sstevel@tonic-gate enp->ec_attrmask |= SHF_WRITE;
7227c478bd9Sstevel@tonic-gate if (!b_bang)
7237c478bd9Sstevel@tonic-gate enp->ec_attrbits |= SHF_WRITE;
7247c478bd9Sstevel@tonic-gate b_bang = FALSE;
7257c478bd9Sstevel@tonic-gate break;
7267c478bd9Sstevel@tonic-gate case 'x':
7277c478bd9Sstevel@tonic-gate if (enp->ec_attrmask & SHF_EXECINSTR) {
72869112eddSAli Bahrami mf_fatal(mf,
7297c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_BADFLAG),
73069112eddSAli Bahrami tkv.tkv_str);
73169112eddSAli Bahrami return (FALSE);
7327c478bd9Sstevel@tonic-gate }
7337c478bd9Sstevel@tonic-gate enp->ec_attrmask |= SHF_EXECINSTR;
7347c478bd9Sstevel@tonic-gate if (!b_bang)
735a953e2b1Srie enp->ec_attrbits |=
736a953e2b1Srie SHF_EXECINSTR;
7377c478bd9Sstevel@tonic-gate b_bang = FALSE;
7387c478bd9Sstevel@tonic-gate break;
7397c478bd9Sstevel@tonic-gate default:
74069112eddSAli Bahrami mf_fatal(mf,
7417c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_BADFLAG),
74269112eddSAli Bahrami tkv.tkv_str);
74369112eddSAli Bahrami return (FALSE);
7447c478bd9Sstevel@tonic-gate }
74569112eddSAli Bahrami if (enp->ec_attrmask != 0)
74669112eddSAli Bahrami enp->ec_flags &= ~FLG_EC_CATCHALL;
74769112eddSAli Bahrami
7487c478bd9Sstevel@tonic-gate /*
7497c478bd9Sstevel@tonic-gate * Section name.
7507c478bd9Sstevel@tonic-gate */
7517c478bd9Sstevel@tonic-gate } else {
7527c478bd9Sstevel@tonic-gate if (b_name) {
75369112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE),
7547c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SECNAME));
75569112eddSAli Bahrami return (FALSE);
7567c478bd9Sstevel@tonic-gate }
7577c478bd9Sstevel@tonic-gate b_name = TRUE;
75869112eddSAli Bahrami enp->ec_is_name = tkv.tkv_str;
75969112eddSAli Bahrami enp->ec_flags &= ~FLG_EC_CATCHALL;
7607c478bd9Sstevel@tonic-gate }
7617c478bd9Sstevel@tonic-gate }
7627c478bd9Sstevel@tonic-gate if (tok == TK_COLON) {
7637c478bd9Sstevel@tonic-gate /*
7647c478bd9Sstevel@tonic-gate * File names.
7657c478bd9Sstevel@tonic-gate */
76669112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_SEMICOLON) {
76769112eddSAli Bahrami Word ecf_type;
7687c478bd9Sstevel@tonic-gate
7697c478bd9Sstevel@tonic-gate if (tok != TK_STRING) {
77071ae4d73Sab if (tok != TK_ERROR)
77169112eddSAli Bahrami mf_fatal0(mf,
77269112eddSAli Bahrami MSG_INTL(MSG_MAP_MALFORM));
77369112eddSAli Bahrami return (FALSE);
77469112eddSAli Bahrami }
77569112eddSAli Bahrami
77669112eddSAli Bahrami /*
77769112eddSAli Bahrami * A leading '*' means that this should be a basename
77869112eddSAli Bahrami * comparison rather than a full path. It's not a glob
77969112eddSAli Bahrami * wildcard, although it looks like one.
78069112eddSAli Bahrami */
78169112eddSAli Bahrami if (tkv.tkv_str[0] == '*') {
78269112eddSAli Bahrami ecf_type = TYP_ECF_BASENAME;
78369112eddSAli Bahrami tkv.tkv_str++;
78469112eddSAli Bahrami } else {
78569112eddSAli Bahrami ecf_type = TYP_ECF_PATH;
7867c478bd9Sstevel@tonic-gate }
78769112eddSAli Bahrami if (!ld_map_seg_ent_files(mf, enp, ecf_type,
78869112eddSAli Bahrami tkv.tkv_str))
78969112eddSAli Bahrami return (FALSE);
79069112eddSAli Bahrami enp->ec_flags &= ~FLG_EC_CATCHALL;
7917c478bd9Sstevel@tonic-gate }
7927c478bd9Sstevel@tonic-gate }
79369112eddSAli Bahrami return (TRUE);
7947c478bd9Sstevel@tonic-gate }
7957c478bd9Sstevel@tonic-gate
7967c478bd9Sstevel@tonic-gate /*
7977c478bd9Sstevel@tonic-gate * Process a mapfile size symbol definition.
7988222814eSRichard Lowe * segment_name @ symbol_name;
7997c478bd9Sstevel@tonic-gate */
80069112eddSAli Bahrami static Boolean
map_atsign(Mapfile * mf,Sg_desc * sgp)80169112eddSAli Bahrami map_atsign(Mapfile *mf, Sg_desc *sgp)
8027c478bd9Sstevel@tonic-gate {
8037c478bd9Sstevel@tonic-gate Token tok; /* Current token. */
80469112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */
8057c478bd9Sstevel@tonic-gate
80669112eddSAli Bahrami if ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_STRING) {
80771ae4d73Sab if (tok != TK_ERROR)
80869112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSYM_1));
80969112eddSAli Bahrami return (FALSE);
8107c478bd9Sstevel@tonic-gate }
8117c478bd9Sstevel@tonic-gate
81269112eddSAli Bahrami /* Add the symbol to the segment */
81369112eddSAli Bahrami if (!ld_map_seg_size_symbol(mf, sgp, TK_PLUSEQ, tkv.tkv_str))
81469112eddSAli Bahrami return (FALSE);
8157c478bd9Sstevel@tonic-gate
8167c478bd9Sstevel@tonic-gate
81769112eddSAli Bahrami if (ld_map_gettoken(mf, 0, &tkv) != TK_SEMICOLON) {
81871ae4d73Sab if (tok != TK_ERROR)
81969112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSCOL));
82069112eddSAli Bahrami return (FALSE);
82171ae4d73Sab }
82271ae4d73Sab
82369112eddSAli Bahrami return (TRUE);
8247c478bd9Sstevel@tonic-gate }
8257c478bd9Sstevel@tonic-gate
8267c478bd9Sstevel@tonic-gate
82769112eddSAli Bahrami static Boolean
map_pipe(Mapfile * mf,Sg_desc * sgp)82869112eddSAli Bahrami map_pipe(Mapfile *mf, Sg_desc *sgp)
8297c478bd9Sstevel@tonic-gate {
8307c478bd9Sstevel@tonic-gate Token tok; /* current token. */
83169112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */
8327c478bd9Sstevel@tonic-gate
83369112eddSAli Bahrami if ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_STRING) {
83471ae4d73Sab if (tok != TK_ERROR)
83569112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEC));
83669112eddSAli Bahrami return (FALSE);
8377c478bd9Sstevel@tonic-gate }
8387c478bd9Sstevel@tonic-gate
83969112eddSAli Bahrami if (!ld_map_seg_os_order_add(mf, sgp, tkv.tkv_str))
84069112eddSAli Bahrami return (FALSE);
8417c478bd9Sstevel@tonic-gate
84269112eddSAli Bahrami if ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_SEMICOLON) {
84371ae4d73Sab if (tok != TK_ERROR)
84469112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSCOL));
84569112eddSAli Bahrami return (FALSE);
8467c478bd9Sstevel@tonic-gate }
8477c478bd9Sstevel@tonic-gate
84869112eddSAli Bahrami return (TRUE);
8497c478bd9Sstevel@tonic-gate }
8507c478bd9Sstevel@tonic-gate
8517c478bd9Sstevel@tonic-gate /*
8527c478bd9Sstevel@tonic-gate * Process a mapfile library specification definition.
8538222814eSRichard Lowe * shared_object_name - shared object definition
8547c478bd9Sstevel@tonic-gate * shared object definition : [ shared object type [ = SONAME ]]
8557c478bd9Sstevel@tonic-gate * [ versions ];
8567c478bd9Sstevel@tonic-gate */
85769112eddSAli Bahrami static Boolean
map_dash(Mapfile * mf,char * name)85869112eddSAli Bahrami map_dash(Mapfile *mf, char *name)
8597c478bd9Sstevel@tonic-gate {
8607c478bd9Sstevel@tonic-gate Token tok;
8617c478bd9Sstevel@tonic-gate Sdf_desc *sdf;
86269112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */
8637c478bd9Sstevel@tonic-gate enum {
8647c478bd9Sstevel@tonic-gate MD_NONE = 0,
8657c478bd9Sstevel@tonic-gate MD_ADDVERS,
8667c478bd9Sstevel@tonic-gate } dolkey = MD_NONE;
8677c478bd9Sstevel@tonic-gate
86869112eddSAli Bahrami /* Get descriptor for dependency */
86969112eddSAli Bahrami if ((sdf = ld_map_dv(mf, name)) == NULL)
87069112eddSAli Bahrami return (FALSE);
8717c478bd9Sstevel@tonic-gate
8727c478bd9Sstevel@tonic-gate /*
8737c478bd9Sstevel@tonic-gate * Get the shared object descriptor string.
8747c478bd9Sstevel@tonic-gate */
87569112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_SEMICOLON) {
8767c478bd9Sstevel@tonic-gate if ((tok != TK_STRING) && (tok != TK_EQUAL)) {
87771ae4d73Sab if (tok != TK_ERROR)
87869112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSO));
87969112eddSAli Bahrami return (FALSE);
8807c478bd9Sstevel@tonic-gate }
8817c478bd9Sstevel@tonic-gate
8827c478bd9Sstevel@tonic-gate /*
8837c478bd9Sstevel@tonic-gate * Determine if the library type is accompanied with a SONAME
8847c478bd9Sstevel@tonic-gate * definition.
8857c478bd9Sstevel@tonic-gate */
8867c478bd9Sstevel@tonic-gate if (tok == TK_EQUAL) {
88769112eddSAli Bahrami if ((tok = ld_map_gettoken(mf, 0, &tkv)) !=
88869112eddSAli Bahrami TK_STRING) {
88971ae4d73Sab if (tok != TK_ERROR)
89069112eddSAli Bahrami mf_fatal0(mf,
89169112eddSAli Bahrami MSG_INTL(MSG_MAP_EXPSO));
89269112eddSAli Bahrami return (FALSE);
8937c478bd9Sstevel@tonic-gate }
8947c478bd9Sstevel@tonic-gate switch (dolkey) {
8957c478bd9Sstevel@tonic-gate case MD_ADDVERS:
89669112eddSAli Bahrami if (!ld_map_dv_entry(mf, sdf, TRUE,
89769112eddSAli Bahrami tkv.tkv_str))
89869112eddSAli Bahrami return (FALSE);
8997c478bd9Sstevel@tonic-gate break;
9007c478bd9Sstevel@tonic-gate case MD_NONE:
90169112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_UNEXTOK), '=');
90269112eddSAli Bahrami return (FALSE);
9037c478bd9Sstevel@tonic-gate }
9047c478bd9Sstevel@tonic-gate dolkey = MD_NONE;
9057c478bd9Sstevel@tonic-gate continue;
9067c478bd9Sstevel@tonic-gate }
9077c478bd9Sstevel@tonic-gate
9087c478bd9Sstevel@tonic-gate /*
9097c478bd9Sstevel@tonic-gate * A shared object type has been specified. This may also be
9107c478bd9Sstevel@tonic-gate * accompanied by an SONAME redefinition (see above).
9117c478bd9Sstevel@tonic-gate */
91269112eddSAli Bahrami if (*tkv.tkv_str == '$') {
9137c478bd9Sstevel@tonic-gate if (dolkey != MD_NONE) {
91469112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_UNEXTOK), '$');
91569112eddSAli Bahrami return (FALSE);
9167c478bd9Sstevel@tonic-gate }
91769112eddSAli Bahrami tkv.tkv_str++;
91869112eddSAli Bahrami ld_map_lowercase(tkv.tkv_str);
91969112eddSAli Bahrami if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_MAP_ADDVERS)) ==
92069112eddSAli Bahrami 0) {
9217c478bd9Sstevel@tonic-gate dolkey = MD_ADDVERS;
92269112eddSAli Bahrami } else {
92369112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSOTYP),
92469112eddSAli Bahrami tkv.tkv_str);
92569112eddSAli Bahrami return (FALSE);
9267c478bd9Sstevel@tonic-gate }
9277c478bd9Sstevel@tonic-gate continue;
9287c478bd9Sstevel@tonic-gate }
9297c478bd9Sstevel@tonic-gate
9307c478bd9Sstevel@tonic-gate /*
9317c478bd9Sstevel@tonic-gate * shared object version requirement.
9327c478bd9Sstevel@tonic-gate */
93369112eddSAli Bahrami if (!ld_map_dv_entry(mf, sdf, FALSE, tkv.tkv_str))
93469112eddSAli Bahrami return (FALSE);
9357c478bd9Sstevel@tonic-gate }
9367c478bd9Sstevel@tonic-gate
93769112eddSAli Bahrami return (TRUE);
9387c478bd9Sstevel@tonic-gate }
9397c478bd9Sstevel@tonic-gate
9407c478bd9Sstevel@tonic-gate
9417c478bd9Sstevel@tonic-gate /*
942c1c6f601Srie * Process a symbol definition. Historically, this originated from processing
943c1c6f601Srie * a version definition. However, this has evolved into a generic means of
944c1c6f601Srie * defining symbol references and definitions (see Defining Additional Symbols
945c1c6f601Srie * in the Linker and Libraries guide for the complete syntax).
946c1c6f601Srie *
947c1c6f601Srie * [ name ] {
948c1c6f601Srie * scope:
949c1c6f601Srie * symbol [ = [ type ] [ value ] [ size ] [ attribute ] ];
950c1c6f601Srie * } [ dependency ];
951c1c6f601Srie *
9527c478bd9Sstevel@tonic-gate */
95369112eddSAli Bahrami static Boolean
map_version(Mapfile * mf,char * name)95469112eddSAli Bahrami map_version(Mapfile *mf, char *name)
9557c478bd9Sstevel@tonic-gate {
9567c478bd9Sstevel@tonic-gate Token tok;
95769112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */
95869112eddSAli Bahrami ld_map_ver_t mv;
95969112eddSAli Bahrami ld_map_sym_t ms;
96069112eddSAli Bahrami Ofl_desc *ofl = mf->mf_ofl;
9617c478bd9Sstevel@tonic-gate
96269112eddSAli Bahrami /* Establish the version descriptor and related data */
96369112eddSAli Bahrami if (!ld_map_sym_ver_init(mf, name, &mv))
96469112eddSAli Bahrami return (FALSE);
9657c478bd9Sstevel@tonic-gate
9667c478bd9Sstevel@tonic-gate /*
9677c478bd9Sstevel@tonic-gate * Scan the mapfile entry picking out scoping and symbol definitions.
9687c478bd9Sstevel@tonic-gate */
96969112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_RIGHTBKT) {
97069112eddSAli Bahrami uint_t filter = 0;
97169112eddSAli Bahrami
97269112eddSAli Bahrami if (tok != TK_STRING) {
97369112eddSAli Bahrami if (tok == TK_ERROR) {
97469112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSYM_2));
97569112eddSAli Bahrami return (FALSE);
97669112eddSAli Bahrami }
97769112eddSAli Bahrami mv.mv_errcnt++;
97860758829Srie continue;
9797c478bd9Sstevel@tonic-gate }
9807c478bd9Sstevel@tonic-gate
98169112eddSAli Bahrami /* The default value for all the symbol attributes is 0 */
98269112eddSAli Bahrami (void) memset(&ms, 0, sizeof (ms));
98369112eddSAli Bahrami ms.ms_name = tkv.tkv_str;
9847c478bd9Sstevel@tonic-gate
98569112eddSAli Bahrami tok = ld_map_gettoken(mf, 0, &tkv);
98669112eddSAli Bahrami if (tok == TK_ERROR) {
98769112eddSAli Bahrami mv.mv_errcnt++;
98869112eddSAli Bahrami continue;
98960758829Srie }
9907c478bd9Sstevel@tonic-gate
9917c478bd9Sstevel@tonic-gate /*
9927c478bd9Sstevel@tonic-gate * Turn off the WEAK flag to indicate that definitions are
9937c478bd9Sstevel@tonic-gate * associated with this version. It would probably be more
9947c478bd9Sstevel@tonic-gate * accurate to only remove this flag with the specification of
9957c478bd9Sstevel@tonic-gate * global symbols, however setting it here allows enough slop
9967c478bd9Sstevel@tonic-gate * to compensate for the various user inputs we've seen so far.
9977c478bd9Sstevel@tonic-gate * Only if a closed version is specified (i.e., "SUNW_1.x {};")
9987c478bd9Sstevel@tonic-gate * will a user get a weak version (which is how we document the
9997c478bd9Sstevel@tonic-gate * creation of weak versions).
10007c478bd9Sstevel@tonic-gate */
100169112eddSAli Bahrami mv.mv_vdp->vd_flags &= ~VER_FLG_WEAK;
10027c478bd9Sstevel@tonic-gate
10037c478bd9Sstevel@tonic-gate switch (tok) {
10047c478bd9Sstevel@tonic-gate case TK_COLON:
100569112eddSAli Bahrami ld_map_sym_scope(mf, ms.ms_name, &mv);
10067c478bd9Sstevel@tonic-gate continue;
10077c478bd9Sstevel@tonic-gate
10087c478bd9Sstevel@tonic-gate case TK_EQUAL:
10097c478bd9Sstevel@tonic-gate /*
10107c478bd9Sstevel@tonic-gate * A full blown symbol definition follows.
10117c478bd9Sstevel@tonic-gate * Determine the symbol type and any virtual address or
10127c478bd9Sstevel@tonic-gate * alignment specified and then fall through to process
10137c478bd9Sstevel@tonic-gate * the entire symbols information.
10147c478bd9Sstevel@tonic-gate */
101569112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, 0, &tkv)) !=
101671ae4d73Sab TK_SEMICOLON) {
101769112eddSAli Bahrami if (tok == TK_ERROR)
101869112eddSAli Bahrami return (FALSE);
101969112eddSAli Bahrami if (tok != TK_STRING) {
102069112eddSAli Bahrami mf_fatal0(mf,
102169112eddSAli Bahrami MSG_INTL(MSG_MAP_MALFORM));
102269112eddSAli Bahrami return (FALSE);
102369112eddSAli Bahrami }
102469112eddSAli Bahrami
10257c478bd9Sstevel@tonic-gate /*
102669112eddSAli Bahrami * If we had previously seen AUX or FILTER,
102769112eddSAli Bahrami * the next string is the filtee itself.
102869112eddSAli Bahrami * Add it, and clear the filter flag.
10297c478bd9Sstevel@tonic-gate */
10307c478bd9Sstevel@tonic-gate if (filter) {
103169112eddSAli Bahrami ld_map_sym_filtee(mf, &mv, &ms,
103269112eddSAli Bahrami filter, tkv.tkv_str);
10337c478bd9Sstevel@tonic-gate filter = 0;
10347c478bd9Sstevel@tonic-gate continue;
10357c478bd9Sstevel@tonic-gate }
10367c478bd9Sstevel@tonic-gate
10377c478bd9Sstevel@tonic-gate /*
10387c478bd9Sstevel@tonic-gate * Determine any Value or Size attributes.
10397c478bd9Sstevel@tonic-gate */
104069112eddSAli Bahrami ld_map_lowercase(tkv.tkv_str);
10417c478bd9Sstevel@tonic-gate
104269112eddSAli Bahrami if (tkv.tkv_str[0] == 'v' ||
104369112eddSAli Bahrami tkv.tkv_str[0] == 's') {
104469112eddSAli Bahrami Xword number;
104569112eddSAli Bahrami
104669112eddSAli Bahrami if (!valuetoxword(mf, &tkv, &number)) {
104769112eddSAli Bahrami mv.mv_errcnt++;
104869112eddSAli Bahrami return (FALSE);
10497c478bd9Sstevel@tonic-gate }
10507c478bd9Sstevel@tonic-gate
105169112eddSAli Bahrami switch (*tkv.tkv_str) {
10527c478bd9Sstevel@tonic-gate case 'v':
1053a953e2b1Srie /* BEGIN CSTYLED */
105469112eddSAli Bahrami if (ms.ms_value) {
105569112eddSAli Bahrami mf_fatal(mf,
10567c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_MOREONCE),
10577c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SYMVAL));
105869112eddSAli Bahrami mv.mv_errcnt++;
105960758829Srie continue;
10607c478bd9Sstevel@tonic-gate }
10617c478bd9Sstevel@tonic-gate /* LINTED */
106269112eddSAli Bahrami ms.ms_value = (Addr)number;
106369112eddSAli Bahrami ms.ms_value_set = TRUE;
10647c478bd9Sstevel@tonic-gate break;
1065a953e2b1Srie /* END CSTYLED */
10667c478bd9Sstevel@tonic-gate case 's':
1067a953e2b1Srie /* BEGIN CSTYLED */
106869112eddSAli Bahrami if (ms.ms_size) {
106969112eddSAli Bahrami mf_fatal(mf,
10707c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_MOREONCE),
10717c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SYMSIZE));
107269112eddSAli Bahrami mv.mv_errcnt++;
107360758829Srie continue;
10747c478bd9Sstevel@tonic-gate }
10757c478bd9Sstevel@tonic-gate /* LINTED */
107669112eddSAli Bahrami ms.ms_size = (Addr)number;
10778222814eSRichard Lowe ms.ms_size_set = TRUE;
10787c478bd9Sstevel@tonic-gate break;
1079a953e2b1Srie /* END CSTYLED */
10807c478bd9Sstevel@tonic-gate }
10817c478bd9Sstevel@tonic-gate
108269112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
10837c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_FUNCTION)) == 0) {
108469112eddSAli Bahrami ms.ms_shndx = SHN_ABS;
108569112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_SPECSEC;
108669112eddSAli Bahrami ms.ms_type = STT_FUNC;
108769112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
10887c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_DATA)) == 0) {
108969112eddSAli Bahrami ms.ms_shndx = SHN_ABS;
109069112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_SPECSEC;
109169112eddSAli Bahrami ms.ms_type = STT_OBJECT;
109269112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
10937c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_COMMON)) == 0) {
109469112eddSAli Bahrami ms.ms_shndx = SHN_COMMON;
109569112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_SPECSEC;
109669112eddSAli Bahrami ms.ms_type = STT_OBJECT;
109769112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
10987c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_PARENT)) == 0) {
109969112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_PARENT;
11007c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_SYMINFO;
110169112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
11027c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_EXTERN)) == 0) {
110369112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_EXTERN;
11047c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_SYMINFO;
110569112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
11067c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_DIRECT)) == 0) {
110769112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_DIR;
11087c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_SYMINFO;
110969112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
11107c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_NODIRECT)) == 0) {
111169112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_NDIR;
11127c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_SYMINFO;
111328bda19cSRod Evans ofl->ofl_flags1 |=
111428bda19cSRod Evans (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR);
111569112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
11167c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_FILTER)) == 0) {
111769112eddSAli Bahrami /* Next token is the filtee */
111869112eddSAli Bahrami filter = FLG_SY_STDFLTR;
111969112eddSAli Bahrami continue;
112069112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
112169112eddSAli Bahrami MSG_ORIG(MSG_MAP_AUXILIARY)) == 0) {
112269112eddSAli Bahrami /* Next token is the filtee */
112369112eddSAli Bahrami filter = FLG_SY_AUXFLTR;
112469112eddSAli Bahrami continue;
112569112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
112669112eddSAli Bahrami MSG_ORIG(MSG_MAP_INTERPOSE)) == 0) {
1127604635faSRod Evans /* BEGIN CSTYLED */
11289a411307Srie if (!(ofl->ofl_flags & FLG_OF_EXEC)) {
112969112eddSAli Bahrami mf_fatal0(mf,
113069112eddSAli Bahrami MSG_INTL(MSG_MAP_NOINTPOSE));
113169112eddSAli Bahrami mv.mv_errcnt++;
1132604635faSRod Evans break;
11339a411307Srie }
1134604635faSRod Evans /* END CSTYLED */
113569112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_INTPOSE;
11369a411307Srie ofl->ofl_flags |= FLG_OF_SYMINFO;
11379a411307Srie ofl->ofl_dtflags_1 |= DF_1_SYMINTPOSE;
11389a411307Srie continue;
113969112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
1140d579eb63Sab MSG_ORIG(MSG_MAP_DYNSORT)) == 0) {
114169112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_DYNSORT;
114269112eddSAli Bahrami ms.ms_sdflags &= ~FLG_SY_NODYNSORT;
1143d579eb63Sab continue;
114469112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
1145d579eb63Sab MSG_ORIG(MSG_MAP_NODYNSORT)) == 0) {
114669112eddSAli Bahrami ms.ms_sdflags &= ~FLG_SY_DYNSORT;
114769112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_NODYNSORT;
1148d579eb63Sab continue;
11497c478bd9Sstevel@tonic-gate } else {
115069112eddSAli Bahrami mf_fatal(mf,
11517c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_UNKSYMDEF),
115269112eddSAli Bahrami tkv.tkv_str);
115369112eddSAli Bahrami mv.mv_errcnt++;
115460758829Srie continue;
11557c478bd9Sstevel@tonic-gate }
11567c478bd9Sstevel@tonic-gate }
11577c478bd9Sstevel@tonic-gate /* FALLTHROUGH */
11587c478bd9Sstevel@tonic-gate
11597c478bd9Sstevel@tonic-gate case TK_SEMICOLON:
116069112eddSAli Bahrami /* Auto-reduction directive ('*')? */
116169112eddSAli Bahrami if (*ms.ms_name == '*') {
116269112eddSAli Bahrami ld_map_sym_autoreduce(mf, &mv);
116369112eddSAli Bahrami continue;
116469112eddSAli Bahrami }
116569112eddSAli Bahrami
11667c478bd9Sstevel@tonic-gate /*
116769112eddSAli Bahrami * Catch the error where the AUX or FILTER keyword
116869112eddSAli Bahrami * was used, but the filtee wasn't supplied.
11697c478bd9Sstevel@tonic-gate */
117069112eddSAli Bahrami if (filter && (ms.ms_filtee == NULL)) {
117169112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_NOFILTER),
117269112eddSAli Bahrami ms.ms_name);
117369112eddSAli Bahrami mv.mv_errcnt++;
11747c478bd9Sstevel@tonic-gate continue;
11757c478bd9Sstevel@tonic-gate }
11767c478bd9Sstevel@tonic-gate
11777c478bd9Sstevel@tonic-gate /*
11787c478bd9Sstevel@tonic-gate * Add the new symbol. It should be noted that all
11797c478bd9Sstevel@tonic-gate * symbols added by the mapfile start out with global
11807c478bd9Sstevel@tonic-gate * scope, thus they will fall through the normal symbol
11817c478bd9Sstevel@tonic-gate * resolution process. Symbols defined as locals will
11827c478bd9Sstevel@tonic-gate * be reduced in scope after all input file processing.
11837c478bd9Sstevel@tonic-gate */
11848222814eSRichard Lowe if (!ld_map_sym_enter(mf, &mv, &ms, NULL))
118569112eddSAli Bahrami return (FALSE);
11867c478bd9Sstevel@tonic-gate break;
11877c478bd9Sstevel@tonic-gate
11887c478bd9Sstevel@tonic-gate default:
118969112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSCOL));
119069112eddSAli Bahrami mv.mv_errcnt++;
119160758829Srie continue;
11927c478bd9Sstevel@tonic-gate }
11937c478bd9Sstevel@tonic-gate }
11947c478bd9Sstevel@tonic-gate
119569112eddSAli Bahrami if (mv.mv_errcnt)
119669112eddSAli Bahrami return (FALSE);
119760758829Srie
11987c478bd9Sstevel@tonic-gate /*
11997c478bd9Sstevel@tonic-gate * Determine if any version references are provided after the close
120069112eddSAli Bahrami * bracket, parsing up to the terminating ';'.
12017c478bd9Sstevel@tonic-gate */
120269112eddSAli Bahrami if (!ld_map_sym_ver_fini(mf, &mv))
120369112eddSAli Bahrami return (FALSE);
120457ef7aa9SRod Evans
120569112eddSAli Bahrami return (TRUE);
12067c478bd9Sstevel@tonic-gate }
12077c478bd9Sstevel@tonic-gate
12087c478bd9Sstevel@tonic-gate /*
120969112eddSAli Bahrami * Parse the mapfile --- Sysv syntax
12107c478bd9Sstevel@tonic-gate */
121169112eddSAli Bahrami Boolean
ld_map_parse_v1(Mapfile * mf)121269112eddSAli Bahrami ld_map_parse_v1(Mapfile *mf)
12137c478bd9Sstevel@tonic-gate {
12147c478bd9Sstevel@tonic-gate Sg_desc *sgp1; /* seg descriptor being manipulated */
121569112eddSAli Bahrami Ent_desc *enp; /* segment entrance criteria. */
12167c478bd9Sstevel@tonic-gate Token tok; /* current token. */
121769112eddSAli Bahrami Boolean new_segment; /* If true, defines new segment */
12187c478bd9Sstevel@tonic-gate char *name;
121969112eddSAli Bahrami Ofl_desc *ofl = mf->mf_ofl;
122069112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */
12218222814eSRichard Lowe avl_index_t where;
12227c478bd9Sstevel@tonic-gate
12237c478bd9Sstevel@tonic-gate /*
12247c478bd9Sstevel@tonic-gate * We now parse the mapfile until the gettoken routine returns EOF.
12257c478bd9Sstevel@tonic-gate */
122669112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, TK_F_EOFOK, &tkv)) != TK_EOF) {
122769112eddSAli Bahrami Xword ndx;
12287c478bd9Sstevel@tonic-gate
12297c478bd9Sstevel@tonic-gate /*
12307c478bd9Sstevel@tonic-gate * At this point we are at the beginning of a line, and the
123169112eddSAli Bahrami * variable tkv.tkv_str points to the first string on the line.
12327c478bd9Sstevel@tonic-gate * All mapfile entries start with some string token except it
12337c478bd9Sstevel@tonic-gate * is possible for a scoping definition to start with `{'.
12347c478bd9Sstevel@tonic-gate */
12357c478bd9Sstevel@tonic-gate if (tok == TK_LEFTBKT) {
123669112eddSAli Bahrami if (!map_version(mf, NULL))
123769112eddSAli Bahrami return (FALSE);
12387c478bd9Sstevel@tonic-gate continue;
12397c478bd9Sstevel@tonic-gate }
12407c478bd9Sstevel@tonic-gate if (tok != TK_STRING) {
124171ae4d73Sab if (tok != TK_ERROR)
124269112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGNAM));
124369112eddSAli Bahrami return (FALSE);
12447c478bd9Sstevel@tonic-gate }
12457c478bd9Sstevel@tonic-gate
12467c478bd9Sstevel@tonic-gate /*
12477c478bd9Sstevel@tonic-gate * Save the initial token.
12487c478bd9Sstevel@tonic-gate */
124969112eddSAli Bahrami name = tkv.tkv_str;
12507c478bd9Sstevel@tonic-gate
12517c478bd9Sstevel@tonic-gate /*
12527c478bd9Sstevel@tonic-gate * Now check the second character on the line. The special `-'
12537c478bd9Sstevel@tonic-gate * and `{' characters do not involve any segment manipulation so
12547c478bd9Sstevel@tonic-gate * we handle them first.
12557c478bd9Sstevel@tonic-gate */
125669112eddSAli Bahrami tok = ld_map_gettoken(mf, 0, &tkv);
125769112eddSAli Bahrami if (tok == TK_ERROR)
125869112eddSAli Bahrami return (FALSE);
125971ae4d73Sab if (tok == TK_DASH) {
126069112eddSAli Bahrami if (!map_dash(mf, name))
126169112eddSAli Bahrami return (FALSE);
12627c478bd9Sstevel@tonic-gate continue;
12637c478bd9Sstevel@tonic-gate }
12647c478bd9Sstevel@tonic-gate if (tok == TK_LEFTBKT) {
126569112eddSAli Bahrami if (!map_version(mf, name))
126669112eddSAli Bahrami return (FALSE);
12677c478bd9Sstevel@tonic-gate continue;
12687c478bd9Sstevel@tonic-gate }
12697c478bd9Sstevel@tonic-gate
12707c478bd9Sstevel@tonic-gate /*
12717c478bd9Sstevel@tonic-gate * If we're here we need to interpret the first string as a
127269112eddSAli Bahrami * segment name. Is this an already known segment?
12737c478bd9Sstevel@tonic-gate */
127469112eddSAli Bahrami sgp1 = ld_seg_lookup(mf->mf_ofl, name, &where);
127569112eddSAli Bahrami new_segment = sgp1 == NULL;
127669112eddSAli Bahrami if (!new_segment)
127769112eddSAli Bahrami sgp1->sg_flags &= ~FLG_SG_DISABLED;
12787c478bd9Sstevel@tonic-gate
12797c478bd9Sstevel@tonic-gate /*
1280635216b6SRod Evans * If the second token is a '|' then we had better have found a
1281635216b6SRod Evans * segment. It is illegal to perform section within segment
1282635216b6SRod Evans * ordering before the segment has been declared.
12837c478bd9Sstevel@tonic-gate */
12847c478bd9Sstevel@tonic-gate if (tok == TK_PIPE) {
12857c478bd9Sstevel@tonic-gate if (sgp1 == NULL) {
128669112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_SECINSEG),
128769112eddSAli Bahrami name);
128869112eddSAli Bahrami return (FALSE);
12897c478bd9Sstevel@tonic-gate }
129069112eddSAli Bahrami if (!map_pipe(mf, sgp1))
129169112eddSAli Bahrami return (FALSE);
129269112eddSAli Bahrami continue;
12937c478bd9Sstevel@tonic-gate }
12947c478bd9Sstevel@tonic-gate
12957c478bd9Sstevel@tonic-gate /*
129669112eddSAli Bahrami * If segment does not exist, allocate a descriptor with
129769112eddSAli Bahrami * its values set to 0 so that map_equal() can detect
129869112eddSAli Bahrami * changing attributes.
12997c478bd9Sstevel@tonic-gate */
130069112eddSAli Bahrami if (new_segment &&
130169112eddSAli Bahrami ((sgp1 = ld_map_seg_alloc(name, PT_NULL, 0)) == NULL))
130269112eddSAli Bahrami return (FALSE);
13037c478bd9Sstevel@tonic-gate
13047c478bd9Sstevel@tonic-gate /*
13057c478bd9Sstevel@tonic-gate * Now check the second token from the input line.
13067c478bd9Sstevel@tonic-gate */
130769112eddSAli Bahrami switch (tok) {
130869112eddSAli Bahrami case TK_EQUAL: /* Create/modify segment */
130969112eddSAli Bahrami /*
131069112eddSAli Bahrami * We use the same syntax for hardware/software
131169112eddSAli Bahrami * capabilities as we do for segments. If the
131269112eddSAli Bahrami * "segment name" matches one of these, then
131369112eddSAli Bahrami * process the capabilities instead of treating it
131469112eddSAli Bahrami * as a segment. Note that no dynamic memory has
131569112eddSAli Bahrami * been allocated for the segment descriptor yet,
131669112eddSAli Bahrami * so we can bail without leaking memory.
131769112eddSAli Bahrami */
13187c478bd9Sstevel@tonic-gate if (strcmp(sgp1->sg_name,
13197c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_HWCAP_1)) == 0) {
132069112eddSAli Bahrami if (!map_cap(mf, CA_SUNW_HW_1,
132108278a5eSRod Evans &ofl->ofl_ocapset.oc_hw_1))
132269112eddSAli Bahrami return (FALSE);
1323d1827f25Srie continue;
132469112eddSAli Bahrami }
132569112eddSAli Bahrami if (strcmp(sgp1->sg_name,
13267c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_SFCAP_1)) == 0) {
132769112eddSAli Bahrami if (!map_cap(mf, CA_SUNW_SF_1,
132808278a5eSRod Evans &ofl->ofl_ocapset.oc_sf_1))
132969112eddSAli Bahrami return (FALSE);
1330d1827f25Srie continue;
13317c478bd9Sstevel@tonic-gate }
133269112eddSAli Bahrami
13337c478bd9Sstevel@tonic-gate /*
133469112eddSAli Bahrami * If not a new segment, show the initial value
133569112eddSAli Bahrami * before modifying it.
13367c478bd9Sstevel@tonic-gate */
133769112eddSAli Bahrami if (!new_segment && DBG_ENABLED) {
133869112eddSAli Bahrami ndx = ld_map_seg_index(mf, sgp1);
133969112eddSAli Bahrami Dbg_map_seg(ofl, DBG_STATE_MOD_BEFORE,
134069112eddSAli Bahrami ndx, sgp1, mf->mf_lineno);
13417c478bd9Sstevel@tonic-gate }
13427c478bd9Sstevel@tonic-gate
134369112eddSAli Bahrami /* Process the segment */
134469112eddSAli Bahrami if (!map_equal(mf, sgp1))
134569112eddSAli Bahrami return (FALSE);
134669112eddSAli Bahrami
13477c478bd9Sstevel@tonic-gate /*
134869112eddSAli Bahrami * Special case for STACK "segments":
134969112eddSAli Bahrami *
135069112eddSAli Bahrami * The ability to modify the stack flags was added
135169112eddSAli Bahrami * long after this sysv syntax was designed. It was
135269112eddSAli Bahrami * fit into the existing syntax by treating it as a
135369112eddSAli Bahrami * segment. However, there can only be one stack program
135469112eddSAli Bahrami * header, while segment syntax requires user to supply
135569112eddSAli Bahrami * a name. This is confusing, and it allows the user to
135669112eddSAli Bahrami * attempt to create more than one stack segment. The
135769112eddSAli Bahrami * original implementation had a test to catch this.
135869112eddSAli Bahrami *
135969112eddSAli Bahrami * If this is a stack segment, locate the real stack
136069112eddSAli Bahrami * descriptor and transfer the flags to it. We then
136169112eddSAli Bahrami * free the allocated descriptor without inserting it.
136269112eddSAli Bahrami * The end result is that all stack segments simply
136369112eddSAli Bahrami * alter the one stack descriptor, and the segment
136469112eddSAli Bahrami * name is ignored.
13657c478bd9Sstevel@tonic-gate */
136669112eddSAli Bahrami if (sgp1->sg_phdr.p_type == PT_SUNWSTACK) {
136769112eddSAli Bahrami Sg_desc *stack = ld_map_seg_stack(mf);
136869112eddSAli Bahrami
136969112eddSAli Bahrami if (sgp1->sg_flags & FLG_SG_P_FLAGS)
137069112eddSAli Bahrami stack->sg_phdr.p_flags =
137169112eddSAli Bahrami sgp1->sg_phdr.p_flags;
137269112eddSAli Bahrami
137369112eddSAli Bahrami DBG_CALL(Dbg_map_seg(ofl,
137469112eddSAli Bahrami DBG_STATE_MOD_AFTER, ndx, sgp1,
137569112eddSAli Bahrami mf->mf_lineno));
1376*fb12490aSRichard Lowe
1377*fb12490aSRichard Lowe free(sgp1);
137869112eddSAli Bahrami break;
137969112eddSAli Bahrami }
13807c478bd9Sstevel@tonic-gate
13817c478bd9Sstevel@tonic-gate /*
138269112eddSAli Bahrami * If this is a new segment, finish its initialization
138369112eddSAli Bahrami * and insert it into the segment list.
13847c478bd9Sstevel@tonic-gate */
138569112eddSAli Bahrami if (new_segment) {
138669112eddSAli Bahrami switch (ld_map_seg_insert(mf, DBG_STATE_NEW,
138769112eddSAli Bahrami sgp1, where)) {
138869112eddSAli Bahrami case SEG_INS_SKIP:
138969112eddSAli Bahrami continue;
139069112eddSAli Bahrami case SEG_INS_FAIL:
139169112eddSAli Bahrami return (FALSE);
1392a953e2b1Srie }
139369112eddSAli Bahrami } else {
139469112eddSAli Bahrami /* Not new. Show what's changed */
139569112eddSAli Bahrami DBG_CALL(Dbg_map_seg(ofl,
139669112eddSAli Bahrami DBG_STATE_MOD_AFTER, ndx, sgp1,
139769112eddSAli Bahrami mf->mf_lineno));
13987c478bd9Sstevel@tonic-gate }
139969112eddSAli Bahrami break;
14007c478bd9Sstevel@tonic-gate
140169112eddSAli Bahrami case TK_COLON: /* Section to segment mapping */
14027c478bd9Sstevel@tonic-gate /*
140369112eddSAli Bahrami * If this is a new segment, finish its initialization
140469112eddSAli Bahrami * and insert it into the segment list.
140557ef7aa9SRod Evans *
140669112eddSAli Bahrami * If it is not a new segment, ensure that it is
140769112eddSAli Bahrami * not an empty segment reservation, as sections
140869112eddSAli Bahrami * cannot be assigned to those.
14097c478bd9Sstevel@tonic-gate */
141069112eddSAli Bahrami if (new_segment) {
141169112eddSAli Bahrami switch (ld_map_seg_insert(mf,
141269112eddSAli Bahrami DBG_STATE_NEW_IMPLICIT, sgp1, where)) {
141369112eddSAli Bahrami case SEG_INS_SKIP:
14147c478bd9Sstevel@tonic-gate continue;
141569112eddSAli Bahrami case SEG_INS_FAIL:
141669112eddSAli Bahrami return (FALSE);
14177c478bd9Sstevel@tonic-gate }
141869112eddSAli Bahrami } else if (sgp1->sg_flags & FLG_SG_EMPTY) {
141969112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPSEC));
142069112eddSAli Bahrami return (FALSE);
14217c478bd9Sstevel@tonic-gate }
142257ef7aa9SRod Evans
142369112eddSAli Bahrami /*
142469112eddSAli Bahrami * Create new entrance criteria descriptor, and
142569112eddSAli Bahrami * process the mapping directive.
142669112eddSAli Bahrami */
142769112eddSAli Bahrami enp = ld_map_seg_ent_add(mf, sgp1, NULL);
142869112eddSAli Bahrami if ((enp == NULL) || !map_colon(mf, enp))
142969112eddSAli Bahrami return (FALSE);
143069112eddSAli Bahrami DBG_CALL(Dbg_map_ent(ofl->ofl_lml, enp, ofl,
143169112eddSAli Bahrami mf->mf_lineno));
143269112eddSAli Bahrami break;
143369112eddSAli Bahrami
143469112eddSAli Bahrami case TK_ATSIGN: /* Section size symbol */
143569112eddSAli Bahrami /*
143669112eddSAli Bahrami * If this is a new segment, finish its initialization
143769112eddSAli Bahrami * and insert it into the segment list.
143869112eddSAli Bahrami */
143969112eddSAli Bahrami if (new_segment) {
144069112eddSAli Bahrami switch (ld_map_seg_insert(mf,
144169112eddSAli Bahrami DBG_STATE_NEW_IMPLICIT, sgp1, where)) {
144269112eddSAli Bahrami case SEG_INS_SKIP:
144357ef7aa9SRod Evans continue;
144469112eddSAli Bahrami case SEG_INS_FAIL:
144569112eddSAli Bahrami return (FALSE);
14467c478bd9Sstevel@tonic-gate }
14477c478bd9Sstevel@tonic-gate }
144869112eddSAli Bahrami if (!map_atsign(mf, sgp1))
144969112eddSAli Bahrami return (FALSE);
145069112eddSAli Bahrami break;
14517c478bd9Sstevel@tonic-gate
145269112eddSAli Bahrami case TK_ERROR:
145369112eddSAli Bahrami return (FALSE); /* Error was already issued */
14547c478bd9Sstevel@tonic-gate
145569112eddSAli Bahrami default:
145669112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPEQU));
145769112eddSAli Bahrami return (FALSE);
145869112eddSAli Bahrami }
145969112eddSAli Bahrami }
14607c478bd9Sstevel@tonic-gate
146169112eddSAli Bahrami return (TRUE);
14627c478bd9Sstevel@tonic-gate }
1463