4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1988 AT&T
26 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
31 * Map file parsing (Original SysV syntax).
47 * Process a hardware/software capabilities segment declaration definition.
48 * hwcap_1 = val,... [ OVERRIDE ]
49 * sfcap_1 = val,... [ OVERRIDE ]
50 * hwcap_2 = val,... [ OVERRIDE ]
51 * platcap = name,... [ OVERRIDE ]
52 * machcap = name,... [ OVERRIDE ]
54 * The values can be defined as a list of machine specify tokens, or numerics.
55 * Tokens are representations of the sys/auxv_$MACH.h capabilities, for example:
57 * #define AV_386_FPU 0x0001 is represented as FPU
58 * #define AV_386_TSC 0x0002 " " " " TSC
60 * Or, the above two capabilities could be represented as V0x3. Note, the
61 * OVERRIDE flag is used to ensure that only those values provided via this
62 * mapfile entry are recorded in the final image, ie. this overrides any
63 * hardware capabilities that may be defined in the objects read as part of
64 * this link-edit. Specifying:
68 * effectively removes any capabilities information from the final image.
71 map_cap(Mapfile
*mf
, Word type
, Capmask
*capmask
)
73 Token tok
; /* Current token. */
76 Ofl_desc
*ofl
= mf
->mf_ofl
;
77 ld_map_tkval_t tkv
; /* Value of token */
78 elfcap_mask_t value
= 0;
81 Dbg_cap_mapfile_title(ofl
->ofl_lml
, mf
->mf_lineno
);
82 Dbg_cap_val_entry(ofl
->ofl_lml
, DBG_STATE_CURRENT
, CA_SUNW_HW_1
,
83 capmask
->cm_val
, ld_targ
.t_m
.m_mach
);
86 while ((tok
= ld_map_gettoken(mf
, TK_F_STRLC
, &tkv
)) !=
88 if (tok
!= TK_STRING
) {
90 mf_fatal0(mf
, MSG_INTL(MSG_MAP_EXPSEGATT
));
95 * First, determine if the token represents the reserved
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
);
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) {
114 * Is the token a numeric value?
116 if (tkv
.tkv_str
[0] == 'v') {
117 if (ld_map_strtoxword(&tkv
.tkv_str
[1], NULL
,
118 &number
) != STRTOXWORD_OK
) {
119 mf_fatal(mf
, MSG_INTL(MSG_MAP_BADCAPVAL
),
129 * We have an unknown token.
132 mf_fatal(mf
, MSG_INTL(MSG_MAP_UNKCAPATTR
), tkv
.tkv_str
);
136 /* Catch empty declarations */
138 mf_warn0(mf
, MSG_INTL(MSG_MAP_EMPTYCAP
));
142 DBG_CALL(Dbg_cap_val_entry(ofl
->ofl_lml
, DBG_STATE_NEW
, type
, value
,
143 ld_targ
.t_m
.m_mach
));
144 capmask
->cm_val
|= value
;
146 /* Sanity check the resulting bits */
147 if (!ld_map_cap_sanitize(mf
, type
, capmask
))
154 * Parse the flags for a segment definition. Called by map_equal().
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.
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
170 map_equal_flags(Mapfile
*mf
, Sg_desc
*sgp
, Boolean
*b_flags
,
171 const char *flag_tok
)
176 mf_fatal(mf
, MSG_INTL(MSG_MAP_MOREONCE
),
177 MSG_INTL(MSG_MAP_SEGFLAG
));
181 /* Skip over the leading '?' character */
185 * If ? has nothing following leave the flags cleared,
186 * otherwise OR in any flags specified.
200 sgp
->sg_flags
|= FLG_SG_EMPTY
;
204 * The version 1 ?O option is incompatible with
205 * the version 2 SEGMENT IS_ORDER attribute.
207 if (aplist_nitems(sgp
->sg_is_order
) > 0) {
208 mf_fatal(mf
, MSG_INTL(MSG_MAP_ISORDVER
),
214 * Set FLG_SG_IS_ORDER to indicate that segment has
215 * had the ?O flag set by a version 1 mapfile.
217 sgp
->sg_flags
|= FLG_SG_IS_ORDER
;
221 * If segment ends up as the first loadable segment,
222 * it will not include the the ELF and program headers.
224 sgp
->sg_flags
|= FLG_SG_NOHDR
;
227 mf_fatal(mf
, MSG_INTL(MSG_MAP_UNKSEGFLG
), *flag_tok
);
234 * Warn when changing flags except when we're adding or removing "X"
235 * from a RW PT_LOAD segment.
237 if ((sgp
->sg_flags
& FLG_SG_P_FLAGS
) &&
238 (sgp
->sg_phdr
.p_flags
!= tmp_flags
) &&
239 !(sgp
->sg_phdr
.p_type
== PT_LOAD
&&
240 (tmp_flags
& (PF_R
|PF_W
)) == (PF_R
|PF_W
) &&
241 (tmp_flags
^ sgp
->sg_phdr
.p_flags
) == PF_X
))
242 mf_warn(mf
, MSG_INTL(MSG_MAP_REDEFATT
),
243 MSG_INTL(MSG_MAP_SEGFLAG
), sgp
->sg_name
);
245 sgp
->sg_flags
|= FLG_SG_P_FLAGS
;
246 sgp
->sg_phdr
.p_flags
= tmp_flags
;
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.
258 * mf - Mapfile descriptor
259 * tkv - TK_STRING token to parse
260 * value - Address of variable to receive the resulting value.
263 * Returns TRUE for success. On failure, issues an error message
267 valuetoxword(Mapfile
*mf
, ld_map_tkval_t
*tkv
, Xword
*value
)
269 switch (ld_map_strtoxword(&tkv
->tkv_str
[1], NULL
, value
)) {
273 case STRTOXWORD_TOOBIG
:
274 mf_fatal(mf
, MSG_INTL(MSG_MAP_SEGADDR
), tkv
->tkv_str
,
275 MSG_INTL(MSG_MAP_EXCLIMIT
));
278 mf_fatal(mf
, MSG_INTL(MSG_MAP_SEGADDR
), tkv
->tkv_str
,
279 MSG_INTL(MSG_MAP_NOBADFRM
));
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
293 map_equal(Mapfile
*mf
, Sg_desc
*sgp
)
296 * Segment type. Users are permitted to define PT_LOAD,
297 * PT_NOTE, PT_SUNWSTACK and PT_NULL segments. Other segment
298 * types are only defined in seg_desc[].
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 */
306 static seg_types_t seg_type_arr
[] = {
307 { MSG_ORIG(MSG_MAP_LOAD
), PT_LOAD
, FLG_SG_P_TYPE
},
308 { MSG_ORIG(MSG_MAP_STACK
), PT_SUNWSTACK
,
309 FLG_SG_P_TYPE
| FLG_SG_EMPTY
},
310 { MSG_ORIG(MSG_MAP_NULL
), PT_NULL
, FLG_SG_P_TYPE
},
311 { MSG_ORIG(MSG_MAP_NOTE
), PT_NOTE
, FLG_SG_P_TYPE
},
313 /* Array must be NULL terminated */
318 seg_types_t
*seg_type
;
319 Token tok
; /* Current token. */
320 ld_map_tkval_t tkv
; /* Value of token */
321 Boolean b_type
= FALSE
; /* True if seg types found. */
322 Boolean b_flags
= FALSE
; /* True if seg flags found. */
323 Boolean b_len
= FALSE
; /* True if seg length found. */
324 Boolean b_round
= FALSE
; /* True if seg rounding found. */
325 Boolean b_vaddr
= FALSE
; /* True if seg virtual addr found. */
326 Boolean b_paddr
= FALSE
; /* True if seg physical addr found. */
327 Boolean b_align
= FALSE
; /* True if seg alignment found. */
329 while ((tok
= ld_map_gettoken(mf
, TK_F_STRLC
, &tkv
)) !=
331 if (tok
!= TK_STRING
) {
333 mf_fatal0(mf
, MSG_INTL(MSG_MAP_EXPSEGATT
));
338 * If it is the name of a segment type, set the type
339 * and flags fields in the descriptor.
341 for (seg_type
= seg_type_arr
; seg_type
->name
; seg_type
++) {
342 if (strcmp(tkv
.tkv_str
, seg_type
->name
) == 0) {
344 mf_fatal(mf
, MSG_INTL(MSG_MAP_MOREONCE
),
345 MSG_INTL(MSG_MAP_SEGTYP
));
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
),
355 sgp
->sg_phdr
.p_type
= seg_type
->p_type
;
356 sgp
->sg_flags
|= seg_type
->sg_flags
;
360 if (seg_type
->name
!= NULL
) /* Matched segment type */
361 continue; /* next token */
364 if (*tkv
.tkv_str
== '?') {
365 if (!map_equal_flags(mf
, sgp
, &b_flags
, tkv
.tkv_str
))
367 continue; /* next token */
371 /* Segment address, length, alignment or rounding number */
372 if ((tkv
.tkv_str
[0] == 'l') || (tkv
.tkv_str
[0] == 'v') ||
373 (tkv
.tkv_str
[0] == 'a') || (tkv
.tkv_str
[0] == 'p') ||
374 (tkv
.tkv_str
[0] == 'r')) {
377 if (!valuetoxword(mf
, &tkv
, &number
))
380 switch (*tkv
.tkv_str
) {
384 MSG_INTL(MSG_MAP_MOREONCE
),
385 MSG_INTL(MSG_MAP_SEGLEN
));
388 if ((sgp
->sg_flags
& FLG_SG_LENGTH
) &&
389 (sgp
->sg_length
!= number
))
391 MSG_INTL(MSG_MAP_REDEFATT
),
392 MSG_INTL(MSG_MAP_SEGLEN
),
394 sgp
->sg_length
= number
;
395 sgp
->sg_flags
|= FLG_SG_LENGTH
;
401 MSG_INTL(MSG_MAP_MOREONCE
),
402 MSG_INTL(MSG_MAP_SEGROUND
));
405 if ((sgp
->sg_flags
& FLG_SG_ROUND
) &&
406 (sgp
->sg_round
!= number
))
408 MSG_INTL(MSG_MAP_REDEFATT
),
409 MSG_INTL(MSG_MAP_SEGROUND
),
411 sgp
->sg_round
= number
;
412 sgp
->sg_flags
|= FLG_SG_ROUND
;
418 MSG_INTL(MSG_MAP_MOREONCE
),
419 MSG_INTL(MSG_MAP_SEGVADDR
));
422 if ((sgp
->sg_flags
& FLG_SG_P_VADDR
) &&
423 (sgp
->sg_phdr
.p_vaddr
!= number
))
425 MSG_INTL(MSG_MAP_REDEFATT
),
426 MSG_INTL(MSG_MAP_SEGVADDR
),
429 sgp
->sg_phdr
.p_vaddr
= (Addr
)number
;
430 sgp
->sg_flags
|= FLG_SG_P_VADDR
;
436 MSG_INTL(MSG_MAP_MOREONCE
),
437 MSG_INTL(MSG_MAP_SEGPHYS
));
440 if ((sgp
->sg_flags
& FLG_SG_P_PADDR
) &&
441 (sgp
->sg_phdr
.p_paddr
!= number
))
443 MSG_INTL(MSG_MAP_REDEFATT
),
444 MSG_INTL(MSG_MAP_SEGPHYS
),
447 sgp
->sg_phdr
.p_paddr
= (Addr
)number
;
448 sgp
->sg_flags
|= FLG_SG_P_PADDR
;
454 MSG_INTL(MSG_MAP_MOREONCE
),
455 MSG_INTL(MSG_MAP_SEGALIGN
));
458 if ((sgp
->sg_flags
& FLG_SG_P_ALIGN
) &&
459 (sgp
->sg_phdr
.p_align
!= number
))
461 MSG_INTL(MSG_MAP_REDEFATT
),
462 MSG_INTL(MSG_MAP_SEGALIGN
),
465 sgp
->sg_phdr
.p_align
= (Xword
)number
;
466 sgp
->sg_flags
|= FLG_SG_P_ALIGN
;
471 continue; /* next token */
475 * If we reach the bottom of this loop, we have an
476 * unrecognized token.
478 mf_fatal(mf
, MSG_INTL(MSG_MAP_UNKSEGATT
), tkv
.tkv_str
);
483 * Empty segments can be used to define PT_LOAD segment reservations, or
484 * to reserve PT_NULL program headers.
486 * PT_LOAD reservations are only allowed within executables, as the
487 * reservation must be established through exec() as part of initial
488 * process loading. In addition, PT_LOAD reservations must have an
489 * associated address and size. Note: This is an obsolete feature,
490 * not supported by the newer mapfile syntax.
492 * PT_NULL program headers are established for later use by applications
493 * such as the post-optimizer. PT_NULL headers should have no other
494 * attributes assigned.
496 if ((sgp
->sg_flags
& FLG_SG_EMPTY
) &&
497 (sgp
->sg_phdr
.p_type
!= PT_SUNWSTACK
)) {
500 * Any style of empty segment should have no permissions.
502 if (sgp
->sg_phdr
.p_flags
!= 0) {
503 mf_fatal(mf
, MSG_INTL(MSG_MAP_SEGEMNOPERM
),
504 EC_WORD(sgp
->sg_phdr
.p_flags
));
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
));
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
));
519 } else if (sgp
->sg_phdr
.p_type
== PT_NULL
) {
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
));
528 mf_warn0(mf
, MSG_INTL(MSG_MAP_SEGEMPLOAD
));
529 sgp
->sg_phdr
.p_type
= PT_LOAD
;
534 * All segment attributes have now been scanned. Certain flags do not
535 * make sense if this is not a loadable segment, fix if necessary.
536 * Note, if the segment is of type PT_NULL it must be new, and any
537 * defaults will be applied by ld_map_seg_insert(). When clearing an
538 * attribute leave the flag set as an indicator for later entries
539 * re-specifying the same segment.
541 if ((sgp
->sg_phdr
.p_type
!= PT_NULL
) &&
542 (sgp
->sg_phdr
.p_type
!= PT_LOAD
)) {
545 if (sgp
->sg_phdr
.p_type
== PT_SUNWSTACK
)
546 fmt
= MSG_INTL(MSG_MAP_NOSTACK1
);
548 fmt
= MSG_INTL(MSG_MAP_NONLOAD
);
550 if ((sgp
->sg_flags
& FLG_SG_P_FLAGS
) &&
551 (sgp
->sg_phdr
.p_type
!= PT_SUNWSTACK
)) {
552 if (sgp
->sg_phdr
.p_flags
!= 0) {
553 mf_warn(mf
, MSG_INTL(MSG_MAP_NONLOAD
),
554 MSG_INTL(MSG_MAP_SEGFLAG
));
555 sgp
->sg_phdr
.p_flags
= 0;
558 if (sgp
->sg_flags
& FLG_SG_LENGTH
)
559 if (sgp
->sg_length
!= 0) {
560 mf_warn(mf
, fmt
, MSG_INTL(MSG_MAP_SEGLEN
));
563 if (sgp
->sg_flags
& FLG_SG_ROUND
)
564 if (sgp
->sg_round
!= 0) {
565 mf_warn(mf
, fmt
, MSG_INTL(MSG_MAP_SEGROUND
));
568 if (sgp
->sg_flags
& FLG_SG_P_VADDR
) {
569 if (sgp
->sg_phdr
.p_vaddr
!= 0) {
570 mf_warn(mf
, fmt
, MSG_INTL(MSG_MAP_SEGVADDR
));
571 sgp
->sg_phdr
.p_vaddr
= 0;
574 if (sgp
->sg_flags
& FLG_SG_P_PADDR
)
575 if (sgp
->sg_phdr
.p_paddr
!= 0) {
576 mf_warn(mf
, fmt
, MSG_INTL(MSG_MAP_SEGPHYS
));
577 sgp
->sg_phdr
.p_paddr
= 0;
579 if (sgp
->sg_flags
& FLG_SG_P_ALIGN
)
580 if (sgp
->sg_phdr
.p_align
!= 0) {
581 mf_warn(mf
, fmt
, MSG_INTL(MSG_MAP_SEGALIGN
));
582 sgp
->sg_phdr
.p_align
= 0;
590 * Process a mapfile mapping directives definition.
592 * segment_name : section_attribute [ : file_name ]
594 * Where segment_attribute is one of: section_name section_type section_flags;
597 map_colon(Mapfile
*mf
, Ent_desc
*enp
)
601 Boolean b_name
= FALSE
;
602 Boolean b_type
= FALSE
;
603 Boolean b_attr
= FALSE
;
604 Boolean b_bang
= FALSE
;
608 * Start out assuming that this entrance criteria will be empty,
609 * and therefore match anything. We clear the CATCHALL flag below
610 * if this turns out not to be the case.
612 enp
->ec_flags
|= FLG_EC_CATCHALL
;
614 while (((tok
= ld_map_gettoken(mf
, 0, &tkv
)) != TK_COLON
) &&
615 (tok
!= TK_SEMICOLON
)) {
618 if (tok
!= TK_STRING
) {
619 mf_fatal0(mf
, MSG_INTL(MSG_MAP_MALFORM
));
625 if (*tkv
.tkv_str
== '$') {
627 mf_fatal(mf
, MSG_INTL(MSG_MAP_MOREONCE
),
628 MSG_INTL(MSG_MAP_SECTYP
));
633 ld_map_lowercase(tkv
.tkv_str
);
634 if (strcmp(tkv
.tkv_str
, MSG_ORIG(MSG_STR_PROGBITS
)) ==
636 enp
->ec_type
= SHT_PROGBITS
;
637 else if (strcmp(tkv
.tkv_str
,
638 MSG_ORIG(MSG_STR_SYMTAB
)) == 0)
639 enp
->ec_type
= SHT_SYMTAB
;
640 else if (strcmp(tkv
.tkv_str
,
641 MSG_ORIG(MSG_STR_DYNSYM
)) == 0)
642 enp
->ec_type
= SHT_DYNSYM
;
643 else if (strcmp(tkv
.tkv_str
,
644 MSG_ORIG(MSG_STR_STRTAB
)) == 0)
645 enp
->ec_type
= SHT_STRTAB
;
646 else if ((strcmp(tkv
.tkv_str
,
647 MSG_ORIG(MSG_STR_REL
)) == 0) ||
648 (strcmp(tkv
.tkv_str
, MSG_ORIG(MSG_STR_RELA
)) == 0))
649 enp
->ec_type
= ld_targ
.t_m
.m_rel_sht_type
;
650 else if (strcmp(tkv
.tkv_str
, MSG_ORIG(MSG_STR_HASH
)) ==
652 enp
->ec_type
= SHT_HASH
;
653 else if (strcmp(tkv
.tkv_str
, MSG_ORIG(MSG_STR_LIB
)) ==
655 enp
->ec_type
= SHT_SHLIB
;
656 else if (strcmp(tkv
.tkv_str
,
657 MSG_ORIG(MSG_STR_LD_DYNAMIC
)) == 0)
658 enp
->ec_type
= SHT_DYNAMIC
;
659 else if (strcmp(tkv
.tkv_str
, MSG_ORIG(MSG_STR_NOTE
)) ==
661 enp
->ec_type
= SHT_NOTE
;
662 else if (strcmp(tkv
.tkv_str
,
663 MSG_ORIG(MSG_STR_NOBITS
)) == 0)
664 enp
->ec_type
= SHT_NOBITS
;
666 mf_fatal(mf
, MSG_INTL(MSG_MAP_UNKSECTYP
),
671 enp
->ec_flags
&= ~FLG_EC_CATCHALL
;
675 * If a segment flag is specified then the appropriate bit is
676 * set in the ec_attrmask, the ec_attrbits fields determine
677 * whether the attrmask fields must be tested true or false
678 * ie. for ?A the attrmask is set and the attrbit is set,
679 * for ?!A the attrmask is set and the attrbit is clear.
681 } else if (*tkv
.tkv_str
== '?') {
683 mf_fatal(mf
, MSG_INTL(MSG_MAP_MOREONCE
),
684 MSG_INTL(MSG_MAP_SECFLAG
));
690 ld_map_lowercase(tkv
.tkv_str
);
691 for (; *tkv
.tkv_str
!= '\0'; tkv
.tkv_str
++)
692 switch (*tkv
.tkv_str
) {
696 MSG_INTL(MSG_MAP_BADFLAG
),
703 if (enp
->ec_attrmask
& SHF_ALLOC
) {
705 MSG_INTL(MSG_MAP_BADFLAG
),
709 enp
->ec_attrmask
|= SHF_ALLOC
;
711 enp
->ec_attrbits
|= SHF_ALLOC
;
715 if (enp
->ec_attrmask
& SHF_WRITE
) {
717 MSG_INTL(MSG_MAP_BADFLAG
),
721 enp
->ec_attrmask
|= SHF_WRITE
;
723 enp
->ec_attrbits
|= SHF_WRITE
;
727 if (enp
->ec_attrmask
& SHF_EXECINSTR
) {
729 MSG_INTL(MSG_MAP_BADFLAG
),
733 enp
->ec_attrmask
|= SHF_EXECINSTR
;
741 MSG_INTL(MSG_MAP_BADFLAG
),
745 if (enp
->ec_attrmask
!= 0)
746 enp
->ec_flags
&= ~FLG_EC_CATCHALL
;
753 mf_fatal(mf
, MSG_INTL(MSG_MAP_MOREONCE
),
754 MSG_INTL(MSG_MAP_SECNAME
));
758 enp
->ec_is_name
= tkv
.tkv_str
;
759 enp
->ec_flags
&= ~FLG_EC_CATCHALL
;
762 if (tok
== TK_COLON
) {
766 while ((tok
= ld_map_gettoken(mf
, 0, &tkv
)) != TK_SEMICOLON
) {
769 if (tok
!= TK_STRING
) {
772 MSG_INTL(MSG_MAP_MALFORM
));
777 * A leading '*' means that this should be a basename
778 * comparison rather than a full path. It's not a glob
779 * wildcard, although it looks like one.
781 if (tkv
.tkv_str
[0] == '*') {
782 ecf_type
= TYP_ECF_BASENAME
;
785 ecf_type
= TYP_ECF_PATH
;
787 if (!ld_map_seg_ent_files(mf
, enp
, ecf_type
,
790 enp
->ec_flags
&= ~FLG_EC_CATCHALL
;
797 * Process a mapfile size symbol definition.
798 * segment_name @ symbol_name;
801 map_atsign(Mapfile
*mf
, Sg_desc
*sgp
)
803 Token tok
; /* Current token. */
804 ld_map_tkval_t tkv
; /* Value of token */
806 if ((tok
= ld_map_gettoken(mf
, 0, &tkv
)) != TK_STRING
) {
808 mf_fatal0(mf
, MSG_INTL(MSG_MAP_EXPSYM_1
));
812 /* Add the symbol to the segment */
813 if (!ld_map_seg_size_symbol(mf
, sgp
, TK_PLUSEQ
, tkv
.tkv_str
))
817 if (ld_map_gettoken(mf
, 0, &tkv
) != TK_SEMICOLON
) {
819 mf_fatal0(mf
, MSG_INTL(MSG_MAP_EXPSCOL
));
828 map_pipe(Mapfile
*mf
, Sg_desc
*sgp
)
830 Token tok
; /* current token. */
831 ld_map_tkval_t tkv
; /* Value of token */
833 if ((tok
= ld_map_gettoken(mf
, 0, &tkv
)) != TK_STRING
) {
835 mf_fatal0(mf
, MSG_INTL(MSG_MAP_EXPSEC
));
839 if (!ld_map_seg_os_order_add(mf
, sgp
, tkv
.tkv_str
))
842 if ((tok
= ld_map_gettoken(mf
, 0, &tkv
)) != TK_SEMICOLON
) {
844 mf_fatal0(mf
, MSG_INTL(MSG_MAP_EXPSCOL
));
852 * Process a mapfile library specification definition.
853 * shared_object_name - shared object definition
854 * shared object definition : [ shared object type [ = SONAME ]]
858 map_dash(Mapfile
*mf
, char *name
)
862 ld_map_tkval_t tkv
; /* Value of token */
868 /* Get descriptor for dependency */
869 if ((sdf
= ld_map_dv(mf
, name
)) == NULL
)
873 * Get the shared object descriptor string.
875 while ((tok
= ld_map_gettoken(mf
, 0, &tkv
)) != TK_SEMICOLON
) {
876 if ((tok
!= TK_STRING
) && (tok
!= TK_EQUAL
)) {
878 mf_fatal0(mf
, MSG_INTL(MSG_MAP_EXPSO
));
883 * Determine if the library type is accompanied with a SONAME
886 if (tok
== TK_EQUAL
) {
887 if ((tok
= ld_map_gettoken(mf
, 0, &tkv
)) !=
891 MSG_INTL(MSG_MAP_EXPSO
));
896 if (!ld_map_dv_entry(mf
, sdf
, TRUE
,
901 mf_fatal(mf
, MSG_INTL(MSG_MAP_UNEXTOK
), '=');
909 * A shared object type has been specified. This may also be
910 * accompanied by an SONAME redefinition (see above).
912 if (*tkv
.tkv_str
== '$') {
913 if (dolkey
!= MD_NONE
) {
914 mf_fatal(mf
, MSG_INTL(MSG_MAP_UNEXTOK
), '$');
918 ld_map_lowercase(tkv
.tkv_str
);
919 if (strcmp(tkv
.tkv_str
, MSG_ORIG(MSG_MAP_ADDVERS
)) ==
923 mf_fatal(mf
, MSG_INTL(MSG_MAP_UNKSOTYP
),
931 * shared object version requirement.
933 if (!ld_map_dv_entry(mf
, sdf
, FALSE
, tkv
.tkv_str
))
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).
949 * symbol [ = [ type ] [ value ] [ size ] [ attribute ] ];
954 map_version(Mapfile
*mf
, char *name
)
957 ld_map_tkval_t tkv
; /* Value of token */
960 Ofl_desc
*ofl
= mf
->mf_ofl
;
962 /* Establish the version descriptor and related data */
963 if (!ld_map_sym_ver_init(mf
, name
, &mv
))
967 * Scan the mapfile entry picking out scoping and symbol definitions.
969 while ((tok
= ld_map_gettoken(mf
, 0, &tkv
)) != TK_RIGHTBKT
) {
972 if (tok
!= TK_STRING
) {
973 if (tok
== TK_ERROR
) {
974 mf_fatal0(mf
, MSG_INTL(MSG_MAP_EXPSYM_2
));
981 /* The default value for all the symbol attributes is 0 */
982 (void) memset(&ms
, 0, sizeof (ms
));
983 ms
.ms_name
= tkv
.tkv_str
;
985 tok
= ld_map_gettoken(mf
, 0, &tkv
);
986 if (tok
== TK_ERROR
) {
992 * Turn off the WEAK flag to indicate that definitions are
993 * associated with this version. It would probably be more
994 * accurate to only remove this flag with the specification of
995 * global symbols, however setting it here allows enough slop
996 * to compensate for the various user inputs we've seen so far.
997 * Only if a closed version is specified (i.e., "SUNW_1.x {};")
998 * will a user get a weak version (which is how we document the
999 * creation of weak versions).
1001 mv
.mv_vdp
->vd_flags
&= ~VER_FLG_WEAK
;
1005 ld_map_sym_scope(mf
, ms
.ms_name
, &mv
);
1010 * A full blown symbol definition follows.
1011 * Determine the symbol type and any virtual address or
1012 * alignment specified and then fall through to process
1013 * the entire symbols information.
1015 while ((tok
= ld_map_gettoken(mf
, 0, &tkv
)) !=
1017 if (tok
== TK_ERROR
)
1019 if (tok
!= TK_STRING
) {
1021 MSG_INTL(MSG_MAP_MALFORM
));
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.
1031 ld_map_sym_filtee(mf
, &mv
, &ms
,
1032 filter
, tkv
.tkv_str
);
1038 * Determine any Value or Size attributes.
1040 ld_map_lowercase(tkv
.tkv_str
);
1042 if (tkv
.tkv_str
[0] == 'v' ||
1043 tkv
.tkv_str
[0] == 's') {
1046 if (!valuetoxword(mf
, &tkv
, &number
)) {
1051 switch (*tkv
.tkv_str
) {
1056 MSG_INTL(MSG_MAP_MOREONCE
),
1057 MSG_INTL(MSG_MAP_SYMVAL
));
1062 ms
.ms_value
= (Addr
)number
;
1063 ms
.ms_value_set
= TRUE
;
1070 MSG_INTL(MSG_MAP_MOREONCE
),
1071 MSG_INTL(MSG_MAP_SYMSIZE
));
1076 ms
.ms_size
= (Addr
)number
;
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
;
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
;
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
;
1124 } else if (strcmp(tkv
.tkv_str
,
1125 MSG_ORIG(MSG_MAP_INTERPOSE
)) == 0) {
1127 if (!(ofl
->ofl_flags
& FLG_OF_EXEC
)) {
1129 MSG_INTL(MSG_MAP_NOINTPOSE
));
1134 ms
.ms_sdflags
|= FLG_SY_INTPOSE
;
1135 ofl
->ofl_flags
|= FLG_OF_SYMINFO
;
1136 ofl
->ofl_dtflags_1
|= DF_1_SYMINTPOSE
;
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
;
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
;
1150 MSG_INTL(MSG_MAP_UNKSYMDEF
),
1159 /* Auto-reduction directive ('*')? */
1160 if (*ms
.ms_name
== '*') {
1161 ld_map_sym_autoreduce(mf
, &mv
);
1166 * Catch the error where the AUX or FILTER keyword
1167 * was used, but the filtee wasn't supplied.
1169 if (filter
&& (ms
.ms_filtee
== NULL
)) {
1170 mf_fatal(mf
, MSG_INTL(MSG_MAP_NOFILTER
),
1177 * Add the new symbol. It should be noted that all
1178 * symbols added by the mapfile start out with global
1179 * scope, thus they will fall through the normal symbol
1180 * resolution process. Symbols defined as locals will
1181 * be reduced in scope after all input file processing.
1183 if (!ld_map_sym_enter(mf
, &mv
, &ms
))
1188 mf_fatal0(mf
, MSG_INTL(MSG_MAP_EXPSCOL
));
1198 * Determine if any version references are provided after the close
1199 * bracket, parsing up to the terminating ';'.
1201 if (!ld_map_sym_ver_fini(mf
, &mv
))
1208 * Parse the mapfile --- Sysv syntax
1211 ld_map_parse_v1(Mapfile
*mf
)
1213 Sg_desc
*sgp1
; /* seg descriptor being manipulated */
1214 Ent_desc
*enp
; /* segment entrance criteria. */
1215 Token tok
; /* current token. */
1216 Boolean new_segment
; /* If true, defines new segment */
1218 Ofl_desc
*ofl
= mf
->mf_ofl
;
1219 ld_map_tkval_t tkv
; /* Value of token */
1223 * We now parse the mapfile until the gettoken routine returns EOF.
1225 while ((tok
= ld_map_gettoken(mf
, TK_F_EOFOK
, &tkv
)) != TK_EOF
) {
1229 * At this point we are at the beginning of a line, and the
1230 * variable tkv.tkv_str points to the first string on the line.
1231 * All mapfile entries start with some string token except it
1232 * is possible for a scoping definition to start with `{'.
1234 if (tok
== TK_LEFTBKT
) {
1235 if (!map_version(mf
, NULL
))
1239 if (tok
!= TK_STRING
) {
1240 if (tok
!= TK_ERROR
)
1241 mf_fatal0(mf
, MSG_INTL(MSG_MAP_EXPSEGNAM
));
1246 * Save the initial token.
1251 * Now check the second character on the line. The special `-'
1252 * and `{' characters do not involve any segment manipulation so
1253 * we handle them first.
1255 tok
= ld_map_gettoken(mf
, 0, &tkv
);
1256 if (tok
== TK_ERROR
)
1258 if (tok
== TK_DASH
) {
1259 if (!map_dash(mf
, name
))
1263 if (tok
== TK_LEFTBKT
) {
1264 if (!map_version(mf
, name
))
1270 * If we're here we need to interpret the first string as a
1271 * segment name. Is this an already known segment?
1273 sgp1
= ld_seg_lookup(mf
->mf_ofl
, name
, &where
);
1274 new_segment
= sgp1
== NULL
;
1276 sgp1
->sg_flags
&= ~FLG_SG_DISABLED
;
1279 * If the second token is a '|' then we had better have found a
1280 * segment. It is illegal to perform section within segment
1281 * ordering before the segment has been declared.
1283 if (tok
== TK_PIPE
) {
1285 mf_fatal(mf
, MSG_INTL(MSG_MAP_SECINSEG
),
1289 if (!map_pipe(mf
, sgp1
))
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.
1300 ((sgp1
= ld_map_seg_alloc(name
, PT_NULL
, 0)) == NULL
))
1304 * Now check the second token from the input line.
1307 case TK_EQUAL
: /* Create/modify segment */
1309 * We use the same syntax for hardware/software
1310 * capabilities as we do for segments. If the
1311 * "segment name" matches one of these, then
1312 * process the capabilities instead of treating it
1313 * as a segment. Note that no dynamic memory has
1314 * been allocated for the segment descriptor yet,
1315 * so we can bail without leaking memory.
1317 if (strcmp(sgp1
->sg_name
,
1318 MSG_ORIG(MSG_STR_HWCAP_1
)) == 0) {
1319 if (!map_cap(mf
, CA_SUNW_HW_1
,
1320 &ofl
->ofl_ocapset
.oc_hw_1
))
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
))
1333 * If not a new segment, show the initial value
1334 * before modifying it.
1336 if (!new_segment
&& DBG_ENABLED
) {
1337 ndx
= ld_map_seg_index(mf
, sgp1
);
1338 Dbg_map_seg(ofl
, DBG_STATE_MOD_BEFORE
,
1339 ndx
, sgp1
, mf
->mf_lineno
);
1342 /* Process the segment */
1343 if (!map_equal(mf
, sgp1
))
1347 * Special case for STACK "segments":
1349 * The ability to modify the stack flags was added
1350 * long after this sysv syntax was designed. It was
1351 * fit into the existing syntax by treating it as a
1352 * segment. However, there can only be one stack program
1353 * header, while segment syntax requires user to supply
1354 * a name. This is confusing, and it allows the user to
1355 * attempt to create more than one stack segment. The
1356 * original implementation had a test to catch this.
1358 * If this is a stack segment, locate the real stack
1359 * descriptor and transfer the flags to it. We then
1360 * free the allocated descriptor without inserting it.
1361 * The end result is that all stack segments simply
1362 * alter the one stack descriptor, and the segment
1365 if (sgp1
->sg_phdr
.p_type
== PT_SUNWSTACK
) {
1366 Sg_desc
*stack
= ld_map_seg_stack(mf
);
1368 if (sgp1
->sg_flags
& FLG_SG_P_FLAGS
)
1369 stack
->sg_phdr
.p_flags
=
1370 sgp1
->sg_phdr
.p_flags
;
1373 DBG_CALL(Dbg_map_seg(ofl
,
1374 DBG_STATE_MOD_AFTER
, ndx
, sgp1
,
1380 * If this is a new segment, finish its initialization
1381 * and insert it into the segment list.
1384 switch (ld_map_seg_insert(mf
, DBG_STATE_NEW
,
1392 /* Not new. Show what's changed */
1393 DBG_CALL(Dbg_map_seg(ofl
,
1394 DBG_STATE_MOD_AFTER
, ndx
, sgp1
,
1399 case TK_COLON
: /* Section to segment mapping */
1401 * If this is a new segment, finish its initialization
1402 * and insert it into the segment list.
1404 * If it is not a new segment, ensure that it is
1405 * not an empty segment reservation, as sections
1406 * cannot be assigned to those.
1409 switch (ld_map_seg_insert(mf
,
1410 DBG_STATE_NEW_IMPLICIT
, sgp1
, where
)) {
1416 } else if (sgp1
->sg_flags
& FLG_SG_EMPTY
) {
1417 mf_fatal0(mf
, MSG_INTL(MSG_MAP_SEGEMPSEC
));
1422 * Create new entrance criteria descriptor, and
1423 * process the mapping directive.
1425 enp
= ld_map_seg_ent_add(mf
, sgp1
, NULL
);
1426 if ((enp
== NULL
) || !map_colon(mf
, enp
))
1428 DBG_CALL(Dbg_map_ent(ofl
->ofl_lml
, enp
, ofl
,
1432 case TK_ATSIGN
: /* Section size symbol */
1434 * If this is a new segment, finish its initialization
1435 * and insert it into the segment list.
1438 switch (ld_map_seg_insert(mf
,
1439 DBG_STATE_NEW_IMPLICIT
, sgp1
, where
)) {
1446 if (!map_atsign(mf
, sgp1
))
1451 return (FALSE
); /* Error was already issued */
1454 mf_fatal0(mf
, MSG_INTL(MSG_MAP_EXPEQU
));