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 ]
50*08278a5eSRod Evans * hwcap_2 = val,... [ OVERRIDE ]
51*08278a5eSRod Evans * platcap = name,... [ OVERRIDE ]
52*08278a5eSRod 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
587c478bd9Sstevel@tonic-gate * #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
63*08278a5eSRod Evans * hardware capabilities that may be defined in the objects read as part of
64*08278a5eSRod 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)71*08278a5eSRod Evans map_cap(Mapfile *mf, Word type, Capmask *capmask)
727c478bd9Sstevel@tonic-gate {
737c478bd9Sstevel@tonic-gate Token tok; /* Current token. */
747c478bd9Sstevel@tonic-gate Xword number;
757c478bd9Sstevel@tonic-gate 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;
797c478bd9Sstevel@tonic-gate
8069112eddSAli Bahrami if (DBG_ENABLED) {
8169112eddSAli Bahrami Dbg_cap_mapfile_title(ofl->ofl_lml, mf->mf_lineno);
82*08278a5eSRod Evans Dbg_cap_val_entry(ofl->ofl_lml, DBG_STATE_CURRENT, CA_SUNW_HW_1,
83*08278a5eSRod Evans capmask->cm_val, ld_targ.t_m.m_mach);
847c478bd9Sstevel@tonic-gate }
857c478bd9Sstevel@tonic-gate
8669112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, TK_F_STRLC, &tkv)) !=
8769112eddSAli Bahrami TK_SEMICOLON) {
8869112eddSAli Bahrami if (tok != TK_STRING) {
8969112eddSAli Bahrami if (tok != TK_ERROR)
9069112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGATT));
9169112eddSAli Bahrami return (FALSE);
9269112eddSAli Bahrami }
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);
10169112eddSAli Bahrami used++;
10269112eddSAli Bahrami continue;
10369112eddSAli Bahrami }
10469112eddSAli Bahrami
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;
1097c478bd9Sstevel@tonic-gate used++;
1107c478bd9Sstevel@tonic-gate 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);
133d1827f25Srie return (FALSE);
134d1827f25Srie }
13569112eddSAli Bahrami
13669112eddSAli Bahrami /* Catch empty declarations */
13769112eddSAli Bahrami if (used == 0) {
13869112eddSAli Bahrami mf_warn0(mf, MSG_INTL(MSG_MAP_EMPTYCAP));
13969112eddSAli Bahrami return (TRUE);
140d1827f25Srie }
14169112eddSAli Bahrami
142*08278a5eSRod Evans DBG_CALL(Dbg_cap_val_entry(ofl->ofl_lml, DBG_STATE_NEW, type, value,
143*08278a5eSRod Evans ld_targ.t_m.m_mach));
144*08278a5eSRod 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
150d1827f25Srie return (TRUE);
151d1827f25Srie }
152d1827f25Srie
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.
1687c478bd9Sstevel@tonic-gate */
16969112eddSAli Bahrami 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)
1727c478bd9Sstevel@tonic-gate {
1737c478bd9Sstevel@tonic-gate Word tmp_flags = 0;
1747c478bd9Sstevel@tonic-gate
17569112eddSAli Bahrami if (*b_flags) {
17669112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE),
1777c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGFLAG));
17869112eddSAli Bahrami return (FALSE);
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate
18169112eddSAli Bahrami /* Skip over the leading '?' character */
18269112eddSAli Bahrami flag_tok++;
18369112eddSAli Bahrami
1847c478bd9Sstevel@tonic-gate /*
1857c478bd9Sstevel@tonic-gate * If ? has nothing following leave the flags cleared,
18669112eddSAli Bahrami * otherwise OR in any flags specified.
1877c478bd9Sstevel@tonic-gate */
1887c478bd9Sstevel@tonic-gate while (*flag_tok) {
1897c478bd9Sstevel@tonic-gate switch (*flag_tok) {
1907c478bd9Sstevel@tonic-gate case 'r':
1917c478bd9Sstevel@tonic-gate tmp_flags |= PF_R;
1927c478bd9Sstevel@tonic-gate break;
1937c478bd9Sstevel@tonic-gate case 'w':
1947c478bd9Sstevel@tonic-gate tmp_flags |= PF_W;
1957c478bd9Sstevel@tonic-gate break;
1967c478bd9Sstevel@tonic-gate case 'x':
1977c478bd9Sstevel@tonic-gate tmp_flags |= PF_X;
1987c478bd9Sstevel@tonic-gate break;
1997c478bd9Sstevel@tonic-gate case 'e':
2007c478bd9Sstevel@tonic-gate sgp->sg_flags |= FLG_SG_EMPTY;
2017c478bd9Sstevel@tonic-gate break;
2027c478bd9Sstevel@tonic-gate 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;
2187c478bd9Sstevel@tonic-gate break;
2197c478bd9Sstevel@tonic-gate 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 */
2247c478bd9Sstevel@tonic-gate sgp->sg_flags |= FLG_SG_NOHDR;
2257c478bd9Sstevel@tonic-gate break;
2267c478bd9Sstevel@tonic-gate default:
22769112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSEGFLG), *flag_tok);
22869112eddSAli Bahrami return (FALSE);
2297c478bd9Sstevel@tonic-gate }
2307c478bd9Sstevel@tonic-gate flag_tok++;
2317c478bd9Sstevel@tonic-gate }
23269112eddSAli Bahrami
2337c478bd9Sstevel@tonic-gate /*
23469112eddSAli Bahrami * Warn when changing flags except when we're adding or removing "X"
23569112eddSAli Bahrami * from a RW PT_LOAD segment.
2367c478bd9Sstevel@tonic-gate */
23769112eddSAli Bahrami if ((sgp->sg_flags & FLG_SG_P_FLAGS) &&
2387c478bd9Sstevel@tonic-gate (sgp->sg_phdr.p_flags != tmp_flags) &&
2397c478bd9Sstevel@tonic-gate !(sgp->sg_phdr.p_type == PT_LOAD &&
2407c478bd9Sstevel@tonic-gate (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),
2437c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGFLAG), sgp->sg_name);
24469112eddSAli Bahrami
24569112eddSAli Bahrami sgp->sg_flags |= FLG_SG_P_FLAGS;
2467c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_flags = tmp_flags;
24769112eddSAli Bahrami *b_flags = TRUE;
24869112eddSAli Bahrami
24969112eddSAli Bahrami return (TRUE);
25069112eddSAli Bahrami }
25169112eddSAli Bahrami
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
28669112eddSAli Bahrami /*
28769112eddSAli Bahrami * Process a mapfile segment declaration definition.
28869112eddSAli Bahrami * segment_name = segment_attribute;
28969112eddSAli Bahrami * segment_attribute : segment_type segment_flags virtual_addr
29069112eddSAli Bahrami * physical_addr length alignment
29169112eddSAli Bahrami */
29269112eddSAli Bahrami static Boolean
map_equal(Mapfile * mf,Sg_desc * sgp)29369112eddSAli Bahrami map_equal(Mapfile *mf, Sg_desc *sgp)
29469112eddSAli Bahrami {
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;
31969112eddSAli Bahrami Token tok; /* Current token. */
32069112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */
32169112eddSAli Bahrami Boolean b_type = FALSE; /* True if seg types found. */
32269112eddSAli Bahrami Boolean b_flags = FALSE; /* True if seg flags found. */
32369112eddSAli Bahrami Boolean b_len = FALSE; /* True if seg length found. */
32469112eddSAli Bahrami Boolean b_round = FALSE; /* True if seg rounding found. */
32569112eddSAli Bahrami Boolean b_vaddr = FALSE; /* True if seg virtual addr found. */
32669112eddSAli Bahrami Boolean b_paddr = FALSE; /* True if seg physical addr found. */
32769112eddSAli Bahrami Boolean b_align = FALSE; /* True if seg alignment found. */
32869112eddSAli Bahrami
32969112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, TK_F_STRLC, &tkv)) !=
33069112eddSAli Bahrami TK_SEMICOLON) {
33169112eddSAli Bahrami if (tok != TK_STRING) {
33269112eddSAli Bahrami if (tok != TK_ERROR)
33369112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGATT));
33469112eddSAli Bahrami return (FALSE);
33569112eddSAli Bahrami }
33669112eddSAli Bahrami
33769112eddSAli Bahrami /*
33869112eddSAli Bahrami * If it is the name of a segment type, set the type
33969112eddSAli Bahrami * and flags fields in the descriptor.
34069112eddSAli Bahrami */
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);
34769112eddSAli Bahrami }
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;
35869112eddSAli Bahrami }
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')) {
3757c478bd9Sstevel@tonic-gate 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),
5047c478bd9Sstevel@tonic-gate EC_WORD(sgp->sg_phdr.p_flags));
50569112eddSAli Bahrami return (FALSE);
5067c478bd9Sstevel@tonic-gate }
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);
5187c478bd9Sstevel@tonic-gate }
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)) {
5437c478bd9Sstevel@tonic-gate 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 *
5927c478bd9Sstevel@tonic-gate * 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))
649ba2be530Sab196087 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) {
77071ae4d73Sab196087 if (tok != TK_ERROR)
77169112eddSAli Bahrami mf_fatal0(mf,
77269112eddSAli Bahrami MSG_INTL(MSG_MAP_MALFORM));
77369112eddSAli Bahrami return (FALSE);
7747c478bd9Sstevel@tonic-gate }
7757c478bd9Sstevel@tonic-gate
7767c478bd9Sstevel@tonic-gate /*
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.
7807c478bd9Sstevel@tonic-gate */
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;
78669112eddSAli Bahrami }
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;
79169112eddSAli Bahrami }
79269112eddSAli Bahrami }
79369112eddSAli Bahrami return (TRUE);
7947c478bd9Sstevel@tonic-gate }
7957c478bd9Sstevel@tonic-gate
7967c478bd9Sstevel@tonic-gate /*
7977c478bd9Sstevel@tonic-gate * Process a mapfile size symbol definition.
7987c478bd9Sstevel@tonic-gate * 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) {
80771ae4d73Sab196087 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) {
81871ae4d73Sab196087 if (tok != TK_ERROR)
81969112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSCOL));
82069112eddSAli Bahrami return (FALSE);
82171ae4d73Sab196087 }
82271ae4d73Sab196087
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) {
83471ae4d73Sab196087 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) {
84371ae4d73Sab196087 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.
8537c478bd9Sstevel@tonic-gate * 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)) {
87771ae4d73Sab196087 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) {
88971ae4d73Sab196087 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;
9717c478bd9Sstevel@tonic-gate
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++;
98860758829Srie 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)) !=
101671ae4d73Sab196087 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);
1041c1c6f601Srie
104269112eddSAli Bahrami if (tkv.tkv_str[0] == 'v' ||
104369112eddSAli Bahrami tkv.tkv_str[0] == 's') {
104469112eddSAli Bahrami Xword number;
10457c478bd9Sstevel@tonic-gate
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;
10777c478bd9Sstevel@tonic-gate break;
1078a953e2b1Srie /* END CSTYLED */
10797c478bd9Sstevel@tonic-gate }
10807c478bd9Sstevel@tonic-gate
108169112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
10827c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_FUNCTION)) == 0) {
108369112eddSAli Bahrami ms.ms_shndx = SHN_ABS;
108469112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_SPECSEC;
108569112eddSAli Bahrami ms.ms_type = STT_FUNC;
108669112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
10877c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_DATA)) == 0) {
108869112eddSAli Bahrami ms.ms_shndx = SHN_ABS;
108969112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_SPECSEC;
109069112eddSAli Bahrami ms.ms_type = STT_OBJECT;
109169112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
10927c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_COMMON)) == 0) {
109369112eddSAli Bahrami ms.ms_shndx = SHN_COMMON;
109469112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_SPECSEC;
109569112eddSAli Bahrami ms.ms_type = STT_OBJECT;
109669112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
10977c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_PARENT)) == 0) {
109869112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_PARENT;
10997c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_SYMINFO;
110069112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
11017c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_EXTERN)) == 0) {
110269112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_EXTERN;
11037c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_SYMINFO;
110469112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
11057c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_DIRECT)) == 0) {
110669112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_DIR;
11077c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_SYMINFO;
110869112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
11097c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_NODIRECT)) == 0) {
111069112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_NDIR;
11117c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_SYMINFO;
111228bda19cSRod Evans ofl->ofl_flags1 |=
111328bda19cSRod Evans (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR);
111469112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
11157c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_FILTER)) == 0) {
111669112eddSAli Bahrami /* Next token is the filtee */
111769112eddSAli Bahrami filter = FLG_SY_STDFLTR;
11187c478bd9Sstevel@tonic-gate continue;
111969112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
11207c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_AUXILIARY)) == 0) {
112169112eddSAli Bahrami /* Next token is the filtee */
112269112eddSAli Bahrami filter = FLG_SY_AUXFLTR;
11237c478bd9Sstevel@tonic-gate continue;
112469112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
11259a411307Srie MSG_ORIG(MSG_MAP_INTERPOSE)) == 0) {
1126604635faSRod Evans /* BEGIN CSTYLED */
11279a411307Srie if (!(ofl->ofl_flags & FLG_OF_EXEC)) {
112869112eddSAli Bahrami mf_fatal0(mf,
112969112eddSAli Bahrami MSG_INTL(MSG_MAP_NOINTPOSE));
113069112eddSAli Bahrami mv.mv_errcnt++;
1131604635faSRod Evans break;
11329a411307Srie }
1133604635faSRod Evans /* END CSTYLED */
113469112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_INTPOSE;
11359a411307Srie ofl->ofl_flags |= FLG_OF_SYMINFO;
11369a411307Srie ofl->ofl_dtflags_1 |= DF_1_SYMINTPOSE;
11379a411307Srie continue;
113869112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
1139d579eb63Sab196087 MSG_ORIG(MSG_MAP_DYNSORT)) == 0) {
114069112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_DYNSORT;
114169112eddSAli Bahrami ms.ms_sdflags &= ~FLG_SY_NODYNSORT;
1142d579eb63Sab196087 continue;
114369112eddSAli Bahrami } else if (strcmp(tkv.tkv_str,
1144d579eb63Sab196087 MSG_ORIG(MSG_MAP_NODYNSORT)) == 0) {
114569112eddSAli Bahrami ms.ms_sdflags &= ~FLG_SY_DYNSORT;
114669112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_NODYNSORT;
1147d579eb63Sab196087 continue;
11487c478bd9Sstevel@tonic-gate } else {
114969112eddSAli Bahrami mf_fatal(mf,
11507c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_UNKSYMDEF),
115169112eddSAli Bahrami tkv.tkv_str);
115269112eddSAli Bahrami mv.mv_errcnt++;
115360758829Srie continue;
11547c478bd9Sstevel@tonic-gate }
11557c478bd9Sstevel@tonic-gate }
11567c478bd9Sstevel@tonic-gate /* FALLTHROUGH */
11577c478bd9Sstevel@tonic-gate
11587c478bd9Sstevel@tonic-gate case TK_SEMICOLON:
115969112eddSAli Bahrami /* Auto-reduction directive ('*')? */
116069112eddSAli Bahrami if (*ms.ms_name == '*') {
116169112eddSAli Bahrami ld_map_sym_autoreduce(mf, &mv);
116269112eddSAli Bahrami continue;
11637c478bd9Sstevel@tonic-gate }
116469112eddSAli Bahrami
116569112eddSAli Bahrami /*
116669112eddSAli Bahrami * Catch the error where the AUX or FILTER keyword
116769112eddSAli Bahrami * was used, but the filtee wasn't supplied.
116869112eddSAli Bahrami */
116969112eddSAli Bahrami if (filter && (ms.ms_filtee == NULL)) {
117069112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_NOFILTER),
117169112eddSAli Bahrami ms.ms_name);
117269112eddSAli Bahrami mv.mv_errcnt++;
11737c478bd9Sstevel@tonic-gate continue;
11747c478bd9Sstevel@tonic-gate }
11757c478bd9Sstevel@tonic-gate
11767c478bd9Sstevel@tonic-gate /*
11777c478bd9Sstevel@tonic-gate * Add the new symbol. It should be noted that all
11787c478bd9Sstevel@tonic-gate * symbols added by the mapfile start out with global
11797c478bd9Sstevel@tonic-gate * scope, thus they will fall through the normal symbol
11807c478bd9Sstevel@tonic-gate * resolution process. Symbols defined as locals will
11817c478bd9Sstevel@tonic-gate * be reduced in scope after all input file processing.
11827c478bd9Sstevel@tonic-gate */
118369112eddSAli Bahrami if (!ld_map_sym_enter(mf, &mv, &ms))
118469112eddSAli Bahrami return (FALSE);
11857c478bd9Sstevel@tonic-gate break;
11867c478bd9Sstevel@tonic-gate
11877c478bd9Sstevel@tonic-gate default:
118869112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSCOL));
118969112eddSAli Bahrami mv.mv_errcnt++;
119060758829Srie continue;
119160758829Srie }
119260758829Srie }
119360758829Srie
119469112eddSAli Bahrami if (mv.mv_errcnt)
119569112eddSAli Bahrami return (FALSE);
11967c478bd9Sstevel@tonic-gate
11977c478bd9Sstevel@tonic-gate /*
11987c478bd9Sstevel@tonic-gate * Determine if any version references are provided after the close
119969112eddSAli Bahrami * bracket, parsing up to the terminating ';'.
12007c478bd9Sstevel@tonic-gate */
120169112eddSAli Bahrami if (!ld_map_sym_ver_fini(mf, &mv))
120269112eddSAli Bahrami return (FALSE);
12037c478bd9Sstevel@tonic-gate
120469112eddSAli Bahrami return (TRUE);
12057c478bd9Sstevel@tonic-gate }
12067c478bd9Sstevel@tonic-gate
12077c478bd9Sstevel@tonic-gate /*
120869112eddSAli Bahrami * Parse the mapfile --- Sysv syntax
12097c478bd9Sstevel@tonic-gate */
121069112eddSAli Bahrami Boolean
ld_map_parse_v1(Mapfile * mf)121169112eddSAli Bahrami ld_map_parse_v1(Mapfile *mf)
12127c478bd9Sstevel@tonic-gate {
12137c478bd9Sstevel@tonic-gate Sg_desc *sgp1; /* seg descriptor being manipulated */
121469112eddSAli Bahrami Ent_desc *enp; /* segment entrance criteria. */
12157c478bd9Sstevel@tonic-gate Token tok; /* current token. */
121669112eddSAli Bahrami Boolean new_segment; /* If true, defines new segment */
12177c478bd9Sstevel@tonic-gate char *name;
121869112eddSAli Bahrami Ofl_desc *ofl = mf->mf_ofl;
121969112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */
122069112eddSAli Bahrami avl_index_t where;
12217c478bd9Sstevel@tonic-gate
12227c478bd9Sstevel@tonic-gate /*
12237c478bd9Sstevel@tonic-gate * We now parse the mapfile until the gettoken routine returns EOF.
12247c478bd9Sstevel@tonic-gate */
122569112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, TK_F_EOFOK, &tkv)) != TK_EOF) {
122669112eddSAli Bahrami Xword ndx;
12277c478bd9Sstevel@tonic-gate
12287c478bd9Sstevel@tonic-gate /*
12297c478bd9Sstevel@tonic-gate * At this point we are at the beginning of a line, and the
123069112eddSAli Bahrami * variable tkv.tkv_str points to the first string on the line.
12317c478bd9Sstevel@tonic-gate * All mapfile entries start with some string token except it
12327c478bd9Sstevel@tonic-gate * is possible for a scoping definition to start with `{'.
12337c478bd9Sstevel@tonic-gate */
12347c478bd9Sstevel@tonic-gate if (tok == TK_LEFTBKT) {
123569112eddSAli Bahrami if (!map_version(mf, NULL))
123669112eddSAli Bahrami return (FALSE);
12377c478bd9Sstevel@tonic-gate continue;
12387c478bd9Sstevel@tonic-gate }
12397c478bd9Sstevel@tonic-gate if (tok != TK_STRING) {
124071ae4d73Sab196087 if (tok != TK_ERROR)
124169112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGNAM));
124269112eddSAli Bahrami return (FALSE);
12437c478bd9Sstevel@tonic-gate }
12447c478bd9Sstevel@tonic-gate
12457c478bd9Sstevel@tonic-gate /*
12467c478bd9Sstevel@tonic-gate * Save the initial token.
12477c478bd9Sstevel@tonic-gate */
124869112eddSAli Bahrami name = tkv.tkv_str;
12497c478bd9Sstevel@tonic-gate
12507c478bd9Sstevel@tonic-gate /*
12517c478bd9Sstevel@tonic-gate * Now check the second character on the line. The special `-'
12527c478bd9Sstevel@tonic-gate * and `{' characters do not involve any segment manipulation so
12537c478bd9Sstevel@tonic-gate * we handle them first.
12547c478bd9Sstevel@tonic-gate */
125569112eddSAli Bahrami tok = ld_map_gettoken(mf, 0, &tkv);
125669112eddSAli Bahrami if (tok == TK_ERROR)
125769112eddSAli Bahrami return (FALSE);
125871ae4d73Sab196087 if (tok == TK_DASH) {
125969112eddSAli Bahrami if (!map_dash(mf, name))
126069112eddSAli Bahrami return (FALSE);
12617c478bd9Sstevel@tonic-gate continue;
12627c478bd9Sstevel@tonic-gate }
12637c478bd9Sstevel@tonic-gate if (tok == TK_LEFTBKT) {
126469112eddSAli Bahrami if (!map_version(mf, name))
126569112eddSAli Bahrami return (FALSE);
12667c478bd9Sstevel@tonic-gate continue;
12677c478bd9Sstevel@tonic-gate }
12687c478bd9Sstevel@tonic-gate
12697c478bd9Sstevel@tonic-gate /*
12707c478bd9Sstevel@tonic-gate * If we're here we need to interpret the first string as a
127169112eddSAli Bahrami * segment name. Is this an already known segment?
12727c478bd9Sstevel@tonic-gate */
127369112eddSAli Bahrami sgp1 = ld_seg_lookup(mf->mf_ofl, name, &where);
127469112eddSAli Bahrami new_segment = sgp1 == NULL;
127569112eddSAli Bahrami if (!new_segment)
127669112eddSAli Bahrami sgp1->sg_flags &= ~FLG_SG_DISABLED;
12777c478bd9Sstevel@tonic-gate
12787c478bd9Sstevel@tonic-gate /*
1279635216b6SRod Evans * If the second token is a '|' then we had better have found a
1280635216b6SRod Evans * segment. It is illegal to perform section within segment
1281635216b6SRod Evans * ordering before the segment has been declared.
12827c478bd9Sstevel@tonic-gate */
12837c478bd9Sstevel@tonic-gate if (tok == TK_PIPE) {
12847c478bd9Sstevel@tonic-gate if (sgp1 == NULL) {
128569112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_SECINSEG),
128669112eddSAli Bahrami name);
128769112eddSAli Bahrami return (FALSE);
12887c478bd9Sstevel@tonic-gate }
128969112eddSAli Bahrami if (!map_pipe(mf, sgp1))
129069112eddSAli Bahrami return (FALSE);
129169112eddSAli Bahrami continue;
12927c478bd9Sstevel@tonic-gate }
12937c478bd9Sstevel@tonic-gate
12947c478bd9Sstevel@tonic-gate /*
129569112eddSAli Bahrami * If segment does not exist, allocate a descriptor with
129669112eddSAli Bahrami * its values set to 0 so that map_equal() can detect
129769112eddSAli Bahrami * changing attributes.
12987c478bd9Sstevel@tonic-gate */
129969112eddSAli Bahrami if (new_segment &&
130069112eddSAli Bahrami ((sgp1 = ld_map_seg_alloc(name, PT_NULL, 0)) == NULL))
130169112eddSAli Bahrami return (FALSE);
13027c478bd9Sstevel@tonic-gate
13037c478bd9Sstevel@tonic-gate /*
13047c478bd9Sstevel@tonic-gate * Now check the second token from the input line.
13057c478bd9Sstevel@tonic-gate */
130669112eddSAli Bahrami switch (tok) {
130769112eddSAli Bahrami case TK_EQUAL: /* Create/modify segment */
130869112eddSAli Bahrami /*
130969112eddSAli Bahrami * We use the same syntax for hardware/software
131069112eddSAli Bahrami * capabilities as we do for segments. If the
131169112eddSAli Bahrami * "segment name" matches one of these, then
131269112eddSAli Bahrami * process the capabilities instead of treating it
131369112eddSAli Bahrami * as a segment. Note that no dynamic memory has
131469112eddSAli Bahrami * been allocated for the segment descriptor yet,
131569112eddSAli Bahrami * so we can bail without leaking memory.
131669112eddSAli Bahrami */
13177c478bd9Sstevel@tonic-gate if (strcmp(sgp1->sg_name,
13187c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_HWCAP_1)) == 0) {
131969112eddSAli Bahrami if (!map_cap(mf, CA_SUNW_HW_1,
1320*08278a5eSRod Evans &ofl->ofl_ocapset.oc_hw_1))
132169112eddSAli Bahrami return (FALSE);
1322d1827f25Srie continue;
132369112eddSAli Bahrami }
132469112eddSAli Bahrami if (strcmp(sgp1->sg_name,
13257c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_SFCAP_1)) == 0) {
132669112eddSAli Bahrami if (!map_cap(mf, CA_SUNW_SF_1,
1327*08278a5eSRod Evans &ofl->ofl_ocapset.oc_sf_1))
132869112eddSAli Bahrami return (FALSE);
1329d1827f25Srie continue;
13307c478bd9Sstevel@tonic-gate }
133169112eddSAli Bahrami
13327c478bd9Sstevel@tonic-gate /*
133369112eddSAli Bahrami * If not a new segment, show the initial value
133469112eddSAli Bahrami * before modifying it.
13357c478bd9Sstevel@tonic-gate */
133669112eddSAli Bahrami if (!new_segment && DBG_ENABLED) {
133769112eddSAli Bahrami ndx = ld_map_seg_index(mf, sgp1);
133869112eddSAli Bahrami Dbg_map_seg(ofl, DBG_STATE_MOD_BEFORE,
133969112eddSAli Bahrami ndx, sgp1, mf->mf_lineno);
13407c478bd9Sstevel@tonic-gate }
13417c478bd9Sstevel@tonic-gate
134269112eddSAli Bahrami /* Process the segment */
134369112eddSAli Bahrami if (!map_equal(mf, sgp1))
134469112eddSAli Bahrami return (FALSE);
134569112eddSAli Bahrami
13467c478bd9Sstevel@tonic-gate /*
134769112eddSAli Bahrami * Special case for STACK "segments":
134869112eddSAli Bahrami *
134969112eddSAli Bahrami * The ability to modify the stack flags was added
135069112eddSAli Bahrami * long after this sysv syntax was designed. It was
135169112eddSAli Bahrami * fit into the existing syntax by treating it as a
135269112eddSAli Bahrami * segment. However, there can only be one stack program
135369112eddSAli Bahrami * header, while segment syntax requires user to supply
135469112eddSAli Bahrami * a name. This is confusing, and it allows the user to
135569112eddSAli Bahrami * attempt to create more than one stack segment. The
135669112eddSAli Bahrami * original implementation had a test to catch this.
135769112eddSAli Bahrami *
135869112eddSAli Bahrami * If this is a stack segment, locate the real stack
135969112eddSAli Bahrami * descriptor and transfer the flags to it. We then
136069112eddSAli Bahrami * free the allocated descriptor without inserting it.
136169112eddSAli Bahrami * The end result is that all stack segments simply
136269112eddSAli Bahrami * alter the one stack descriptor, and the segment
136369112eddSAli Bahrami * name is ignored.
13647c478bd9Sstevel@tonic-gate */
136569112eddSAli Bahrami if (sgp1->sg_phdr.p_type == PT_SUNWSTACK) {
136669112eddSAli Bahrami Sg_desc *stack = ld_map_seg_stack(mf);
136757ef7aa9SRod Evans
136869112eddSAli Bahrami if (sgp1->sg_flags & FLG_SG_P_FLAGS)
136969112eddSAli Bahrami stack->sg_phdr.p_flags =
137069112eddSAli Bahrami sgp1->sg_phdr.p_flags;
137169112eddSAli Bahrami free(sgp1);
13727c478bd9Sstevel@tonic-gate
137369112eddSAli Bahrami DBG_CALL(Dbg_map_seg(ofl,
137469112eddSAli Bahrami DBG_STATE_MOD_AFTER, ndx, sgp1,
137569112eddSAli Bahrami mf->mf_lineno));
137669112eddSAli Bahrami break;
13777c478bd9Sstevel@tonic-gate }
13787c478bd9Sstevel@tonic-gate
13797c478bd9Sstevel@tonic-gate /*
138069112eddSAli Bahrami * If this is a new segment, finish its initialization
138169112eddSAli Bahrami * and insert it into the segment list.
13827c478bd9Sstevel@tonic-gate */
13837c478bd9Sstevel@tonic-gate if (new_segment) {
138469112eddSAli Bahrami switch (ld_map_seg_insert(mf, DBG_STATE_NEW,
138569112eddSAli Bahrami sgp1, where)) {
138669112eddSAli Bahrami case SEG_INS_SKIP:
138769112eddSAli Bahrami continue;
138869112eddSAli Bahrami case SEG_INS_FAIL:
138969112eddSAli Bahrami return (FALSE);
13907c478bd9Sstevel@tonic-gate }
139169112eddSAli Bahrami } else {
139269112eddSAli Bahrami /* Not new. Show what's changed */
139369112eddSAli Bahrami DBG_CALL(Dbg_map_seg(ofl,
139469112eddSAli Bahrami DBG_STATE_MOD_AFTER, ndx, sgp1,
139569112eddSAli Bahrami mf->mf_lineno));
13967c478bd9Sstevel@tonic-gate }
139769112eddSAli Bahrami break;
139869112eddSAli Bahrami
139969112eddSAli Bahrami case TK_COLON: /* Section to segment mapping */
1400a953e2b1Srie /*
140169112eddSAli Bahrami * If this is a new segment, finish its initialization
140269112eddSAli Bahrami * and insert it into the segment list.
140369112eddSAli Bahrami *
140469112eddSAli Bahrami * If it is not a new segment, ensure that it is
140569112eddSAli Bahrami * not an empty segment reservation, as sections
140669112eddSAli Bahrami * cannot be assigned to those.
1407a953e2b1Srie */
140869112eddSAli Bahrami if (new_segment) {
140969112eddSAli Bahrami switch (ld_map_seg_insert(mf,
141069112eddSAli Bahrami DBG_STATE_NEW_IMPLICIT, sgp1, where)) {
141169112eddSAli Bahrami case SEG_INS_SKIP:
141269112eddSAli Bahrami continue;
141369112eddSAli Bahrami case SEG_INS_FAIL:
141469112eddSAli Bahrami return (FALSE);
1415a953e2b1Srie }
141669112eddSAli Bahrami } else if (sgp1->sg_flags & FLG_SG_EMPTY) {
141769112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPSEC));
141869112eddSAli Bahrami return (FALSE);
1419a953e2b1Srie }
14207c478bd9Sstevel@tonic-gate
14217c478bd9Sstevel@tonic-gate /*
142269112eddSAli Bahrami * Create new entrance criteria descriptor, and
142369112eddSAli Bahrami * process the mapping directive.
14247c478bd9Sstevel@tonic-gate */
142569112eddSAli Bahrami enp = ld_map_seg_ent_add(mf, sgp1, NULL);
142669112eddSAli Bahrami if ((enp == NULL) || !map_colon(mf, enp))
142769112eddSAli Bahrami return (FALSE);
142869112eddSAli Bahrami DBG_CALL(Dbg_map_ent(ofl->ofl_lml, enp, ofl,
142969112eddSAli Bahrami mf->mf_lineno));
14307c478bd9Sstevel@tonic-gate break;
143169112eddSAli Bahrami
143269112eddSAli Bahrami case TK_ATSIGN: /* Section size symbol */
14337c478bd9Sstevel@tonic-gate /*
143469112eddSAli Bahrami * If this is a new segment, finish its initialization
143569112eddSAli Bahrami * and insert it into the segment list.
14367c478bd9Sstevel@tonic-gate */
143769112eddSAli Bahrami if (new_segment) {
143869112eddSAli Bahrami switch (ld_map_seg_insert(mf,
143969112eddSAli Bahrami DBG_STATE_NEW_IMPLICIT, sgp1, where)) {
144069112eddSAli Bahrami case SEG_INS_SKIP:
14417c478bd9Sstevel@tonic-gate continue;
144269112eddSAli Bahrami case SEG_INS_FAIL:
144369112eddSAli Bahrami return (FALSE);
14447c478bd9Sstevel@tonic-gate }
144569112eddSAli Bahrami }
144669112eddSAli Bahrami if (!map_atsign(mf, sgp1))
144769112eddSAli Bahrami return (FALSE);
14487c478bd9Sstevel@tonic-gate break;
144969112eddSAli Bahrami
145069112eddSAli Bahrami case TK_ERROR:
145169112eddSAli Bahrami return (FALSE); /* Error was already issued */
145269112eddSAli Bahrami
14537c478bd9Sstevel@tonic-gate default:
145469112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPEQU));
145569112eddSAli Bahrami return (FALSE);
14567c478bd9Sstevel@tonic-gate }
14577c478bd9Sstevel@tonic-gate }
14587c478bd9Sstevel@tonic-gate
145969112eddSAli Bahrami return (TRUE);
14607c478bd9Sstevel@tonic-gate }
1461