1 /*-
2  * Copyright (c) 2011,2012 Kai Wang
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include "ld.h"
28 #include "ld_arch.h"
29 #include "ld_script.h"
30 #include "ld_exp.h"
31 #include "ld_layout.h"
32 
33 ELFTC_VCSID("$Id: ld_exp.c 3278 2015-12-11 21:39:13Z kaiwang27 $");
34 
35 /*
36  * Support routines for ldscript expression.
37  */
38 
39 static struct ld_exp *_alloc_exp(struct ld *ld);
40 static int64_t _assignment(struct ld *ld, struct ld_exp *le);
41 static int64_t _func_addr(struct ld *ld, struct ld_exp *le);
42 static int64_t _func_align(struct ld *ld, struct ld_exp *le);
43 static int64_t _func_alignof(struct ld *ld, struct ld_exp *le);
44 static int64_t _func_data_segment_align(struct ld *ld, struct ld_exp *le);
45 static int64_t _func_data_segment_end(struct ld *ld, struct ld_exp *le);
46 static int64_t _func_data_segment_relro_end(struct ld *ld, struct ld_exp *le);
47 static int64_t _func_defined(struct ld *ld, struct ld_exp *le);
48 static int64_t _func_length(struct ld *ld, struct ld_exp *le);
49 static int64_t _func_loadaddr(struct ld *ld, struct ld_exp *le);
50 static int64_t _func_max(struct ld *ld, struct ld_exp *le);
51 static int64_t _func_min(struct ld *ld, struct ld_exp *le);
52 static int64_t _func_next(struct ld *ld, struct ld_exp *le);
53 static int64_t _func_origin(struct ld *ld, struct ld_exp *le);
54 static int64_t _func_segment_start(struct ld *ld, struct ld_exp *le);
55 static int64_t _func_sizeof(struct ld *ld, struct ld_exp *le);
56 static int64_t _func_sizeof_headers(struct ld *ld);
57 static int64_t _symbol_val(struct ld *ld, char *name);
58 static int64_t _symbolic_constant(struct ld *ld, const char *name);
59 
60 #define	_EXP_EVAL(x) ld_exp_eval(ld, (x))
61 #define	_EXP_DUMP(x) ld_exp_dump(ld, (x))
62 
63 void
ld_exp_free(struct ld_exp * le)64 ld_exp_free(struct ld_exp *le)
65 {
66 
67 	if (le == NULL)
68 		return;
69 
70 	ld_exp_free(le->le_e1);
71 	ld_exp_free(le->le_e2);
72 	ld_exp_free(le->le_e3);
73 	if (le->le_assign != NULL)
74 		ld_script_assign_free(le->le_assign);
75 	if (le->le_name != NULL)
76 		free(le->le_name);
77 	free(le);
78 }
79 
80 struct ld_exp *
ld_exp_unary(struct ld * ld,enum ld_exp_op op,struct ld_exp * e1)81 ld_exp_unary(struct ld *ld, enum ld_exp_op op, struct ld_exp *e1)
82 {
83 	struct ld_exp *le;
84 
85 	le = _alloc_exp(ld);
86 	le->le_op = op;
87 	le->le_e1 = e1;
88 
89 	return (le);
90 }
91 
92 struct ld_exp *
ld_exp_binary(struct ld * ld,enum ld_exp_op op,struct ld_exp * e1,struct ld_exp * e2)93 ld_exp_binary(struct ld *ld, enum ld_exp_op op, struct ld_exp *e1,
94     struct ld_exp *e2)
95 {
96 	struct ld_exp *le;
97 
98 	le = _alloc_exp(ld);
99 	le->le_op = op;
100 	le->le_e1 = e1;
101 	le->le_e2 = e2;
102 
103 	return (le);
104 }
105 
106 struct ld_exp *
ld_exp_trinary(struct ld * ld,struct ld_exp * e1,struct ld_exp * e2,struct ld_exp * e3)107 ld_exp_trinary(struct ld *ld, struct ld_exp *e1, struct ld_exp *e2,
108     struct ld_exp *e3)
109 {
110 	struct ld_exp *le;
111 
112 	le = _alloc_exp(ld);
113 	le->le_op = LEOP_TRINARY;
114 	le->le_e1 = e1;
115 	le->le_e2 = e2;
116 	le->le_e3 = e3;
117 
118 	return (le);
119 }
120 
121 struct ld_exp *
ld_exp_sizeof_headers(struct ld * ld)122 ld_exp_sizeof_headers(struct ld *ld)
123 {
124 	struct ld_exp *le;
125 
126 	le = _alloc_exp(ld);
127 	le->le_op = LEOP_SIZEOF_HEADERS;
128 
129 	return (le);
130 }
131 
132 struct ld_exp *
ld_exp_constant(struct ld * ld,int64_t val)133 ld_exp_constant(struct ld *ld, int64_t val)
134 {
135 	struct ld_exp *le;
136 
137 	le = _alloc_exp(ld);
138 	le->le_op = LEOP_CONSTANT;
139 	le->le_val = val;
140 
141 	return (le);
142 }
143 
144 struct ld_exp *
ld_exp_symbolic_constant(struct ld * ld,const char * name)145 ld_exp_symbolic_constant(struct ld *ld, const char *name)
146 {
147 	struct ld_exp *le;
148 
149 	le = _alloc_exp(ld);
150 	le->le_op = LEOP_SYMBOLIC_CONSTANT;
151 	le->le_name = strdup(name);
152 	if (le->le_name == NULL)
153 		ld_fatal_std(ld, "calloc");
154 
155 	return (le);
156 }
157 
158 struct ld_exp *
ld_exp_symbol(struct ld * ld,const char * name)159 ld_exp_symbol(struct ld *ld, const char *name)
160 {
161 	struct ld_exp *le;
162 
163 	le = _alloc_exp(ld);
164 	le->le_op = LEOP_SYMBOL;
165 	le->le_name = strdup(name);
166 	if (le->le_name == NULL)
167 		ld_fatal_std(ld, "calloc");
168 
169 	return (le);
170 }
171 
172 struct ld_exp *
ld_exp_name(struct ld * ld,const char * name)173 ld_exp_name(struct ld *ld, const char *name)
174 {
175 	struct ld_exp *le;
176 
177 	le = _alloc_exp(ld);
178 	le->le_op = LEOP_SECTION_NAME;
179 	le->le_name = strdup(name);
180 	if (le->le_name == NULL)
181 		ld_fatal_std(ld, "calloc");
182 
183 	return (le);
184 }
185 
186 struct ld_exp *
ld_exp_assign(struct ld * ld,struct ld_script_assign * assign)187 ld_exp_assign(struct ld *ld, struct ld_script_assign *assign)
188 {
189 	struct ld_exp *le;
190 
191 	le = _alloc_exp(ld);
192 	le->le_op = LEOP_ASSIGN;
193 	le->le_assign = assign;
194 
195 	return (le);
196 }
197 
198 int64_t
ld_exp_eval(struct ld * ld,struct ld_exp * le)199 ld_exp_eval(struct ld* ld, struct ld_exp *le)
200 {
201 
202 	assert(le != NULL);
203 	switch (le->le_op) {
204 	case LEOP_ABS:
205 		return (llabs(_EXP_EVAL(le->le_e1)));
206 	case LEOP_ADD:
207 		return (_EXP_EVAL(le->le_e1) + _EXP_EVAL(le->le_e2));
208 	case LEOP_ADDR:
209 		return (_func_addr(ld, le));
210 	case LEOP_ALIGN:
211 	case LEOP_BLOCK:
212 		return (_func_align(ld, le));
213 	case LEOP_ALIGNOF:
214 		return (_func_alignof(ld, le));
215 	case LEOP_AND:
216 		return (_EXP_EVAL(le->le_e1) & _EXP_EVAL(le->le_e2));
217 	case LEOP_ASSIGN:
218 		return (_assignment(ld, le));
219 	case LEOP_CONSTANT:
220 		return (le->le_val);
221 	case LEOP_DIV:
222 		return (_EXP_EVAL(le->le_e1) / _EXP_EVAL(le->le_e2));
223 	case LEOP_DSA:
224 		return (_func_data_segment_align(ld, le));
225 	case LEOP_DSE:
226 		return (_func_data_segment_end(ld, le));
227 	case LEOP_DSRE:
228 		return (_func_data_segment_relro_end(ld, le));
229 	case LEOP_DEFINED:
230 		return (_func_defined(ld, le));
231 	case LEOP_EQUAL:
232 		return (_EXP_EVAL(le->le_e1) == _EXP_EVAL(le->le_e2));
233 	case LEOP_GE:
234 		return (_EXP_EVAL(le->le_e1) >= _EXP_EVAL(le->le_e2));
235 	case LEOP_GREATER:
236 		return (_EXP_EVAL(le->le_e1) > _EXP_EVAL(le->le_e2));
237 	case LEOP_LENGTH:
238 		return (_func_length(ld, le));
239 	case LEOP_LOADADDR:
240 		return (_func_loadaddr(ld, le));
241 	case LEOP_LOGICAL_AND:
242 		return (_EXP_EVAL(le->le_e1) && _EXP_EVAL(le->le_e2));
243 	case LEOP_LOGICAL_OR:
244 		return (_EXP_EVAL(le->le_e1) || _EXP_EVAL(le->le_e2));
245 	case LEOP_LSHIFT:
246 		return (_EXP_EVAL(le->le_e1) << _EXP_EVAL(le->le_e2));
247 	case LEOP_MAX:
248 		return (_func_max(ld, le));
249 	case LEOP_MIN:
250 		return (_func_min(ld, le));
251 	case LEOP_MINUS:
252 		return (-(_EXP_EVAL(le->le_e1)));
253 	case LEOP_MOD:
254 		return (_EXP_EVAL(le->le_e1) % _EXP_EVAL(le->le_e2));
255 	case LEOP_MUL:
256 		return (_EXP_EVAL(le->le_e1) * _EXP_EVAL(le->le_e2));
257 	case LEOP_NE:
258 		return (_EXP_EVAL(le->le_e1) != _EXP_EVAL(le->le_e2));
259 	case LEOP_NEGATION:
260 		return (~(_EXP_EVAL(le->le_e1)));
261 	case LEOP_NEXT:
262 		return (_func_next(ld, le));
263 	case LEOP_NOT:
264 		return (!(_EXP_EVAL(le->le_e1)));
265 	case LEOP_OR:
266 		return (_EXP_EVAL(le->le_e1) | _EXP_EVAL(le->le_e2));
267 	case LEOP_ORIGIN:
268 		return (_func_origin(ld, le));
269 	case LEOP_RSHIFT:
270 		return (_EXP_EVAL(le->le_e1) >> _EXP_EVAL(le->le_e2));
271 	case LEOP_SEGMENT_START:
272 		return (_func_segment_start(ld, le));
273 	case LEOP_SIZEOF:
274 		return (_func_sizeof(ld, le));
275 	case LEOP_SIZEOF_HEADERS:
276 		return (_func_sizeof_headers(ld));
277 	case LEOP_SUBSTRACT:
278 		return (_EXP_EVAL(le->le_e1) - _EXP_EVAL(le->le_e2));
279 	case LEOP_SYMBOL:
280 		return (_symbol_val(ld, le->le_name));
281 	case LEOP_SYMBOLIC_CONSTANT:
282 		return (_symbolic_constant(ld, le->le_name));
283 	case LEOP_TRINARY:
284 		return (_EXP_EVAL(le->le_e1) ? _EXP_EVAL(le->le_e2) :
285 		    _EXP_EVAL(le->le_e3));
286 	default:
287 		ld_fatal(ld, "internal: unknown ldscript expression op");
288 	}
289 
290 	return (0);
291 }
292 
293 void
ld_exp_dump(struct ld * ld,struct ld_exp * le)294 ld_exp_dump(struct ld *ld, struct ld_exp *le)
295 {
296 
297 	assert(le != NULL);
298 
299 	if (le->le_par)
300 		printf("(");
301 
302 	switch (le->le_op) {
303 	case LEOP_ABS:
304 		printf("ABS(");
305 		_EXP_DUMP(le->le_e1);
306 		printf(")");
307 		break;
308 	case LEOP_ADD:
309 		_EXP_DUMP(le->le_e1);
310 		printf(" + ");
311 		_EXP_DUMP(le->le_e2);
312 		break;
313 	case LEOP_ADDR:
314 		printf("ADDR(");
315 		_EXP_DUMP(le->le_e1);
316 		printf(")");
317 		break;
318 	case LEOP_ALIGN:
319 	case LEOP_BLOCK:
320 		printf("ALIGN(");
321 		_EXP_DUMP(le->le_e1);
322 		if (le->le_e2 != NULL) {
323 			printf(", ");
324 			_EXP_DUMP(le->le_e2);
325 		}
326 		printf(")");
327 		break;
328 	case LEOP_ALIGNOF:
329 		printf("ALIGNOF(");
330 		_EXP_DUMP(le->le_e1);
331 		printf(")");
332 		break;
333 	case LEOP_AND:
334 		_EXP_DUMP(le->le_e1);
335 		printf(" & ");
336 		_EXP_DUMP(le->le_e2);
337 		break;
338 	case LEOP_ASSIGN:
339 		printf("0x%jx", (uintmax_t)  le->le_assign->lda_res);
340 		break;
341 	case LEOP_CONSTANT:
342 		printf("0x%jx", (uintmax_t) le->le_val);
343 		break;
344 	case LEOP_DIV:
345 		_EXP_DUMP(le->le_e1);
346 		printf(" / ");
347 		_EXP_DUMP(le->le_e2);
348 		break;
349 	case LEOP_DSA:
350 		printf("DATA_SEGMENT_ALIGN(");
351 		_EXP_DUMP(le->le_e1);
352 		printf(", ");
353 		_EXP_DUMP(le->le_e2);
354 		printf(")");
355 		break;
356 	case LEOP_DSE:
357 		printf("DATA_SEGMENT_END(");
358 		_EXP_DUMP(le->le_e1);
359 		printf(")");
360 		break;
361 	case LEOP_DSRE:
362 		printf("DATA_SEGMENT_RELRO_END(");
363 		_EXP_DUMP(le->le_e1);
364 		printf(", ");
365 		_EXP_DUMP(le->le_e2);
366 		printf(")");
367 		break;
368 	case LEOP_DEFINED:
369 		printf("DEFINED(");
370 		_EXP_DUMP(le->le_e1);
371 		printf(")");
372 		break;
373 	case LEOP_EQUAL:
374 		_EXP_DUMP(le->le_e1);
375 		printf(" == ");
376 		_EXP_DUMP(le->le_e2);
377 		break;
378 	case LEOP_GE:
379 		_EXP_DUMP(le->le_e1);
380 		printf(" >= ");
381 		_EXP_DUMP(le->le_e2);
382 		break;
383 	case LEOP_GREATER:
384 		_EXP_DUMP(le->le_e1);
385 		printf(" > ");
386 		_EXP_DUMP(le->le_e2);
387 		break;
388 	case LEOP_LENGTH:
389 		printf("LENGTH(");
390 		_EXP_DUMP(le->le_e1);
391 		printf(")");
392 		break;
393 	case LEOP_LOADADDR:
394 		printf("LOADADDR(");
395 		_EXP_DUMP(le->le_e1);
396 		printf(")");
397 		break;
398 	case LEOP_LOGICAL_AND:
399 		_EXP_DUMP(le->le_e1);
400 		printf(" && ");
401 		_EXP_DUMP(le->le_e2);
402 		break;
403 	case LEOP_LOGICAL_OR:
404 		_EXP_DUMP(le->le_e1);
405 		printf(" || ");
406 		_EXP_DUMP(le->le_e2);
407 		break;
408 	case LEOP_LSHIFT:
409 		_EXP_DUMP(le->le_e1);
410 		printf(" << ");
411 		_EXP_DUMP(le->le_e2);
412 		break;
413 	case LEOP_MAX:
414 		printf("MAX(");
415 		_EXP_DUMP(le->le_e1);
416 		printf(", ");
417 		_EXP_DUMP(le->le_e2);
418 		printf(")");
419 		break;
420 	case LEOP_MIN:
421 		printf("MIN(");
422 		_EXP_DUMP(le->le_e1);
423 		printf(", ");
424 		_EXP_DUMP(le->le_e2);
425 		printf(")");
426 		break;
427 	case LEOP_MINUS:
428 		printf("-");
429 		_EXP_DUMP(le->le_e1);
430 		break;
431 	case LEOP_MOD:
432 		_EXP_DUMP(le->le_e1);
433 		printf(" %% ");
434 		_EXP_DUMP(le->le_e2);
435 		break;
436 	case LEOP_MUL:
437 		_EXP_DUMP(le->le_e1);
438 		printf(" * ");
439 		_EXP_DUMP(le->le_e2);
440 		break;
441 	case LEOP_NE:
442 		_EXP_DUMP(le->le_e1);
443 		printf(" != ");
444 		_EXP_DUMP(le->le_e2);
445 		break;
446 	case LEOP_NEGATION:
447 		printf("~");
448 		_EXP_DUMP(le->le_e1);
449 		break;
450 	case LEOP_NEXT:
451 		printf("NEXT(");
452 		_EXP_DUMP(le->le_e1);
453 		printf(")");
454 		break;
455 	case LEOP_NOT:
456 		printf("!");
457 		_EXP_DUMP(le->le_e1);
458 		break;
459 	case LEOP_OR:
460 		_EXP_DUMP(le->le_e1);
461 		printf(" | ");
462 		_EXP_DUMP(le->le_e2);
463 		break;
464 	case LEOP_ORIGIN:
465 		printf("ORIGIN(");
466 		_EXP_DUMP(le->le_e1);
467 		printf(")");
468 		break;
469 	case LEOP_RSHIFT:
470 		_EXP_DUMP(le->le_e1);
471 		printf(" >> ");
472 		_EXP_DUMP(le->le_e2);
473 		break;
474 	case LEOP_SEGMENT_START:
475 		printf("SEGMENT_START(");
476 		_EXP_DUMP(le->le_e1);
477 		printf(", ");
478 		_EXP_DUMP(le->le_e2);
479 		printf(")");
480 		break;
481 	case LEOP_SIZEOF:
482 		printf("SIZEOF(");
483 		_EXP_DUMP(le->le_e1);
484 		printf(")");
485 		break;
486 	case LEOP_SIZEOF_HEADERS:
487 		printf("SIZEOF_HEADERS");
488 		break;
489 	case LEOP_SUBSTRACT:
490 		_EXP_DUMP(le->le_e1);
491 		printf(" - ");
492 		_EXP_DUMP(le->le_e2);
493 		break;
494 	case LEOP_SYMBOL:
495 		printf("%s", le->le_name);
496 		break;
497 	case LEOP_SYMBOLIC_CONSTANT:
498 		printf("0x%jx",
499 		    (uintmax_t) _symbolic_constant(ld, le->le_name));
500 		break;
501 	case LEOP_TRINARY:
502 		_EXP_DUMP(le->le_e1);
503 		printf(" ? ");
504 		_EXP_DUMP(le->le_e2);
505 		printf(" : ");
506 		_EXP_DUMP(le->le_e3);
507 		break;
508 	default:
509 		ld_fatal(ld, "internal: unknown ldscript expression op");
510 	}
511 
512 	if (le->le_par)
513 		printf(")");
514 }
515 
516 static struct ld_exp *
_alloc_exp(struct ld * ld)517 _alloc_exp(struct ld *ld)
518 {
519 	struct ld_exp *le;
520 
521 	if ((le = calloc(1, sizeof(*le))) == NULL)
522 		ld_fatal_std(ld, "calloc");
523 
524 	return (le);
525 }
526 
527 static int64_t
_assignment(struct ld * ld,struct ld_exp * le)528 _assignment(struct ld *ld, struct ld_exp *le)
529 {
530 	struct ld_exp *var;
531 
532 	assert(le->le_assign != NULL);
533 	ld_script_process_assign(ld, le->le_assign);
534 	var = le->le_assign->lda_var;
535 	return (ld_script_variable_value(ld, var->le_name));
536 }
537 
538 static int64_t
_func_addr(struct ld * ld,struct ld_exp * le)539 _func_addr(struct ld *ld, struct ld_exp *le)
540 {
541 
542 	/* TODO */
543 	(void) ld; (void) le;
544 	return (0);
545 }
546 
547 static int64_t
_func_align(struct ld * ld,struct ld_exp * le)548 _func_align(struct ld *ld, struct ld_exp *le)
549 {
550 	struct ld_state *ls;
551 
552 	ls = &ld->ld_state;
553 	if (le->le_e2 != NULL)
554 		return (roundup(_EXP_EVAL(le->le_e1), _EXP_EVAL(le->le_e2)));
555 	else
556 		return (roundup(ls->ls_loc_counter, _EXP_EVAL(le->le_e1)));
557 }
558 
559 static int64_t
_func_alignof(struct ld * ld,struct ld_exp * le)560 _func_alignof(struct ld *ld, struct ld_exp *le)
561 {
562 
563 	/* TODO */
564 	(void) ld; (void) le;
565 	return (0);
566 }
567 
568 static int64_t
_func_data_segment_align(struct ld * ld,struct ld_exp * le)569 _func_data_segment_align(struct ld *ld, struct ld_exp *le)
570 {
571 	struct ld_state *ls;
572 	uint64_t maxpagesize;
573 	/* uint64_t commonpagesize; */
574 
575 	/*
576 	 * TODO: test if align to common page size use less number
577 	 * of pages.
578 	 */
579 	ls = &ld->ld_state;
580 	maxpagesize = _EXP_EVAL(le->le_e1);
581 	/* commonpagesize = _EXP_EVAL(le->le_e2); */
582 
583 	return (roundup(ls->ls_loc_counter, maxpagesize) +
584 	    (ls->ls_loc_counter & (maxpagesize - 1)));
585 }
586 
587 static int64_t
_func_data_segment_end(struct ld * ld,struct ld_exp * le)588 _func_data_segment_end(struct ld *ld, struct ld_exp *le)
589 {
590 
591 	return (_EXP_EVAL(le->le_e1));
592 }
593 
594 static int64_t
_func_data_segment_relro_end(struct ld * ld,struct ld_exp * le)595 _func_data_segment_relro_end(struct ld *ld, struct ld_exp *le)
596 {
597 
598 	/* TODO */
599 	(void) ld; (void) le;
600 	return (0);
601 }
602 
603 static int64_t
_func_defined(struct ld * ld,struct ld_exp * le)604 _func_defined(struct ld *ld, struct ld_exp *le)
605 {
606 
607 	/* TODO */
608 	(void) ld; (void) le;
609 	return (0);
610 }
611 
612 static int64_t
_func_length(struct ld * ld,struct ld_exp * le)613 _func_length(struct ld *ld, struct ld_exp *le)
614 {
615 
616 	/* TODO */
617 	(void) ld; (void) le;
618 	return (0);
619 }
620 
621 static int64_t
_func_loadaddr(struct ld * ld,struct ld_exp * le)622 _func_loadaddr(struct ld *ld, struct ld_exp *le)
623 {
624 
625 	/* TODO */
626 	(void) ld; (void) le;
627 	return (0);
628 }
629 
630 static int64_t
_func_max(struct ld * ld,struct ld_exp * le)631 _func_max(struct ld *ld, struct ld_exp *le)
632 {
633 	uint64_t val1, val2;
634 
635 	val1 = _EXP_EVAL(le->le_e1);
636 	val2 = _EXP_EVAL(le->le_e2);
637 
638 	return (val1 > val2 ? val1 : val2);
639 }
640 
641 static int64_t
_func_min(struct ld * ld,struct ld_exp * le)642 _func_min(struct ld *ld, struct ld_exp *le)
643 {
644 	uint64_t val1, val2;
645 
646 	val1 = _EXP_EVAL(le->le_e1);
647 	val2 = _EXP_EVAL(le->le_e2);
648 
649 	return (val1 > val2 ? val2 : val1);
650 }
651 
652 static int64_t
_func_next(struct ld * ld,struct ld_exp * le)653 _func_next(struct ld *ld, struct ld_exp *le)
654 {
655 
656 	/* TODO */
657 	(void) ld; (void) le;
658 	return (0);
659 }
660 
661 static int64_t
_func_origin(struct ld * ld,struct ld_exp * le)662 _func_origin(struct ld *ld, struct ld_exp *le)
663 {
664 
665 	/* TODO */
666 	(void) ld; (void) le;
667 	return (0);
668 }
669 
670 static int64_t
_func_segment_start(struct ld * ld,struct ld_exp * le)671 _func_segment_start(struct ld *ld, struct ld_exp *le)
672 {
673 
674 	/* TODO */
675 	(void) ld; (void) le;
676 	return (0);
677 }
678 
679 static int64_t
_func_sizeof(struct ld * ld,struct ld_exp * le)680 _func_sizeof(struct ld *ld, struct ld_exp *le)
681 {
682 
683 	/* TODO */
684 	(void) ld; (void) le;
685 	return (0);
686 }
687 
688 static int64_t
_func_sizeof_headers(struct ld * ld)689 _func_sizeof_headers(struct ld *ld)
690 {
691 
692 	return (ld_layout_calc_header_size(ld));
693 }
694 
695 static int64_t
_symbol_val(struct ld * ld,char * name)696 _symbol_val(struct ld *ld, char *name)
697 {
698 
699 	return (ld_script_variable_value(ld, name));
700 }
701 
702 static int64_t
_symbolic_constant(struct ld * ld,const char * name)703 _symbolic_constant(struct ld *ld, const char *name)
704 {
705 
706 	if (ld->ld_arch == NULL)
707 		return (0);
708 
709 	if (strcmp(name, "COMMONPAGESIZE") == 0)
710 		return (ld->ld_arch->get_common_page_size(ld));
711 	else if (strcmp(name, "MAXPAGESIZE") == 0)
712 		return (ld->ld_arch->get_max_page_size(ld));
713 
714 	return (0);
715 }
716