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 */
70 static Boolean
map_cap(Mapfile * mf,Word type,Capmask * capmask)71 map_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 */
169 static Boolean
map_equal_flags(Mapfile * mf,Sg_desc * sgp,Boolean * b_flags,const char * flag_tok)170 map_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 */
266 static Boolean
valuetoxword(Mapfile * mf,ld_map_tkval_t * tkv,Xword * value)267 valuetoxword(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 */
292 static Boolean
map_equal(Mapfile * mf,Sg_desc * sgp)293 map_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 */
596 static Boolean
map_colon(Mapfile * mf,Ent_desc * enp)597 map_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 */
800 static Boolean
map_atsign(Mapfile * mf,Sg_desc * sgp)801 map_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
827 static Boolean
map_pipe(Mapfile * mf,Sg_desc * sgp)828 map_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 */
857 static Boolean
map_dash(Mapfile * mf,char * name)858 map_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 */
953 static Boolean
map_version(Mapfile * mf,char * name)954 map_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 ms.ms_size_set = TRUE;
1078 break;
1079 /* END CSTYLED */
1080 }
1081
1082 } else if (strcmp(tkv.tkv_str,
1083 MSG_ORIG(MSG_MAP_FUNCTION)) == 0) {
1084 ms.ms_shndx = SHN_ABS;
1085 ms.ms_sdflags |= FLG_SY_SPECSEC;
1086 ms.ms_type = STT_FUNC;
1087 } else if (strcmp(tkv.tkv_str,
1088 MSG_ORIG(MSG_MAP_DATA)) == 0) {
1089 ms.ms_shndx = SHN_ABS;
1090 ms.ms_sdflags |= FLG_SY_SPECSEC;
1091 ms.ms_type = STT_OBJECT;
1092 } else if (strcmp(tkv.tkv_str,
1093 MSG_ORIG(MSG_MAP_COMMON)) == 0) {
1094 ms.ms_shndx = SHN_COMMON;
1095 ms.ms_sdflags |= FLG_SY_SPECSEC;
1096 ms.ms_type = STT_OBJECT;
1097 } else if (strcmp(tkv.tkv_str,
1098 MSG_ORIG(MSG_MAP_PARENT)) == 0) {
1099 ms.ms_sdflags |= FLG_SY_PARENT;
1100 ofl->ofl_flags |= FLG_OF_SYMINFO;
1101 } else if (strcmp(tkv.tkv_str,
1102 MSG_ORIG(MSG_MAP_EXTERN)) == 0) {
1103 ms.ms_sdflags |= FLG_SY_EXTERN;
1104 ofl->ofl_flags |= FLG_OF_SYMINFO;
1105 } else if (strcmp(tkv.tkv_str,
1106 MSG_ORIG(MSG_MAP_DIRECT)) == 0) {
1107 ms.ms_sdflags |= FLG_SY_DIR;
1108 ofl->ofl_flags |= FLG_OF_SYMINFO;
1109 } else if (strcmp(tkv.tkv_str,
1110 MSG_ORIG(MSG_MAP_NODIRECT)) == 0) {
1111 ms.ms_sdflags |= FLG_SY_NDIR;
1112 ofl->ofl_flags |= FLG_OF_SYMINFO;
1113 ofl->ofl_flags1 |=
1114 (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR);
1115 } else if (strcmp(tkv.tkv_str,
1116 MSG_ORIG(MSG_MAP_FILTER)) == 0) {
1117 /* Next token is the filtee */
1118 filter = FLG_SY_STDFLTR;
1119 continue;
1120 } else if (strcmp(tkv.tkv_str,
1121 MSG_ORIG(MSG_MAP_AUXILIARY)) == 0) {
1122 /* Next token is the filtee */
1123 filter = FLG_SY_AUXFLTR;
1124 continue;
1125 } else if (strcmp(tkv.tkv_str,
1126 MSG_ORIG(MSG_MAP_INTERPOSE)) == 0) {
1127 /* BEGIN CSTYLED */
1128 if (!(ofl->ofl_flags & FLG_OF_EXEC)) {
1129 mf_fatal0(mf,
1130 MSG_INTL(MSG_MAP_NOINTPOSE));
1131 mv.mv_errcnt++;
1132 break;
1133 }
1134 /* END CSTYLED */
1135 ms.ms_sdflags |= FLG_SY_INTPOSE;
1136 ofl->ofl_flags |= FLG_OF_SYMINFO;
1137 ofl->ofl_dtflags_1 |= DF_1_SYMINTPOSE;
1138 continue;
1139 } else if (strcmp(tkv.tkv_str,
1140 MSG_ORIG(MSG_MAP_DYNSORT)) == 0) {
1141 ms.ms_sdflags |= FLG_SY_DYNSORT;
1142 ms.ms_sdflags &= ~FLG_SY_NODYNSORT;
1143 continue;
1144 } else if (strcmp(tkv.tkv_str,
1145 MSG_ORIG(MSG_MAP_NODYNSORT)) == 0) {
1146 ms.ms_sdflags &= ~FLG_SY_DYNSORT;
1147 ms.ms_sdflags |= FLG_SY_NODYNSORT;
1148 continue;
1149 } else {
1150 mf_fatal(mf,
1151 MSG_INTL(MSG_MAP_UNKSYMDEF),
1152 tkv.tkv_str);
1153 mv.mv_errcnt++;
1154 continue;
1155 }
1156 }
1157 /* FALLTHROUGH */
1158
1159 case TK_SEMICOLON:
1160 /* Auto-reduction directive ('*')? */
1161 if (*ms.ms_name == '*') {
1162 ld_map_sym_autoreduce(mf, &mv);
1163 continue;
1164 }
1165
1166 /*
1167 * Catch the error where the AUX or FILTER keyword
1168 * was used, but the filtee wasn't supplied.
1169 */
1170 if (filter && (ms.ms_filtee == NULL)) {
1171 mf_fatal(mf, MSG_INTL(MSG_MAP_NOFILTER),
1172 ms.ms_name);
1173 mv.mv_errcnt++;
1174 continue;
1175 }
1176
1177 /*
1178 * Add the new symbol. It should be noted that all
1179 * symbols added by the mapfile start out with global
1180 * scope, thus they will fall through the normal symbol
1181 * resolution process. Symbols defined as locals will
1182 * be reduced in scope after all input file processing.
1183 */
1184 if (!ld_map_sym_enter(mf, &mv, &ms, NULL))
1185 return (FALSE);
1186 break;
1187
1188 default:
1189 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSCOL));
1190 mv.mv_errcnt++;
1191 continue;
1192 }
1193 }
1194
1195 if (mv.mv_errcnt)
1196 return (FALSE);
1197
1198 /*
1199 * Determine if any version references are provided after the close
1200 * bracket, parsing up to the terminating ';'.
1201 */
1202 if (!ld_map_sym_ver_fini(mf, &mv))
1203 return (FALSE);
1204
1205 return (TRUE);
1206 }
1207
1208 /*
1209 * Parse the mapfile --- Sysv syntax
1210 */
1211 Boolean
ld_map_parse_v1(Mapfile * mf)1212 ld_map_parse_v1(Mapfile *mf)
1213 {
1214 Sg_desc *sgp1; /* seg descriptor being manipulated */
1215 Ent_desc *enp; /* segment entrance criteria. */
1216 Token tok; /* current token. */
1217 Boolean new_segment; /* If true, defines new segment */
1218 char *name;
1219 Ofl_desc *ofl = mf->mf_ofl;
1220 ld_map_tkval_t tkv; /* Value of token */
1221 avl_index_t where;
1222
1223 /*
1224 * We now parse the mapfile until the gettoken routine returns EOF.
1225 */
1226 while ((tok = ld_map_gettoken(mf, TK_F_EOFOK, &tkv)) != TK_EOF) {
1227 Xword ndx;
1228
1229 /*
1230 * At this point we are at the beginning of a line, and the
1231 * variable tkv.tkv_str points to the first string on the line.
1232 * All mapfile entries start with some string token except it
1233 * is possible for a scoping definition to start with `{'.
1234 */
1235 if (tok == TK_LEFTBKT) {
1236 if (!map_version(mf, NULL))
1237 return (FALSE);
1238 continue;
1239 }
1240 if (tok != TK_STRING) {
1241 if (tok != TK_ERROR)
1242 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGNAM));
1243 return (FALSE);
1244 }
1245
1246 /*
1247 * Save the initial token.
1248 */
1249 name = tkv.tkv_str;
1250
1251 /*
1252 * Now check the second character on the line. The special `-'
1253 * and `{' characters do not involve any segment manipulation so
1254 * we handle them first.
1255 */
1256 tok = ld_map_gettoken(mf, 0, &tkv);
1257 if (tok == TK_ERROR)
1258 return (FALSE);
1259 if (tok == TK_DASH) {
1260 if (!map_dash(mf, name))
1261 return (FALSE);
1262 continue;
1263 }
1264 if (tok == TK_LEFTBKT) {
1265 if (!map_version(mf, name))
1266 return (FALSE);
1267 continue;
1268 }
1269
1270 /*
1271 * If we're here we need to interpret the first string as a
1272 * segment name. Is this an already known segment?
1273 */
1274 sgp1 = ld_seg_lookup(mf->mf_ofl, name, &where);
1275 new_segment = sgp1 == NULL;
1276 if (!new_segment)
1277 sgp1->sg_flags &= ~FLG_SG_DISABLED;
1278
1279 /*
1280 * If the second token is a '|' then we had better have found a
1281 * segment. It is illegal to perform section within segment
1282 * ordering before the segment has been declared.
1283 */
1284 if (tok == TK_PIPE) {
1285 if (sgp1 == NULL) {
1286 mf_fatal(mf, MSG_INTL(MSG_MAP_SECINSEG),
1287 name);
1288 return (FALSE);
1289 }
1290 if (!map_pipe(mf, sgp1))
1291 return (FALSE);
1292 continue;
1293 }
1294
1295 /*
1296 * If segment does not exist, allocate a descriptor with
1297 * its values set to 0 so that map_equal() can detect
1298 * changing attributes.
1299 */
1300 if (new_segment &&
1301 ((sgp1 = ld_map_seg_alloc(name, PT_NULL, 0)) == NULL))
1302 return (FALSE);
1303
1304 /*
1305 * Now check the second token from the input line.
1306 */
1307 switch (tok) {
1308 case TK_EQUAL: /* Create/modify segment */
1309 /*
1310 * We use the same syntax for hardware/software
1311 * capabilities as we do for segments. If the
1312 * "segment name" matches one of these, then
1313 * process the capabilities instead of treating it
1314 * as a segment. Note that no dynamic memory has
1315 * been allocated for the segment descriptor yet,
1316 * so we can bail without leaking memory.
1317 */
1318 if (strcmp(sgp1->sg_name,
1319 MSG_ORIG(MSG_STR_HWCAP_1)) == 0) {
1320 if (!map_cap(mf, CA_SUNW_HW_1,
1321 &ofl->ofl_ocapset.oc_hw_1))
1322 return (FALSE);
1323 continue;
1324 }
1325 if (strcmp(sgp1->sg_name,
1326 MSG_ORIG(MSG_STR_SFCAP_1)) == 0) {
1327 if (!map_cap(mf, CA_SUNW_SF_1,
1328 &ofl->ofl_ocapset.oc_sf_1))
1329 return (FALSE);
1330 continue;
1331 }
1332
1333 /*
1334 * If not a new segment, show the initial value
1335 * before modifying it.
1336 */
1337 if (!new_segment && DBG_ENABLED) {
1338 ndx = ld_map_seg_index(mf, sgp1);
1339 Dbg_map_seg(ofl, DBG_STATE_MOD_BEFORE,
1340 ndx, sgp1, mf->mf_lineno);
1341 }
1342
1343 /* Process the segment */
1344 if (!map_equal(mf, sgp1))
1345 return (FALSE);
1346
1347 /*
1348 * Special case for STACK "segments":
1349 *
1350 * The ability to modify the stack flags was added
1351 * long after this sysv syntax was designed. It was
1352 * fit into the existing syntax by treating it as a
1353 * segment. However, there can only be one stack program
1354 * header, while segment syntax requires user to supply
1355 * a name. This is confusing, and it allows the user to
1356 * attempt to create more than one stack segment. The
1357 * original implementation had a test to catch this.
1358 *
1359 * If this is a stack segment, locate the real stack
1360 * descriptor and transfer the flags to it. We then
1361 * free the allocated descriptor without inserting it.
1362 * The end result is that all stack segments simply
1363 * alter the one stack descriptor, and the segment
1364 * name is ignored.
1365 */
1366 if (sgp1->sg_phdr.p_type == PT_SUNWSTACK) {
1367 Sg_desc *stack = ld_map_seg_stack(mf);
1368
1369 if (sgp1->sg_flags & FLG_SG_P_FLAGS)
1370 stack->sg_phdr.p_flags =
1371 sgp1->sg_phdr.p_flags;
1372
1373 DBG_CALL(Dbg_map_seg(ofl,
1374 DBG_STATE_MOD_AFTER, ndx, sgp1,
1375 mf->mf_lineno));
1376
1377 free(sgp1);
1378 break;
1379 }
1380
1381 /*
1382 * If this is a new segment, finish its initialization
1383 * and insert it into the segment list.
1384 */
1385 if (new_segment) {
1386 switch (ld_map_seg_insert(mf, DBG_STATE_NEW,
1387 sgp1, where)) {
1388 case SEG_INS_SKIP:
1389 continue;
1390 case SEG_INS_FAIL:
1391 return (FALSE);
1392 }
1393 } else {
1394 /* Not new. Show what's changed */
1395 DBG_CALL(Dbg_map_seg(ofl,
1396 DBG_STATE_MOD_AFTER, ndx, sgp1,
1397 mf->mf_lineno));
1398 }
1399 break;
1400
1401 case TK_COLON: /* Section to segment mapping */
1402 /*
1403 * If this is a new segment, finish its initialization
1404 * and insert it into the segment list.
1405 *
1406 * If it is not a new segment, ensure that it is
1407 * not an empty segment reservation, as sections
1408 * cannot be assigned to those.
1409 */
1410 if (new_segment) {
1411 switch (ld_map_seg_insert(mf,
1412 DBG_STATE_NEW_IMPLICIT, sgp1, where)) {
1413 case SEG_INS_SKIP:
1414 continue;
1415 case SEG_INS_FAIL:
1416 return (FALSE);
1417 }
1418 } else if (sgp1->sg_flags & FLG_SG_EMPTY) {
1419 mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPSEC));
1420 return (FALSE);
1421 }
1422
1423 /*
1424 * Create new entrance criteria descriptor, and
1425 * process the mapping directive.
1426 */
1427 enp = ld_map_seg_ent_add(mf, sgp1, NULL);
1428 if ((enp == NULL) || !map_colon(mf, enp))
1429 return (FALSE);
1430 DBG_CALL(Dbg_map_ent(ofl->ofl_lml, enp, ofl,
1431 mf->mf_lineno));
1432 break;
1433
1434 case TK_ATSIGN: /* Section size symbol */
1435 /*
1436 * If this is a new segment, finish its initialization
1437 * and insert it into the segment list.
1438 */
1439 if (new_segment) {
1440 switch (ld_map_seg_insert(mf,
1441 DBG_STATE_NEW_IMPLICIT, sgp1, where)) {
1442 case SEG_INS_SKIP:
1443 continue;
1444 case SEG_INS_FAIL:
1445 return (FALSE);
1446 }
1447 }
1448 if (!map_atsign(mf, sgp1))
1449 return (FALSE);
1450 break;
1451
1452 case TK_ERROR:
1453 return (FALSE); /* Error was already issued */
1454
1455 default:
1456 mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPEQU));
1457 return (FALSE);
1458 }
1459 }
1460
1461 return (TRUE);
1462 }
1463