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