1ed0d50c3Schristos /* This module handles expression trees.
2*b88e3e88Schristos Copyright (C) 1991-2020 Free Software Foundation, Inc.
3ed0d50c3Schristos Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
4ed0d50c3Schristos
5ed0d50c3Schristos This file is part of the GNU Binutils.
6ed0d50c3Schristos
7ed0d50c3Schristos This program is free software; you can redistribute it and/or modify
8ed0d50c3Schristos it under the terms of the GNU General Public License as published by
9ed0d50c3Schristos the Free Software Foundation; either version 3 of the License, or
10ed0d50c3Schristos (at your option) any later version.
11ed0d50c3Schristos
12ed0d50c3Schristos This program is distributed in the hope that it will be useful,
13ed0d50c3Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
14ed0d50c3Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15ed0d50c3Schristos GNU General Public License for more details.
16ed0d50c3Schristos
17ed0d50c3Schristos You should have received a copy of the GNU General Public License
18ed0d50c3Schristos along with this program; if not, write to the Free Software
19ed0d50c3Schristos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20ed0d50c3Schristos MA 02110-1301, USA. */
21ed0d50c3Schristos
22ed0d50c3Schristos
23ed0d50c3Schristos /* This module is in charge of working out the contents of expressions.
24ed0d50c3Schristos
25ed0d50c3Schristos It has to keep track of the relative/absness of a symbol etc. This
26ed0d50c3Schristos is done by keeping all values in a struct (an etree_value_type)
27ed0d50c3Schristos which contains a value, a section to which it is relative and a
28ed0d50c3Schristos valid bit. */
29ed0d50c3Schristos
30ed0d50c3Schristos #include "sysdep.h"
31ed0d50c3Schristos #include "bfd.h"
32ed0d50c3Schristos #include "bfdlink.h"
33*b88e3e88Schristos #include "ctf-api.h"
34ed0d50c3Schristos
35ed0d50c3Schristos #include "ld.h"
36ed0d50c3Schristos #include "ldmain.h"
37ed0d50c3Schristos #include "ldmisc.h"
38ed0d50c3Schristos #include "ldexp.h"
39ed0d50c3Schristos #include "ldlex.h"
40ed0d50c3Schristos #include <ldgram.h>
41ed0d50c3Schristos #include "ldlang.h"
42ed0d50c3Schristos #include "libiberty.h"
43ed0d50c3Schristos #include "safe-ctype.h"
44ed0d50c3Schristos
45ed0d50c3Schristos static void exp_fold_tree_1 (etree_type *);
46ed0d50c3Schristos static bfd_vma align_n (bfd_vma, bfd_vma);
47ed0d50c3Schristos
48ed0d50c3Schristos segment_type *segments;
49ed0d50c3Schristos
50ed0d50c3Schristos struct ldexp_control expld;
51ed0d50c3Schristos
52ed0d50c3Schristos /* This structure records symbols for which we need to keep track of
53ed0d50c3Schristos definedness for use in the DEFINED () test. It is also used in
54ed0d50c3Schristos making absolute symbols section relative late in the link. */
55ed0d50c3Schristos
56ed0d50c3Schristos struct definedness_hash_entry
57ed0d50c3Schristos {
58ed0d50c3Schristos struct bfd_hash_entry root;
59ed0d50c3Schristos
60ed0d50c3Schristos /* If this symbol was assigned from "dot" outside of an output
61ed0d50c3Schristos section statement, the section we'd like it relative to. */
62ed0d50c3Schristos asection *final_sec;
63ed0d50c3Schristos
6406324dcfSchristos /* Low bits of iteration count. Symbols with matching iteration have
6506324dcfSchristos been defined in this pass over the script. */
6606324dcfSchristos unsigned int iteration : 8;
6706324dcfSchristos
68ed0d50c3Schristos /* Symbol was defined by an object file. */
69ed0d50c3Schristos unsigned int by_object : 1;
70ed0d50c3Schristos };
71ed0d50c3Schristos
72ed0d50c3Schristos static struct bfd_hash_table definedness_table;
73ed0d50c3Schristos
74ed0d50c3Schristos /* Print the string representation of the given token. Surround it
75ed0d50c3Schristos with spaces if INFIX_P is TRUE. */
76ed0d50c3Schristos
77ed0d50c3Schristos static void
exp_print_token(token_code_type code,int infix_p)78ed0d50c3Schristos exp_print_token (token_code_type code, int infix_p)
79ed0d50c3Schristos {
80ed0d50c3Schristos static const struct
81ed0d50c3Schristos {
82ed0d50c3Schristos token_code_type code;
83ed0d50c3Schristos const char *name;
84ed0d50c3Schristos }
85ed0d50c3Schristos table[] =
86ed0d50c3Schristos {
87ed0d50c3Schristos { INT, "int" },
88ed0d50c3Schristos { NAME, "NAME" },
89ed0d50c3Schristos { PLUSEQ, "+=" },
90ed0d50c3Schristos { MINUSEQ, "-=" },
91ed0d50c3Schristos { MULTEQ, "*=" },
92ed0d50c3Schristos { DIVEQ, "/=" },
93ed0d50c3Schristos { LSHIFTEQ, "<<=" },
94ed0d50c3Schristos { RSHIFTEQ, ">>=" },
95ed0d50c3Schristos { ANDEQ, "&=" },
96ed0d50c3Schristos { OREQ, "|=" },
97ed0d50c3Schristos { OROR, "||" },
98ed0d50c3Schristos { ANDAND, "&&" },
99ed0d50c3Schristos { EQ, "==" },
100ed0d50c3Schristos { NE, "!=" },
101ed0d50c3Schristos { LE, "<=" },
102ed0d50c3Schristos { GE, ">=" },
103ed0d50c3Schristos { LSHIFT, "<<" },
104ed0d50c3Schristos { RSHIFT, ">>" },
105ed0d50c3Schristos { LOG2CEIL, "LOG2CEIL" },
106ed0d50c3Schristos { ALIGN_K, "ALIGN" },
107ed0d50c3Schristos { BLOCK, "BLOCK" },
108ed0d50c3Schristos { QUAD, "QUAD" },
109ed0d50c3Schristos { SQUAD, "SQUAD" },
110ed0d50c3Schristos { LONG, "LONG" },
111ed0d50c3Schristos { SHORT, "SHORT" },
112ed0d50c3Schristos { BYTE, "BYTE" },
113ed0d50c3Schristos { SECTIONS, "SECTIONS" },
114ed0d50c3Schristos { SIZEOF_HEADERS, "SIZEOF_HEADERS" },
115ed0d50c3Schristos { MEMORY, "MEMORY" },
116ed0d50c3Schristos { DEFINED, "DEFINED" },
117ed0d50c3Schristos { TARGET_K, "TARGET" },
118ed0d50c3Schristos { SEARCH_DIR, "SEARCH_DIR" },
119ed0d50c3Schristos { MAP, "MAP" },
120ed0d50c3Schristos { ENTRY, "ENTRY" },
121ed0d50c3Schristos { NEXT, "NEXT" },
122ed0d50c3Schristos { ALIGNOF, "ALIGNOF" },
123ed0d50c3Schristos { SIZEOF, "SIZEOF" },
124ed0d50c3Schristos { ADDR, "ADDR" },
125ed0d50c3Schristos { LOADADDR, "LOADADDR" },
126ed0d50c3Schristos { CONSTANT, "CONSTANT" },
127ed0d50c3Schristos { ABSOLUTE, "ABSOLUTE" },
128ed0d50c3Schristos { MAX_K, "MAX" },
129ed0d50c3Schristos { MIN_K, "MIN" },
130ed0d50c3Schristos { ASSERT_K, "ASSERT" },
131ed0d50c3Schristos { REL, "relocatable" },
132ed0d50c3Schristos { DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" },
133ed0d50c3Schristos { DATA_SEGMENT_RELRO_END, "DATA_SEGMENT_RELRO_END" },
134ed0d50c3Schristos { DATA_SEGMENT_END, "DATA_SEGMENT_END" },
135ed0d50c3Schristos { ORIGIN, "ORIGIN" },
136ed0d50c3Schristos { LENGTH, "LENGTH" },
137ed0d50c3Schristos { SEGMENT_START, "SEGMENT_START" }
138ed0d50c3Schristos };
139ed0d50c3Schristos unsigned int idx;
140ed0d50c3Schristos
141ed0d50c3Schristos for (idx = 0; idx < ARRAY_SIZE (table); idx++)
142ed0d50c3Schristos if (table[idx].code == code)
143ed0d50c3Schristos break;
144ed0d50c3Schristos
145ed0d50c3Schristos if (infix_p)
146ed0d50c3Schristos fputc (' ', config.map_file);
147ed0d50c3Schristos
148ed0d50c3Schristos if (idx < ARRAY_SIZE (table))
149ed0d50c3Schristos fputs (table[idx].name, config.map_file);
150ed0d50c3Schristos else if (code < 127)
151ed0d50c3Schristos fputc (code, config.map_file);
152ed0d50c3Schristos else
153ed0d50c3Schristos fprintf (config.map_file, "<code %d>", code);
154ed0d50c3Schristos
155ed0d50c3Schristos if (infix_p)
156ed0d50c3Schristos fputc (' ', config.map_file);
157ed0d50c3Schristos }
158ed0d50c3Schristos
159ed0d50c3Schristos static void
make_log2ceil(void)160ed0d50c3Schristos make_log2ceil (void)
161ed0d50c3Schristos {
162ed0d50c3Schristos bfd_vma value = expld.result.value;
163ed0d50c3Schristos bfd_vma result = -1;
164ed0d50c3Schristos bfd_boolean round_up = FALSE;
165ed0d50c3Schristos
166ed0d50c3Schristos do
167ed0d50c3Schristos {
168ed0d50c3Schristos result++;
169ed0d50c3Schristos /* If more than one bit is set in the value we will need to round up. */
170ed0d50c3Schristos if ((value > 1) && (value & 1))
171ed0d50c3Schristos round_up = TRUE;
172ed0d50c3Schristos }
173ed0d50c3Schristos while (value >>= 1);
174ed0d50c3Schristos
175ed0d50c3Schristos if (round_up)
176ed0d50c3Schristos result += 1;
177ed0d50c3Schristos expld.result.section = NULL;
178ed0d50c3Schristos expld.result.value = result;
179ed0d50c3Schristos }
180ed0d50c3Schristos
181ed0d50c3Schristos static void
make_abs(void)182ed0d50c3Schristos make_abs (void)
183ed0d50c3Schristos {
184ed0d50c3Schristos if (expld.result.section != NULL)
185ed0d50c3Schristos expld.result.value += expld.result.section->vma;
186ed0d50c3Schristos expld.result.section = bfd_abs_section_ptr;
187ed0d50c3Schristos expld.rel_from_abs = FALSE;
188ed0d50c3Schristos }
189ed0d50c3Schristos
190ed0d50c3Schristos static void
new_abs(bfd_vma value)191ed0d50c3Schristos new_abs (bfd_vma value)
192ed0d50c3Schristos {
193ed0d50c3Schristos expld.result.valid_p = TRUE;
194ed0d50c3Schristos expld.result.section = bfd_abs_section_ptr;
195ed0d50c3Schristos expld.result.value = value;
196ed0d50c3Schristos expld.result.str = NULL;
197ed0d50c3Schristos }
198ed0d50c3Schristos
199ed0d50c3Schristos etree_type *
exp_intop(bfd_vma value)200ed0d50c3Schristos exp_intop (bfd_vma value)
201ed0d50c3Schristos {
202*b88e3e88Schristos etree_type *new_e = stat_alloc (sizeof (new_e->value));
203ed0d50c3Schristos new_e->type.node_code = INT;
204ed0d50c3Schristos new_e->type.filename = ldlex_filename ();
205ed0d50c3Schristos new_e->type.lineno = lineno;
206ed0d50c3Schristos new_e->value.value = value;
207ed0d50c3Schristos new_e->value.str = NULL;
208ed0d50c3Schristos new_e->type.node_class = etree_value;
209ed0d50c3Schristos return new_e;
210ed0d50c3Schristos }
211ed0d50c3Schristos
212ed0d50c3Schristos etree_type *
exp_bigintop(bfd_vma value,char * str)213ed0d50c3Schristos exp_bigintop (bfd_vma value, char *str)
214ed0d50c3Schristos {
215*b88e3e88Schristos etree_type *new_e = stat_alloc (sizeof (new_e->value));
216ed0d50c3Schristos new_e->type.node_code = INT;
217ed0d50c3Schristos new_e->type.filename = ldlex_filename ();
218ed0d50c3Schristos new_e->type.lineno = lineno;
219ed0d50c3Schristos new_e->value.value = value;
220ed0d50c3Schristos new_e->value.str = str;
221ed0d50c3Schristos new_e->type.node_class = etree_value;
222ed0d50c3Schristos return new_e;
223ed0d50c3Schristos }
224ed0d50c3Schristos
225ed0d50c3Schristos /* Build an expression representing an unnamed relocatable value. */
226ed0d50c3Schristos
227ed0d50c3Schristos etree_type *
exp_relop(asection * section,bfd_vma value)228ed0d50c3Schristos exp_relop (asection *section, bfd_vma value)
229ed0d50c3Schristos {
230*b88e3e88Schristos etree_type *new_e = stat_alloc (sizeof (new_e->rel));
231ed0d50c3Schristos new_e->type.node_code = REL;
232ed0d50c3Schristos new_e->type.filename = ldlex_filename ();
233ed0d50c3Schristos new_e->type.lineno = lineno;
234ed0d50c3Schristos new_e->type.node_class = etree_rel;
235ed0d50c3Schristos new_e->rel.section = section;
236ed0d50c3Schristos new_e->rel.value = value;
237ed0d50c3Schristos return new_e;
238ed0d50c3Schristos }
239ed0d50c3Schristos
240ed0d50c3Schristos static void
new_number(bfd_vma value)241ed0d50c3Schristos new_number (bfd_vma value)
242ed0d50c3Schristos {
243ed0d50c3Schristos expld.result.valid_p = TRUE;
244ed0d50c3Schristos expld.result.value = value;
245ed0d50c3Schristos expld.result.str = NULL;
246ed0d50c3Schristos expld.result.section = NULL;
247ed0d50c3Schristos }
248ed0d50c3Schristos
249ed0d50c3Schristos static void
new_rel(bfd_vma value,asection * section)250ed0d50c3Schristos new_rel (bfd_vma value, asection *section)
251ed0d50c3Schristos {
252ed0d50c3Schristos expld.result.valid_p = TRUE;
253ed0d50c3Schristos expld.result.value = value;
254ed0d50c3Schristos expld.result.str = NULL;
255ed0d50c3Schristos expld.result.section = section;
256ed0d50c3Schristos }
257ed0d50c3Schristos
258ed0d50c3Schristos static void
new_rel_from_abs(bfd_vma value)259ed0d50c3Schristos new_rel_from_abs (bfd_vma value)
260ed0d50c3Schristos {
261ed0d50c3Schristos asection *s = expld.section;
262ed0d50c3Schristos
263ed0d50c3Schristos expld.rel_from_abs = TRUE;
264ed0d50c3Schristos expld.result.valid_p = TRUE;
265ed0d50c3Schristos expld.result.value = value - s->vma;
266ed0d50c3Schristos expld.result.str = NULL;
267ed0d50c3Schristos expld.result.section = s;
268ed0d50c3Schristos }
269ed0d50c3Schristos
270ed0d50c3Schristos /* New-function for the definedness hash table. */
271ed0d50c3Schristos
272ed0d50c3Schristos static struct bfd_hash_entry *
definedness_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table ATTRIBUTE_UNUSED,const char * name ATTRIBUTE_UNUSED)273ed0d50c3Schristos definedness_newfunc (struct bfd_hash_entry *entry,
274ed0d50c3Schristos struct bfd_hash_table *table ATTRIBUTE_UNUSED,
275ed0d50c3Schristos const char *name ATTRIBUTE_UNUSED)
276ed0d50c3Schristos {
277ed0d50c3Schristos struct definedness_hash_entry *ret = (struct definedness_hash_entry *) entry;
278ed0d50c3Schristos
279ed0d50c3Schristos if (ret == NULL)
280ed0d50c3Schristos ret = (struct definedness_hash_entry *)
281ed0d50c3Schristos bfd_hash_allocate (table, sizeof (struct definedness_hash_entry));
282ed0d50c3Schristos
283ed0d50c3Schristos if (ret == NULL)
28406324dcfSchristos einfo (_("%F%P: bfd_hash_allocate failed creating symbol %s\n"), name);
285ed0d50c3Schristos
286ed0d50c3Schristos ret->by_object = 0;
287ed0d50c3Schristos ret->iteration = 0;
288ed0d50c3Schristos return &ret->root;
289ed0d50c3Schristos }
290ed0d50c3Schristos
291ed0d50c3Schristos /* Called during processing of linker script script expressions.
292ed0d50c3Schristos For symbols assigned in a linker script, return a struct describing
293ed0d50c3Schristos where the symbol is defined relative to the current expression,
294ed0d50c3Schristos otherwise return NULL. */
295ed0d50c3Schristos
296ed0d50c3Schristos static struct definedness_hash_entry *
symbol_defined(const char * name)297ed0d50c3Schristos symbol_defined (const char *name)
298ed0d50c3Schristos {
299ed0d50c3Schristos return ((struct definedness_hash_entry *)
300ed0d50c3Schristos bfd_hash_lookup (&definedness_table, name, FALSE, FALSE));
301ed0d50c3Schristos }
302ed0d50c3Schristos
303ed0d50c3Schristos /* Update the definedness state of NAME. Return FALSE if script symbol
304ed0d50c3Schristos is multiply defining a strong symbol in an object. */
305ed0d50c3Schristos
306ed0d50c3Schristos static bfd_boolean
update_definedness(const char * name,struct bfd_link_hash_entry * h)307ed0d50c3Schristos update_definedness (const char *name, struct bfd_link_hash_entry *h)
308ed0d50c3Schristos {
309ed0d50c3Schristos bfd_boolean ret;
310ed0d50c3Schristos struct definedness_hash_entry *defentry
311ed0d50c3Schristos = (struct definedness_hash_entry *)
312ed0d50c3Schristos bfd_hash_lookup (&definedness_table, name, TRUE, FALSE);
313ed0d50c3Schristos
314ed0d50c3Schristos if (defentry == NULL)
31506324dcfSchristos einfo (_("%F%P: bfd_hash_lookup failed creating symbol %s\n"), name);
316ed0d50c3Schristos
317ed0d50c3Schristos /* If the symbol was already defined, and not by a script, then it
318ed0d50c3Schristos must be defined by an object file or by the linker target code. */
319ed0d50c3Schristos ret = TRUE;
32006324dcfSchristos if (!h->ldscript_def
321ed0d50c3Schristos && (h->type == bfd_link_hash_defined
322ed0d50c3Schristos || h->type == bfd_link_hash_defweak
323ed0d50c3Schristos || h->type == bfd_link_hash_common))
324ed0d50c3Schristos {
325ed0d50c3Schristos defentry->by_object = 1;
326ed0d50c3Schristos if (h->type == bfd_link_hash_defined
327ed0d50c3Schristos && h->u.def.section->output_section != NULL
328ed0d50c3Schristos && !h->linker_def)
329ed0d50c3Schristos ret = FALSE;
330ed0d50c3Schristos }
331ed0d50c3Schristos
332ed0d50c3Schristos defentry->iteration = lang_statement_iteration;
333ed0d50c3Schristos defentry->final_sec = bfd_abs_section_ptr;
334ed0d50c3Schristos if (expld.phase == lang_final_phase_enum
335ed0d50c3Schristos && expld.rel_from_abs
336ed0d50c3Schristos && expld.result.section == bfd_abs_section_ptr)
337ed0d50c3Schristos defentry->final_sec = section_for_dot ();
338ed0d50c3Schristos return ret;
339ed0d50c3Schristos }
340ed0d50c3Schristos
341ed0d50c3Schristos static void
fold_segment_end(seg_align_type * seg)34206324dcfSchristos fold_segment_end (seg_align_type *seg)
34306324dcfSchristos {
34406324dcfSchristos if (expld.phase == lang_first_phase_enum
34506324dcfSchristos || expld.section != bfd_abs_section_ptr)
34606324dcfSchristos {
34706324dcfSchristos expld.result.valid_p = FALSE;
34806324dcfSchristos }
34906324dcfSchristos else if (seg->phase == exp_seg_align_seen
35006324dcfSchristos || seg->phase == exp_seg_relro_seen)
35106324dcfSchristos {
35206324dcfSchristos seg->phase = exp_seg_end_seen;
35306324dcfSchristos seg->end = expld.result.value;
35406324dcfSchristos }
35506324dcfSchristos else if (seg->phase == exp_seg_done
35606324dcfSchristos || seg->phase == exp_seg_adjust
35706324dcfSchristos || seg->phase == exp_seg_relro_adjust)
35806324dcfSchristos {
35906324dcfSchristos /* OK. */
36006324dcfSchristos }
36106324dcfSchristos else
36206324dcfSchristos expld.result.valid_p = FALSE;
36306324dcfSchristos }
36406324dcfSchristos
36506324dcfSchristos static void
fold_unary(etree_type * tree)366ed0d50c3Schristos fold_unary (etree_type *tree)
367ed0d50c3Schristos {
368ed0d50c3Schristos exp_fold_tree_1 (tree->unary.child);
369ed0d50c3Schristos if (expld.result.valid_p)
370ed0d50c3Schristos {
371ed0d50c3Schristos switch (tree->type.node_code)
372ed0d50c3Schristos {
373ed0d50c3Schristos case ALIGN_K:
374ed0d50c3Schristos if (expld.phase != lang_first_phase_enum)
375ed0d50c3Schristos new_rel_from_abs (align_n (expld.dot, expld.result.value));
376ed0d50c3Schristos else
377ed0d50c3Schristos expld.result.valid_p = FALSE;
378ed0d50c3Schristos break;
379ed0d50c3Schristos
380ed0d50c3Schristos case ABSOLUTE:
381ed0d50c3Schristos make_abs ();
382ed0d50c3Schristos break;
383ed0d50c3Schristos
384ed0d50c3Schristos case LOG2CEIL:
385ed0d50c3Schristos make_log2ceil ();
386ed0d50c3Schristos break;
387ed0d50c3Schristos
388ed0d50c3Schristos case '~':
389ed0d50c3Schristos expld.result.value = ~expld.result.value;
390ed0d50c3Schristos break;
391ed0d50c3Schristos
392ed0d50c3Schristos case '!':
393ed0d50c3Schristos expld.result.value = !expld.result.value;
394ed0d50c3Schristos break;
395ed0d50c3Schristos
396ed0d50c3Schristos case '-':
397ed0d50c3Schristos expld.result.value = -expld.result.value;
398ed0d50c3Schristos break;
399ed0d50c3Schristos
400ed0d50c3Schristos case NEXT:
401ed0d50c3Schristos /* Return next place aligned to value. */
402ed0d50c3Schristos if (expld.phase != lang_first_phase_enum)
403ed0d50c3Schristos {
404ed0d50c3Schristos make_abs ();
405ed0d50c3Schristos expld.result.value = align_n (expld.dot, expld.result.value);
406ed0d50c3Schristos }
407ed0d50c3Schristos else
408ed0d50c3Schristos expld.result.valid_p = FALSE;
409ed0d50c3Schristos break;
410ed0d50c3Schristos
411ed0d50c3Schristos case DATA_SEGMENT_END:
41206324dcfSchristos fold_segment_end (&expld.dataseg);
413ed0d50c3Schristos break;
414ed0d50c3Schristos
415ed0d50c3Schristos default:
416ed0d50c3Schristos FAIL ();
417ed0d50c3Schristos break;
418ed0d50c3Schristos }
419ed0d50c3Schristos }
420ed0d50c3Schristos }
421ed0d50c3Schristos
42206324dcfSchristos /* Arithmetic operators, bitwise AND, bitwise OR and XOR keep the
42306324dcfSchristos section of one of their operands only when the other operand is a
42406324dcfSchristos plain number. Losing the section when operating on two symbols,
42506324dcfSchristos ie. a result of a plain number, is required for subtraction and
42606324dcfSchristos XOR. It's justifiable for the other operations on the grounds that
42706324dcfSchristos adding, multiplying etc. two section relative values does not
42806324dcfSchristos really make sense unless they are just treated as numbers.
42906324dcfSchristos The same argument could be made for many expressions involving one
43006324dcfSchristos symbol and a number. For example, "1 << x" and "100 / x" probably
43106324dcfSchristos should not be given the section of x. The trouble is that if we
43206324dcfSchristos fuss about such things the rules become complex and it is onerous
43306324dcfSchristos to document ld expression evaluation. */
43406324dcfSchristos static void
arith_result_section(const etree_value_type * lhs)43506324dcfSchristos arith_result_section (const etree_value_type *lhs)
43606324dcfSchristos {
43706324dcfSchristos if (expld.result.section == lhs->section)
43806324dcfSchristos {
43906324dcfSchristos if (expld.section == bfd_abs_section_ptr
44006324dcfSchristos && !config.sane_expr)
44106324dcfSchristos /* Duplicate the insanity in exp_fold_tree_1 case etree_value. */
44206324dcfSchristos expld.result.section = bfd_abs_section_ptr;
44306324dcfSchristos else
44406324dcfSchristos expld.result.section = NULL;
44506324dcfSchristos }
44606324dcfSchristos }
44706324dcfSchristos
44806324dcfSchristos static void
fold_segment_align(seg_align_type * seg,etree_value_type * lhs)44906324dcfSchristos fold_segment_align (seg_align_type *seg, etree_value_type *lhs)
45006324dcfSchristos {
45106324dcfSchristos seg->relro = exp_seg_relro_start;
45206324dcfSchristos if (expld.phase == lang_first_phase_enum
45306324dcfSchristos || expld.section != bfd_abs_section_ptr)
45406324dcfSchristos expld.result.valid_p = FALSE;
45506324dcfSchristos else
45606324dcfSchristos {
45706324dcfSchristos bfd_vma maxpage = lhs->value;
45806324dcfSchristos bfd_vma commonpage = expld.result.value;
45906324dcfSchristos
46006324dcfSchristos expld.result.value = align_n (expld.dot, maxpage);
46106324dcfSchristos if (seg->phase == exp_seg_relro_adjust)
46206324dcfSchristos expld.result.value = seg->base;
46306324dcfSchristos else if (seg->phase == exp_seg_adjust)
46406324dcfSchristos {
46506324dcfSchristos if (commonpage < maxpage)
46606324dcfSchristos expld.result.value += ((expld.dot + commonpage - 1)
46706324dcfSchristos & (maxpage - commonpage));
46806324dcfSchristos }
46906324dcfSchristos else
47006324dcfSchristos {
47106324dcfSchristos expld.result.value += expld.dot & (maxpage - 1);
47206324dcfSchristos if (seg->phase == exp_seg_done)
47306324dcfSchristos {
47406324dcfSchristos /* OK. */
47506324dcfSchristos }
47606324dcfSchristos else if (seg->phase == exp_seg_none)
47706324dcfSchristos {
47806324dcfSchristos seg->phase = exp_seg_align_seen;
47906324dcfSchristos seg->base = expld.result.value;
48006324dcfSchristos seg->pagesize = commonpage;
48106324dcfSchristos seg->maxpagesize = maxpage;
48206324dcfSchristos seg->relro_end = 0;
48306324dcfSchristos }
48406324dcfSchristos else
48506324dcfSchristos expld.result.valid_p = FALSE;
48606324dcfSchristos }
48706324dcfSchristos }
48806324dcfSchristos }
48906324dcfSchristos
49006324dcfSchristos static void
fold_segment_relro_end(seg_align_type * seg,etree_value_type * lhs)49106324dcfSchristos fold_segment_relro_end (seg_align_type *seg, etree_value_type *lhs)
49206324dcfSchristos {
49306324dcfSchristos /* Operands swapped! XXX_SEGMENT_RELRO_END(offset,exp) has offset
49406324dcfSchristos in expld.result and exp in lhs. */
49506324dcfSchristos seg->relro = exp_seg_relro_end;
49606324dcfSchristos seg->relro_offset = expld.result.value;
49706324dcfSchristos if (expld.phase == lang_first_phase_enum
49806324dcfSchristos || expld.section != bfd_abs_section_ptr)
49906324dcfSchristos expld.result.valid_p = FALSE;
50006324dcfSchristos else if (seg->phase == exp_seg_align_seen
50106324dcfSchristos || seg->phase == exp_seg_adjust
50206324dcfSchristos || seg->phase == exp_seg_relro_adjust
50306324dcfSchristos || seg->phase == exp_seg_done)
50406324dcfSchristos {
50506324dcfSchristos if (seg->phase == exp_seg_align_seen
50606324dcfSchristos || seg->phase == exp_seg_relro_adjust)
50706324dcfSchristos seg->relro_end = lhs->value + expld.result.value;
50806324dcfSchristos
50906324dcfSchristos if (seg->phase == exp_seg_relro_adjust
51006324dcfSchristos && (seg->relro_end & (seg->pagesize - 1)))
51106324dcfSchristos {
51206324dcfSchristos seg->relro_end += seg->pagesize - 1;
51306324dcfSchristos seg->relro_end &= ~(seg->pagesize - 1);
51406324dcfSchristos expld.result.value = seg->relro_end - expld.result.value;
51506324dcfSchristos }
51606324dcfSchristos else
51706324dcfSchristos expld.result.value = lhs->value;
51806324dcfSchristos
51906324dcfSchristos if (seg->phase == exp_seg_align_seen)
52006324dcfSchristos seg->phase = exp_seg_relro_seen;
52106324dcfSchristos }
52206324dcfSchristos else
52306324dcfSchristos expld.result.valid_p = FALSE;
52406324dcfSchristos }
52506324dcfSchristos
526ed0d50c3Schristos static void
fold_binary(etree_type * tree)527ed0d50c3Schristos fold_binary (etree_type *tree)
528ed0d50c3Schristos {
529ed0d50c3Schristos etree_value_type lhs;
530ed0d50c3Schristos exp_fold_tree_1 (tree->binary.lhs);
531ed0d50c3Schristos
532ed0d50c3Schristos /* The SEGMENT_START operator is special because its first
533ed0d50c3Schristos operand is a string, not the name of a symbol. Note that the
534ed0d50c3Schristos operands have been swapped, so binary.lhs is second (default)
535ed0d50c3Schristos operand, binary.rhs is first operand. */
536ed0d50c3Schristos if (expld.result.valid_p && tree->type.node_code == SEGMENT_START)
537ed0d50c3Schristos {
538*b88e3e88Schristos bfd_vma value = expld.result.value;
539ed0d50c3Schristos const char *segment_name;
540ed0d50c3Schristos segment_type *seg;
541ed0d50c3Schristos
542ed0d50c3Schristos /* Check to see if the user has overridden the default
543ed0d50c3Schristos value. */
544ed0d50c3Schristos segment_name = tree->binary.rhs->name.name;
545ed0d50c3Schristos for (seg = segments; seg; seg = seg->next)
546ed0d50c3Schristos if (strcmp (seg->name, segment_name) == 0)
547ed0d50c3Schristos {
548ed0d50c3Schristos if (!seg->used
549ed0d50c3Schristos && config.magic_demand_paged
550*b88e3e88Schristos && config.maxpagesize != 0
551ed0d50c3Schristos && (seg->value % config.maxpagesize) != 0)
552ed0d50c3Schristos einfo (_("%P: warning: address of `%s' "
553ed0d50c3Schristos "isn't multiple of maximum page size\n"),
554ed0d50c3Schristos segment_name);
555ed0d50c3Schristos seg->used = TRUE;
556*b88e3e88Schristos value = seg->value;
557ed0d50c3Schristos break;
558ed0d50c3Schristos }
559*b88e3e88Schristos new_rel_from_abs (value);
560ed0d50c3Schristos return;
561ed0d50c3Schristos }
562ed0d50c3Schristos
563ed0d50c3Schristos lhs = expld.result;
564ed0d50c3Schristos exp_fold_tree_1 (tree->binary.rhs);
565ed0d50c3Schristos expld.result.valid_p &= lhs.valid_p;
566ed0d50c3Schristos
567ed0d50c3Schristos if (expld.result.valid_p)
568ed0d50c3Schristos {
569ed0d50c3Schristos if (lhs.section != expld.result.section)
570ed0d50c3Schristos {
571ed0d50c3Schristos /* If the values are from different sections, and neither is
572ed0d50c3Schristos just a number, make both the source arguments absolute. */
573ed0d50c3Schristos if (expld.result.section != NULL
574ed0d50c3Schristos && lhs.section != NULL)
575ed0d50c3Schristos {
576ed0d50c3Schristos make_abs ();
577ed0d50c3Schristos lhs.value += lhs.section->vma;
578ed0d50c3Schristos lhs.section = bfd_abs_section_ptr;
579ed0d50c3Schristos }
580ed0d50c3Schristos
581ed0d50c3Schristos /* If the rhs is just a number, keep the lhs section. */
582ed0d50c3Schristos else if (expld.result.section == NULL)
583ed0d50c3Schristos {
584ed0d50c3Schristos expld.result.section = lhs.section;
585ed0d50c3Schristos /* Make this NULL so that we know one of the operands
586ed0d50c3Schristos was just a number, for later tests. */
587ed0d50c3Schristos lhs.section = NULL;
588ed0d50c3Schristos }
589ed0d50c3Schristos }
590ed0d50c3Schristos /* At this point we know that both operands have the same
591ed0d50c3Schristos section, or at least one of them is a plain number. */
592ed0d50c3Schristos
593ed0d50c3Schristos switch (tree->type.node_code)
594ed0d50c3Schristos {
595ed0d50c3Schristos #define BOP(x, y) \
596ed0d50c3Schristos case x: \
597ed0d50c3Schristos expld.result.value = lhs.value y expld.result.value; \
59806324dcfSchristos arith_result_section (&lhs); \
599ed0d50c3Schristos break;
600ed0d50c3Schristos
601ed0d50c3Schristos /* Comparison operators, logical AND, and logical OR always
602ed0d50c3Schristos return a plain number. */
603ed0d50c3Schristos #define BOPN(x, y) \
604ed0d50c3Schristos case x: \
605ed0d50c3Schristos expld.result.value = lhs.value y expld.result.value; \
606ed0d50c3Schristos expld.result.section = NULL; \
607ed0d50c3Schristos break;
608ed0d50c3Schristos
609ed0d50c3Schristos BOP ('+', +);
610ed0d50c3Schristos BOP ('*', *);
611ed0d50c3Schristos BOP ('-', -);
612ed0d50c3Schristos BOP (LSHIFT, <<);
613ed0d50c3Schristos BOP (RSHIFT, >>);
614ed0d50c3Schristos BOP ('&', &);
615ed0d50c3Schristos BOP ('^', ^);
616ed0d50c3Schristos BOP ('|', |);
617ed0d50c3Schristos BOPN (EQ, ==);
618ed0d50c3Schristos BOPN (NE, !=);
619ed0d50c3Schristos BOPN ('<', <);
620ed0d50c3Schristos BOPN ('>', >);
621ed0d50c3Schristos BOPN (LE, <=);
622ed0d50c3Schristos BOPN (GE, >=);
623ed0d50c3Schristos BOPN (ANDAND, &&);
624ed0d50c3Schristos BOPN (OROR, ||);
625ed0d50c3Schristos
626ed0d50c3Schristos case '%':
627ed0d50c3Schristos if (expld.result.value != 0)
628ed0d50c3Schristos expld.result.value = ((bfd_signed_vma) lhs.value
629ed0d50c3Schristos % (bfd_signed_vma) expld.result.value);
630ed0d50c3Schristos else if (expld.phase != lang_mark_phase_enum)
63106324dcfSchristos einfo (_("%F%P:%pS %% by zero\n"), tree->binary.rhs);
63206324dcfSchristos arith_result_section (&lhs);
633ed0d50c3Schristos break;
634ed0d50c3Schristos
635ed0d50c3Schristos case '/':
636ed0d50c3Schristos if (expld.result.value != 0)
637ed0d50c3Schristos expld.result.value = ((bfd_signed_vma) lhs.value
638ed0d50c3Schristos / (bfd_signed_vma) expld.result.value);
639ed0d50c3Schristos else if (expld.phase != lang_mark_phase_enum)
64006324dcfSchristos einfo (_("%F%P:%pS / by zero\n"), tree->binary.rhs);
64106324dcfSchristos arith_result_section (&lhs);
642ed0d50c3Schristos break;
643ed0d50c3Schristos
644ed0d50c3Schristos case MAX_K:
645ed0d50c3Schristos if (lhs.value > expld.result.value)
646ed0d50c3Schristos expld.result.value = lhs.value;
647ed0d50c3Schristos break;
648ed0d50c3Schristos
649ed0d50c3Schristos case MIN_K:
650ed0d50c3Schristos if (lhs.value < expld.result.value)
651ed0d50c3Schristos expld.result.value = lhs.value;
652ed0d50c3Schristos break;
653ed0d50c3Schristos
654ed0d50c3Schristos case ALIGN_K:
655ed0d50c3Schristos expld.result.value = align_n (lhs.value, expld.result.value);
656ed0d50c3Schristos break;
657ed0d50c3Schristos
658ed0d50c3Schristos case DATA_SEGMENT_ALIGN:
65906324dcfSchristos fold_segment_align (&expld.dataseg, &lhs);
660ed0d50c3Schristos break;
661ed0d50c3Schristos
662ed0d50c3Schristos case DATA_SEGMENT_RELRO_END:
66306324dcfSchristos fold_segment_relro_end (&expld.dataseg, &lhs);
664ed0d50c3Schristos break;
665ed0d50c3Schristos
666ed0d50c3Schristos default:
667ed0d50c3Schristos FAIL ();
668ed0d50c3Schristos }
669ed0d50c3Schristos }
670ed0d50c3Schristos }
671ed0d50c3Schristos
672ed0d50c3Schristos static void
fold_trinary(etree_type * tree)673ed0d50c3Schristos fold_trinary (etree_type *tree)
674ed0d50c3Schristos {
67506324dcfSchristos struct bfd_link_hash_entry *save = expld.assign_src;
67606324dcfSchristos
677ed0d50c3Schristos exp_fold_tree_1 (tree->trinary.cond);
67806324dcfSchristos expld.assign_src = save;
679ed0d50c3Schristos if (expld.result.valid_p)
680ed0d50c3Schristos exp_fold_tree_1 (expld.result.value
681ed0d50c3Schristos ? tree->trinary.lhs
682ed0d50c3Schristos : tree->trinary.rhs);
683ed0d50c3Schristos }
684ed0d50c3Schristos
685ed0d50c3Schristos static void
fold_name(etree_type * tree)686ed0d50c3Schristos fold_name (etree_type *tree)
687ed0d50c3Schristos {
68806324dcfSchristos struct bfd_link_hash_entry *h;
68906324dcfSchristos struct definedness_hash_entry *def;
69006324dcfSchristos
691ed0d50c3Schristos memset (&expld.result, 0, sizeof (expld.result));
692ed0d50c3Schristos
693ed0d50c3Schristos switch (tree->type.node_code)
694ed0d50c3Schristos {
695ed0d50c3Schristos case SIZEOF_HEADERS:
696*b88e3e88Schristos link_info.load_phdrs = 1;
697ed0d50c3Schristos if (expld.phase != lang_first_phase_enum)
698ed0d50c3Schristos {
699ed0d50c3Schristos bfd_vma hdr_size = 0;
700ed0d50c3Schristos /* Don't find the real header size if only marking sections;
701ed0d50c3Schristos The bfd function may cache incorrect data. */
702ed0d50c3Schristos if (expld.phase != lang_mark_phase_enum)
703ed0d50c3Schristos hdr_size = bfd_sizeof_headers (link_info.output_bfd, &link_info);
704ed0d50c3Schristos new_number (hdr_size);
705ed0d50c3Schristos }
706ed0d50c3Schristos break;
707ed0d50c3Schristos
708ed0d50c3Schristos case DEFINED:
709ed0d50c3Schristos h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
710ed0d50c3Schristos &link_info,
711ed0d50c3Schristos tree->name.name,
712ed0d50c3Schristos FALSE, FALSE, TRUE);
713ed0d50c3Schristos new_number (h != NULL
714ed0d50c3Schristos && (h->type == bfd_link_hash_defined
715ed0d50c3Schristos || h->type == bfd_link_hash_defweak
716ed0d50c3Schristos || h->type == bfd_link_hash_common)
71706324dcfSchristos && (!h->ldscript_def
71806324dcfSchristos || (def = symbol_defined (tree->name.name)) == NULL
719ed0d50c3Schristos || def->by_object
72006324dcfSchristos || def->iteration == (lang_statement_iteration & 255)));
721ed0d50c3Schristos break;
722ed0d50c3Schristos
723ed0d50c3Schristos case NAME:
72406324dcfSchristos if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
725ed0d50c3Schristos new_rel_from_abs (expld.dot);
726ed0d50c3Schristos else
727ed0d50c3Schristos {
728ed0d50c3Schristos h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
729ed0d50c3Schristos &link_info,
730ed0d50c3Schristos tree->name.name,
731ed0d50c3Schristos TRUE, FALSE, TRUE);
732ed0d50c3Schristos if (!h)
733*b88e3e88Schristos {
734*b88e3e88Schristos if (expld.phase != lang_first_phase_enum)
73506324dcfSchristos einfo (_("%F%P: bfd_link_hash_lookup failed: %E\n"));
736*b88e3e88Schristos }
737ed0d50c3Schristos else if (h->type == bfd_link_hash_defined
738ed0d50c3Schristos || h->type == bfd_link_hash_defweak)
739ed0d50c3Schristos {
740ed0d50c3Schristos asection *output_section;
741ed0d50c3Schristos
742ed0d50c3Schristos output_section = h->u.def.section->output_section;
743ed0d50c3Schristos if (output_section == NULL)
744ed0d50c3Schristos {
74506324dcfSchristos if (expld.phase <= lang_mark_phase_enum)
746ed0d50c3Schristos new_rel (h->u.def.value, h->u.def.section);
747ed0d50c3Schristos else
74806324dcfSchristos einfo (_("%X%P:%pS: unresolvable symbol `%s'"
749ed0d50c3Schristos " referenced in expression\n"),
750ed0d50c3Schristos tree, tree->name.name);
751ed0d50c3Schristos }
752ed0d50c3Schristos else if (output_section == bfd_abs_section_ptr
753ed0d50c3Schristos && (expld.section != bfd_abs_section_ptr
754ed0d50c3Schristos || config.sane_expr))
755ed0d50c3Schristos new_number (h->u.def.value + h->u.def.section->output_offset);
756ed0d50c3Schristos else
757ed0d50c3Schristos new_rel (h->u.def.value + h->u.def.section->output_offset,
758ed0d50c3Schristos output_section);
759ed0d50c3Schristos }
760ed0d50c3Schristos else if (expld.phase == lang_final_phase_enum
761ed0d50c3Schristos || (expld.phase != lang_mark_phase_enum
762ed0d50c3Schristos && expld.assigning_to_dot))
76306324dcfSchristos einfo (_("%F%P:%pS: undefined symbol `%s'"
764ed0d50c3Schristos " referenced in expression\n"),
765ed0d50c3Schristos tree, tree->name.name);
766ed0d50c3Schristos else if (h->type == bfd_link_hash_new)
767ed0d50c3Schristos {
768ed0d50c3Schristos h->type = bfd_link_hash_undefined;
769ed0d50c3Schristos h->u.undef.abfd = NULL;
770ed0d50c3Schristos if (h->u.undef.next == NULL && h != link_info.hash->undefs_tail)
771ed0d50c3Schristos bfd_link_add_undef (link_info.hash, h);
772ed0d50c3Schristos }
77306324dcfSchristos if (expld.assign_src == NULL)
77406324dcfSchristos expld.assign_src = h;
77506324dcfSchristos else
77606324dcfSchristos expld.assign_src = (struct bfd_link_hash_entry *) - 1;
777*b88e3e88Schristos
778*b88e3e88Schristos /* Self-assignment is only allowed for absolute symbols
779*b88e3e88Schristos defined in a linker script. */
780*b88e3e88Schristos if (expld.assign_name != NULL
781*b88e3e88Schristos && strcmp (expld.assign_name, tree->name.name) == 0
782*b88e3e88Schristos && !(h != NULL
783*b88e3e88Schristos && (h->type == bfd_link_hash_defined
784*b88e3e88Schristos || h->type == bfd_link_hash_defweak)
785*b88e3e88Schristos && h->u.def.section == bfd_abs_section_ptr
786*b88e3e88Schristos && (def = symbol_defined (tree->name.name)) != NULL
787*b88e3e88Schristos && def->iteration == (lang_statement_iteration & 255)))
788*b88e3e88Schristos expld.assign_name = NULL;
789ed0d50c3Schristos }
790ed0d50c3Schristos break;
791ed0d50c3Schristos
792ed0d50c3Schristos case ADDR:
793ed0d50c3Schristos if (expld.phase != lang_first_phase_enum)
794ed0d50c3Schristos {
795ed0d50c3Schristos lang_output_section_statement_type *os;
796ed0d50c3Schristos
797ed0d50c3Schristos os = lang_output_section_find (tree->name.name);
798ed0d50c3Schristos if (os == NULL)
799ed0d50c3Schristos {
800ed0d50c3Schristos if (expld.phase == lang_final_phase_enum)
80106324dcfSchristos einfo (_("%F%P:%pS: undefined section `%s'"
802ed0d50c3Schristos " referenced in expression\n"),
803ed0d50c3Schristos tree, tree->name.name);
804ed0d50c3Schristos }
805ed0d50c3Schristos else if (os->processed_vma)
806ed0d50c3Schristos new_rel (0, os->bfd_section);
807ed0d50c3Schristos }
808ed0d50c3Schristos break;
809ed0d50c3Schristos
810ed0d50c3Schristos case LOADADDR:
811ed0d50c3Schristos if (expld.phase != lang_first_phase_enum)
812ed0d50c3Schristos {
813ed0d50c3Schristos lang_output_section_statement_type *os;
814ed0d50c3Schristos
815ed0d50c3Schristos os = lang_output_section_find (tree->name.name);
816ed0d50c3Schristos if (os == NULL)
817ed0d50c3Schristos {
818ed0d50c3Schristos if (expld.phase == lang_final_phase_enum)
81906324dcfSchristos einfo (_("%F%P:%pS: undefined section `%s'"
820ed0d50c3Schristos " referenced in expression\n"),
821ed0d50c3Schristos tree, tree->name.name);
822ed0d50c3Schristos }
823ed0d50c3Schristos else if (os->processed_lma)
824ed0d50c3Schristos {
825ed0d50c3Schristos if (os->load_base == NULL)
826ed0d50c3Schristos new_abs (os->bfd_section->lma);
827ed0d50c3Schristos else
828ed0d50c3Schristos {
829ed0d50c3Schristos exp_fold_tree_1 (os->load_base);
830ed0d50c3Schristos if (expld.result.valid_p)
831ed0d50c3Schristos make_abs ();
832ed0d50c3Schristos }
833ed0d50c3Schristos }
834ed0d50c3Schristos }
835ed0d50c3Schristos break;
836ed0d50c3Schristos
837ed0d50c3Schristos case SIZEOF:
838ed0d50c3Schristos case ALIGNOF:
839ed0d50c3Schristos if (expld.phase != lang_first_phase_enum)
840ed0d50c3Schristos {
841ed0d50c3Schristos lang_output_section_statement_type *os;
842ed0d50c3Schristos
843ed0d50c3Schristos os = lang_output_section_find (tree->name.name);
844ed0d50c3Schristos if (os == NULL)
845ed0d50c3Schristos {
846ed0d50c3Schristos if (expld.phase == lang_final_phase_enum)
84706324dcfSchristos einfo (_("%F%P:%pS: undefined section `%s'"
848ed0d50c3Schristos " referenced in expression\n"),
849ed0d50c3Schristos tree, tree->name.name);
850ed0d50c3Schristos new_number (0);
851ed0d50c3Schristos }
852ed0d50c3Schristos else if (os->bfd_section != NULL)
853ed0d50c3Schristos {
854ed0d50c3Schristos bfd_vma val;
855ed0d50c3Schristos
856ed0d50c3Schristos if (tree->type.node_code == SIZEOF)
857ed0d50c3Schristos val = (os->bfd_section->size
858*b88e3e88Schristos / bfd_octets_per_byte (link_info.output_bfd,
859*b88e3e88Schristos os->bfd_section));
860ed0d50c3Schristos else
861ed0d50c3Schristos val = (bfd_vma)1 << os->bfd_section->alignment_power;
862ed0d50c3Schristos
863ed0d50c3Schristos new_number (val);
864ed0d50c3Schristos }
865ed0d50c3Schristos else
866ed0d50c3Schristos new_number (0);
867ed0d50c3Schristos }
868ed0d50c3Schristos break;
869ed0d50c3Schristos
870ed0d50c3Schristos case LENGTH:
871ed0d50c3Schristos {
872ed0d50c3Schristos lang_memory_region_type *mem;
873ed0d50c3Schristos
874ed0d50c3Schristos mem = lang_memory_region_lookup (tree->name.name, FALSE);
875ed0d50c3Schristos if (mem != NULL)
876ed0d50c3Schristos new_number (mem->length);
877ed0d50c3Schristos else
87806324dcfSchristos einfo (_("%F%P:%pS: undefined MEMORY region `%s'"
879ed0d50c3Schristos " referenced in expression\n"),
880ed0d50c3Schristos tree, tree->name.name);
881ed0d50c3Schristos }
882ed0d50c3Schristos break;
883ed0d50c3Schristos
884ed0d50c3Schristos case ORIGIN:
885ed0d50c3Schristos {
886ed0d50c3Schristos lang_memory_region_type *mem;
887ed0d50c3Schristos
888ed0d50c3Schristos mem = lang_memory_region_lookup (tree->name.name, FALSE);
889ed0d50c3Schristos if (mem != NULL)
890ed0d50c3Schristos new_rel_from_abs (mem->origin);
891ed0d50c3Schristos else
89206324dcfSchristos einfo (_("%F%P:%pS: undefined MEMORY region `%s'"
893ed0d50c3Schristos " referenced in expression\n"),
894ed0d50c3Schristos tree, tree->name.name);
895ed0d50c3Schristos }
896ed0d50c3Schristos break;
897ed0d50c3Schristos
898ed0d50c3Schristos case CONSTANT:
899ed0d50c3Schristos if (strcmp (tree->name.name, "MAXPAGESIZE") == 0)
900ed0d50c3Schristos new_number (config.maxpagesize);
901ed0d50c3Schristos else if (strcmp (tree->name.name, "COMMONPAGESIZE") == 0)
902ed0d50c3Schristos new_number (config.commonpagesize);
903ed0d50c3Schristos else
90406324dcfSchristos einfo (_("%F%P:%pS: unknown constant `%s' referenced in expression\n"),
905ed0d50c3Schristos tree, tree->name.name);
906ed0d50c3Schristos break;
907ed0d50c3Schristos
908ed0d50c3Schristos default:
909ed0d50c3Schristos FAIL ();
910ed0d50c3Schristos break;
911ed0d50c3Schristos }
912ed0d50c3Schristos }
913ed0d50c3Schristos
914ed0d50c3Schristos /* Return true if TREE is '.'. */
915ed0d50c3Schristos
916ed0d50c3Schristos static bfd_boolean
is_dot(const etree_type * tree)917ed0d50c3Schristos is_dot (const etree_type *tree)
918ed0d50c3Schristos {
919ed0d50c3Schristos return (tree->type.node_class == etree_name
920ed0d50c3Schristos && tree->type.node_code == NAME
921ed0d50c3Schristos && tree->name.name[0] == '.'
922ed0d50c3Schristos && tree->name.name[1] == 0);
923ed0d50c3Schristos }
924ed0d50c3Schristos
925ed0d50c3Schristos /* Return true if TREE is a constant equal to VAL. */
926ed0d50c3Schristos
927ed0d50c3Schristos static bfd_boolean
is_value(const etree_type * tree,bfd_vma val)928ed0d50c3Schristos is_value (const etree_type *tree, bfd_vma val)
929ed0d50c3Schristos {
930ed0d50c3Schristos return (tree->type.node_class == etree_value
931ed0d50c3Schristos && tree->value.value == val);
932ed0d50c3Schristos }
933ed0d50c3Schristos
934ed0d50c3Schristos /* Return true if TREE is an absolute symbol equal to VAL defined in
935ed0d50c3Schristos a linker script. */
936ed0d50c3Schristos
937ed0d50c3Schristos static bfd_boolean
is_sym_value(const etree_type * tree,bfd_vma val)938ed0d50c3Schristos is_sym_value (const etree_type *tree, bfd_vma val)
939ed0d50c3Schristos {
940ed0d50c3Schristos struct bfd_link_hash_entry *h;
941ed0d50c3Schristos struct definedness_hash_entry *def;
942ed0d50c3Schristos
943ed0d50c3Schristos return (tree->type.node_class == etree_name
944ed0d50c3Schristos && tree->type.node_code == NAME
945ed0d50c3Schristos && (def = symbol_defined (tree->name.name)) != NULL
94606324dcfSchristos && def->iteration == (lang_statement_iteration & 255)
947ed0d50c3Schristos && (h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
948ed0d50c3Schristos &link_info,
949ed0d50c3Schristos tree->name.name,
950ed0d50c3Schristos FALSE, FALSE, TRUE)) != NULL
95106324dcfSchristos && h->ldscript_def
952ed0d50c3Schristos && h->type == bfd_link_hash_defined
953ed0d50c3Schristos && h->u.def.section == bfd_abs_section_ptr
954ed0d50c3Schristos && h->u.def.value == val);
955ed0d50c3Schristos }
956ed0d50c3Schristos
957ed0d50c3Schristos /* Return true if TREE is ". != 0". */
958ed0d50c3Schristos
959ed0d50c3Schristos static bfd_boolean
is_dot_ne_0(const etree_type * tree)960ed0d50c3Schristos is_dot_ne_0 (const etree_type *tree)
961ed0d50c3Schristos {
962ed0d50c3Schristos return (tree->type.node_class == etree_binary
963ed0d50c3Schristos && tree->type.node_code == NE
964ed0d50c3Schristos && is_dot (tree->binary.lhs)
965ed0d50c3Schristos && is_value (tree->binary.rhs, 0));
966ed0d50c3Schristos }
967ed0d50c3Schristos
968ed0d50c3Schristos /* Return true if TREE is ". = . + 0" or ". = . + sym" where sym is an
969ed0d50c3Schristos absolute constant with value 0 defined in a linker script. */
970ed0d50c3Schristos
971ed0d50c3Schristos static bfd_boolean
is_dot_plus_0(const etree_type * tree)972ed0d50c3Schristos is_dot_plus_0 (const etree_type *tree)
973ed0d50c3Schristos {
974ed0d50c3Schristos return (tree->type.node_class == etree_binary
975ed0d50c3Schristos && tree->type.node_code == '+'
976ed0d50c3Schristos && is_dot (tree->binary.lhs)
977ed0d50c3Schristos && (is_value (tree->binary.rhs, 0)
978ed0d50c3Schristos || is_sym_value (tree->binary.rhs, 0)));
979ed0d50c3Schristos }
980ed0d50c3Schristos
981ed0d50c3Schristos /* Return true if TREE is "ALIGN (. != 0 ? some_expression : 1)". */
982ed0d50c3Schristos
983ed0d50c3Schristos static bfd_boolean
is_align_conditional(const etree_type * tree)984ed0d50c3Schristos is_align_conditional (const etree_type *tree)
985ed0d50c3Schristos {
986ed0d50c3Schristos if (tree->type.node_class == etree_unary
987ed0d50c3Schristos && tree->type.node_code == ALIGN_K)
988ed0d50c3Schristos {
989ed0d50c3Schristos tree = tree->unary.child;
990ed0d50c3Schristos return (tree->type.node_class == etree_trinary
991ed0d50c3Schristos && is_dot_ne_0 (tree->trinary.cond)
992ed0d50c3Schristos && is_value (tree->trinary.rhs, 1));
993ed0d50c3Schristos }
994ed0d50c3Schristos return FALSE;
995ed0d50c3Schristos }
996ed0d50c3Schristos
997ed0d50c3Schristos static void
exp_fold_tree_1(etree_type * tree)998ed0d50c3Schristos exp_fold_tree_1 (etree_type *tree)
999ed0d50c3Schristos {
1000ed0d50c3Schristos if (tree == NULL)
1001ed0d50c3Schristos {
1002ed0d50c3Schristos memset (&expld.result, 0, sizeof (expld.result));
1003ed0d50c3Schristos return;
1004ed0d50c3Schristos }
1005ed0d50c3Schristos
1006ed0d50c3Schristos switch (tree->type.node_class)
1007ed0d50c3Schristos {
1008ed0d50c3Schristos case etree_value:
1009ed0d50c3Schristos if (expld.section == bfd_abs_section_ptr
1010ed0d50c3Schristos && !config.sane_expr)
1011ed0d50c3Schristos new_abs (tree->value.value);
1012ed0d50c3Schristos else
1013ed0d50c3Schristos new_number (tree->value.value);
1014ed0d50c3Schristos expld.result.str = tree->value.str;
1015ed0d50c3Schristos break;
1016ed0d50c3Schristos
1017ed0d50c3Schristos case etree_rel:
1018ed0d50c3Schristos if (expld.phase != lang_first_phase_enum)
1019ed0d50c3Schristos {
1020ed0d50c3Schristos asection *output_section = tree->rel.section->output_section;
1021ed0d50c3Schristos new_rel (tree->rel.value + tree->rel.section->output_offset,
1022ed0d50c3Schristos output_section);
1023ed0d50c3Schristos }
1024ed0d50c3Schristos else
1025ed0d50c3Schristos memset (&expld.result, 0, sizeof (expld.result));
1026ed0d50c3Schristos break;
1027ed0d50c3Schristos
1028ed0d50c3Schristos case etree_assert:
1029ed0d50c3Schristos exp_fold_tree_1 (tree->assert_s.child);
1030ed0d50c3Schristos if (expld.phase == lang_final_phase_enum && !expld.result.value)
1031ed0d50c3Schristos einfo ("%X%P: %s\n", tree->assert_s.message);
1032ed0d50c3Schristos break;
1033ed0d50c3Schristos
1034ed0d50c3Schristos case etree_unary:
1035ed0d50c3Schristos fold_unary (tree);
1036ed0d50c3Schristos break;
1037ed0d50c3Schristos
1038ed0d50c3Schristos case etree_binary:
1039ed0d50c3Schristos fold_binary (tree);
1040ed0d50c3Schristos break;
1041ed0d50c3Schristos
1042ed0d50c3Schristos case etree_trinary:
1043ed0d50c3Schristos fold_trinary (tree);
1044ed0d50c3Schristos break;
1045ed0d50c3Schristos
1046ed0d50c3Schristos case etree_assign:
1047ed0d50c3Schristos case etree_provide:
1048ed0d50c3Schristos case etree_provided:
1049ed0d50c3Schristos if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0)
1050ed0d50c3Schristos {
1051ed0d50c3Schristos if (tree->type.node_class != etree_assign)
105206324dcfSchristos einfo (_("%F%P:%pS can not PROVIDE assignment to"
1053ed0d50c3Schristos " location counter\n"), tree);
1054ed0d50c3Schristos if (expld.phase != lang_first_phase_enum)
1055ed0d50c3Schristos {
1056ed0d50c3Schristos /* Notify the folder that this is an assignment to dot. */
1057ed0d50c3Schristos expld.assigning_to_dot = TRUE;
1058ed0d50c3Schristos exp_fold_tree_1 (tree->assign.src);
1059ed0d50c3Schristos expld.assigning_to_dot = FALSE;
1060ed0d50c3Schristos
1061ed0d50c3Schristos /* If we are assigning to dot inside an output section
1062ed0d50c3Schristos arrange to keep the section, except for certain
1063ed0d50c3Schristos expressions that evaluate to zero. We ignore . = 0,
1064ed0d50c3Schristos . = . + 0, and . = ALIGN (. != 0 ? expr : 1).
1065ed0d50c3Schristos We can't ignore all expressions that evaluate to zero
1066ed0d50c3Schristos because an otherwise empty section might have padding
1067ed0d50c3Schristos added by an alignment expression that changes with
1068ed0d50c3Schristos relaxation. Such a section might have zero size
1069ed0d50c3Schristos before relaxation and so be stripped incorrectly. */
1070ed0d50c3Schristos if (expld.phase == lang_mark_phase_enum
1071ed0d50c3Schristos && expld.section != bfd_abs_section_ptr
107206324dcfSchristos && expld.section != bfd_und_section_ptr
1073ed0d50c3Schristos && !(expld.result.valid_p
1074ed0d50c3Schristos && expld.result.value == 0
1075ed0d50c3Schristos && (is_value (tree->assign.src, 0)
1076ed0d50c3Schristos || is_sym_value (tree->assign.src, 0)
1077ed0d50c3Schristos || is_dot_plus_0 (tree->assign.src)
1078ed0d50c3Schristos || is_align_conditional (tree->assign.src))))
1079ed0d50c3Schristos expld.section->flags |= SEC_KEEP;
1080ed0d50c3Schristos
108106324dcfSchristos if (!expld.result.valid_p
108206324dcfSchristos || expld.section == bfd_und_section_ptr)
1083ed0d50c3Schristos {
1084ed0d50c3Schristos if (expld.phase != lang_mark_phase_enum)
108506324dcfSchristos einfo (_("%F%P:%pS invalid assignment to"
1086ed0d50c3Schristos " location counter\n"), tree);
1087ed0d50c3Schristos }
1088ed0d50c3Schristos else if (expld.dotp == NULL)
108906324dcfSchristos einfo (_("%F%P:%pS assignment to location counter"
1090ed0d50c3Schristos " invalid outside of SECTIONS\n"), tree);
1091ed0d50c3Schristos
1092ed0d50c3Schristos /* After allocation, assignment to dot should not be
1093ed0d50c3Schristos done inside an output section since allocation adds a
1094ed0d50c3Schristos padding statement that effectively duplicates the
1095ed0d50c3Schristos assignment. */
1096ed0d50c3Schristos else if (expld.phase <= lang_allocating_phase_enum
1097ed0d50c3Schristos || expld.section == bfd_abs_section_ptr)
1098ed0d50c3Schristos {
1099ed0d50c3Schristos bfd_vma nextdot;
1100ed0d50c3Schristos
1101ed0d50c3Schristos nextdot = expld.result.value;
1102ed0d50c3Schristos if (expld.result.section != NULL)
1103ed0d50c3Schristos nextdot += expld.result.section->vma;
1104ed0d50c3Schristos else
1105ed0d50c3Schristos nextdot += expld.section->vma;
1106ed0d50c3Schristos if (nextdot < expld.dot
1107ed0d50c3Schristos && expld.section != bfd_abs_section_ptr)
110806324dcfSchristos einfo (_("%F%P:%pS cannot move location counter backwards"
1109ed0d50c3Schristos " (from %V to %V)\n"),
1110ed0d50c3Schristos tree, expld.dot, nextdot);
1111ed0d50c3Schristos else
1112ed0d50c3Schristos {
1113ed0d50c3Schristos expld.dot = nextdot;
1114ed0d50c3Schristos *expld.dotp = nextdot;
1115ed0d50c3Schristos }
1116ed0d50c3Schristos }
1117ed0d50c3Schristos }
1118ed0d50c3Schristos else
1119ed0d50c3Schristos memset (&expld.result, 0, sizeof (expld.result));
1120ed0d50c3Schristos }
1121ed0d50c3Schristos else
1122ed0d50c3Schristos {
1123ed0d50c3Schristos struct bfd_link_hash_entry *h = NULL;
1124ed0d50c3Schristos
1125ed0d50c3Schristos if (tree->type.node_class == etree_provide)
1126ed0d50c3Schristos {
1127ed0d50c3Schristos h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
1128ed0d50c3Schristos FALSE, FALSE, TRUE);
1129ed0d50c3Schristos if (h == NULL
1130ed0d50c3Schristos || !(h->type == bfd_link_hash_new
1131ed0d50c3Schristos || h->type == bfd_link_hash_undefined
1132ed0d50c3Schristos || h->type == bfd_link_hash_undefweak
1133ed0d50c3Schristos || h->linker_def))
1134ed0d50c3Schristos {
1135ed0d50c3Schristos /* Do nothing. The symbol was never referenced, or
1136ed0d50c3Schristos was defined in some object file. Note that
1137ed0d50c3Schristos undefweak symbols are defined by PROVIDE. This
1138ed0d50c3Schristos is to support glibc use of __rela_iplt_start and
1139ed0d50c3Schristos similar weak references. */
1140ed0d50c3Schristos break;
1141ed0d50c3Schristos }
1142ed0d50c3Schristos }
1143ed0d50c3Schristos
1144ed0d50c3Schristos expld.assign_name = tree->assign.dst;
114506324dcfSchristos expld.assign_src = NULL;
1146ed0d50c3Schristos exp_fold_tree_1 (tree->assign.src);
1147ed0d50c3Schristos /* expld.assign_name remaining equal to tree->assign.dst
1148ed0d50c3Schristos below indicates the evaluation of tree->assign.src did
1149ed0d50c3Schristos not use the value of tree->assign.dst. We don't allow
1150ed0d50c3Schristos self assignment until the final phase for two reasons:
1151ed0d50c3Schristos 1) Expressions are evaluated multiple times. With
1152ed0d50c3Schristos relaxation, the number of times may vary.
1153ed0d50c3Schristos 2) Section relative symbol values cannot be correctly
1154ed0d50c3Schristos converted to absolute values, as is required by many
1155ed0d50c3Schristos expressions, until final section sizing is complete. */
115606324dcfSchristos if (expld.phase == lang_final_phase_enum
1157*b88e3e88Schristos || expld.phase == lang_fixed_phase_enum
115806324dcfSchristos || expld.assign_name != NULL)
1159ed0d50c3Schristos {
116006324dcfSchristos if (tree->type.node_class == etree_provide)
116106324dcfSchristos tree->type.node_class = etree_provided;
116206324dcfSchristos
1163ed0d50c3Schristos if (h == NULL)
1164ed0d50c3Schristos {
1165ed0d50c3Schristos h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
1166ed0d50c3Schristos TRUE, FALSE, TRUE);
1167ed0d50c3Schristos if (h == NULL)
116806324dcfSchristos einfo (_("%F%P:%s: hash creation failed\n"),
1169ed0d50c3Schristos tree->assign.dst);
1170ed0d50c3Schristos }
1171ed0d50c3Schristos
117206324dcfSchristos /* If the expression is not valid then fake a zero value. In
117306324dcfSchristos the final phase any errors will already have been raised,
117406324dcfSchristos in earlier phases we want to create this definition so
117506324dcfSchristos that it can be seen by other expressions. */
117606324dcfSchristos if (!expld.result.valid_p
117706324dcfSchristos && h->type == bfd_link_hash_new)
117806324dcfSchristos {
117906324dcfSchristos expld.result.value = 0;
118006324dcfSchristos expld.result.section = NULL;
118106324dcfSchristos expld.result.valid_p = TRUE;
118206324dcfSchristos }
118306324dcfSchristos
118406324dcfSchristos if (expld.result.valid_p)
118506324dcfSchristos {
1186ed0d50c3Schristos if (expld.result.section == NULL)
1187ed0d50c3Schristos expld.result.section = expld.section;
1188ed0d50c3Schristos if (!update_definedness (tree->assign.dst, h) && 0)
1189ed0d50c3Schristos {
1190ed0d50c3Schristos /* Symbol was already defined. For now this error
1191ed0d50c3Schristos is disabled because it causes failures in the ld
1192ed0d50c3Schristos testsuite: ld-elf/var1, ld-scripts/defined5, and
1193ed0d50c3Schristos ld-scripts/pr14962. Some of these no doubt
1194ed0d50c3Schristos reflect scripts used in the wild. */
1195ed0d50c3Schristos (*link_info.callbacks->multiple_definition)
1196ed0d50c3Schristos (&link_info, h, link_info.output_bfd,
1197ed0d50c3Schristos expld.result.section, expld.result.value);
1198ed0d50c3Schristos }
1199*b88e3e88Schristos if (expld.phase == lang_fixed_phase_enum)
1200*b88e3e88Schristos {
1201*b88e3e88Schristos if (h->type == bfd_link_hash_defined)
1202*b88e3e88Schristos {
1203*b88e3e88Schristos expld.result.value = h->u.def.value;
1204*b88e3e88Schristos expld.result.section = h->u.def.section;
1205*b88e3e88Schristos }
1206*b88e3e88Schristos }
1207*b88e3e88Schristos else
1208*b88e3e88Schristos {
1209ed0d50c3Schristos h->type = bfd_link_hash_defined;
1210ed0d50c3Schristos h->u.def.value = expld.result.value;
1211ed0d50c3Schristos h->u.def.section = expld.result.section;
121206324dcfSchristos h->linker_def = ! tree->assign.type.lineno;
121306324dcfSchristos h->ldscript_def = 1;
1214*b88e3e88Schristos h->rel_from_abs = expld.rel_from_abs;
121506324dcfSchristos if (tree->assign.hidden)
121606324dcfSchristos bfd_link_hide_symbol (link_info.output_bfd,
121706324dcfSchristos &link_info, h);
1218ed0d50c3Schristos
121906324dcfSchristos /* Copy the symbol type if this is an expression only
122006324dcfSchristos referencing a single symbol. (If the expression
122106324dcfSchristos contains ternary conditions, ignoring symbols on
122206324dcfSchristos false branches.) */
122306324dcfSchristos if (expld.assign_src != NULL
122406324dcfSchristos && (expld.assign_src
122506324dcfSchristos != (struct bfd_link_hash_entry *) -1))
1226*b88e3e88Schristos bfd_copy_link_hash_symbol_type (link_info.output_bfd,
1227*b88e3e88Schristos h, expld.assign_src);
1228ed0d50c3Schristos }
1229ed0d50c3Schristos }
1230*b88e3e88Schristos }
1231*b88e3e88Schristos if (expld.phase != lang_fixed_phase_enum)
1232ed0d50c3Schristos expld.assign_name = NULL;
1233ed0d50c3Schristos }
1234ed0d50c3Schristos break;
1235ed0d50c3Schristos
1236ed0d50c3Schristos case etree_name:
1237ed0d50c3Schristos fold_name (tree);
1238ed0d50c3Schristos break;
1239ed0d50c3Schristos
1240ed0d50c3Schristos default:
1241ed0d50c3Schristos FAIL ();
1242ed0d50c3Schristos memset (&expld.result, 0, sizeof (expld.result));
1243ed0d50c3Schristos break;
1244ed0d50c3Schristos }
1245ed0d50c3Schristos }
1246ed0d50c3Schristos
1247ed0d50c3Schristos void
exp_fold_tree(etree_type * tree,asection * current_section,bfd_vma * dotp)1248ed0d50c3Schristos exp_fold_tree (etree_type *tree, asection *current_section, bfd_vma *dotp)
1249ed0d50c3Schristos {
1250ed0d50c3Schristos expld.rel_from_abs = FALSE;
1251ed0d50c3Schristos expld.dot = *dotp;
1252ed0d50c3Schristos expld.dotp = dotp;
1253ed0d50c3Schristos expld.section = current_section;
1254ed0d50c3Schristos exp_fold_tree_1 (tree);
1255ed0d50c3Schristos }
1256ed0d50c3Schristos
1257ed0d50c3Schristos void
exp_fold_tree_no_dot(etree_type * tree)1258ed0d50c3Schristos exp_fold_tree_no_dot (etree_type *tree)
1259ed0d50c3Schristos {
1260ed0d50c3Schristos expld.rel_from_abs = FALSE;
1261ed0d50c3Schristos expld.dot = 0;
1262ed0d50c3Schristos expld.dotp = NULL;
1263ed0d50c3Schristos expld.section = bfd_abs_section_ptr;
1264ed0d50c3Schristos exp_fold_tree_1 (tree);
1265ed0d50c3Schristos }
1266ed0d50c3Schristos
126706324dcfSchristos static void
exp_value_fold(etree_type * tree)126806324dcfSchristos exp_value_fold (etree_type *tree)
126906324dcfSchristos {
127006324dcfSchristos exp_fold_tree_no_dot (tree);
127106324dcfSchristos if (expld.result.valid_p)
127206324dcfSchristos {
127306324dcfSchristos tree->type.node_code = INT;
127406324dcfSchristos tree->value.value = expld.result.value;
127506324dcfSchristos tree->value.str = NULL;
127606324dcfSchristos tree->type.node_class = etree_value;
127706324dcfSchristos }
127806324dcfSchristos }
127906324dcfSchristos
128006324dcfSchristos #define MAX(a, b) ((a) > (b) ? (a) : (b))
128106324dcfSchristos
1282ed0d50c3Schristos etree_type *
exp_binop(int code,etree_type * lhs,etree_type * rhs)1283ed0d50c3Schristos exp_binop (int code, etree_type *lhs, etree_type *rhs)
1284ed0d50c3Schristos {
1285*b88e3e88Schristos etree_type *new_e = stat_alloc (MAX (sizeof (new_e->binary),
128606324dcfSchristos sizeof (new_e->value)));
128706324dcfSchristos new_e->type.node_code = code;
128806324dcfSchristos new_e->type.filename = lhs->type.filename;
128906324dcfSchristos new_e->type.lineno = lhs->type.lineno;
129006324dcfSchristos new_e->binary.lhs = lhs;
129106324dcfSchristos new_e->binary.rhs = rhs;
129206324dcfSchristos new_e->type.node_class = etree_binary;
129306324dcfSchristos if (lhs->type.node_class == etree_value
129406324dcfSchristos && rhs->type.node_class == etree_value
129506324dcfSchristos && code != ALIGN_K
129606324dcfSchristos && code != DATA_SEGMENT_ALIGN
129706324dcfSchristos && code != DATA_SEGMENT_RELRO_END)
129806324dcfSchristos exp_value_fold (new_e);
1299ed0d50c3Schristos return new_e;
1300ed0d50c3Schristos }
1301ed0d50c3Schristos
1302ed0d50c3Schristos etree_type *
exp_trinop(int code,etree_type * cond,etree_type * lhs,etree_type * rhs)1303ed0d50c3Schristos exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs)
1304ed0d50c3Schristos {
1305*b88e3e88Schristos etree_type *new_e = stat_alloc (MAX (sizeof (new_e->trinary),
130606324dcfSchristos sizeof (new_e->value)));
130706324dcfSchristos new_e->type.node_code = code;
130806324dcfSchristos new_e->type.filename = cond->type.filename;
130906324dcfSchristos new_e->type.lineno = cond->type.lineno;
131006324dcfSchristos new_e->trinary.lhs = lhs;
131106324dcfSchristos new_e->trinary.cond = cond;
131206324dcfSchristos new_e->trinary.rhs = rhs;
131306324dcfSchristos new_e->type.node_class = etree_trinary;
131406324dcfSchristos if (cond->type.node_class == etree_value
131506324dcfSchristos && lhs->type.node_class == etree_value
131606324dcfSchristos && rhs->type.node_class == etree_value)
131706324dcfSchristos exp_value_fold (new_e);
1318ed0d50c3Schristos return new_e;
1319ed0d50c3Schristos }
1320ed0d50c3Schristos
1321ed0d50c3Schristos etree_type *
exp_unop(int code,etree_type * child)1322ed0d50c3Schristos exp_unop (int code, etree_type *child)
1323ed0d50c3Schristos {
1324*b88e3e88Schristos etree_type *new_e = stat_alloc (MAX (sizeof (new_e->unary),
132506324dcfSchristos sizeof (new_e->value)));
132606324dcfSchristos new_e->unary.type.node_code = code;
132706324dcfSchristos new_e->unary.type.filename = child->type.filename;
132806324dcfSchristos new_e->unary.type.lineno = child->type.lineno;
132906324dcfSchristos new_e->unary.child = child;
133006324dcfSchristos new_e->unary.type.node_class = etree_unary;
133106324dcfSchristos if (child->type.node_class == etree_value
133206324dcfSchristos && code != ALIGN_K
133306324dcfSchristos && code != ABSOLUTE
133406324dcfSchristos && code != NEXT
133506324dcfSchristos && code != DATA_SEGMENT_END)
133606324dcfSchristos exp_value_fold (new_e);
1337ed0d50c3Schristos return new_e;
1338ed0d50c3Schristos }
1339ed0d50c3Schristos
1340ed0d50c3Schristos etree_type *
exp_nameop(int code,const char * name)1341ed0d50c3Schristos exp_nameop (int code, const char *name)
1342ed0d50c3Schristos {
1343*b88e3e88Schristos etree_type *new_e = stat_alloc (sizeof (new_e->name));
1344ed0d50c3Schristos
134506324dcfSchristos new_e->name.type.node_code = code;
134606324dcfSchristos new_e->name.type.filename = ldlex_filename ();
134706324dcfSchristos new_e->name.type.lineno = lineno;
134806324dcfSchristos new_e->name.name = name;
134906324dcfSchristos new_e->name.type.node_class = etree_name;
1350ed0d50c3Schristos return new_e;
1351ed0d50c3Schristos
1352ed0d50c3Schristos }
1353ed0d50c3Schristos
1354ed0d50c3Schristos static etree_type *
exp_assop(const char * dst,etree_type * src,enum node_tree_enum class,bfd_boolean hidden)1355ed0d50c3Schristos exp_assop (const char *dst,
1356ed0d50c3Schristos etree_type *src,
1357ed0d50c3Schristos enum node_tree_enum class,
1358ed0d50c3Schristos bfd_boolean hidden)
1359ed0d50c3Schristos {
1360ed0d50c3Schristos etree_type *n;
1361ed0d50c3Schristos
1362*b88e3e88Schristos n = stat_alloc (sizeof (n->assign));
1363ed0d50c3Schristos n->assign.type.node_code = '=';
1364ed0d50c3Schristos n->assign.type.filename = src->type.filename;
1365ed0d50c3Schristos n->assign.type.lineno = src->type.lineno;
1366ed0d50c3Schristos n->assign.type.node_class = class;
1367ed0d50c3Schristos n->assign.src = src;
1368ed0d50c3Schristos n->assign.dst = dst;
1369ed0d50c3Schristos n->assign.hidden = hidden;
1370ed0d50c3Schristos return n;
1371ed0d50c3Schristos }
1372ed0d50c3Schristos
1373ed0d50c3Schristos /* Handle linker script assignments and HIDDEN. */
1374ed0d50c3Schristos
1375ed0d50c3Schristos etree_type *
exp_assign(const char * dst,etree_type * src,bfd_boolean hidden)1376ed0d50c3Schristos exp_assign (const char *dst, etree_type *src, bfd_boolean hidden)
1377ed0d50c3Schristos {
137806324dcfSchristos return exp_assop (dst, src, etree_assign, hidden);
1379ed0d50c3Schristos }
1380ed0d50c3Schristos
1381ed0d50c3Schristos /* Handle --defsym command-line option. */
1382ed0d50c3Schristos
1383ed0d50c3Schristos etree_type *
exp_defsym(const char * dst,etree_type * src)1384ed0d50c3Schristos exp_defsym (const char *dst, etree_type *src)
1385ed0d50c3Schristos {
138606324dcfSchristos return exp_assop (dst, src, etree_assign, FALSE);
1387ed0d50c3Schristos }
1388ed0d50c3Schristos
1389ed0d50c3Schristos /* Handle PROVIDE. */
1390ed0d50c3Schristos
1391ed0d50c3Schristos etree_type *
exp_provide(const char * dst,etree_type * src,bfd_boolean hidden)1392ed0d50c3Schristos exp_provide (const char *dst, etree_type *src, bfd_boolean hidden)
1393ed0d50c3Schristos {
139406324dcfSchristos return exp_assop (dst, src, etree_provide, hidden);
1395ed0d50c3Schristos }
1396ed0d50c3Schristos
1397ed0d50c3Schristos /* Handle ASSERT. */
1398ed0d50c3Schristos
1399ed0d50c3Schristos etree_type *
exp_assert(etree_type * exp,const char * message)1400ed0d50c3Schristos exp_assert (etree_type *exp, const char *message)
1401ed0d50c3Schristos {
1402ed0d50c3Schristos etree_type *n;
1403ed0d50c3Schristos
1404*b88e3e88Schristos n = stat_alloc (sizeof (n->assert_s));
1405ed0d50c3Schristos n->assert_s.type.node_code = '!';
1406ed0d50c3Schristos n->assert_s.type.filename = exp->type.filename;
1407ed0d50c3Schristos n->assert_s.type.lineno = exp->type.lineno;
1408ed0d50c3Schristos n->assert_s.type.node_class = etree_assert;
1409ed0d50c3Schristos n->assert_s.child = exp;
1410ed0d50c3Schristos n->assert_s.message = message;
1411ed0d50c3Schristos return n;
1412ed0d50c3Schristos }
1413ed0d50c3Schristos
1414ed0d50c3Schristos void
exp_print_tree(etree_type * tree)1415ed0d50c3Schristos exp_print_tree (etree_type *tree)
1416ed0d50c3Schristos {
1417ed0d50c3Schristos bfd_boolean function_like;
1418ed0d50c3Schristos
1419ed0d50c3Schristos if (config.map_file == NULL)
1420ed0d50c3Schristos config.map_file = stderr;
1421ed0d50c3Schristos
1422ed0d50c3Schristos if (tree == NULL)
1423ed0d50c3Schristos {
1424ed0d50c3Schristos minfo ("NULL TREE\n");
1425ed0d50c3Schristos return;
1426ed0d50c3Schristos }
1427ed0d50c3Schristos
1428ed0d50c3Schristos switch (tree->type.node_class)
1429ed0d50c3Schristos {
1430ed0d50c3Schristos case etree_value:
1431ed0d50c3Schristos minfo ("0x%v", tree->value.value);
1432ed0d50c3Schristos return;
1433ed0d50c3Schristos case etree_rel:
1434ed0d50c3Schristos if (tree->rel.section->owner != NULL)
143506324dcfSchristos minfo ("%pB:", tree->rel.section->owner);
1436ed0d50c3Schristos minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value);
1437ed0d50c3Schristos return;
1438ed0d50c3Schristos case etree_assign:
1439ed0d50c3Schristos fputs (tree->assign.dst, config.map_file);
1440ed0d50c3Schristos exp_print_token (tree->type.node_code, TRUE);
1441ed0d50c3Schristos exp_print_tree (tree->assign.src);
1442ed0d50c3Schristos break;
1443ed0d50c3Schristos case etree_provide:
1444ed0d50c3Schristos case etree_provided:
144506324dcfSchristos fprintf (config.map_file, "PROVIDE (%s = ", tree->assign.dst);
1446ed0d50c3Schristos exp_print_tree (tree->assign.src);
1447ed0d50c3Schristos fputc (')', config.map_file);
1448ed0d50c3Schristos break;
1449ed0d50c3Schristos case etree_binary:
1450ed0d50c3Schristos function_like = FALSE;
1451ed0d50c3Schristos switch (tree->type.node_code)
1452ed0d50c3Schristos {
1453ed0d50c3Schristos case MAX_K:
1454ed0d50c3Schristos case MIN_K:
1455ed0d50c3Schristos case ALIGN_K:
1456ed0d50c3Schristos case DATA_SEGMENT_ALIGN:
1457ed0d50c3Schristos case DATA_SEGMENT_RELRO_END:
1458ed0d50c3Schristos function_like = TRUE;
1459ed0d50c3Schristos break;
1460ed0d50c3Schristos case SEGMENT_START:
1461ed0d50c3Schristos /* Special handling because arguments are in reverse order and
1462ed0d50c3Schristos the segment name is quoted. */
1463ed0d50c3Schristos exp_print_token (tree->type.node_code, FALSE);
1464ed0d50c3Schristos fputs (" (\"", config.map_file);
1465ed0d50c3Schristos exp_print_tree (tree->binary.rhs);
1466ed0d50c3Schristos fputs ("\", ", config.map_file);
1467ed0d50c3Schristos exp_print_tree (tree->binary.lhs);
1468ed0d50c3Schristos fputc (')', config.map_file);
1469ed0d50c3Schristos return;
1470ed0d50c3Schristos }
1471ed0d50c3Schristos if (function_like)
1472ed0d50c3Schristos {
1473ed0d50c3Schristos exp_print_token (tree->type.node_code, FALSE);
1474ed0d50c3Schristos fputc (' ', config.map_file);
1475ed0d50c3Schristos }
1476ed0d50c3Schristos fputc ('(', config.map_file);
1477ed0d50c3Schristos exp_print_tree (tree->binary.lhs);
1478ed0d50c3Schristos if (function_like)
1479ed0d50c3Schristos fprintf (config.map_file, ", ");
1480ed0d50c3Schristos else
1481ed0d50c3Schristos exp_print_token (tree->type.node_code, TRUE);
1482ed0d50c3Schristos exp_print_tree (tree->binary.rhs);
1483ed0d50c3Schristos fputc (')', config.map_file);
1484ed0d50c3Schristos break;
1485ed0d50c3Schristos case etree_trinary:
1486ed0d50c3Schristos exp_print_tree (tree->trinary.cond);
1487ed0d50c3Schristos fputc ('?', config.map_file);
1488ed0d50c3Schristos exp_print_tree (tree->trinary.lhs);
1489ed0d50c3Schristos fputc (':', config.map_file);
1490ed0d50c3Schristos exp_print_tree (tree->trinary.rhs);
1491ed0d50c3Schristos break;
1492ed0d50c3Schristos case etree_unary:
1493ed0d50c3Schristos exp_print_token (tree->unary.type.node_code, FALSE);
1494ed0d50c3Schristos if (tree->unary.child)
1495ed0d50c3Schristos {
1496ed0d50c3Schristos fprintf (config.map_file, " (");
1497ed0d50c3Schristos exp_print_tree (tree->unary.child);
1498ed0d50c3Schristos fputc (')', config.map_file);
1499ed0d50c3Schristos }
1500ed0d50c3Schristos break;
1501ed0d50c3Schristos
1502ed0d50c3Schristos case etree_assert:
1503ed0d50c3Schristos fprintf (config.map_file, "ASSERT (");
1504ed0d50c3Schristos exp_print_tree (tree->assert_s.child);
1505ed0d50c3Schristos fprintf (config.map_file, ", %s)", tree->assert_s.message);
1506ed0d50c3Schristos break;
1507ed0d50c3Schristos
1508ed0d50c3Schristos case etree_name:
1509ed0d50c3Schristos if (tree->type.node_code == NAME)
1510ed0d50c3Schristos fputs (tree->name.name, config.map_file);
1511ed0d50c3Schristos else
1512ed0d50c3Schristos {
1513ed0d50c3Schristos exp_print_token (tree->type.node_code, FALSE);
1514ed0d50c3Schristos if (tree->name.name)
1515ed0d50c3Schristos fprintf (config.map_file, " (%s)", tree->name.name);
1516ed0d50c3Schristos }
1517ed0d50c3Schristos break;
1518ed0d50c3Schristos default:
1519ed0d50c3Schristos FAIL ();
1520ed0d50c3Schristos break;
1521ed0d50c3Schristos }
1522ed0d50c3Schristos }
1523ed0d50c3Schristos
1524ed0d50c3Schristos bfd_vma
exp_get_vma(etree_type * tree,bfd_vma def,char * name)1525ed0d50c3Schristos exp_get_vma (etree_type *tree, bfd_vma def, char *name)
1526ed0d50c3Schristos {
1527ed0d50c3Schristos if (tree != NULL)
1528ed0d50c3Schristos {
1529ed0d50c3Schristos exp_fold_tree_no_dot (tree);
1530ed0d50c3Schristos if (expld.result.valid_p)
1531ed0d50c3Schristos return expld.result.value;
1532ed0d50c3Schristos else if (name != NULL && expld.phase != lang_mark_phase_enum)
153306324dcfSchristos einfo (_("%F%P:%pS: nonconstant expression for %s\n"),
1534ed0d50c3Schristos tree, name);
1535ed0d50c3Schristos }
1536ed0d50c3Schristos return def;
1537ed0d50c3Schristos }
1538ed0d50c3Schristos
1539*b88e3e88Schristos /* Return the smallest non-negative integer such that two raised to
1540*b88e3e88Schristos that power is at least as large as the vma evaluated at TREE, if
1541*b88e3e88Schristos TREE is a non-NULL expression that can be resolved. If TREE is
1542*b88e3e88Schristos NULL or cannot be resolved, return -1. */
1543*b88e3e88Schristos
1544ed0d50c3Schristos int
exp_get_power(etree_type * tree,char * name)1545*b88e3e88Schristos exp_get_power (etree_type *tree, char *name)
1546ed0d50c3Schristos {
1547*b88e3e88Schristos bfd_vma x = exp_get_vma (tree, -1, name);
1548*b88e3e88Schristos bfd_vma p2;
1549*b88e3e88Schristos int n;
1550*b88e3e88Schristos
1551*b88e3e88Schristos if (x == (bfd_vma) -1)
1552*b88e3e88Schristos return -1;
1553*b88e3e88Schristos
1554*b88e3e88Schristos for (n = 0, p2 = 1; p2 < x; ++n, p2 <<= 1)
1555*b88e3e88Schristos if (p2 == 0)
1556*b88e3e88Schristos break;
1557*b88e3e88Schristos
1558*b88e3e88Schristos return n;
1559ed0d50c3Schristos }
1560ed0d50c3Schristos
1561ed0d50c3Schristos fill_type *
exp_get_fill(etree_type * tree,fill_type * def,char * name)1562ed0d50c3Schristos exp_get_fill (etree_type *tree, fill_type *def, char *name)
1563ed0d50c3Schristos {
1564ed0d50c3Schristos fill_type *fill;
1565ed0d50c3Schristos size_t len;
1566ed0d50c3Schristos unsigned int val;
1567ed0d50c3Schristos
1568ed0d50c3Schristos if (tree == NULL)
1569ed0d50c3Schristos return def;
1570ed0d50c3Schristos
1571ed0d50c3Schristos exp_fold_tree_no_dot (tree);
1572ed0d50c3Schristos if (!expld.result.valid_p)
1573ed0d50c3Schristos {
1574ed0d50c3Schristos if (name != NULL && expld.phase != lang_mark_phase_enum)
157506324dcfSchristos einfo (_("%F%P:%pS: nonconstant expression for %s\n"),
1576ed0d50c3Schristos tree, name);
1577ed0d50c3Schristos return def;
1578ed0d50c3Schristos }
1579ed0d50c3Schristos
1580ed0d50c3Schristos if (expld.result.str != NULL && (len = strlen (expld.result.str)) != 0)
1581ed0d50c3Schristos {
1582ed0d50c3Schristos unsigned char *dst;
1583ed0d50c3Schristos unsigned char *s;
1584ed0d50c3Schristos fill = (fill_type *) xmalloc ((len + 1) / 2 + sizeof (*fill) - 1);
1585ed0d50c3Schristos fill->size = (len + 1) / 2;
1586ed0d50c3Schristos dst = fill->data;
1587ed0d50c3Schristos s = (unsigned char *) expld.result.str;
1588ed0d50c3Schristos val = 0;
1589ed0d50c3Schristos do
1590ed0d50c3Schristos {
1591ed0d50c3Schristos unsigned int digit;
1592ed0d50c3Schristos
1593ed0d50c3Schristos digit = *s++ - '0';
1594ed0d50c3Schristos if (digit > 9)
1595ed0d50c3Schristos digit = (digit - 'A' + '0' + 10) & 0xf;
1596ed0d50c3Schristos val <<= 4;
1597ed0d50c3Schristos val += digit;
1598ed0d50c3Schristos --len;
1599ed0d50c3Schristos if ((len & 1) == 0)
1600ed0d50c3Schristos {
1601ed0d50c3Schristos *dst++ = val;
1602ed0d50c3Schristos val = 0;
1603ed0d50c3Schristos }
1604ed0d50c3Schristos }
1605ed0d50c3Schristos while (len != 0);
1606ed0d50c3Schristos }
1607ed0d50c3Schristos else
1608ed0d50c3Schristos {
1609ed0d50c3Schristos fill = (fill_type *) xmalloc (4 + sizeof (*fill) - 1);
1610ed0d50c3Schristos val = expld.result.value;
1611ed0d50c3Schristos fill->data[0] = (val >> 24) & 0xff;
1612ed0d50c3Schristos fill->data[1] = (val >> 16) & 0xff;
1613ed0d50c3Schristos fill->data[2] = (val >> 8) & 0xff;
1614ed0d50c3Schristos fill->data[3] = (val >> 0) & 0xff;
1615ed0d50c3Schristos fill->size = 4;
1616ed0d50c3Schristos }
1617ed0d50c3Schristos return fill;
1618ed0d50c3Schristos }
1619ed0d50c3Schristos
1620ed0d50c3Schristos bfd_vma
exp_get_abs_int(etree_type * tree,int def,char * name)1621ed0d50c3Schristos exp_get_abs_int (etree_type *tree, int def, char *name)
1622ed0d50c3Schristos {
1623ed0d50c3Schristos if (tree != NULL)
1624ed0d50c3Schristos {
1625ed0d50c3Schristos exp_fold_tree_no_dot (tree);
1626ed0d50c3Schristos
1627ed0d50c3Schristos if (expld.result.valid_p)
1628ed0d50c3Schristos {
1629ed0d50c3Schristos if (expld.result.section != NULL)
1630ed0d50c3Schristos expld.result.value += expld.result.section->vma;
1631ed0d50c3Schristos return expld.result.value;
1632ed0d50c3Schristos }
1633ed0d50c3Schristos else if (name != NULL && expld.phase != lang_mark_phase_enum)
1634ed0d50c3Schristos {
163506324dcfSchristos einfo (_("%F%P:%pS: nonconstant expression for %s\n"),
1636ed0d50c3Schristos tree, name);
1637ed0d50c3Schristos }
1638ed0d50c3Schristos }
1639ed0d50c3Schristos return def;
1640ed0d50c3Schristos }
1641ed0d50c3Schristos
1642ed0d50c3Schristos static bfd_vma
align_n(bfd_vma value,bfd_vma align)1643ed0d50c3Schristos align_n (bfd_vma value, bfd_vma align)
1644ed0d50c3Schristos {
1645ed0d50c3Schristos if (align <= 1)
1646ed0d50c3Schristos return value;
1647ed0d50c3Schristos
1648ed0d50c3Schristos value = (value + align - 1) / align;
1649ed0d50c3Schristos return value * align;
1650ed0d50c3Schristos }
1651ed0d50c3Schristos
1652ed0d50c3Schristos void
ldexp_init(void)1653ed0d50c3Schristos ldexp_init (void)
1654ed0d50c3Schristos {
1655ed0d50c3Schristos /* The value "13" is ad-hoc, somewhat related to the expected number of
1656ed0d50c3Schristos assignments in a linker script. */
1657ed0d50c3Schristos if (!bfd_hash_table_init_n (&definedness_table,
1658ed0d50c3Schristos definedness_newfunc,
1659ed0d50c3Schristos sizeof (struct definedness_hash_entry),
1660ed0d50c3Schristos 13))
166106324dcfSchristos einfo (_("%F%P: can not create hash table: %E\n"));
1662ed0d50c3Schristos }
1663ed0d50c3Schristos
1664ed0d50c3Schristos /* Convert absolute symbols defined by a script from "dot" (also
1665ed0d50c3Schristos SEGMENT_START or ORIGIN) outside of an output section statement,
1666ed0d50c3Schristos to section relative. */
1667ed0d50c3Schristos
1668ed0d50c3Schristos static bfd_boolean
set_sym_sections(struct bfd_hash_entry * bh,void * inf ATTRIBUTE_UNUSED)1669ed0d50c3Schristos set_sym_sections (struct bfd_hash_entry *bh, void *inf ATTRIBUTE_UNUSED)
1670ed0d50c3Schristos {
1671ed0d50c3Schristos struct definedness_hash_entry *def = (struct definedness_hash_entry *) bh;
1672ed0d50c3Schristos if (def->final_sec != bfd_abs_section_ptr)
1673ed0d50c3Schristos {
1674ed0d50c3Schristos struct bfd_link_hash_entry *h;
1675ed0d50c3Schristos h = bfd_link_hash_lookup (link_info.hash, bh->string,
1676ed0d50c3Schristos FALSE, FALSE, TRUE);
1677ed0d50c3Schristos if (h != NULL
1678ed0d50c3Schristos && h->type == bfd_link_hash_defined
1679ed0d50c3Schristos && h->u.def.section == bfd_abs_section_ptr)
1680ed0d50c3Schristos {
1681ed0d50c3Schristos h->u.def.value -= def->final_sec->vma;
1682ed0d50c3Schristos h->u.def.section = def->final_sec;
1683ed0d50c3Schristos }
1684ed0d50c3Schristos }
1685ed0d50c3Schristos return TRUE;
1686ed0d50c3Schristos }
1687ed0d50c3Schristos
1688ed0d50c3Schristos void
ldexp_finalize_syms(void)1689ed0d50c3Schristos ldexp_finalize_syms (void)
1690ed0d50c3Schristos {
1691ed0d50c3Schristos bfd_hash_traverse (&definedness_table, set_sym_sections, NULL);
1692ed0d50c3Schristos }
1693ed0d50c3Schristos
1694ed0d50c3Schristos void
ldexp_finish(void)1695ed0d50c3Schristos ldexp_finish (void)
1696ed0d50c3Schristos {
1697ed0d50c3Schristos bfd_hash_table_free (&definedness_table);
1698ed0d50c3Schristos }
1699