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) 2010, Oracle and/or its affiliates. All rights reserved.
27 * Local include file for libld mapfile subsystem.
38 * Macro used to size name buffer corresponding to a NULL terminated array
39 * of structures each of which contains a name string. Macro is used per-name.
40 * 2 extra characters are allowed per item to allow for a ', ' delimiter
41 * or NULL termination.
43 #define KW_NAME_SIZE(_size) (_size##_SIZE + 2)
46 * Variant of isspace() that excludes newline characters. Requires <ctype.h>.
48 #define isspace_nonl(_s) (isspace(_s) && ((_s) != '\n'))
51 * Type used to insert NULL characters in the mapfile text and later
52 * back them out and restore the original character. The mapfile text
53 * is held in a single string, so when we want to access sub-strings,
54 * it is necessary to temporarily insert NULLs to prevent the entire
55 * mapfile from that point forward being output.
58 char *np_ptr
; /* Address patched with NULL character */
59 char np_ch
; /* Character originally found at *np_ptr */
63 * ld_map_gettoken() uses a table of 128 bytes to determine how to
64 * process a token starting with any 7-bit ASCII value. The table is
65 * indexed by the character code, and returns one of the TK_* token values.
67 typedef const char mf_tokdisp_t
[128];
70 * The definition of an unquoted identifier differs based on the mapfile
71 * version. Rather than write a separate function to locate identifiers
72 * for each version, we use a single function that relies on a per-character
73 * table that encodes which characters can start an identifier, and which
74 * can continue one, for each supported mapfile version.
76 * Two bits are used for each version, one for the start attribute, and the
77 * other for continuation. The first two bits are not used (version 0), the
78 * next 2 are used for version 1, the following 2 for version 2, and so on.
80 #define TKID_ATTR_B_START 1
81 #define TKID_ATTR_B_CONT 2
83 #define TKID_ATTR_START(_ver) (TKID_ATTR_B_START << (_ver * 2))
84 #define TKID_ATTR_CONT(_ver) (TKID_ATTR_B_CONT << (_ver * 2))
86 /* Convenience macros for chars that both start and continue an identifier */
87 #define TKID_ATTR(_ver) ((TKID_ATTR_B_START | TKID_ATTR_B_CONT) << (_ver * 2))
90 * State for a mapfile held in memory.
93 Ofl_desc
*mf_ofl
; /* Output descriptor being processed */
94 char *mf_name
; /* Mapfile name */
95 Ifl_desc
*mf_ifl
; /* NULL, or pseudo input file */
96 /* descriptor from ld_map_ifl() */
97 char *mf_text
; /* Text of mapfile */
98 char *mf_next
; /* Next char in mapfile to examine */
99 const char *mf_tokdisp
; /* mf_tokdisp_t dispatch table to use */
100 Lineno mf_lineno
; /* Line # within mf_text */
101 int mf_version
; /* Mapfile syntax version */
102 int mf_tkid_start
; /* TKID bitvalue for characters that */
103 /* start an unquoted identifier */
104 int mf_tkid_cont
; /* TKID bitvalue for characters that */
105 /* continue an unquoted ident. */
106 int mf_next_ch
; /* 0, or character read from *mf_next */
107 /* prior to inserting NULL */
108 Aliste mf_ec_insndx
; /* Insert index for entrance criteria */
109 /* Each mapfile starts at the */
110 /* top, inserting each ec in the */
111 /* file in the order seen. */
115 * A very large percentage of mapfile errors start with the
117 * ld_eprintf(ofl, ERR_XXX, format, mf->mf_name, mf->mf_lineno...)
118 * The mf_fatal() and mf_warn() varadic macros are used to supply all
119 * of boilerplate, resulting in visually simpler code.
121 * mf_fatal0()/mf_warn0() are used when the format does not require any
122 * additional arguments and the varargs list is empty. The GNU cpp has a
123 * syntax for eliminating the extra comma (, ##__VA_ARGS__), but this isn't
124 * supported by the Sun compilers yet.
126 #define mf_fatal0(_mf, _fmt) \
127 ld_eprintf((_mf)->mf_ofl, ERR_FATAL, _fmt, (_mf)->mf_name, \
128 EC_LINENO((_mf)->mf_lineno))
129 #define mf_fatal(_mf, _fmt, ...) \
130 ld_eprintf((_mf)->mf_ofl, ERR_FATAL, _fmt, (_mf)->mf_name, \
131 EC_LINENO((_mf)->mf_lineno), __VA_ARGS__)
133 #define mf_warn0(_mf, _fmt) \
134 ld_eprintf((_mf)->mf_ofl, ERR_WARNING, _fmt, (_mf)->mf_name, \
135 EC_LINENO((_mf)->mf_lineno))
136 #define mf_warn(_mf, _fmt, ...) \
137 ld_eprintf((_mf)->mf_ofl, ERR_WARNING, _fmt, (_mf)->mf_name, \
138 EC_LINENO((_mf)->mf_lineno), __VA_ARGS__)
140 /* Possible return values from ld_map_gettoken */
142 TK_ERROR
= -1, /* Error in lexical analysis */
143 TK_EOF
= 0, /* End of file: Requires TK_F_EOFOK to be set */
144 /* or EOF results in TK_ERROR */
145 TK_STRING
= 1, /* String literal */
146 TK_COLON
= 2, /* : */
147 TK_SEMICOLON
= 3, /* ; */
148 TK_EQUAL
= 4, /* = */
149 TK_PLUSEQ
= 5, /* += */
150 TK_MINUSEQ
= 6, /* -= */
151 TK_ATSIGN
= 7, /* @ */
153 TK_LEFTBKT
= 9, /* { */
154 TK_RIGHTBKT
= 10, /* } */
155 TK_PIPE
= 11, /* | */
156 TK_INT
= 12, /* Integer value: Unsigned machine word */
157 TK_STAR
= 13, /* * */
158 TK_BANG
= 14, /* ! */
161 * Items below this point are for the use of ld_map_gettoken().
162 * They indicate a character that requires the lexical analyzer
163 * to carry out some additional computation (OPeration), resulting
164 * in one of the simple token types above, which is returned to
165 * the caller. The TK_OP_ tokens are implementation details that are
166 * never returned to a caller of ld_map_gettoken().
168 TK_OP_EOF
, /* end of file */
169 TK_OP_ILLCHR
, /* unprintable illegal character */
170 TK_OP_BADCHR
, /* printable but unexpected character */
171 TK_OP_WS
, /* whitespace */
172 TK_OP_NL
, /* newline */
173 TK_OP_SIMQUOTE
, /* simple quoting */
174 TK_OP_CQUOTE
, /* quoting with C string literal escapes */
175 TK_OP_CMT
, /* Comment */
176 TK_OP_CDIR
, /* Control directive */
177 TK_OP_NUM
, /* Decimial, hex, or octal value */
178 TK_OP_ID
, /* unquoted identifier using syntax rules */
179 /* appropriate for mapfile version */
180 TK_OP_CEQUAL
, /* One of += or -= */
184 * Type used by ld_map_gettoken() to return values for token types that
188 char *tkv_str
; /* TK_STRING */
189 struct { /* TK_INT */
190 char *tkvi_str
; /* String making up integer */
191 size_t tkvi_cnt
; /* # characters in tkvi_str */
192 Xword tkvi_value
; /* Resulting value */
197 * Values for gettoken() flags argument. These flags are used to
198 * alter gettoken() default behavior under certain conditions.
200 #define TK_F_EOFOK 1 /* Quietly return TK_EOF instead of normal */
201 /* TK_ERROR "premature EOF" error */
202 #define TK_F_STRLC 2 /* TK_STRING: Convert string to lowercase */
203 #define TK_F_KEYWORD 4 /* For directives and attributes: Disallow */
204 /* quoted TK_STRING tokens */
207 * Possible return values from ld_map_strtoxword()
210 STRTOXWORD_OK
, /* Operation successful */
211 STRTOXWORD_TOOBIG
, /* Otherwise valid value is too large */
212 STRTOXWORD_BAD
/* String not recognized as an integer */
213 } ld_map_strtoxword_t
;
216 * Possible return values from ld_map_seg_insert()
219 SEG_INS_OK
= 0, /* Segment was inserted */
220 SEG_INS_FAIL
= 1, /* Segment not inserted --- fatal */
221 SEG_INS_SKIP
= 2 /* Segment not inserted --- ignore */
225 * Enumeration of different symbol scope possible in a mapfile
228 FLG_SCOPE_HIDD
, /* symbol defined hidden/local */
229 FLG_SCOPE_DFLT
, /* symbol defined default/global */
230 FLG_SCOPE_PROT
, /* symbol defined protected/symbolic */
231 FLG_SCOPE_EXPT
, /* symbol defined exported */
232 FLG_SCOPE_SNGL
, /* symbol defined singleton */
233 FLG_SCOPE_ELIM
/* symbol defined eliminate */
236 /* State of a mapfile symbol version */
238 const char *mv_name
; /* NULL, or version name */
239 Ver_desc
*mv_vdp
; /* Descriptor for version */
240 ld_map_scope_t mv_scope
; /* Current scope type */
241 size_t mv_errcnt
; /* Count of errors against version */
244 /* State of a mapfile symbol definition */
246 const char *ms_name
; /* symbol name */
247 sd_flag_t ms_sdflags
; /* 0 / mapfile set flags */
248 Word ms_shndx
; /* SHN_UNDEF / mapfile set sec index */
249 uchar_t ms_type
; /* STT_NOTYPE / mapfile set type */
250 Addr ms_value
; /* user set value, if ms_value_set */
251 Addr ms_size
; /* 0 / mapfile set size */
252 const char *ms_filtee
; /* NULL or filtee name */
253 Boolean ms_value_set
; /* TRUE if ms_value set, even if to 0 */
254 Word ms_dft_flag
; /* 0, or type of filter in ms_filtee */
259 #define ld_map_cap_sanitize ld64_map_cap_sanitize
260 #define ld_map_cap_set_ovflag ld64_map_cap_set_ovflag
261 #define ld_map_dv ld64_map_dv
262 #define ld_map_dv_entry ld64_map_dv_entry
263 #define ld_map_gettoken ld64_map_gettoken
264 #define ld_map_ifl ld64_map_ifl
265 #define ld_map_parse_v1 ld64_map_parse_v1
266 #define ld_map_parse_v2 ld64_map_parse_v2
267 #define ld_map_seg_alloc ld64_map_seg_alloc
268 #define ld_map_seg_ent_add ld64_map_seg_ent_add
269 #define ld_map_seg_ent_files ld64_map_seg_ent_files
270 #define ld_map_seg_index ld64_map_seg_index
271 #define ld_map_seg_insert ld64_map_seg_insert
272 #define ld_map_seg_lookup ld64_map_seg_lookup
273 #define ld_map_seg_os_order_add ld64_map_seg_os_order_add
274 #define ld_map_seg_size_symbol ld64_map_seg_size_symbol
275 #define ld_map_seg_stack ld64_map_seg_stack
276 #define ld_map_strtoxword ld64_map_strtoxword
277 #define ld_map_sym_enter ld64_map_sym_enter
278 #define ld_map_sym_filtee ld64_map_sym_filtee
279 #define ld_map_sym_scope ld64_map_sym_scope
280 #define ld_map_sym_autoreduce ld64_map_sym_autoreduce
281 #define ld_map_sym_ver_fini ld64_map_sym_ver_fini
282 #define ld_map_sym_ver_init ld64_map_sym_ver_init
283 #define ld_map_tokenstr ld64_map_tokenstr
287 #define ld_map_cap_sanitize ld32_map_cap_sanitize
288 #define ld_map_cap_set_ovflag ld32_map_cap_set_ovflag
289 #define ld_map_dv ld32_map_dv
290 #define ld_map_dv_entry ld32_map_dv_entry
291 #define ld_map_gettoken ld32_map_gettoken
292 #define ld_map_ifl ld32_map_ifl
293 #define ld_map_parse_v1 ld32_map_parse_v1
294 #define ld_map_parse_v2 ld32_map_parse_v2
295 #define ld_map_seg_alloc ld32_map_seg_alloc
296 #define ld_map_seg_ent_add ld32_map_seg_ent_add
297 #define ld_map_seg_ent_files ld32_map_seg_ent_files
298 #define ld_map_seg_index ld32_map_seg_index
299 #define ld_map_seg_insert ld32_map_seg_insert
300 #define ld_map_seg_lookup ld32_map_seg_lookup
301 #define ld_map_seg_os_order_add ld32_map_seg_os_order_add
302 #define ld_map_seg_size_symbol ld32_map_seg_size_symbol
303 #define ld_map_seg_stack ld32_map_seg_stack
304 #define ld_map_strtoxword ld32_map_strtoxword
305 #define ld_map_sym_enter ld32_map_sym_enter
306 #define ld_map_sym_filtee ld32_map_sym_filtee
307 #define ld_map_sym_scope ld32_map_sym_scope
308 #define ld_map_sym_autoreduce ld32_map_sym_autoreduce
309 #define ld_map_sym_ver_fini ld32_map_sym_ver_fini
310 #define ld_map_sym_ver_init ld32_map_sym_ver_init
311 #define ld_map_tokenstr ld32_map_tokenstr
316 * Core functions used to parse mapfiles
318 extern void ld_map_lowercase(char *);
319 extern Token
ld_map_gettoken(Mapfile
*, int, ld_map_tkval_t
*);
320 extern Boolean
ld_map_parse_v1(Mapfile
*);
321 extern Boolean
ld_map_parse_v2(Mapfile
*);
322 extern ld_map_strtoxword_t
ld_map_strtoxword(const char *restrict
,
323 char **restrict
, Xword
*);
324 extern const char *ld_map_tokenstr(Token
, ld_map_tkval_t
*,
328 * Support code shared between the different mapfile parsing code, used to
329 * provide a common implementation manipulating link-editor state.
331 extern Boolean
ld_map_cap_sanitize(Mapfile
*, Word
, Capmask
*);
332 extern void ld_map_cap_set_ovflag(Mapfile
*, Word
);
333 extern void *ld_map_kwfind(const char *, void *, size_t, size_t);
334 extern char *ld_map_kwnames(void *, size_t, size_t, char *, size_t);
335 extern Sdf_desc
*ld_map_dv(Mapfile
*, const char *);
336 extern Boolean
ld_map_dv_entry(Mapfile
*, Sdf_desc
*, Boolean
,
338 extern Ifl_desc
*ld_map_ifl(Mapfile
*);
339 extern Sg_desc
*ld_map_seg_alloc(const char *, Word
, sg_flags_t
);
340 extern Ent_desc
*ld_map_seg_ent_add(Mapfile
*, Sg_desc
*, const char *);
341 extern Boolean
ld_map_seg_ent_files(Mapfile
*mf
, Ent_desc
*,
343 extern Xword
ld_map_seg_index(Mapfile
*, Sg_desc
*);
344 extern ld_map_seg_ins_t
ld_map_seg_insert(Mapfile
*, dbg_state_t
, Sg_desc
*,
346 extern Boolean
ld_map_seg_os_order_add(Mapfile
*, Sg_desc
*,
348 extern Boolean
ld_map_seg_size_symbol(Mapfile
*, Sg_desc
*, Token
,
349 const char *symname
);
350 extern Sg_desc
*ld_map_seg_stack(Mapfile
*);
351 extern Boolean
ld_map_sym_enter(Mapfile
*, ld_map_ver_t
*,
353 extern void ld_map_sym_filtee(Mapfile
*, ld_map_ver_t
*,
354 ld_map_sym_t
*, Word
, const char *);
355 extern void ld_map_sym_scope(Mapfile
*, const char *,
357 extern void ld_map_sym_autoreduce(Mapfile
*, ld_map_ver_t
*);
358 extern Boolean
ld_map_sym_ver_fini(Mapfile
*, ld_map_ver_t
*);
359 extern Boolean
ld_map_sym_ver_init(Mapfile
*, char *, ld_map_ver_t
*);
365 #endif /* _MAP_DOT_H */