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