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