17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 55aefb655Srie * Common Development and Distribution License (the "License"). 65aefb655Srie * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 215aefb655Srie 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright (c) 1988 AT&T 247c478bd9Sstevel@tonic-gate * All Rights Reserved 257c478bd9Sstevel@tonic-gate * 2669112eddSAli Bahrami * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 277c478bd9Sstevel@tonic-gate * Use is subject to license terms. 287c478bd9Sstevel@tonic-gate */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate /* 3169112eddSAli Bahrami * Map file parsing (Original SysV syntax). 327c478bd9Sstevel@tonic-gate */ 337c478bd9Sstevel@tonic-gate #include <string.h> 3469112eddSAli Bahrami #include <strings.h> 357c478bd9Sstevel@tonic-gate #include <stdio.h> 367c478bd9Sstevel@tonic-gate #include <unistd.h> 377c478bd9Sstevel@tonic-gate #include <errno.h> 387c478bd9Sstevel@tonic-gate #include <limits.h> 397c478bd9Sstevel@tonic-gate #include <ctype.h> 407c478bd9Sstevel@tonic-gate #include <elfcap.h> 415aefb655Srie #include <debug.h> 427c478bd9Sstevel@tonic-gate #include "msg.h" 437c478bd9Sstevel@tonic-gate #include "_libld.h" 4469112eddSAli Bahrami #include "_map.h" 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate /* 477c478bd9Sstevel@tonic-gate * Process a hardware/software capabilities segment declaration definition. 487c478bd9Sstevel@tonic-gate * hwcap_1 = val,... [ OVERRIDE ] 497c478bd9Sstevel@tonic-gate * sfcap_1 = val,... [ OVERRIDE ] 50*08278a5eSRod Evans * hwcap_2 = val,... [ OVERRIDE ] 51*08278a5eSRod Evans * platcap = name,... [ OVERRIDE ] 52*08278a5eSRod Evans * machcap = name,... [ OVERRIDE ] 537c478bd9Sstevel@tonic-gate * 547c478bd9Sstevel@tonic-gate * The values can be defined as a list of machine specify tokens, or numerics. 557c478bd9Sstevel@tonic-gate * Tokens are representations of the sys/auxv_$MACH.h capabilities, for example: 567c478bd9Sstevel@tonic-gate * 577c478bd9Sstevel@tonic-gate * #define AV_386_FPU 0x0001 is represented as FPU 587c478bd9Sstevel@tonic-gate * #define AV_386_TSC 0x0002 " " " " TSC 597c478bd9Sstevel@tonic-gate * 607c478bd9Sstevel@tonic-gate * Or, the above two capabilities could be represented as V0x3. Note, the 61635216b6SRod Evans * OVERRIDE flag is used to ensure that only those values provided via this 627c478bd9Sstevel@tonic-gate * mapfile entry are recorded in the final image, ie. this overrides any 63*08278a5eSRod Evans * hardware capabilities that may be defined in the objects read as part of 64*08278a5eSRod Evans * this link-edit. Specifying: 657c478bd9Sstevel@tonic-gate * 667c478bd9Sstevel@tonic-gate * V0x0 OVERRIDE 677c478bd9Sstevel@tonic-gate * 687c478bd9Sstevel@tonic-gate * effectively removes any capabilities information from the final image. 697c478bd9Sstevel@tonic-gate */ 7069112eddSAli Bahrami static Boolean 71*08278a5eSRod Evans map_cap(Mapfile *mf, Word type, Capmask *capmask) 727c478bd9Sstevel@tonic-gate { 737c478bd9Sstevel@tonic-gate Token tok; /* Current token. */ 747c478bd9Sstevel@tonic-gate Xword number; 757c478bd9Sstevel@tonic-gate int used = 0; 7669112eddSAli Bahrami Ofl_desc *ofl = mf->mf_ofl; 7769112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */ 7869112eddSAli Bahrami elfcap_mask_t value = 0; 797c478bd9Sstevel@tonic-gate 8069112eddSAli Bahrami if (DBG_ENABLED) { 8169112eddSAli Bahrami Dbg_cap_mapfile_title(ofl->ofl_lml, mf->mf_lineno); 82*08278a5eSRod Evans Dbg_cap_val_entry(ofl->ofl_lml, DBG_STATE_CURRENT, CA_SUNW_HW_1, 83*08278a5eSRod Evans capmask->cm_val, ld_targ.t_m.m_mach); 847c478bd9Sstevel@tonic-gate } 857c478bd9Sstevel@tonic-gate 8669112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, TK_F_STRLC, &tkv)) != 8769112eddSAli Bahrami TK_SEMICOLON) { 8869112eddSAli Bahrami if (tok != TK_STRING) { 8969112eddSAli Bahrami if (tok != TK_ERROR) 9069112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGATT)); 9169112eddSAli Bahrami return (FALSE); 9269112eddSAli Bahrami } 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate /* 957c478bd9Sstevel@tonic-gate * First, determine if the token represents the reserved 967c478bd9Sstevel@tonic-gate * OVERRIDE keyword. 977c478bd9Sstevel@tonic-gate */ 9869112eddSAli Bahrami if (strncmp(tkv.tkv_str, MSG_ORIG(MSG_MAP_OVERRIDE), 997c478bd9Sstevel@tonic-gate MSG_MAP_OVERRIDE_SIZE) == 0) { 10069112eddSAli Bahrami ld_map_cap_set_ovflag(mf, type); 10169112eddSAli Bahrami used++; 10269112eddSAli Bahrami continue; 10369112eddSAli Bahrami } 10469112eddSAli Bahrami 10569112eddSAli Bahrami /* Is the token a symbolic capability name? */ 10669112eddSAli Bahrami if ((number = (Xword)elfcap_tag_from_str(ELFCAP_STYLE_LC, 10769112eddSAli Bahrami type, tkv.tkv_str, ld_targ.t_m.m_mach)) != 0) { 10869112eddSAli Bahrami value |= number; 1097c478bd9Sstevel@tonic-gate used++; 1107c478bd9Sstevel@tonic-gate continue; 1117c478bd9Sstevel@tonic-gate } 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate /* 11469112eddSAli Bahrami * Is the token a numeric value? 1157c478bd9Sstevel@tonic-gate */ 11669112eddSAli Bahrami if (tkv.tkv_str[0] == 'v') { 11769112eddSAli Bahrami if (ld_map_strtoxword(&tkv.tkv_str[1], NULL, 11869112eddSAli Bahrami &number) != STRTOXWORD_OK) { 11969112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_BADCAPVAL), 12069112eddSAli Bahrami tkv.tkv_str); 12169112eddSAli Bahrami return (FALSE); 1227c478bd9Sstevel@tonic-gate } 12369112eddSAli Bahrami value |= number; 1247c478bd9Sstevel@tonic-gate used++; 1257c478bd9Sstevel@tonic-gate continue; 1267c478bd9Sstevel@tonic-gate } 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate /* 1297c478bd9Sstevel@tonic-gate * We have an unknown token. 1307c478bd9Sstevel@tonic-gate */ 1317c478bd9Sstevel@tonic-gate used++; 13269112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_UNKCAPATTR), tkv.tkv_str); 133d1827f25Srie return (FALSE); 134d1827f25Srie } 13569112eddSAli Bahrami 13669112eddSAli Bahrami /* Catch empty declarations */ 13769112eddSAli Bahrami if (used == 0) { 13869112eddSAli Bahrami mf_warn0(mf, MSG_INTL(MSG_MAP_EMPTYCAP)); 13969112eddSAli Bahrami return (TRUE); 140d1827f25Srie } 14169112eddSAli Bahrami 142*08278a5eSRod Evans DBG_CALL(Dbg_cap_val_entry(ofl->ofl_lml, DBG_STATE_NEW, type, value, 143*08278a5eSRod Evans ld_targ.t_m.m_mach)); 144*08278a5eSRod Evans capmask->cm_val |= value; 14569112eddSAli Bahrami 14669112eddSAli Bahrami /* Sanity check the resulting bits */ 14769112eddSAli Bahrami if (!ld_map_cap_sanitize(mf, type, capmask)) 14869112eddSAli Bahrami return (FALSE); 14969112eddSAli Bahrami 150d1827f25Srie return (TRUE); 151d1827f25Srie } 152d1827f25Srie 153d1827f25Srie /* 15469112eddSAli Bahrami * Parse the flags for a segment definition. Called by map_equal(). 15569112eddSAli Bahrami * 15669112eddSAli Bahrami * entry: 15769112eddSAli Bahrami * mf - Mapfile descriptor 15869112eddSAli Bahrami * sgp - Segment being defined 15969112eddSAli Bahrami * b_flags - Address of b_flags variable from map_equal(). 16069112eddSAli Bahrami * *bflags is TRUE if flags have already been seen in, the 16169112eddSAli Bahrami * current segment definition directive, and FALSE otherwise. 16269112eddSAli Bahrami * flag_tok - Flags string, starting with the '?' character. 16369112eddSAli Bahrami * 16469112eddSAli Bahrami * exit: 16569112eddSAli Bahrami * On success, the flags have been parsed and the segment updated, 16669112eddSAli Bahrami * *b_flags is set to TRUE, and TRUE is returned. On error, FALSE 16769112eddSAli Bahrami * is returned. 1687c478bd9Sstevel@tonic-gate */ 16969112eddSAli Bahrami static Boolean 17069112eddSAli Bahrami map_equal_flags(Mapfile *mf, Sg_desc *sgp, Boolean *b_flags, 17169112eddSAli Bahrami const char *flag_tok) 1727c478bd9Sstevel@tonic-gate { 1737c478bd9Sstevel@tonic-gate Word tmp_flags = 0; 1747c478bd9Sstevel@tonic-gate 17569112eddSAli Bahrami if (*b_flags) { 17669112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE), 1777c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGFLAG)); 17869112eddSAli Bahrami return (FALSE); 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate 18169112eddSAli Bahrami /* Skip over the leading '?' character */ 18269112eddSAli Bahrami flag_tok++; 18369112eddSAli Bahrami 1847c478bd9Sstevel@tonic-gate /* 1857c478bd9Sstevel@tonic-gate * If ? has nothing following leave the flags cleared, 18669112eddSAli Bahrami * otherwise OR in any flags specified. 1877c478bd9Sstevel@tonic-gate */ 1887c478bd9Sstevel@tonic-gate while (*flag_tok) { 1897c478bd9Sstevel@tonic-gate switch (*flag_tok) { 1907c478bd9Sstevel@tonic-gate case 'r': 1917c478bd9Sstevel@tonic-gate tmp_flags |= PF_R; 1927c478bd9Sstevel@tonic-gate break; 1937c478bd9Sstevel@tonic-gate case 'w': 1947c478bd9Sstevel@tonic-gate tmp_flags |= PF_W; 1957c478bd9Sstevel@tonic-gate break; 1967c478bd9Sstevel@tonic-gate case 'x': 1977c478bd9Sstevel@tonic-gate tmp_flags |= PF_X; 1987c478bd9Sstevel@tonic-gate break; 1997c478bd9Sstevel@tonic-gate case 'e': 2007c478bd9Sstevel@tonic-gate sgp->sg_flags |= FLG_SG_EMPTY; 2017c478bd9Sstevel@tonic-gate break; 2027c478bd9Sstevel@tonic-gate case 'o': 20369112eddSAli Bahrami /* 20469112eddSAli Bahrami * The version 1 ?O option is incompatible with 20569112eddSAli Bahrami * the version 2 SEGMENT IS_ORDER attribute. 20669112eddSAli Bahrami */ 20769112eddSAli Bahrami if (aplist_nitems(sgp->sg_is_order) > 0) { 20869112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_ISORDVER), 20969112eddSAli Bahrami sgp->sg_name); 21069112eddSAli Bahrami return (FALSE); 21169112eddSAli Bahrami } 21269112eddSAli Bahrami 21369112eddSAli Bahrami /* 21469112eddSAli Bahrami * Set FLG_SG_IS_ORDER to indicate that segment has 21569112eddSAli Bahrami * had the ?O flag set by a version 1 mapfile. 21669112eddSAli Bahrami */ 21769112eddSAli Bahrami sgp->sg_flags |= FLG_SG_IS_ORDER; 2187c478bd9Sstevel@tonic-gate break; 2197c478bd9Sstevel@tonic-gate case 'n': 22069112eddSAli Bahrami /* 22169112eddSAli Bahrami * If segment ends up as the first loadable segment, 22269112eddSAli Bahrami * it will not include the the ELF and program headers. 22369112eddSAli Bahrami */ 2247c478bd9Sstevel@tonic-gate sgp->sg_flags |= FLG_SG_NOHDR; 2257c478bd9Sstevel@tonic-gate break; 2267c478bd9Sstevel@tonic-gate default: 22769112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSEGFLG), *flag_tok); 22869112eddSAli Bahrami return (FALSE); 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate flag_tok++; 2317c478bd9Sstevel@tonic-gate } 23269112eddSAli Bahrami 2337c478bd9Sstevel@tonic-gate /* 23469112eddSAli Bahrami * Warn when changing flags except when we're adding or removing "X" 23569112eddSAli Bahrami * from a RW PT_LOAD segment. 2367c478bd9Sstevel@tonic-gate */ 23769112eddSAli Bahrami if ((sgp->sg_flags & FLG_SG_P_FLAGS) && 2387c478bd9Sstevel@tonic-gate (sgp->sg_phdr.p_flags != tmp_flags) && 2397c478bd9Sstevel@tonic-gate !(sgp->sg_phdr.p_type == PT_LOAD && 2407c478bd9Sstevel@tonic-gate (tmp_flags & (PF_R|PF_W)) == (PF_R|PF_W) && 24169112eddSAli Bahrami (tmp_flags ^ sgp->sg_phdr.p_flags) == PF_X)) 24269112eddSAli Bahrami mf_warn(mf, MSG_INTL(MSG_MAP_REDEFATT), 2437c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGFLAG), sgp->sg_name); 24469112eddSAli Bahrami 24569112eddSAli Bahrami sgp->sg_flags |= FLG_SG_P_FLAGS; 2467c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_flags = tmp_flags; 24769112eddSAli Bahrami *b_flags = TRUE; 24869112eddSAli Bahrami 24969112eddSAli Bahrami return (TRUE); 25069112eddSAli Bahrami } 25169112eddSAli Bahrami 25269112eddSAli Bahrami /* 25369112eddSAli Bahrami * Read an address (value) or size Xword from a TK_STRING token value 25469112eddSAli Bahrami * where the first letter of the string is a letter ('v', 'l', 's', ...) 25569112eddSAli Bahrami * followed by the numeric value. 25669112eddSAli Bahrami * 25769112eddSAli Bahrami * entry: 25869112eddSAli Bahrami * mf - Mapfile descriptor 25969112eddSAli Bahrami * tkv - TK_STRING token to parse 26069112eddSAli Bahrami * value - Address of variable to receive the resulting value. 26169112eddSAli Bahrami * 26269112eddSAli Bahrami * exit: 26369112eddSAli Bahrami * Returns TRUE for success. On failure, issues an error message 26469112eddSAli Bahrami * and returns FALSE. 26569112eddSAli Bahrami */ 26669112eddSAli Bahrami static Boolean 26769112eddSAli Bahrami valuetoxword(Mapfile *mf, ld_map_tkval_t *tkv, Xword *value) 26869112eddSAli Bahrami { 26969112eddSAli Bahrami switch (ld_map_strtoxword(&tkv->tkv_str[1], NULL, value)) { 27069112eddSAli Bahrami case STRTOXWORD_OK: 27169112eddSAli Bahrami return (TRUE); 27269112eddSAli Bahrami 27369112eddSAli Bahrami case STRTOXWORD_TOOBIG: 27469112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_SEGADDR), tkv->tkv_str, 27569112eddSAli Bahrami MSG_INTL(MSG_MAP_EXCLIMIT)); 27669112eddSAli Bahrami break; 27769112eddSAli Bahrami default: 27869112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_SEGADDR), tkv->tkv_str, 27969112eddSAli Bahrami MSG_INTL(MSG_MAP_NOBADFRM)); 28069112eddSAli Bahrami break; 28169112eddSAli Bahrami } 28269112eddSAli Bahrami 28369112eddSAli Bahrami return (FALSE); 28469112eddSAli Bahrami } 28569112eddSAli Bahrami 28669112eddSAli Bahrami /* 28769112eddSAli Bahrami * Process a mapfile segment declaration definition. 28869112eddSAli Bahrami * segment_name = segment_attribute; 28969112eddSAli Bahrami * segment_attribute : segment_type segment_flags virtual_addr 29069112eddSAli Bahrami * physical_addr length alignment 29169112eddSAli Bahrami */ 29269112eddSAli Bahrami static Boolean 29369112eddSAli Bahrami map_equal(Mapfile *mf, Sg_desc *sgp) 29469112eddSAli Bahrami { 29569112eddSAli Bahrami /* 29669112eddSAli Bahrami * Segment type. Users are permitted to define PT_LOAD, 29769112eddSAli Bahrami * PT_NOTE, PT_SUNWSTACK and PT_NULL segments. Other segment 29869112eddSAli Bahrami * types are only defined in seg_desc[]. 29969112eddSAli Bahrami */ 30069112eddSAli Bahrami typedef struct { 30169112eddSAli Bahrami const char *name; /* Name for segment type */ 30269112eddSAli Bahrami Word p_type; /* PT_ constant corresponding to name */ 30369112eddSAli Bahrami sg_flags_t sg_flags; /* Seg descriptor flags to apply */ 30469112eddSAli Bahrami } seg_types_t; 30569112eddSAli Bahrami 30669112eddSAli Bahrami static seg_types_t seg_type_arr[] = { 30769112eddSAli Bahrami { MSG_ORIG(MSG_MAP_LOAD), PT_LOAD, FLG_SG_P_TYPE }, 30869112eddSAli Bahrami { MSG_ORIG(MSG_MAP_STACK), PT_SUNWSTACK, 30969112eddSAli Bahrami FLG_SG_P_TYPE | FLG_SG_EMPTY }, 31069112eddSAli Bahrami { MSG_ORIG(MSG_MAP_NULL), PT_NULL, FLG_SG_P_TYPE }, 31169112eddSAli Bahrami { MSG_ORIG(MSG_MAP_NOTE), PT_NOTE, FLG_SG_P_TYPE }, 31269112eddSAli Bahrami 31369112eddSAli Bahrami /* Array must be NULL terminated */ 31469112eddSAli Bahrami { NULL } 31569112eddSAli Bahrami }; 31669112eddSAli Bahrami 31769112eddSAli Bahrami 31869112eddSAli Bahrami seg_types_t *seg_type; 31969112eddSAli Bahrami Token tok; /* Current token. */ 32069112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */ 32169112eddSAli Bahrami Boolean b_type = FALSE; /* True if seg types found. */ 32269112eddSAli Bahrami Boolean b_flags = FALSE; /* True if seg flags found. */ 32369112eddSAli Bahrami Boolean b_len = FALSE; /* True if seg length found. */ 32469112eddSAli Bahrami Boolean b_round = FALSE; /* True if seg rounding found. */ 32569112eddSAli Bahrami Boolean b_vaddr = FALSE; /* True if seg virtual addr found. */ 32669112eddSAli Bahrami Boolean b_paddr = FALSE; /* True if seg physical addr found. */ 32769112eddSAli Bahrami Boolean b_align = FALSE; /* True if seg alignment found. */ 32869112eddSAli Bahrami 32969112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, TK_F_STRLC, &tkv)) != 33069112eddSAli Bahrami TK_SEMICOLON) { 33169112eddSAli Bahrami if (tok != TK_STRING) { 33269112eddSAli Bahrami if (tok != TK_ERROR) 33369112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGATT)); 33469112eddSAli Bahrami return (FALSE); 33569112eddSAli Bahrami } 33669112eddSAli Bahrami 33769112eddSAli Bahrami /* 33869112eddSAli Bahrami * If it is the name of a segment type, set the type 33969112eddSAli Bahrami * and flags fields in the descriptor. 34069112eddSAli Bahrami */ 34169112eddSAli Bahrami for (seg_type = seg_type_arr; seg_type->name; seg_type++) { 34269112eddSAli Bahrami if (strcmp(tkv.tkv_str, seg_type->name) == 0) { 34369112eddSAli Bahrami if (b_type) { 34469112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE), 34569112eddSAli Bahrami MSG_INTL(MSG_MAP_SEGTYP)); 34669112eddSAli Bahrami return (FALSE); 34769112eddSAli Bahrami } 34869112eddSAli Bahrami if ((sgp->sg_flags & FLG_SG_P_TYPE) && 34969112eddSAli Bahrami (sgp->sg_phdr.p_type != seg_type->p_type)) { 35069112eddSAli Bahrami mf_warn(mf, MSG_INTL(MSG_MAP_REDEFATT), 35169112eddSAli Bahrami MSG_INTL(MSG_MAP_SEGTYP), 35269112eddSAli Bahrami sgp->sg_name); 35369112eddSAli Bahrami } 35469112eddSAli Bahrami 35569112eddSAli Bahrami sgp->sg_phdr.p_type = seg_type->p_type; 35669112eddSAli Bahrami sgp->sg_flags |= seg_type->sg_flags; 35769112eddSAli Bahrami break; 35869112eddSAli Bahrami } 35969112eddSAli Bahrami } 36069112eddSAli Bahrami if (seg_type->name != NULL) /* Matched segment type */ 36169112eddSAli Bahrami continue; /* next token */ 36269112eddSAli Bahrami 36369112eddSAli Bahrami /* Segment Flags */ 36469112eddSAli Bahrami if (*tkv.tkv_str == '?') { 36569112eddSAli Bahrami if (!map_equal_flags(mf, sgp, &b_flags, tkv.tkv_str)) 36669112eddSAli Bahrami return (FALSE); 36769112eddSAli Bahrami continue; /* next token */ 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate 37169112eddSAli Bahrami /* Segment address, length, alignment or rounding number */ 37269112eddSAli Bahrami if ((tkv.tkv_str[0] == 'l') || (tkv.tkv_str[0] == 'v') || 37369112eddSAli Bahrami (tkv.tkv_str[0] == 'a') || (tkv.tkv_str[0] == 'p') || 37469112eddSAli Bahrami (tkv.tkv_str[0] == 'r')) { 3757c478bd9Sstevel@tonic-gate Xword number; 3767c478bd9Sstevel@tonic-gate 37769112eddSAli Bahrami if (!valuetoxword(mf, &tkv, &number)) 37869112eddSAli Bahrami return (FALSE); 3797c478bd9Sstevel@tonic-gate 38069112eddSAli Bahrami switch (*tkv.tkv_str) { 3817c478bd9Sstevel@tonic-gate case 'l': 3827c478bd9Sstevel@tonic-gate if (b_len) { 38369112eddSAli Bahrami mf_fatal(mf, 3847c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_MOREONCE), 3857c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGLEN)); 38669112eddSAli Bahrami return (FALSE); 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate if ((sgp->sg_flags & FLG_SG_LENGTH) && 3897c478bd9Sstevel@tonic-gate (sgp->sg_length != number)) 39069112eddSAli Bahrami mf_warn(mf, 3917c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_REDEFATT), 3927c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGLEN), 3937c478bd9Sstevel@tonic-gate sgp->sg_name); 3947c478bd9Sstevel@tonic-gate sgp->sg_length = number; 3957c478bd9Sstevel@tonic-gate sgp->sg_flags |= FLG_SG_LENGTH; 3967c478bd9Sstevel@tonic-gate b_len = TRUE; 3977c478bd9Sstevel@tonic-gate break; 3987c478bd9Sstevel@tonic-gate case 'r': 3997c478bd9Sstevel@tonic-gate if (b_round) { 40069112eddSAli Bahrami mf_fatal(mf, 4017c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_MOREONCE), 4027c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGROUND)); 40369112eddSAli Bahrami return (FALSE); 4047c478bd9Sstevel@tonic-gate } 4057c478bd9Sstevel@tonic-gate if ((sgp->sg_flags & FLG_SG_ROUND) && 4067c478bd9Sstevel@tonic-gate (sgp->sg_round != number)) 40769112eddSAli Bahrami mf_warn(mf, 4087c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_REDEFATT), 4097c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGROUND), 4107c478bd9Sstevel@tonic-gate sgp->sg_name); 4117c478bd9Sstevel@tonic-gate sgp->sg_round = number; 4127c478bd9Sstevel@tonic-gate sgp->sg_flags |= FLG_SG_ROUND; 4137c478bd9Sstevel@tonic-gate b_round = TRUE; 4147c478bd9Sstevel@tonic-gate break; 4157c478bd9Sstevel@tonic-gate case 'v': 4167c478bd9Sstevel@tonic-gate if (b_vaddr) { 41769112eddSAli Bahrami mf_fatal(mf, 4187c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_MOREONCE), 4197c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGVADDR)); 42069112eddSAli Bahrami return (FALSE); 4217c478bd9Sstevel@tonic-gate } 42269112eddSAli Bahrami if ((sgp->sg_flags & FLG_SG_P_VADDR) && 4237c478bd9Sstevel@tonic-gate (sgp->sg_phdr.p_vaddr != number)) 42469112eddSAli Bahrami mf_warn(mf, 4257c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_REDEFATT), 4267c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGVADDR), 4277c478bd9Sstevel@tonic-gate sgp->sg_name); 4287c478bd9Sstevel@tonic-gate /* LINTED */ 4297c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_vaddr = (Addr)number; 43069112eddSAli Bahrami sgp->sg_flags |= FLG_SG_P_VADDR; 4317c478bd9Sstevel@tonic-gate b_vaddr = TRUE; 4327c478bd9Sstevel@tonic-gate break; 4337c478bd9Sstevel@tonic-gate case 'p': 4347c478bd9Sstevel@tonic-gate if (b_paddr) { 43569112eddSAli Bahrami mf_fatal(mf, 4367c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_MOREONCE), 4377c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGPHYS)); 43869112eddSAli Bahrami return (FALSE); 4397c478bd9Sstevel@tonic-gate } 44069112eddSAli Bahrami if ((sgp->sg_flags & FLG_SG_P_PADDR) && 4417c478bd9Sstevel@tonic-gate (sgp->sg_phdr.p_paddr != number)) 44269112eddSAli Bahrami mf_warn(mf, 4437c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_REDEFATT), 4447c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGPHYS), 4457c478bd9Sstevel@tonic-gate sgp->sg_name); 4467c478bd9Sstevel@tonic-gate /* LINTED */ 4477c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_paddr = (Addr)number; 44869112eddSAli Bahrami sgp->sg_flags |= FLG_SG_P_PADDR; 4497c478bd9Sstevel@tonic-gate b_paddr = TRUE; 4507c478bd9Sstevel@tonic-gate break; 4517c478bd9Sstevel@tonic-gate case 'a': 4527c478bd9Sstevel@tonic-gate if (b_align) { 45369112eddSAli Bahrami mf_fatal(mf, 4547c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_MOREONCE), 4557c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGALIGN)); 45669112eddSAli Bahrami return (FALSE); 4577c478bd9Sstevel@tonic-gate } 45869112eddSAli Bahrami if ((sgp->sg_flags & FLG_SG_P_ALIGN) && 4597c478bd9Sstevel@tonic-gate (sgp->sg_phdr.p_align != number)) 46069112eddSAli Bahrami mf_warn(mf, 4617c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_REDEFATT), 4627c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGALIGN), 4637c478bd9Sstevel@tonic-gate sgp->sg_name); 4647c478bd9Sstevel@tonic-gate /* LINTED */ 4657c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_align = (Xword)number; 46669112eddSAli Bahrami sgp->sg_flags |= FLG_SG_P_ALIGN; 4677c478bd9Sstevel@tonic-gate b_align = TRUE; 4687c478bd9Sstevel@tonic-gate break; 4697c478bd9Sstevel@tonic-gate } 47069112eddSAli Bahrami 47169112eddSAli Bahrami continue; /* next token */ 4727c478bd9Sstevel@tonic-gate } 47369112eddSAli Bahrami 47469112eddSAli Bahrami /* 47569112eddSAli Bahrami * If we reach the bottom of this loop, we have an 47669112eddSAli Bahrami * unrecognized token. 47769112eddSAli Bahrami */ 47869112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSEGATT), tkv.tkv_str); 47969112eddSAli Bahrami return (FALSE); 4807c478bd9Sstevel@tonic-gate } 4817c478bd9Sstevel@tonic-gate 4827c478bd9Sstevel@tonic-gate /* 483d1827f25Srie * Empty segments can be used to define PT_LOAD segment reservations, or 484d1827f25Srie * to reserve PT_NULL program headers. 485d1827f25Srie * 486d1827f25Srie * PT_LOAD reservations are only allowed within executables, as the 487d1827f25Srie * reservation must be established through exec() as part of initial 488d1827f25Srie * process loading. In addition, PT_LOAD reservations must have an 48969112eddSAli Bahrami * associated address and size. Note: This is an obsolete feature, 49069112eddSAli Bahrami * not supported by the newer mapfile syntax. 491d1827f25Srie * 492d1827f25Srie * PT_NULL program headers are established for later use by applications 493d1827f25Srie * such as the post-optimizer. PT_NULL headers should have no other 494d1827f25Srie * attributes assigned. 4957c478bd9Sstevel@tonic-gate */ 4967c478bd9Sstevel@tonic-gate if ((sgp->sg_flags & FLG_SG_EMPTY) && 4977c478bd9Sstevel@tonic-gate (sgp->sg_phdr.p_type != PT_SUNWSTACK)) { 498d1827f25Srie 499d1827f25Srie /* 500d1827f25Srie * Any style of empty segment should have no permissions. 501d1827f25Srie */ 5027c478bd9Sstevel@tonic-gate if (sgp->sg_phdr.p_flags != 0) { 50369112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_SEGEMNOPERM), 5047c478bd9Sstevel@tonic-gate EC_WORD(sgp->sg_phdr.p_flags)); 50569112eddSAli Bahrami return (FALSE); 5067c478bd9Sstevel@tonic-gate } 507d1827f25Srie 508d1827f25Srie if (sgp->sg_phdr.p_type == PT_LOAD) { 50969112eddSAli Bahrami if ((mf->mf_ofl->ofl_flags & FLG_OF_EXEC) == 0) { 51069112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPEXE)); 51169112eddSAli Bahrami return (FALSE); 512d1827f25Srie } 51369112eddSAli Bahrami if ((sgp->sg_flags & 51469112eddSAli Bahrami (FLG_SG_LENGTH | FLG_SG_P_VADDR)) != 51569112eddSAli Bahrami (FLG_SG_LENGTH | FLG_SG_P_VADDR)) { 51669112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPATT)); 51769112eddSAli Bahrami return (FALSE); 5187c478bd9Sstevel@tonic-gate } 519d1827f25Srie } else if (sgp->sg_phdr.p_type == PT_NULL) { 52069112eddSAli Bahrami if ((sgp->sg_flags & 52169112eddSAli Bahrami (FLG_SG_LENGTH | FLG_SG_P_VADDR)) && 522d1827f25Srie ((sgp->sg_length != 0) || 523d1827f25Srie (sgp->sg_phdr.p_vaddr != 0))) { 52469112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPNOATT)); 52569112eddSAli Bahrami return (FALSE); 526d1827f25Srie } 527d1827f25Srie } else { 52869112eddSAli Bahrami mf_warn0(mf, MSG_INTL(MSG_MAP_SEGEMPLOAD)); 5297c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_type = PT_LOAD; 5307c478bd9Sstevel@tonic-gate } 5317c478bd9Sstevel@tonic-gate } 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate /* 5347c478bd9Sstevel@tonic-gate * All segment attributes have now been scanned. Certain flags do not 5357c478bd9Sstevel@tonic-gate * make sense if this is not a loadable segment, fix if necessary. 5367c478bd9Sstevel@tonic-gate * Note, if the segment is of type PT_NULL it must be new, and any 53769112eddSAli Bahrami * defaults will be applied by ld_map_seg_insert(). When clearing an 53869112eddSAli Bahrami * attribute leave the flag set as an indicator for later entries 53969112eddSAli Bahrami * re-specifying the same segment. 5407c478bd9Sstevel@tonic-gate */ 541d1827f25Srie if ((sgp->sg_phdr.p_type != PT_NULL) && 542d1827f25Srie (sgp->sg_phdr.p_type != PT_LOAD)) { 5437c478bd9Sstevel@tonic-gate const char *fmt; 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate if (sgp->sg_phdr.p_type == PT_SUNWSTACK) 5467c478bd9Sstevel@tonic-gate fmt = MSG_INTL(MSG_MAP_NOSTACK1); 5477c478bd9Sstevel@tonic-gate else 5487c478bd9Sstevel@tonic-gate fmt = MSG_INTL(MSG_MAP_NONLOAD); 5497c478bd9Sstevel@tonic-gate 55069112eddSAli Bahrami if ((sgp->sg_flags & FLG_SG_P_FLAGS) && 5517c478bd9Sstevel@tonic-gate (sgp->sg_phdr.p_type != PT_SUNWSTACK)) { 5527c478bd9Sstevel@tonic-gate if (sgp->sg_phdr.p_flags != 0) { 55369112eddSAli Bahrami mf_warn(mf, MSG_INTL(MSG_MAP_NONLOAD), 5547c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SEGFLAG)); 5557c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_flags = 0; 5567c478bd9Sstevel@tonic-gate } 5577c478bd9Sstevel@tonic-gate } 5587c478bd9Sstevel@tonic-gate if (sgp->sg_flags & FLG_SG_LENGTH) 5597c478bd9Sstevel@tonic-gate if (sgp->sg_length != 0) { 56069112eddSAli Bahrami mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGLEN)); 5617c478bd9Sstevel@tonic-gate sgp->sg_length = 0; 5627c478bd9Sstevel@tonic-gate } 5637c478bd9Sstevel@tonic-gate if (sgp->sg_flags & FLG_SG_ROUND) 5647c478bd9Sstevel@tonic-gate if (sgp->sg_round != 0) { 56569112eddSAli Bahrami mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGROUND)); 5667c478bd9Sstevel@tonic-gate sgp->sg_round = 0; 5677c478bd9Sstevel@tonic-gate } 56869112eddSAli Bahrami if (sgp->sg_flags & FLG_SG_P_VADDR) { 5697c478bd9Sstevel@tonic-gate if (sgp->sg_phdr.p_vaddr != 0) { 57069112eddSAli Bahrami mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGVADDR)); 5717c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_vaddr = 0; 5727c478bd9Sstevel@tonic-gate } 5737c478bd9Sstevel@tonic-gate } 57469112eddSAli Bahrami if (sgp->sg_flags & FLG_SG_P_PADDR) 5757c478bd9Sstevel@tonic-gate if (sgp->sg_phdr.p_paddr != 0) { 57669112eddSAli Bahrami mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGPHYS)); 5777c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_paddr = 0; 5787c478bd9Sstevel@tonic-gate } 57969112eddSAli Bahrami if (sgp->sg_flags & FLG_SG_P_ALIGN) 5807c478bd9Sstevel@tonic-gate if (sgp->sg_phdr.p_align != 0) { 58169112eddSAli Bahrami mf_warn(mf, fmt, MSG_INTL(MSG_MAP_SEGALIGN)); 5827c478bd9Sstevel@tonic-gate sgp->sg_phdr.p_align = 0; 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate } 58569112eddSAli Bahrami return (TRUE); 5867c478bd9Sstevel@tonic-gate } 5877c478bd9Sstevel@tonic-gate 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate /* 5907c478bd9Sstevel@tonic-gate * Process a mapfile mapping directives definition. 59169112eddSAli Bahrami * 5927c478bd9Sstevel@tonic-gate * segment_name : section_attribute [ : file_name ] 59369112eddSAli Bahrami * 59469112eddSAli Bahrami * Where segment_attribute is one of: section_name section_type section_flags; 5957c478bd9Sstevel@tonic-gate */ 59669112eddSAli Bahrami static Boolean 59769112eddSAli Bahrami map_colon(Mapfile *mf, Ent_desc *enp) 5987c478bd9Sstevel@tonic-gate { 59969112eddSAli Bahrami Token tok; 60069112eddSAli Bahrami ld_map_tkval_t tkv; 6017c478bd9Sstevel@tonic-gate Boolean b_name = FALSE; 6027c478bd9Sstevel@tonic-gate Boolean b_type = FALSE; 6037c478bd9Sstevel@tonic-gate Boolean b_attr = FALSE; 6047c478bd9Sstevel@tonic-gate Boolean b_bang = FALSE; 6057c478bd9Sstevel@tonic-gate 6067c478bd9Sstevel@tonic-gate 60769112eddSAli Bahrami /* 60869112eddSAli Bahrami * Start out assuming that this entrance criteria will be empty, 60969112eddSAli Bahrami * and therefore match anything. We clear the CATCHALL flag below 61069112eddSAli Bahrami * if this turns out not to be the case. 61169112eddSAli Bahrami */ 61269112eddSAli Bahrami enp->ec_flags |= FLG_EC_CATCHALL; 61369112eddSAli Bahrami 61469112eddSAli Bahrami while (((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_COLON) && 6155aefb655Srie (tok != TK_SEMICOLON)) { 61669112eddSAli Bahrami if (tok == TK_ERROR) 61769112eddSAli Bahrami return (FALSE); 61869112eddSAli Bahrami if (tok != TK_STRING) { 61969112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_MALFORM)); 62069112eddSAli Bahrami return (FALSE); 62169112eddSAli Bahrami } 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate /* Segment type. */ 6247c478bd9Sstevel@tonic-gate 62569112eddSAli Bahrami if (*tkv.tkv_str == '$') { 6267c478bd9Sstevel@tonic-gate if (b_type) { 62769112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE), 6287c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SECTYP)); 62969112eddSAli Bahrami return (FALSE); 6307c478bd9Sstevel@tonic-gate } 6317c478bd9Sstevel@tonic-gate b_type = TRUE; 63269112eddSAli Bahrami tkv.tkv_str++; 63369112eddSAli Bahrami ld_map_lowercase(tkv.tkv_str); 63469112eddSAli Bahrami if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_PROGBITS)) == 63569112eddSAli Bahrami 0) 6367c478bd9Sstevel@tonic-gate enp->ec_type = SHT_PROGBITS; 63769112eddSAli Bahrami else if (strcmp(tkv.tkv_str, 6387c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_SYMTAB)) == 0) 6397c478bd9Sstevel@tonic-gate enp->ec_type = SHT_SYMTAB; 64069112eddSAli Bahrami else if (strcmp(tkv.tkv_str, 6417c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_DYNSYM)) == 0) 6427c478bd9Sstevel@tonic-gate enp->ec_type = SHT_DYNSYM; 64369112eddSAli Bahrami else if (strcmp(tkv.tkv_str, 6447c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_STRTAB)) == 0) 6457c478bd9Sstevel@tonic-gate enp->ec_type = SHT_STRTAB; 64669112eddSAli Bahrami else if ((strcmp(tkv.tkv_str, 6477c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_REL)) == 0) || 64869112eddSAli Bahrami (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_RELA)) == 0)) 649ba2be530Sab196087 enp->ec_type = ld_targ.t_m.m_rel_sht_type; 65069112eddSAli Bahrami else if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_HASH)) == 65169112eddSAli Bahrami 0) 6527c478bd9Sstevel@tonic-gate enp->ec_type = SHT_HASH; 65369112eddSAli Bahrami else if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_LIB)) == 65469112eddSAli Bahrami 0) 6557c478bd9Sstevel@tonic-gate enp->ec_type = SHT_SHLIB; 65669112eddSAli Bahrami else if (strcmp(tkv.tkv_str, 6577c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_LD_DYNAMIC)) == 0) 6587c478bd9Sstevel@tonic-gate enp->ec_type = SHT_DYNAMIC; 65969112eddSAli Bahrami else if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_STR_NOTE)) == 66069112eddSAli Bahrami 0) 6617c478bd9Sstevel@tonic-gate enp->ec_type = SHT_NOTE; 66269112eddSAli Bahrami else if (strcmp(tkv.tkv_str, 6637c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_NOBITS)) == 0) 6647c478bd9Sstevel@tonic-gate enp->ec_type = SHT_NOBITS; 6657c478bd9Sstevel@tonic-gate else { 66669112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSECTYP), 66769112eddSAli Bahrami tkv.tkv_str); 66869112eddSAli Bahrami return (FALSE); 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate 67169112eddSAli Bahrami enp->ec_flags &= ~FLG_EC_CATCHALL; 67269112eddSAli Bahrami 6737c478bd9Sstevel@tonic-gate /* 6747c478bd9Sstevel@tonic-gate * Segment flags. 6757c478bd9Sstevel@tonic-gate * If a segment flag is specified then the appropriate bit is 6767c478bd9Sstevel@tonic-gate * set in the ec_attrmask, the ec_attrbits fields determine 6777c478bd9Sstevel@tonic-gate * whether the attrmask fields must be tested true or false 6787c478bd9Sstevel@tonic-gate * ie. for ?A the attrmask is set and the attrbit is set, 6797c478bd9Sstevel@tonic-gate * for ?!A the attrmask is set and the attrbit is clear. 6807c478bd9Sstevel@tonic-gate */ 68169112eddSAli Bahrami } else if (*tkv.tkv_str == '?') { 6827c478bd9Sstevel@tonic-gate if (b_attr) { 68369112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE), 6847c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SECFLAG)); 68569112eddSAli Bahrami return (FALSE); 6867c478bd9Sstevel@tonic-gate } 6877c478bd9Sstevel@tonic-gate b_attr = TRUE; 6887c478bd9Sstevel@tonic-gate b_bang = FALSE; 68969112eddSAli Bahrami tkv.tkv_str++; 69069112eddSAli Bahrami ld_map_lowercase(tkv.tkv_str); 69169112eddSAli Bahrami for (; *tkv.tkv_str != '\0'; tkv.tkv_str++) 69269112eddSAli Bahrami switch (*tkv.tkv_str) { 6937c478bd9Sstevel@tonic-gate case '!': 6947c478bd9Sstevel@tonic-gate if (b_bang) { 69569112eddSAli Bahrami mf_fatal(mf, 6967c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_BADFLAG), 69769112eddSAli Bahrami tkv.tkv_str); 69869112eddSAli Bahrami return (FALSE); 6997c478bd9Sstevel@tonic-gate } 7007c478bd9Sstevel@tonic-gate b_bang = TRUE; 7017c478bd9Sstevel@tonic-gate break; 7027c478bd9Sstevel@tonic-gate case 'a': 7037c478bd9Sstevel@tonic-gate if (enp->ec_attrmask & SHF_ALLOC) { 70469112eddSAli Bahrami mf_fatal(mf, 7057c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_BADFLAG), 70669112eddSAli Bahrami tkv.tkv_str); 70769112eddSAli Bahrami return (FALSE); 7087c478bd9Sstevel@tonic-gate } 7097c478bd9Sstevel@tonic-gate enp->ec_attrmask |= SHF_ALLOC; 7107c478bd9Sstevel@tonic-gate if (!b_bang) 7117c478bd9Sstevel@tonic-gate enp->ec_attrbits |= SHF_ALLOC; 7127c478bd9Sstevel@tonic-gate b_bang = FALSE; 7137c478bd9Sstevel@tonic-gate break; 7147c478bd9Sstevel@tonic-gate case 'w': 7157c478bd9Sstevel@tonic-gate if (enp->ec_attrmask & SHF_WRITE) { 71669112eddSAli Bahrami mf_fatal(mf, 7177c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_BADFLAG), 71869112eddSAli Bahrami tkv.tkv_str); 71969112eddSAli Bahrami return (FALSE); 7207c478bd9Sstevel@tonic-gate } 7217c478bd9Sstevel@tonic-gate enp->ec_attrmask |= SHF_WRITE; 7227c478bd9Sstevel@tonic-gate if (!b_bang) 7237c478bd9Sstevel@tonic-gate enp->ec_attrbits |= SHF_WRITE; 7247c478bd9Sstevel@tonic-gate b_bang = FALSE; 7257c478bd9Sstevel@tonic-gate break; 7267c478bd9Sstevel@tonic-gate case 'x': 7277c478bd9Sstevel@tonic-gate if (enp->ec_attrmask & SHF_EXECINSTR) { 72869112eddSAli Bahrami mf_fatal(mf, 7297c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_BADFLAG), 73069112eddSAli Bahrami tkv.tkv_str); 73169112eddSAli Bahrami return (FALSE); 7327c478bd9Sstevel@tonic-gate } 7337c478bd9Sstevel@tonic-gate enp->ec_attrmask |= SHF_EXECINSTR; 7347c478bd9Sstevel@tonic-gate if (!b_bang) 735a953e2b1Srie enp->ec_attrbits |= 736a953e2b1Srie SHF_EXECINSTR; 7377c478bd9Sstevel@tonic-gate b_bang = FALSE; 7387c478bd9Sstevel@tonic-gate break; 7397c478bd9Sstevel@tonic-gate default: 74069112eddSAli Bahrami mf_fatal(mf, 7417c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_BADFLAG), 74269112eddSAli Bahrami tkv.tkv_str); 74369112eddSAli Bahrami return (FALSE); 7447c478bd9Sstevel@tonic-gate } 74569112eddSAli Bahrami if (enp->ec_attrmask != 0) 74669112eddSAli Bahrami enp->ec_flags &= ~FLG_EC_CATCHALL; 74769112eddSAli Bahrami 7487c478bd9Sstevel@tonic-gate /* 7497c478bd9Sstevel@tonic-gate * Section name. 7507c478bd9Sstevel@tonic-gate */ 7517c478bd9Sstevel@tonic-gate } else { 7527c478bd9Sstevel@tonic-gate if (b_name) { 75369112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_MOREONCE), 7547c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SECNAME)); 75569112eddSAli Bahrami return (FALSE); 7567c478bd9Sstevel@tonic-gate } 7577c478bd9Sstevel@tonic-gate b_name = TRUE; 75869112eddSAli Bahrami enp->ec_is_name = tkv.tkv_str; 75969112eddSAli Bahrami enp->ec_flags &= ~FLG_EC_CATCHALL; 7607c478bd9Sstevel@tonic-gate } 7617c478bd9Sstevel@tonic-gate } 7627c478bd9Sstevel@tonic-gate if (tok == TK_COLON) { 7637c478bd9Sstevel@tonic-gate /* 7647c478bd9Sstevel@tonic-gate * File names. 7657c478bd9Sstevel@tonic-gate */ 76669112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_SEMICOLON) { 76769112eddSAli Bahrami Word ecf_type; 7687c478bd9Sstevel@tonic-gate 7697c478bd9Sstevel@tonic-gate if (tok != TK_STRING) { 77071ae4d73Sab196087 if (tok != TK_ERROR) 77169112eddSAli Bahrami mf_fatal0(mf, 77269112eddSAli Bahrami MSG_INTL(MSG_MAP_MALFORM)); 77369112eddSAli Bahrami return (FALSE); 7747c478bd9Sstevel@tonic-gate } 7757c478bd9Sstevel@tonic-gate 7767c478bd9Sstevel@tonic-gate /* 77769112eddSAli Bahrami * A leading '*' means that this should be a basename 77869112eddSAli Bahrami * comparison rather than a full path. It's not a glob 77969112eddSAli Bahrami * wildcard, although it looks like one. 7807c478bd9Sstevel@tonic-gate */ 78169112eddSAli Bahrami if (tkv.tkv_str[0] == '*') { 78269112eddSAli Bahrami ecf_type = TYP_ECF_BASENAME; 78369112eddSAli Bahrami tkv.tkv_str++; 78469112eddSAli Bahrami } else { 78569112eddSAli Bahrami ecf_type = TYP_ECF_PATH; 78669112eddSAli Bahrami } 78769112eddSAli Bahrami if (!ld_map_seg_ent_files(mf, enp, ecf_type, 78869112eddSAli Bahrami tkv.tkv_str)) 78969112eddSAli Bahrami return (FALSE); 79069112eddSAli Bahrami enp->ec_flags &= ~FLG_EC_CATCHALL; 79169112eddSAli Bahrami } 79269112eddSAli Bahrami } 79369112eddSAli Bahrami return (TRUE); 7947c478bd9Sstevel@tonic-gate } 7957c478bd9Sstevel@tonic-gate 7967c478bd9Sstevel@tonic-gate /* 7977c478bd9Sstevel@tonic-gate * Process a mapfile size symbol definition. 7987c478bd9Sstevel@tonic-gate * segment_name @ symbol_name; 7997c478bd9Sstevel@tonic-gate */ 80069112eddSAli Bahrami static Boolean 80169112eddSAli Bahrami map_atsign(Mapfile *mf, Sg_desc *sgp) 8027c478bd9Sstevel@tonic-gate { 8037c478bd9Sstevel@tonic-gate Token tok; /* Current token. */ 80469112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */ 8057c478bd9Sstevel@tonic-gate 80669112eddSAli Bahrami if ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_STRING) { 80771ae4d73Sab196087 if (tok != TK_ERROR) 80869112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSYM_1)); 80969112eddSAli Bahrami return (FALSE); 8107c478bd9Sstevel@tonic-gate } 8117c478bd9Sstevel@tonic-gate 81269112eddSAli Bahrami /* Add the symbol to the segment */ 81369112eddSAli Bahrami if (!ld_map_seg_size_symbol(mf, sgp, TK_PLUSEQ, tkv.tkv_str)) 81469112eddSAli Bahrami return (FALSE); 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate 81769112eddSAli Bahrami if (ld_map_gettoken(mf, 0, &tkv) != TK_SEMICOLON) { 81871ae4d73Sab196087 if (tok != TK_ERROR) 81969112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSCOL)); 82069112eddSAli Bahrami return (FALSE); 82171ae4d73Sab196087 } 82271ae4d73Sab196087 82369112eddSAli Bahrami return (TRUE); 8247c478bd9Sstevel@tonic-gate } 8257c478bd9Sstevel@tonic-gate 8267c478bd9Sstevel@tonic-gate 82769112eddSAli Bahrami static Boolean 82869112eddSAli Bahrami map_pipe(Mapfile *mf, Sg_desc *sgp) 8297c478bd9Sstevel@tonic-gate { 8307c478bd9Sstevel@tonic-gate Token tok; /* current token. */ 83169112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */ 8327c478bd9Sstevel@tonic-gate 83369112eddSAli Bahrami if ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_STRING) { 83471ae4d73Sab196087 if (tok != TK_ERROR) 83569112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEC)); 83669112eddSAli Bahrami return (FALSE); 8377c478bd9Sstevel@tonic-gate } 8387c478bd9Sstevel@tonic-gate 83969112eddSAli Bahrami if (!ld_map_seg_os_order_add(mf, sgp, tkv.tkv_str)) 84069112eddSAli Bahrami return (FALSE); 8417c478bd9Sstevel@tonic-gate 84269112eddSAli Bahrami if ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_SEMICOLON) { 84371ae4d73Sab196087 if (tok != TK_ERROR) 84469112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSCOL)); 84569112eddSAli Bahrami return (FALSE); 8467c478bd9Sstevel@tonic-gate } 8477c478bd9Sstevel@tonic-gate 84869112eddSAli Bahrami return (TRUE); 8497c478bd9Sstevel@tonic-gate } 8507c478bd9Sstevel@tonic-gate 8517c478bd9Sstevel@tonic-gate /* 8527c478bd9Sstevel@tonic-gate * Process a mapfile library specification definition. 8537c478bd9Sstevel@tonic-gate * shared_object_name - shared object definition 8547c478bd9Sstevel@tonic-gate * shared object definition : [ shared object type [ = SONAME ]] 8557c478bd9Sstevel@tonic-gate * [ versions ]; 8567c478bd9Sstevel@tonic-gate */ 85769112eddSAli Bahrami static Boolean 85869112eddSAli Bahrami map_dash(Mapfile *mf, char *name) 8597c478bd9Sstevel@tonic-gate { 8607c478bd9Sstevel@tonic-gate Token tok; 8617c478bd9Sstevel@tonic-gate Sdf_desc *sdf; 86269112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */ 8637c478bd9Sstevel@tonic-gate enum { 8647c478bd9Sstevel@tonic-gate MD_NONE = 0, 8657c478bd9Sstevel@tonic-gate MD_ADDVERS, 8667c478bd9Sstevel@tonic-gate } dolkey = MD_NONE; 8677c478bd9Sstevel@tonic-gate 86869112eddSAli Bahrami /* Get descriptor for dependency */ 86969112eddSAli Bahrami if ((sdf = ld_map_dv(mf, name)) == NULL) 87069112eddSAli Bahrami return (FALSE); 8717c478bd9Sstevel@tonic-gate 8727c478bd9Sstevel@tonic-gate /* 8737c478bd9Sstevel@tonic-gate * Get the shared object descriptor string. 8747c478bd9Sstevel@tonic-gate */ 87569112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_SEMICOLON) { 8767c478bd9Sstevel@tonic-gate if ((tok != TK_STRING) && (tok != TK_EQUAL)) { 87771ae4d73Sab196087 if (tok != TK_ERROR) 87869112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSO)); 87969112eddSAli Bahrami return (FALSE); 8807c478bd9Sstevel@tonic-gate } 8817c478bd9Sstevel@tonic-gate 8827c478bd9Sstevel@tonic-gate /* 8837c478bd9Sstevel@tonic-gate * Determine if the library type is accompanied with a SONAME 8847c478bd9Sstevel@tonic-gate * definition. 8857c478bd9Sstevel@tonic-gate */ 8867c478bd9Sstevel@tonic-gate if (tok == TK_EQUAL) { 88769112eddSAli Bahrami if ((tok = ld_map_gettoken(mf, 0, &tkv)) != 88869112eddSAli Bahrami TK_STRING) { 88971ae4d73Sab196087 if (tok != TK_ERROR) 89069112eddSAli Bahrami mf_fatal0(mf, 89169112eddSAli Bahrami MSG_INTL(MSG_MAP_EXPSO)); 89269112eddSAli Bahrami return (FALSE); 8937c478bd9Sstevel@tonic-gate } 8947c478bd9Sstevel@tonic-gate switch (dolkey) { 8957c478bd9Sstevel@tonic-gate case MD_ADDVERS: 89669112eddSAli Bahrami if (!ld_map_dv_entry(mf, sdf, TRUE, 89769112eddSAli Bahrami tkv.tkv_str)) 89869112eddSAli Bahrami return (FALSE); 8997c478bd9Sstevel@tonic-gate break; 9007c478bd9Sstevel@tonic-gate case MD_NONE: 90169112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_UNEXTOK), '='); 90269112eddSAli Bahrami return (FALSE); 9037c478bd9Sstevel@tonic-gate } 9047c478bd9Sstevel@tonic-gate dolkey = MD_NONE; 9057c478bd9Sstevel@tonic-gate continue; 9067c478bd9Sstevel@tonic-gate } 9077c478bd9Sstevel@tonic-gate 9087c478bd9Sstevel@tonic-gate /* 9097c478bd9Sstevel@tonic-gate * A shared object type has been specified. This may also be 9107c478bd9Sstevel@tonic-gate * accompanied by an SONAME redefinition (see above). 9117c478bd9Sstevel@tonic-gate */ 91269112eddSAli Bahrami if (*tkv.tkv_str == '$') { 9137c478bd9Sstevel@tonic-gate if (dolkey != MD_NONE) { 91469112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_UNEXTOK), '$'); 91569112eddSAli Bahrami return (FALSE); 9167c478bd9Sstevel@tonic-gate } 91769112eddSAli Bahrami tkv.tkv_str++; 91869112eddSAli Bahrami ld_map_lowercase(tkv.tkv_str); 91969112eddSAli Bahrami if (strcmp(tkv.tkv_str, MSG_ORIG(MSG_MAP_ADDVERS)) == 92069112eddSAli Bahrami 0) { 9217c478bd9Sstevel@tonic-gate dolkey = MD_ADDVERS; 92269112eddSAli Bahrami } else { 92369112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSOTYP), 92469112eddSAli Bahrami tkv.tkv_str); 92569112eddSAli Bahrami return (FALSE); 9267c478bd9Sstevel@tonic-gate } 9277c478bd9Sstevel@tonic-gate continue; 9287c478bd9Sstevel@tonic-gate } 9297c478bd9Sstevel@tonic-gate 9307c478bd9Sstevel@tonic-gate /* 9317c478bd9Sstevel@tonic-gate * shared object version requirement. 9327c478bd9Sstevel@tonic-gate */ 93369112eddSAli Bahrami if (!ld_map_dv_entry(mf, sdf, FALSE, tkv.tkv_str)) 93469112eddSAli Bahrami return (FALSE); 9357c478bd9Sstevel@tonic-gate } 9367c478bd9Sstevel@tonic-gate 93769112eddSAli Bahrami return (TRUE); 9387c478bd9Sstevel@tonic-gate } 9397c478bd9Sstevel@tonic-gate 9407c478bd9Sstevel@tonic-gate 9417c478bd9Sstevel@tonic-gate /* 942c1c6f601Srie * Process a symbol definition. Historically, this originated from processing 943c1c6f601Srie * a version definition. However, this has evolved into a generic means of 944c1c6f601Srie * defining symbol references and definitions (see Defining Additional Symbols 945c1c6f601Srie * in the Linker and Libraries guide for the complete syntax). 946c1c6f601Srie * 947c1c6f601Srie * [ name ] { 948c1c6f601Srie * scope: 949c1c6f601Srie * symbol [ = [ type ] [ value ] [ size ] [ attribute ] ]; 950c1c6f601Srie * } [ dependency ]; 951c1c6f601Srie * 9527c478bd9Sstevel@tonic-gate */ 95369112eddSAli Bahrami static Boolean 95469112eddSAli Bahrami map_version(Mapfile *mf, char *name) 9557c478bd9Sstevel@tonic-gate { 9567c478bd9Sstevel@tonic-gate Token tok; 95769112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */ 95869112eddSAli Bahrami ld_map_ver_t mv; 95969112eddSAli Bahrami ld_map_sym_t ms; 96069112eddSAli Bahrami Ofl_desc *ofl = mf->mf_ofl; 9617c478bd9Sstevel@tonic-gate 96269112eddSAli Bahrami /* Establish the version descriptor and related data */ 96369112eddSAli Bahrami if (!ld_map_sym_ver_init(mf, name, &mv)) 96469112eddSAli Bahrami return (FALSE); 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate /* 9677c478bd9Sstevel@tonic-gate * Scan the mapfile entry picking out scoping and symbol definitions. 9687c478bd9Sstevel@tonic-gate */ 96969112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, 0, &tkv)) != TK_RIGHTBKT) { 97069112eddSAli Bahrami uint_t filter = 0; 9717c478bd9Sstevel@tonic-gate 97269112eddSAli Bahrami if (tok != TK_STRING) { 97369112eddSAli Bahrami if (tok == TK_ERROR) { 97469112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSYM_2)); 97569112eddSAli Bahrami return (FALSE); 97669112eddSAli Bahrami } 97769112eddSAli Bahrami mv.mv_errcnt++; 97860758829Srie continue; 9797c478bd9Sstevel@tonic-gate } 9807c478bd9Sstevel@tonic-gate 98169112eddSAli Bahrami /* The default value for all the symbol attributes is 0 */ 98269112eddSAli Bahrami (void) memset(&ms, 0, sizeof (ms)); 98369112eddSAli Bahrami ms.ms_name = tkv.tkv_str; 9847c478bd9Sstevel@tonic-gate 98569112eddSAli Bahrami tok = ld_map_gettoken(mf, 0, &tkv); 98669112eddSAli Bahrami if (tok == TK_ERROR) { 98769112eddSAli Bahrami mv.mv_errcnt++; 98860758829Srie continue; 98960758829Srie } 9907c478bd9Sstevel@tonic-gate 9917c478bd9Sstevel@tonic-gate /* 9927c478bd9Sstevel@tonic-gate * Turn off the WEAK flag to indicate that definitions are 9937c478bd9Sstevel@tonic-gate * associated with this version. It would probably be more 9947c478bd9Sstevel@tonic-gate * accurate to only remove this flag with the specification of 9957c478bd9Sstevel@tonic-gate * global symbols, however setting it here allows enough slop 9967c478bd9Sstevel@tonic-gate * to compensate for the various user inputs we've seen so far. 9977c478bd9Sstevel@tonic-gate * Only if a closed version is specified (i.e., "SUNW_1.x {};") 9987c478bd9Sstevel@tonic-gate * will a user get a weak version (which is how we document the 9997c478bd9Sstevel@tonic-gate * creation of weak versions). 10007c478bd9Sstevel@tonic-gate */ 100169112eddSAli Bahrami mv.mv_vdp->vd_flags &= ~VER_FLG_WEAK; 10027c478bd9Sstevel@tonic-gate 10037c478bd9Sstevel@tonic-gate switch (tok) { 10047c478bd9Sstevel@tonic-gate case TK_COLON: 100569112eddSAli Bahrami ld_map_sym_scope(mf, ms.ms_name, &mv); 10067c478bd9Sstevel@tonic-gate continue; 10077c478bd9Sstevel@tonic-gate 10087c478bd9Sstevel@tonic-gate case TK_EQUAL: 10097c478bd9Sstevel@tonic-gate /* 10107c478bd9Sstevel@tonic-gate * A full blown symbol definition follows. 10117c478bd9Sstevel@tonic-gate * Determine the symbol type and any virtual address or 10127c478bd9Sstevel@tonic-gate * alignment specified and then fall through to process 10137c478bd9Sstevel@tonic-gate * the entire symbols information. 10147c478bd9Sstevel@tonic-gate */ 101569112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, 0, &tkv)) != 101671ae4d73Sab196087 TK_SEMICOLON) { 101769112eddSAli Bahrami if (tok == TK_ERROR) 101869112eddSAli Bahrami return (FALSE); 101969112eddSAli Bahrami if (tok != TK_STRING) { 102069112eddSAli Bahrami mf_fatal0(mf, 102169112eddSAli Bahrami MSG_INTL(MSG_MAP_MALFORM)); 102269112eddSAli Bahrami return (FALSE); 102369112eddSAli Bahrami } 102469112eddSAli Bahrami 10257c478bd9Sstevel@tonic-gate /* 102669112eddSAli Bahrami * If we had previously seen AUX or FILTER, 102769112eddSAli Bahrami * the next string is the filtee itself. 102869112eddSAli Bahrami * Add it, and clear the filter flag. 10297c478bd9Sstevel@tonic-gate */ 10307c478bd9Sstevel@tonic-gate if (filter) { 103169112eddSAli Bahrami ld_map_sym_filtee(mf, &mv, &ms, 103269112eddSAli Bahrami filter, tkv.tkv_str); 10337c478bd9Sstevel@tonic-gate filter = 0; 10347c478bd9Sstevel@tonic-gate continue; 10357c478bd9Sstevel@tonic-gate } 10367c478bd9Sstevel@tonic-gate 10377c478bd9Sstevel@tonic-gate /* 10387c478bd9Sstevel@tonic-gate * Determine any Value or Size attributes. 10397c478bd9Sstevel@tonic-gate */ 104069112eddSAli Bahrami ld_map_lowercase(tkv.tkv_str); 1041c1c6f601Srie 104269112eddSAli Bahrami if (tkv.tkv_str[0] == 'v' || 104369112eddSAli Bahrami tkv.tkv_str[0] == 's') { 104469112eddSAli Bahrami Xword number; 10457c478bd9Sstevel@tonic-gate 104669112eddSAli Bahrami if (!valuetoxword(mf, &tkv, &number)) { 104769112eddSAli Bahrami mv.mv_errcnt++; 104869112eddSAli Bahrami return (FALSE); 10497c478bd9Sstevel@tonic-gate } 10507c478bd9Sstevel@tonic-gate 105169112eddSAli Bahrami switch (*tkv.tkv_str) { 10527c478bd9Sstevel@tonic-gate case 'v': 1053a953e2b1Srie /* BEGIN CSTYLED */ 105469112eddSAli Bahrami if (ms.ms_value) { 105569112eddSAli Bahrami mf_fatal(mf, 10567c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_MOREONCE), 10577c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SYMVAL)); 105869112eddSAli Bahrami mv.mv_errcnt++; 105960758829Srie continue; 10607c478bd9Sstevel@tonic-gate } 10617c478bd9Sstevel@tonic-gate /* LINTED */ 106269112eddSAli Bahrami ms.ms_value = (Addr)number; 106369112eddSAli Bahrami ms.ms_value_set = TRUE; 10647c478bd9Sstevel@tonic-gate break; 1065a953e2b1Srie /* END CSTYLED */ 10667c478bd9Sstevel@tonic-gate case 's': 1067a953e2b1Srie /* BEGIN CSTYLED */ 106869112eddSAli Bahrami if (ms.ms_size) { 106969112eddSAli Bahrami mf_fatal(mf, 10707c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_MOREONCE), 10717c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_SYMSIZE)); 107269112eddSAli Bahrami mv.mv_errcnt++; 107360758829Srie continue; 10747c478bd9Sstevel@tonic-gate } 10757c478bd9Sstevel@tonic-gate /* LINTED */ 107669112eddSAli Bahrami ms.ms_size = (Addr)number; 10777c478bd9Sstevel@tonic-gate break; 1078a953e2b1Srie /* END CSTYLED */ 10797c478bd9Sstevel@tonic-gate } 10807c478bd9Sstevel@tonic-gate 108169112eddSAli Bahrami } else if (strcmp(tkv.tkv_str, 10827c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_FUNCTION)) == 0) { 108369112eddSAli Bahrami ms.ms_shndx = SHN_ABS; 108469112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_SPECSEC; 108569112eddSAli Bahrami ms.ms_type = STT_FUNC; 108669112eddSAli Bahrami } else if (strcmp(tkv.tkv_str, 10877c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_DATA)) == 0) { 108869112eddSAli Bahrami ms.ms_shndx = SHN_ABS; 108969112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_SPECSEC; 109069112eddSAli Bahrami ms.ms_type = STT_OBJECT; 109169112eddSAli Bahrami } else if (strcmp(tkv.tkv_str, 10927c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_COMMON)) == 0) { 109369112eddSAli Bahrami ms.ms_shndx = SHN_COMMON; 109469112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_SPECSEC; 109569112eddSAli Bahrami ms.ms_type = STT_OBJECT; 109669112eddSAli Bahrami } else if (strcmp(tkv.tkv_str, 10977c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_PARENT)) == 0) { 109869112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_PARENT; 10997c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_SYMINFO; 110069112eddSAli Bahrami } else if (strcmp(tkv.tkv_str, 11017c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_EXTERN)) == 0) { 110269112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_EXTERN; 11037c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_SYMINFO; 110469112eddSAli Bahrami } else if (strcmp(tkv.tkv_str, 11057c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_DIRECT)) == 0) { 110669112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_DIR; 11077c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_SYMINFO; 110869112eddSAli Bahrami } else if (strcmp(tkv.tkv_str, 11097c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_NODIRECT)) == 0) { 111069112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_NDIR; 11117c478bd9Sstevel@tonic-gate ofl->ofl_flags |= FLG_OF_SYMINFO; 111228bda19cSRod Evans ofl->ofl_flags1 |= 111328bda19cSRod Evans (FLG_OF1_NDIRECT | FLG_OF1_NGLBDIR); 111469112eddSAli Bahrami } else if (strcmp(tkv.tkv_str, 11157c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_FILTER)) == 0) { 111669112eddSAli Bahrami /* Next token is the filtee */ 111769112eddSAli Bahrami filter = FLG_SY_STDFLTR; 11187c478bd9Sstevel@tonic-gate continue; 111969112eddSAli Bahrami } else if (strcmp(tkv.tkv_str, 11207c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_MAP_AUXILIARY)) == 0) { 112169112eddSAli Bahrami /* Next token is the filtee */ 112269112eddSAli Bahrami filter = FLG_SY_AUXFLTR; 11237c478bd9Sstevel@tonic-gate continue; 112469112eddSAli Bahrami } else if (strcmp(tkv.tkv_str, 11259a411307Srie MSG_ORIG(MSG_MAP_INTERPOSE)) == 0) { 1126604635faSRod Evans /* BEGIN CSTYLED */ 11279a411307Srie if (!(ofl->ofl_flags & FLG_OF_EXEC)) { 112869112eddSAli Bahrami mf_fatal0(mf, 112969112eddSAli Bahrami MSG_INTL(MSG_MAP_NOINTPOSE)); 113069112eddSAli Bahrami mv.mv_errcnt++; 1131604635faSRod Evans break; 11329a411307Srie } 1133604635faSRod Evans /* END CSTYLED */ 113469112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_INTPOSE; 11359a411307Srie ofl->ofl_flags |= FLG_OF_SYMINFO; 11369a411307Srie ofl->ofl_dtflags_1 |= DF_1_SYMINTPOSE; 11379a411307Srie continue; 113869112eddSAli Bahrami } else if (strcmp(tkv.tkv_str, 1139d579eb63Sab196087 MSG_ORIG(MSG_MAP_DYNSORT)) == 0) { 114069112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_DYNSORT; 114169112eddSAli Bahrami ms.ms_sdflags &= ~FLG_SY_NODYNSORT; 1142d579eb63Sab196087 continue; 114369112eddSAli Bahrami } else if (strcmp(tkv.tkv_str, 1144d579eb63Sab196087 MSG_ORIG(MSG_MAP_NODYNSORT)) == 0) { 114569112eddSAli Bahrami ms.ms_sdflags &= ~FLG_SY_DYNSORT; 114669112eddSAli Bahrami ms.ms_sdflags |= FLG_SY_NODYNSORT; 1147d579eb63Sab196087 continue; 11487c478bd9Sstevel@tonic-gate } else { 114969112eddSAli Bahrami mf_fatal(mf, 11507c478bd9Sstevel@tonic-gate MSG_INTL(MSG_MAP_UNKSYMDEF), 115169112eddSAli Bahrami tkv.tkv_str); 115269112eddSAli Bahrami mv.mv_errcnt++; 115360758829Srie continue; 11547c478bd9Sstevel@tonic-gate } 11557c478bd9Sstevel@tonic-gate } 11567c478bd9Sstevel@tonic-gate /* FALLTHROUGH */ 11577c478bd9Sstevel@tonic-gate 11587c478bd9Sstevel@tonic-gate case TK_SEMICOLON: 115969112eddSAli Bahrami /* Auto-reduction directive ('*')? */ 116069112eddSAli Bahrami if (*ms.ms_name == '*') { 116169112eddSAli Bahrami ld_map_sym_autoreduce(mf, &mv); 116269112eddSAli Bahrami continue; 11637c478bd9Sstevel@tonic-gate } 116469112eddSAli Bahrami 116569112eddSAli Bahrami /* 116669112eddSAli Bahrami * Catch the error where the AUX or FILTER keyword 116769112eddSAli Bahrami * was used, but the filtee wasn't supplied. 116869112eddSAli Bahrami */ 116969112eddSAli Bahrami if (filter && (ms.ms_filtee == NULL)) { 117069112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_NOFILTER), 117169112eddSAli Bahrami ms.ms_name); 117269112eddSAli Bahrami mv.mv_errcnt++; 11737c478bd9Sstevel@tonic-gate continue; 11747c478bd9Sstevel@tonic-gate } 11757c478bd9Sstevel@tonic-gate 11767c478bd9Sstevel@tonic-gate /* 11777c478bd9Sstevel@tonic-gate * Add the new symbol. It should be noted that all 11787c478bd9Sstevel@tonic-gate * symbols added by the mapfile start out with global 11797c478bd9Sstevel@tonic-gate * scope, thus they will fall through the normal symbol 11807c478bd9Sstevel@tonic-gate * resolution process. Symbols defined as locals will 11817c478bd9Sstevel@tonic-gate * be reduced in scope after all input file processing. 11827c478bd9Sstevel@tonic-gate */ 118369112eddSAli Bahrami if (!ld_map_sym_enter(mf, &mv, &ms)) 118469112eddSAli Bahrami return (FALSE); 11857c478bd9Sstevel@tonic-gate break; 11867c478bd9Sstevel@tonic-gate 11877c478bd9Sstevel@tonic-gate default: 118869112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSCOL)); 118969112eddSAli Bahrami mv.mv_errcnt++; 119060758829Srie continue; 119160758829Srie } 119260758829Srie } 119360758829Srie 119469112eddSAli Bahrami if (mv.mv_errcnt) 119569112eddSAli Bahrami return (FALSE); 11967c478bd9Sstevel@tonic-gate 11977c478bd9Sstevel@tonic-gate /* 11987c478bd9Sstevel@tonic-gate * Determine if any version references are provided after the close 119969112eddSAli Bahrami * bracket, parsing up to the terminating ';'. 12007c478bd9Sstevel@tonic-gate */ 120169112eddSAli Bahrami if (!ld_map_sym_ver_fini(mf, &mv)) 120269112eddSAli Bahrami return (FALSE); 12037c478bd9Sstevel@tonic-gate 120469112eddSAli Bahrami return (TRUE); 12057c478bd9Sstevel@tonic-gate } 12067c478bd9Sstevel@tonic-gate 12077c478bd9Sstevel@tonic-gate /* 120869112eddSAli Bahrami * Parse the mapfile --- Sysv syntax 12097c478bd9Sstevel@tonic-gate */ 121069112eddSAli Bahrami Boolean 121169112eddSAli Bahrami ld_map_parse_v1(Mapfile *mf) 12127c478bd9Sstevel@tonic-gate { 12137c478bd9Sstevel@tonic-gate Sg_desc *sgp1; /* seg descriptor being manipulated */ 121469112eddSAli Bahrami Ent_desc *enp; /* segment entrance criteria. */ 12157c478bd9Sstevel@tonic-gate Token tok; /* current token. */ 121669112eddSAli Bahrami Boolean new_segment; /* If true, defines new segment */ 12177c478bd9Sstevel@tonic-gate char *name; 121869112eddSAli Bahrami Ofl_desc *ofl = mf->mf_ofl; 121969112eddSAli Bahrami ld_map_tkval_t tkv; /* Value of token */ 122069112eddSAli Bahrami avl_index_t where; 12217c478bd9Sstevel@tonic-gate 12227c478bd9Sstevel@tonic-gate /* 12237c478bd9Sstevel@tonic-gate * We now parse the mapfile until the gettoken routine returns EOF. 12247c478bd9Sstevel@tonic-gate */ 122569112eddSAli Bahrami while ((tok = ld_map_gettoken(mf, TK_F_EOFOK, &tkv)) != TK_EOF) { 122669112eddSAli Bahrami Xword ndx; 12277c478bd9Sstevel@tonic-gate 12287c478bd9Sstevel@tonic-gate /* 12297c478bd9Sstevel@tonic-gate * At this point we are at the beginning of a line, and the 123069112eddSAli Bahrami * variable tkv.tkv_str points to the first string on the line. 12317c478bd9Sstevel@tonic-gate * All mapfile entries start with some string token except it 12327c478bd9Sstevel@tonic-gate * is possible for a scoping definition to start with `{'. 12337c478bd9Sstevel@tonic-gate */ 12347c478bd9Sstevel@tonic-gate if (tok == TK_LEFTBKT) { 123569112eddSAli Bahrami if (!map_version(mf, NULL)) 123669112eddSAli Bahrami return (FALSE); 12377c478bd9Sstevel@tonic-gate continue; 12387c478bd9Sstevel@tonic-gate } 12397c478bd9Sstevel@tonic-gate if (tok != TK_STRING) { 124071ae4d73Sab196087 if (tok != TK_ERROR) 124169112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPSEGNAM)); 124269112eddSAli Bahrami return (FALSE); 12437c478bd9Sstevel@tonic-gate } 12447c478bd9Sstevel@tonic-gate 12457c478bd9Sstevel@tonic-gate /* 12467c478bd9Sstevel@tonic-gate * Save the initial token. 12477c478bd9Sstevel@tonic-gate */ 124869112eddSAli Bahrami name = tkv.tkv_str; 12497c478bd9Sstevel@tonic-gate 12507c478bd9Sstevel@tonic-gate /* 12517c478bd9Sstevel@tonic-gate * Now check the second character on the line. The special `-' 12527c478bd9Sstevel@tonic-gate * and `{' characters do not involve any segment manipulation so 12537c478bd9Sstevel@tonic-gate * we handle them first. 12547c478bd9Sstevel@tonic-gate */ 125569112eddSAli Bahrami tok = ld_map_gettoken(mf, 0, &tkv); 125669112eddSAli Bahrami if (tok == TK_ERROR) 125769112eddSAli Bahrami return (FALSE); 125871ae4d73Sab196087 if (tok == TK_DASH) { 125969112eddSAli Bahrami if (!map_dash(mf, name)) 126069112eddSAli Bahrami return (FALSE); 12617c478bd9Sstevel@tonic-gate continue; 12627c478bd9Sstevel@tonic-gate } 12637c478bd9Sstevel@tonic-gate if (tok == TK_LEFTBKT) { 126469112eddSAli Bahrami if (!map_version(mf, name)) 126569112eddSAli Bahrami return (FALSE); 12667c478bd9Sstevel@tonic-gate continue; 12677c478bd9Sstevel@tonic-gate } 12687c478bd9Sstevel@tonic-gate 12697c478bd9Sstevel@tonic-gate /* 12707c478bd9Sstevel@tonic-gate * If we're here we need to interpret the first string as a 127169112eddSAli Bahrami * segment name. Is this an already known segment? 12727c478bd9Sstevel@tonic-gate */ 127369112eddSAli Bahrami sgp1 = ld_seg_lookup(mf->mf_ofl, name, &where); 127469112eddSAli Bahrami new_segment = sgp1 == NULL; 127569112eddSAli Bahrami if (!new_segment) 127669112eddSAli Bahrami sgp1->sg_flags &= ~FLG_SG_DISABLED; 12777c478bd9Sstevel@tonic-gate 12787c478bd9Sstevel@tonic-gate /* 1279635216b6SRod Evans * If the second token is a '|' then we had better have found a 1280635216b6SRod Evans * segment. It is illegal to perform section within segment 1281635216b6SRod Evans * ordering before the segment has been declared. 12827c478bd9Sstevel@tonic-gate */ 12837c478bd9Sstevel@tonic-gate if (tok == TK_PIPE) { 12847c478bd9Sstevel@tonic-gate if (sgp1 == NULL) { 128569112eddSAli Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_SECINSEG), 128669112eddSAli Bahrami name); 128769112eddSAli Bahrami return (FALSE); 12887c478bd9Sstevel@tonic-gate } 128969112eddSAli Bahrami if (!map_pipe(mf, sgp1)) 129069112eddSAli Bahrami return (FALSE); 129169112eddSAli Bahrami continue; 12927c478bd9Sstevel@tonic-gate } 12937c478bd9Sstevel@tonic-gate 12947c478bd9Sstevel@tonic-gate /* 129569112eddSAli Bahrami * If segment does not exist, allocate a descriptor with 129669112eddSAli Bahrami * its values set to 0 so that map_equal() can detect 129769112eddSAli Bahrami * changing attributes. 12987c478bd9Sstevel@tonic-gate */ 129969112eddSAli Bahrami if (new_segment && 130069112eddSAli Bahrami ((sgp1 = ld_map_seg_alloc(name, PT_NULL, 0)) == NULL)) 130169112eddSAli Bahrami return (FALSE); 13027c478bd9Sstevel@tonic-gate 13037c478bd9Sstevel@tonic-gate /* 13047c478bd9Sstevel@tonic-gate * Now check the second token from the input line. 13057c478bd9Sstevel@tonic-gate */ 130669112eddSAli Bahrami switch (tok) { 130769112eddSAli Bahrami case TK_EQUAL: /* Create/modify segment */ 130869112eddSAli Bahrami /* 130969112eddSAli Bahrami * We use the same syntax for hardware/software 131069112eddSAli Bahrami * capabilities as we do for segments. If the 131169112eddSAli Bahrami * "segment name" matches one of these, then 131269112eddSAli Bahrami * process the capabilities instead of treating it 131369112eddSAli Bahrami * as a segment. Note that no dynamic memory has 131469112eddSAli Bahrami * been allocated for the segment descriptor yet, 131569112eddSAli Bahrami * so we can bail without leaking memory. 131669112eddSAli Bahrami */ 13177c478bd9Sstevel@tonic-gate if (strcmp(sgp1->sg_name, 13187c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_HWCAP_1)) == 0) { 131969112eddSAli Bahrami if (!map_cap(mf, CA_SUNW_HW_1, 1320*08278a5eSRod Evans &ofl->ofl_ocapset.oc_hw_1)) 132169112eddSAli Bahrami return (FALSE); 1322d1827f25Srie continue; 132369112eddSAli Bahrami } 132469112eddSAli Bahrami if (strcmp(sgp1->sg_name, 13257c478bd9Sstevel@tonic-gate MSG_ORIG(MSG_STR_SFCAP_1)) == 0) { 132669112eddSAli Bahrami if (!map_cap(mf, CA_SUNW_SF_1, 1327*08278a5eSRod Evans &ofl->ofl_ocapset.oc_sf_1)) 132869112eddSAli Bahrami return (FALSE); 1329d1827f25Srie continue; 13307c478bd9Sstevel@tonic-gate } 133169112eddSAli Bahrami 13327c478bd9Sstevel@tonic-gate /* 133369112eddSAli Bahrami * If not a new segment, show the initial value 133469112eddSAli Bahrami * before modifying it. 13357c478bd9Sstevel@tonic-gate */ 133669112eddSAli Bahrami if (!new_segment && DBG_ENABLED) { 133769112eddSAli Bahrami ndx = ld_map_seg_index(mf, sgp1); 133869112eddSAli Bahrami Dbg_map_seg(ofl, DBG_STATE_MOD_BEFORE, 133969112eddSAli Bahrami ndx, sgp1, mf->mf_lineno); 13407c478bd9Sstevel@tonic-gate } 13417c478bd9Sstevel@tonic-gate 134269112eddSAli Bahrami /* Process the segment */ 134369112eddSAli Bahrami if (!map_equal(mf, sgp1)) 134469112eddSAli Bahrami return (FALSE); 134569112eddSAli Bahrami 13467c478bd9Sstevel@tonic-gate /* 134769112eddSAli Bahrami * Special case for STACK "segments": 134869112eddSAli Bahrami * 134969112eddSAli Bahrami * The ability to modify the stack flags was added 135069112eddSAli Bahrami * long after this sysv syntax was designed. It was 135169112eddSAli Bahrami * fit into the existing syntax by treating it as a 135269112eddSAli Bahrami * segment. However, there can only be one stack program 135369112eddSAli Bahrami * header, while segment syntax requires user to supply 135469112eddSAli Bahrami * a name. This is confusing, and it allows the user to 135569112eddSAli Bahrami * attempt to create more than one stack segment. The 135669112eddSAli Bahrami * original implementation had a test to catch this. 135769112eddSAli Bahrami * 135869112eddSAli Bahrami * If this is a stack segment, locate the real stack 135969112eddSAli Bahrami * descriptor and transfer the flags to it. We then 136069112eddSAli Bahrami * free the allocated descriptor without inserting it. 136169112eddSAli Bahrami * The end result is that all stack segments simply 136269112eddSAli Bahrami * alter the one stack descriptor, and the segment 136369112eddSAli Bahrami * name is ignored. 13647c478bd9Sstevel@tonic-gate */ 136569112eddSAli Bahrami if (sgp1->sg_phdr.p_type == PT_SUNWSTACK) { 136669112eddSAli Bahrami Sg_desc *stack = ld_map_seg_stack(mf); 136757ef7aa9SRod Evans 136869112eddSAli Bahrami if (sgp1->sg_flags & FLG_SG_P_FLAGS) 136969112eddSAli Bahrami stack->sg_phdr.p_flags = 137069112eddSAli Bahrami sgp1->sg_phdr.p_flags; 137169112eddSAli Bahrami free(sgp1); 13727c478bd9Sstevel@tonic-gate 137369112eddSAli Bahrami DBG_CALL(Dbg_map_seg(ofl, 137469112eddSAli Bahrami DBG_STATE_MOD_AFTER, ndx, sgp1, 137569112eddSAli Bahrami mf->mf_lineno)); 137669112eddSAli Bahrami break; 13777c478bd9Sstevel@tonic-gate } 13787c478bd9Sstevel@tonic-gate 13797c478bd9Sstevel@tonic-gate /* 138069112eddSAli Bahrami * If this is a new segment, finish its initialization 138169112eddSAli Bahrami * and insert it into the segment list. 13827c478bd9Sstevel@tonic-gate */ 13837c478bd9Sstevel@tonic-gate if (new_segment) { 138469112eddSAli Bahrami switch (ld_map_seg_insert(mf, DBG_STATE_NEW, 138569112eddSAli Bahrami sgp1, where)) { 138669112eddSAli Bahrami case SEG_INS_SKIP: 138769112eddSAli Bahrami continue; 138869112eddSAli Bahrami case SEG_INS_FAIL: 138969112eddSAli Bahrami return (FALSE); 13907c478bd9Sstevel@tonic-gate } 139169112eddSAli Bahrami } else { 139269112eddSAli Bahrami /* Not new. Show what's changed */ 139369112eddSAli Bahrami DBG_CALL(Dbg_map_seg(ofl, 139469112eddSAli Bahrami DBG_STATE_MOD_AFTER, ndx, sgp1, 139569112eddSAli Bahrami mf->mf_lineno)); 13967c478bd9Sstevel@tonic-gate } 139769112eddSAli Bahrami break; 139869112eddSAli Bahrami 139969112eddSAli Bahrami case TK_COLON: /* Section to segment mapping */ 1400a953e2b1Srie /* 140169112eddSAli Bahrami * If this is a new segment, finish its initialization 140269112eddSAli Bahrami * and insert it into the segment list. 140369112eddSAli Bahrami * 140469112eddSAli Bahrami * If it is not a new segment, ensure that it is 140569112eddSAli Bahrami * not an empty segment reservation, as sections 140669112eddSAli Bahrami * cannot be assigned to those. 1407a953e2b1Srie */ 140869112eddSAli Bahrami if (new_segment) { 140969112eddSAli Bahrami switch (ld_map_seg_insert(mf, 141069112eddSAli Bahrami DBG_STATE_NEW_IMPLICIT, sgp1, where)) { 141169112eddSAli Bahrami case SEG_INS_SKIP: 141269112eddSAli Bahrami continue; 141369112eddSAli Bahrami case SEG_INS_FAIL: 141469112eddSAli Bahrami return (FALSE); 1415a953e2b1Srie } 141669112eddSAli Bahrami } else if (sgp1->sg_flags & FLG_SG_EMPTY) { 141769112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_SEGEMPSEC)); 141869112eddSAli Bahrami return (FALSE); 1419a953e2b1Srie } 14207c478bd9Sstevel@tonic-gate 14217c478bd9Sstevel@tonic-gate /* 142269112eddSAli Bahrami * Create new entrance criteria descriptor, and 142369112eddSAli Bahrami * process the mapping directive. 14247c478bd9Sstevel@tonic-gate */ 142569112eddSAli Bahrami enp = ld_map_seg_ent_add(mf, sgp1, NULL); 142669112eddSAli Bahrami if ((enp == NULL) || !map_colon(mf, enp)) 142769112eddSAli Bahrami return (FALSE); 142869112eddSAli Bahrami DBG_CALL(Dbg_map_ent(ofl->ofl_lml, enp, ofl, 142969112eddSAli Bahrami mf->mf_lineno)); 14307c478bd9Sstevel@tonic-gate break; 143169112eddSAli Bahrami 143269112eddSAli Bahrami case TK_ATSIGN: /* Section size symbol */ 14337c478bd9Sstevel@tonic-gate /* 143469112eddSAli Bahrami * If this is a new segment, finish its initialization 143569112eddSAli Bahrami * and insert it into the segment list. 14367c478bd9Sstevel@tonic-gate */ 143769112eddSAli Bahrami if (new_segment) { 143869112eddSAli Bahrami switch (ld_map_seg_insert(mf, 143969112eddSAli Bahrami DBG_STATE_NEW_IMPLICIT, sgp1, where)) { 144069112eddSAli Bahrami case SEG_INS_SKIP: 14417c478bd9Sstevel@tonic-gate continue; 144269112eddSAli Bahrami case SEG_INS_FAIL: 144369112eddSAli Bahrami return (FALSE); 14447c478bd9Sstevel@tonic-gate } 144569112eddSAli Bahrami } 144669112eddSAli Bahrami if (!map_atsign(mf, sgp1)) 144769112eddSAli Bahrami return (FALSE); 14487c478bd9Sstevel@tonic-gate break; 144969112eddSAli Bahrami 145069112eddSAli Bahrami case TK_ERROR: 145169112eddSAli Bahrami return (FALSE); /* Error was already issued */ 145269112eddSAli Bahrami 14537c478bd9Sstevel@tonic-gate default: 145469112eddSAli Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_EXPEQU)); 145569112eddSAli Bahrami return (FALSE); 14567c478bd9Sstevel@tonic-gate } 14577c478bd9Sstevel@tonic-gate } 14587c478bd9Sstevel@tonic-gate 145969112eddSAli Bahrami return (TRUE); 14607c478bd9Sstevel@tonic-gate } 1461