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