1*fae548d3Szrj // script.cc -- handle linker scripts for gold.
2*fae548d3Szrj 
3*fae548d3Szrj // Copyright (C) 2006-2020 Free Software Foundation, Inc.
4*fae548d3Szrj // Written by Ian Lance Taylor <iant@google.com>.
5*fae548d3Szrj 
6*fae548d3Szrj // This file is part of gold.
7*fae548d3Szrj 
8*fae548d3Szrj // This program is free software; you can redistribute it and/or modify
9*fae548d3Szrj // it under the terms of the GNU General Public License as published by
10*fae548d3Szrj // the Free Software Foundation; either version 3 of the License, or
11*fae548d3Szrj // (at your option) any later version.
12*fae548d3Szrj 
13*fae548d3Szrj // This program is distributed in the hope that it will be useful,
14*fae548d3Szrj // but WITHOUT ANY WARRANTY; without even the implied warranty of
15*fae548d3Szrj // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*fae548d3Szrj // GNU General Public License for more details.
17*fae548d3Szrj 
18*fae548d3Szrj // You should have received a copy of the GNU General Public License
19*fae548d3Szrj // along with this program; if not, write to the Free Software
20*fae548d3Szrj // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21*fae548d3Szrj // MA 02110-1301, USA.
22*fae548d3Szrj 
23*fae548d3Szrj #include "gold.h"
24*fae548d3Szrj 
25*fae548d3Szrj #include <cstdio>
26*fae548d3Szrj #include <cstdlib>
27*fae548d3Szrj #include <cstring>
28*fae548d3Szrj #include <fnmatch.h>
29*fae548d3Szrj #include <string>
30*fae548d3Szrj #include <vector>
31*fae548d3Szrj #include "filenames.h"
32*fae548d3Szrj 
33*fae548d3Szrj #include "elfcpp.h"
34*fae548d3Szrj #include "demangle.h"
35*fae548d3Szrj #include "dirsearch.h"
36*fae548d3Szrj #include "options.h"
37*fae548d3Szrj #include "fileread.h"
38*fae548d3Szrj #include "workqueue.h"
39*fae548d3Szrj #include "readsyms.h"
40*fae548d3Szrj #include "parameters.h"
41*fae548d3Szrj #include "layout.h"
42*fae548d3Szrj #include "symtab.h"
43*fae548d3Szrj #include "target-select.h"
44*fae548d3Szrj #include "script.h"
45*fae548d3Szrj #include "script-c.h"
46*fae548d3Szrj #include "incremental.h"
47*fae548d3Szrj 
48*fae548d3Szrj namespace gold
49*fae548d3Szrj {
50*fae548d3Szrj 
51*fae548d3Szrj // A token read from a script file.  We don't implement keywords here;
52*fae548d3Szrj // all keywords are simply represented as a string.
53*fae548d3Szrj 
54*fae548d3Szrj class Token
55*fae548d3Szrj {
56*fae548d3Szrj  public:
57*fae548d3Szrj   // Token classification.
58*fae548d3Szrj   enum Classification
59*fae548d3Szrj   {
60*fae548d3Szrj     // Token is invalid.
61*fae548d3Szrj     TOKEN_INVALID,
62*fae548d3Szrj     // Token indicates end of input.
63*fae548d3Szrj     TOKEN_EOF,
64*fae548d3Szrj     // Token is a string of characters.
65*fae548d3Szrj     TOKEN_STRING,
66*fae548d3Szrj     // Token is a quoted string of characters.
67*fae548d3Szrj     TOKEN_QUOTED_STRING,
68*fae548d3Szrj     // Token is an operator.
69*fae548d3Szrj     TOKEN_OPERATOR,
70*fae548d3Szrj     // Token is a number (an integer).
71*fae548d3Szrj     TOKEN_INTEGER
72*fae548d3Szrj   };
73*fae548d3Szrj 
74*fae548d3Szrj   // We need an empty constructor so that we can put this STL objects.
Token()75*fae548d3Szrj   Token()
76*fae548d3Szrj     : classification_(TOKEN_INVALID), value_(NULL), value_length_(0),
77*fae548d3Szrj       opcode_(0), lineno_(0), charpos_(0)
78*fae548d3Szrj   { }
79*fae548d3Szrj 
80*fae548d3Szrj   // A general token with no value.
Token(Classification classification,int lineno,int charpos)81*fae548d3Szrj   Token(Classification classification, int lineno, int charpos)
82*fae548d3Szrj     : classification_(classification), value_(NULL), value_length_(0),
83*fae548d3Szrj       opcode_(0), lineno_(lineno), charpos_(charpos)
84*fae548d3Szrj   {
85*fae548d3Szrj     gold_assert(classification == TOKEN_INVALID
86*fae548d3Szrj 		|| classification == TOKEN_EOF);
87*fae548d3Szrj   }
88*fae548d3Szrj 
89*fae548d3Szrj   // A general token with a value.
Token(Classification classification,const char * value,size_t length,int lineno,int charpos)90*fae548d3Szrj   Token(Classification classification, const char* value, size_t length,
91*fae548d3Szrj 	int lineno, int charpos)
92*fae548d3Szrj     : classification_(classification), value_(value), value_length_(length),
93*fae548d3Szrj       opcode_(0), lineno_(lineno), charpos_(charpos)
94*fae548d3Szrj   {
95*fae548d3Szrj     gold_assert(classification != TOKEN_INVALID
96*fae548d3Szrj 		&& classification != TOKEN_EOF);
97*fae548d3Szrj   }
98*fae548d3Szrj 
99*fae548d3Szrj   // A token representing an operator.
Token(int opcode,int lineno,int charpos)100*fae548d3Szrj   Token(int opcode, int lineno, int charpos)
101*fae548d3Szrj     : classification_(TOKEN_OPERATOR), value_(NULL), value_length_(0),
102*fae548d3Szrj       opcode_(opcode), lineno_(lineno), charpos_(charpos)
103*fae548d3Szrj   { }
104*fae548d3Szrj 
105*fae548d3Szrj   // Return whether the token is invalid.
106*fae548d3Szrj   bool
is_invalid() const107*fae548d3Szrj   is_invalid() const
108*fae548d3Szrj   { return this->classification_ == TOKEN_INVALID; }
109*fae548d3Szrj 
110*fae548d3Szrj   // Return whether this is an EOF token.
111*fae548d3Szrj   bool
is_eof() const112*fae548d3Szrj   is_eof() const
113*fae548d3Szrj   { return this->classification_ == TOKEN_EOF; }
114*fae548d3Szrj 
115*fae548d3Szrj   // Return the token classification.
116*fae548d3Szrj   Classification
classification() const117*fae548d3Szrj   classification() const
118*fae548d3Szrj   { return this->classification_; }
119*fae548d3Szrj 
120*fae548d3Szrj   // Return the line number at which the token starts.
121*fae548d3Szrj   int
lineno() const122*fae548d3Szrj   lineno() const
123*fae548d3Szrj   { return this->lineno_; }
124*fae548d3Szrj 
125*fae548d3Szrj   // Return the character position at this the token starts.
126*fae548d3Szrj   int
charpos() const127*fae548d3Szrj   charpos() const
128*fae548d3Szrj   { return this->charpos_; }
129*fae548d3Szrj 
130*fae548d3Szrj   // Get the value of a token.
131*fae548d3Szrj 
132*fae548d3Szrj   const char*
string_value(size_t * length) const133*fae548d3Szrj   string_value(size_t* length) const
134*fae548d3Szrj   {
135*fae548d3Szrj     gold_assert(this->classification_ == TOKEN_STRING
136*fae548d3Szrj 		|| this->classification_ == TOKEN_QUOTED_STRING);
137*fae548d3Szrj     *length = this->value_length_;
138*fae548d3Szrj     return this->value_;
139*fae548d3Szrj   }
140*fae548d3Szrj 
141*fae548d3Szrj   int
operator_value() const142*fae548d3Szrj   operator_value() const
143*fae548d3Szrj   {
144*fae548d3Szrj     gold_assert(this->classification_ == TOKEN_OPERATOR);
145*fae548d3Szrj     return this->opcode_;
146*fae548d3Szrj   }
147*fae548d3Szrj 
148*fae548d3Szrj   uint64_t
149*fae548d3Szrj   integer_value() const;
150*fae548d3Szrj 
151*fae548d3Szrj  private:
152*fae548d3Szrj   // The token classification.
153*fae548d3Szrj   Classification classification_;
154*fae548d3Szrj   // The token value, for TOKEN_STRING or TOKEN_QUOTED_STRING or
155*fae548d3Szrj   // TOKEN_INTEGER.
156*fae548d3Szrj   const char* value_;
157*fae548d3Szrj   // The length of the token value.
158*fae548d3Szrj   size_t value_length_;
159*fae548d3Szrj   // The token value, for TOKEN_OPERATOR.
160*fae548d3Szrj   int opcode_;
161*fae548d3Szrj   // The line number where this token started (one based).
162*fae548d3Szrj   int lineno_;
163*fae548d3Szrj   // The character position within the line where this token started
164*fae548d3Szrj   // (one based).
165*fae548d3Szrj   int charpos_;
166*fae548d3Szrj };
167*fae548d3Szrj 
168*fae548d3Szrj // Return the value of a TOKEN_INTEGER.
169*fae548d3Szrj 
170*fae548d3Szrj uint64_t
integer_value() const171*fae548d3Szrj Token::integer_value() const
172*fae548d3Szrj {
173*fae548d3Szrj   gold_assert(this->classification_ == TOKEN_INTEGER);
174*fae548d3Szrj 
175*fae548d3Szrj   size_t len = this->value_length_;
176*fae548d3Szrj 
177*fae548d3Szrj   uint64_t multiplier = 1;
178*fae548d3Szrj   char last = this->value_[len - 1];
179*fae548d3Szrj   if (last == 'm' || last == 'M')
180*fae548d3Szrj     {
181*fae548d3Szrj       multiplier = 1024 * 1024;
182*fae548d3Szrj       --len;
183*fae548d3Szrj     }
184*fae548d3Szrj   else if (last == 'k' || last == 'K')
185*fae548d3Szrj     {
186*fae548d3Szrj       multiplier = 1024;
187*fae548d3Szrj       --len;
188*fae548d3Szrj     }
189*fae548d3Szrj 
190*fae548d3Szrj   char *end;
191*fae548d3Szrj   uint64_t ret = strtoull(this->value_, &end, 0);
192*fae548d3Szrj   gold_assert(static_cast<size_t>(end - this->value_) == len);
193*fae548d3Szrj 
194*fae548d3Szrj   return ret * multiplier;
195*fae548d3Szrj }
196*fae548d3Szrj 
197*fae548d3Szrj // This class handles lexing a file into a sequence of tokens.
198*fae548d3Szrj 
199*fae548d3Szrj class Lex
200*fae548d3Szrj {
201*fae548d3Szrj  public:
202*fae548d3Szrj   // We unfortunately have to support different lexing modes, because
203*fae548d3Szrj   // when reading different parts of a linker script we need to parse
204*fae548d3Szrj   // things differently.
205*fae548d3Szrj   enum Mode
206*fae548d3Szrj   {
207*fae548d3Szrj     // Reading an ordinary linker script.
208*fae548d3Szrj     LINKER_SCRIPT,
209*fae548d3Szrj     // Reading an expression in a linker script.
210*fae548d3Szrj     EXPRESSION,
211*fae548d3Szrj     // Reading a version script.
212*fae548d3Szrj     VERSION_SCRIPT,
213*fae548d3Szrj     // Reading a --dynamic-list file.
214*fae548d3Szrj     DYNAMIC_LIST
215*fae548d3Szrj   };
216*fae548d3Szrj 
Lex(const char * input_string,size_t input_length,int parsing_token)217*fae548d3Szrj   Lex(const char* input_string, size_t input_length, int parsing_token)
218*fae548d3Szrj     : input_string_(input_string), input_length_(input_length),
219*fae548d3Szrj       current_(input_string), mode_(LINKER_SCRIPT),
220*fae548d3Szrj       first_token_(parsing_token), token_(),
221*fae548d3Szrj       lineno_(1), linestart_(input_string)
222*fae548d3Szrj   { }
223*fae548d3Szrj 
224*fae548d3Szrj   // Read a file into a string.
225*fae548d3Szrj   static void
226*fae548d3Szrj   read_file(Input_file*, std::string*);
227*fae548d3Szrj 
228*fae548d3Szrj   // Return the next token.
229*fae548d3Szrj   const Token*
230*fae548d3Szrj   next_token();
231*fae548d3Szrj 
232*fae548d3Szrj   // Return the current lexing mode.
233*fae548d3Szrj   Lex::Mode
mode() const234*fae548d3Szrj   mode() const
235*fae548d3Szrj   { return this->mode_; }
236*fae548d3Szrj 
237*fae548d3Szrj   // Set the lexing mode.
238*fae548d3Szrj   void
set_mode(Mode mode)239*fae548d3Szrj   set_mode(Mode mode)
240*fae548d3Szrj   { this->mode_ = mode; }
241*fae548d3Szrj 
242*fae548d3Szrj  private:
243*fae548d3Szrj   Lex(const Lex&);
244*fae548d3Szrj   Lex& operator=(const Lex&);
245*fae548d3Szrj 
246*fae548d3Szrj   // Make a general token with no value at the current location.
247*fae548d3Szrj   Token
make_token(Token::Classification c,const char * start) const248*fae548d3Szrj   make_token(Token::Classification c, const char* start) const
249*fae548d3Szrj   { return Token(c, this->lineno_, start - this->linestart_ + 1); }
250*fae548d3Szrj 
251*fae548d3Szrj   // Make a general token with a value at the current location.
252*fae548d3Szrj   Token
make_token(Token::Classification c,const char * v,size_t len,const char * start) const253*fae548d3Szrj   make_token(Token::Classification c, const char* v, size_t len,
254*fae548d3Szrj 	     const char* start)
255*fae548d3Szrj     const
256*fae548d3Szrj   { return Token(c, v, len, this->lineno_, start - this->linestart_ + 1); }
257*fae548d3Szrj 
258*fae548d3Szrj   // Make an operator token at the current location.
259*fae548d3Szrj   Token
make_token(int opcode,const char * start) const260*fae548d3Szrj   make_token(int opcode, const char* start) const
261*fae548d3Szrj   { return Token(opcode, this->lineno_, start - this->linestart_ + 1); }
262*fae548d3Szrj 
263*fae548d3Szrj   // Make an invalid token at the current location.
264*fae548d3Szrj   Token
make_invalid_token(const char * start)265*fae548d3Szrj   make_invalid_token(const char* start)
266*fae548d3Szrj   { return this->make_token(Token::TOKEN_INVALID, start); }
267*fae548d3Szrj 
268*fae548d3Szrj   // Make an EOF token at the current location.
269*fae548d3Szrj   Token
make_eof_token(const char * start)270*fae548d3Szrj   make_eof_token(const char* start)
271*fae548d3Szrj   { return this->make_token(Token::TOKEN_EOF, start); }
272*fae548d3Szrj 
273*fae548d3Szrj   // Return whether C can be the first character in a name.  C2 is the
274*fae548d3Szrj   // next character, since we sometimes need that.
275*fae548d3Szrj   inline bool
276*fae548d3Szrj   can_start_name(char c, char c2);
277*fae548d3Szrj 
278*fae548d3Szrj   // If C can appear in a name which has already started, return a
279*fae548d3Szrj   // pointer to a character later in the token or just past
280*fae548d3Szrj   // it. Otherwise, return NULL.
281*fae548d3Szrj   inline const char*
282*fae548d3Szrj   can_continue_name(const char* c);
283*fae548d3Szrj 
284*fae548d3Szrj   // Return whether C, C2, C3 can start a hex number.
285*fae548d3Szrj   inline bool
286*fae548d3Szrj   can_start_hex(char c, char c2, char c3);
287*fae548d3Szrj 
288*fae548d3Szrj   // If C can appear in a hex number which has already started, return
289*fae548d3Szrj   // a pointer to a character later in the token or just past
290*fae548d3Szrj   // it. Otherwise, return NULL.
291*fae548d3Szrj   inline const char*
292*fae548d3Szrj   can_continue_hex(const char* c);
293*fae548d3Szrj 
294*fae548d3Szrj   // Return whether C can start a non-hex number.
295*fae548d3Szrj   static inline bool
296*fae548d3Szrj   can_start_number(char c);
297*fae548d3Szrj 
298*fae548d3Szrj   // If C can appear in a decimal number which has already started,
299*fae548d3Szrj   // return a pointer to a character later in the token or just past
300*fae548d3Szrj   // it. Otherwise, return NULL.
301*fae548d3Szrj   inline const char*
can_continue_number(const char * c)302*fae548d3Szrj   can_continue_number(const char* c)
303*fae548d3Szrj   { return Lex::can_start_number(*c) ? c + 1 : NULL; }
304*fae548d3Szrj 
305*fae548d3Szrj   // If C1 C2 C3 form a valid three character operator, return the
306*fae548d3Szrj   // opcode.  Otherwise return 0.
307*fae548d3Szrj   static inline int
308*fae548d3Szrj   three_char_operator(char c1, char c2, char c3);
309*fae548d3Szrj 
310*fae548d3Szrj   // If C1 C2 form a valid two character operator, return the opcode.
311*fae548d3Szrj   // Otherwise return 0.
312*fae548d3Szrj   static inline int
313*fae548d3Szrj   two_char_operator(char c1, char c2);
314*fae548d3Szrj 
315*fae548d3Szrj   // If C1 is a valid one character operator, return the opcode.
316*fae548d3Szrj   // Otherwise return 0.
317*fae548d3Szrj   static inline int
318*fae548d3Szrj   one_char_operator(char c1);
319*fae548d3Szrj 
320*fae548d3Szrj   // Read the next token.
321*fae548d3Szrj   Token
322*fae548d3Szrj   get_token(const char**);
323*fae548d3Szrj 
324*fae548d3Szrj   // Skip a C style /* */ comment.  Return false if the comment did
325*fae548d3Szrj   // not end.
326*fae548d3Szrj   bool
327*fae548d3Szrj   skip_c_comment(const char**);
328*fae548d3Szrj 
329*fae548d3Szrj   // Skip a line # comment.  Return false if there was no newline.
330*fae548d3Szrj   bool
331*fae548d3Szrj   skip_line_comment(const char**);
332*fae548d3Szrj 
333*fae548d3Szrj   // Build a token CLASSIFICATION from all characters that match
334*fae548d3Szrj   // CAN_CONTINUE_FN.  The token starts at START.  Start matching from
335*fae548d3Szrj   // MATCH.  Set *PP to the character following the token.
336*fae548d3Szrj   inline Token
337*fae548d3Szrj   gather_token(Token::Classification,
338*fae548d3Szrj 	       const char* (Lex::*can_continue_fn)(const char*),
339*fae548d3Szrj 	       const char* start, const char* match, const char** pp);
340*fae548d3Szrj 
341*fae548d3Szrj   // Build a token from a quoted string.
342*fae548d3Szrj   Token
343*fae548d3Szrj   gather_quoted_string(const char** pp);
344*fae548d3Szrj 
345*fae548d3Szrj   // The string we are tokenizing.
346*fae548d3Szrj   const char* input_string_;
347*fae548d3Szrj   // The length of the string.
348*fae548d3Szrj   size_t input_length_;
349*fae548d3Szrj   // The current offset into the string.
350*fae548d3Szrj   const char* current_;
351*fae548d3Szrj   // The current lexing mode.
352*fae548d3Szrj   Mode mode_;
353*fae548d3Szrj   // The code to use for the first token.  This is set to 0 after it
354*fae548d3Szrj   // is used.
355*fae548d3Szrj   int first_token_;
356*fae548d3Szrj   // The current token.
357*fae548d3Szrj   Token token_;
358*fae548d3Szrj   // The current line number.
359*fae548d3Szrj   int lineno_;
360*fae548d3Szrj   // The start of the current line in the string.
361*fae548d3Szrj   const char* linestart_;
362*fae548d3Szrj };
363*fae548d3Szrj 
364*fae548d3Szrj // Read the whole file into memory.  We don't expect linker scripts to
365*fae548d3Szrj // be large, so we just use a std::string as a buffer.  We ignore the
366*fae548d3Szrj // data we've already read, so that we read aligned buffers.
367*fae548d3Szrj 
368*fae548d3Szrj void
read_file(Input_file * input_file,std::string * contents)369*fae548d3Szrj Lex::read_file(Input_file* input_file, std::string* contents)
370*fae548d3Szrj {
371*fae548d3Szrj   off_t filesize = input_file->file().filesize();
372*fae548d3Szrj   contents->clear();
373*fae548d3Szrj   contents->reserve(filesize);
374*fae548d3Szrj 
375*fae548d3Szrj   off_t off = 0;
376*fae548d3Szrj   unsigned char buf[BUFSIZ];
377*fae548d3Szrj   while (off < filesize)
378*fae548d3Szrj     {
379*fae548d3Szrj       off_t get = BUFSIZ;
380*fae548d3Szrj       if (get > filesize - off)
381*fae548d3Szrj 	get = filesize - off;
382*fae548d3Szrj       input_file->file().read(off, get, buf);
383*fae548d3Szrj       contents->append(reinterpret_cast<char*>(&buf[0]), get);
384*fae548d3Szrj       off += get;
385*fae548d3Szrj     }
386*fae548d3Szrj }
387*fae548d3Szrj 
388*fae548d3Szrj // Return whether C can be the start of a name, if the next character
389*fae548d3Szrj // is C2.  A name can being with a letter, underscore, period, or
390*fae548d3Szrj // dollar sign.  Because a name can be a file name, we also permit
391*fae548d3Szrj // forward slash, backslash, and tilde.  Tilde is the tricky case
392*fae548d3Szrj // here; GNU ld also uses it as a bitwise not operator.  It is only
393*fae548d3Szrj // recognized as the operator if it is not immediately followed by
394*fae548d3Szrj // some character which can appear in a symbol.  That is, when we
395*fae548d3Szrj // don't know that we are looking at an expression, "~0" is a file
396*fae548d3Szrj // name, and "~ 0" is an expression using bitwise not.  We are
397*fae548d3Szrj // compatible.
398*fae548d3Szrj 
399*fae548d3Szrj inline bool
can_start_name(char c,char c2)400*fae548d3Szrj Lex::can_start_name(char c, char c2)
401*fae548d3Szrj {
402*fae548d3Szrj   switch (c)
403*fae548d3Szrj     {
404*fae548d3Szrj     case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
405*fae548d3Szrj     case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
406*fae548d3Szrj     case 'M': case 'N': case 'O': case 'Q': case 'P': case 'R':
407*fae548d3Szrj     case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
408*fae548d3Szrj     case 'Y': case 'Z':
409*fae548d3Szrj     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
410*fae548d3Szrj     case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
411*fae548d3Szrj     case 'm': case 'n': case 'o': case 'q': case 'p': case 'r':
412*fae548d3Szrj     case 's': case 't': case 'u': case 'v': case 'w': case 'x':
413*fae548d3Szrj     case 'y': case 'z':
414*fae548d3Szrj     case '_': case '.': case '$':
415*fae548d3Szrj       return true;
416*fae548d3Szrj 
417*fae548d3Szrj     case '/': case '\\':
418*fae548d3Szrj       return this->mode_ == LINKER_SCRIPT;
419*fae548d3Szrj 
420*fae548d3Szrj     case '~':
421*fae548d3Szrj       return this->mode_ == LINKER_SCRIPT && can_continue_name(&c2);
422*fae548d3Szrj 
423*fae548d3Szrj     case '*': case '[':
424*fae548d3Szrj       return (this->mode_ == VERSION_SCRIPT
425*fae548d3Szrj               || this->mode_ == DYNAMIC_LIST
426*fae548d3Szrj 	      || (this->mode_ == LINKER_SCRIPT
427*fae548d3Szrj 		  && can_continue_name(&c2)));
428*fae548d3Szrj 
429*fae548d3Szrj     default:
430*fae548d3Szrj       return false;
431*fae548d3Szrj     }
432*fae548d3Szrj }
433*fae548d3Szrj 
434*fae548d3Szrj // Return whether C can continue a name which has already started.
435*fae548d3Szrj // Subsequent characters in a name are the same as the leading
436*fae548d3Szrj // characters, plus digits and "=+-:[],?*".  So in general the linker
437*fae548d3Szrj // script language requires spaces around operators, unless we know
438*fae548d3Szrj // that we are parsing an expression.
439*fae548d3Szrj 
440*fae548d3Szrj inline const char*
can_continue_name(const char * c)441*fae548d3Szrj Lex::can_continue_name(const char* c)
442*fae548d3Szrj {
443*fae548d3Szrj   switch (*c)
444*fae548d3Szrj     {
445*fae548d3Szrj     case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
446*fae548d3Szrj     case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
447*fae548d3Szrj     case 'M': case 'N': case 'O': case 'Q': case 'P': case 'R':
448*fae548d3Szrj     case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
449*fae548d3Szrj     case 'Y': case 'Z':
450*fae548d3Szrj     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
451*fae548d3Szrj     case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
452*fae548d3Szrj     case 'm': case 'n': case 'o': case 'q': case 'p': case 'r':
453*fae548d3Szrj     case 's': case 't': case 'u': case 'v': case 'w': case 'x':
454*fae548d3Szrj     case 'y': case 'z':
455*fae548d3Szrj     case '_': case '.': case '$':
456*fae548d3Szrj     case '0': case '1': case '2': case '3': case '4':
457*fae548d3Szrj     case '5': case '6': case '7': case '8': case '9':
458*fae548d3Szrj       return c + 1;
459*fae548d3Szrj 
460*fae548d3Szrj     // TODO(csilvers): why not allow ~ in names for version-scripts?
461*fae548d3Szrj     case '/': case '\\': case '~':
462*fae548d3Szrj     case '=': case '+':
463*fae548d3Szrj     case ',':
464*fae548d3Szrj       if (this->mode_ == LINKER_SCRIPT)
465*fae548d3Szrj         return c + 1;
466*fae548d3Szrj       return NULL;
467*fae548d3Szrj 
468*fae548d3Szrj     case '[': case ']': case '*': case '?': case '-':
469*fae548d3Szrj       if (this->mode_ == LINKER_SCRIPT || this->mode_ == VERSION_SCRIPT
470*fae548d3Szrj           || this->mode_ == DYNAMIC_LIST)
471*fae548d3Szrj         return c + 1;
472*fae548d3Szrj       return NULL;
473*fae548d3Szrj 
474*fae548d3Szrj     // TODO(csilvers): why allow this?  ^ is meaningless in version scripts.
475*fae548d3Szrj     case '^':
476*fae548d3Szrj       if (this->mode_ == VERSION_SCRIPT || this->mode_ == DYNAMIC_LIST)
477*fae548d3Szrj         return c + 1;
478*fae548d3Szrj       return NULL;
479*fae548d3Szrj 
480*fae548d3Szrj     case ':':
481*fae548d3Szrj       if (this->mode_ == LINKER_SCRIPT)
482*fae548d3Szrj         return c + 1;
483*fae548d3Szrj       else if ((this->mode_ == VERSION_SCRIPT || this->mode_ == DYNAMIC_LIST)
484*fae548d3Szrj                && (c[1] == ':'))
485*fae548d3Szrj         {
486*fae548d3Szrj           // A name can have '::' in it, as that's a c++ namespace
487*fae548d3Szrj           // separator. But a single colon is not part of a name.
488*fae548d3Szrj           return c + 2;
489*fae548d3Szrj         }
490*fae548d3Szrj       return NULL;
491*fae548d3Szrj 
492*fae548d3Szrj     default:
493*fae548d3Szrj       return NULL;
494*fae548d3Szrj     }
495*fae548d3Szrj }
496*fae548d3Szrj 
497*fae548d3Szrj // For a number we accept 0x followed by hex digits, or any sequence
498*fae548d3Szrj // of digits.  The old linker accepts leading '$' for hex, and
499*fae548d3Szrj // trailing HXBOD.  Those are for MRI compatibility and we don't
500*fae548d3Szrj // accept them.
501*fae548d3Szrj 
502*fae548d3Szrj // Return whether C1 C2 C3 can start a hex number.
503*fae548d3Szrj 
504*fae548d3Szrj inline bool
can_start_hex(char c1,char c2,char c3)505*fae548d3Szrj Lex::can_start_hex(char c1, char c2, char c3)
506*fae548d3Szrj {
507*fae548d3Szrj   if (c1 == '0' && (c2 == 'x' || c2 == 'X'))
508*fae548d3Szrj     return this->can_continue_hex(&c3);
509*fae548d3Szrj   return false;
510*fae548d3Szrj }
511*fae548d3Szrj 
512*fae548d3Szrj // Return whether C can appear in a hex number.
513*fae548d3Szrj 
514*fae548d3Szrj inline const char*
can_continue_hex(const char * c)515*fae548d3Szrj Lex::can_continue_hex(const char* c)
516*fae548d3Szrj {
517*fae548d3Szrj   switch (*c)
518*fae548d3Szrj     {
519*fae548d3Szrj     case '0': case '1': case '2': case '3': case '4':
520*fae548d3Szrj     case '5': case '6': case '7': case '8': case '9':
521*fae548d3Szrj     case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
522*fae548d3Szrj     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
523*fae548d3Szrj       return c + 1;
524*fae548d3Szrj 
525*fae548d3Szrj     default:
526*fae548d3Szrj       return NULL;
527*fae548d3Szrj     }
528*fae548d3Szrj }
529*fae548d3Szrj 
530*fae548d3Szrj // Return whether C can start a non-hex number.
531*fae548d3Szrj 
532*fae548d3Szrj inline bool
can_start_number(char c)533*fae548d3Szrj Lex::can_start_number(char c)
534*fae548d3Szrj {
535*fae548d3Szrj   switch (c)
536*fae548d3Szrj     {
537*fae548d3Szrj     case '0': case '1': case '2': case '3': case '4':
538*fae548d3Szrj     case '5': case '6': case '7': case '8': case '9':
539*fae548d3Szrj       return true;
540*fae548d3Szrj 
541*fae548d3Szrj     default:
542*fae548d3Szrj       return false;
543*fae548d3Szrj     }
544*fae548d3Szrj }
545*fae548d3Szrj 
546*fae548d3Szrj // If C1 C2 C3 form a valid three character operator, return the
547*fae548d3Szrj // opcode (defined in the yyscript.h file generated from yyscript.y).
548*fae548d3Szrj // Otherwise return 0.
549*fae548d3Szrj 
550*fae548d3Szrj inline int
three_char_operator(char c1,char c2,char c3)551*fae548d3Szrj Lex::three_char_operator(char c1, char c2, char c3)
552*fae548d3Szrj {
553*fae548d3Szrj   switch (c1)
554*fae548d3Szrj     {
555*fae548d3Szrj     case '<':
556*fae548d3Szrj       if (c2 == '<' && c3 == '=')
557*fae548d3Szrj 	return LSHIFTEQ;
558*fae548d3Szrj       break;
559*fae548d3Szrj     case '>':
560*fae548d3Szrj       if (c2 == '>' && c3 == '=')
561*fae548d3Szrj 	return RSHIFTEQ;
562*fae548d3Szrj       break;
563*fae548d3Szrj     default:
564*fae548d3Szrj       break;
565*fae548d3Szrj     }
566*fae548d3Szrj   return 0;
567*fae548d3Szrj }
568*fae548d3Szrj 
569*fae548d3Szrj // If C1 C2 form a valid two character operator, return the opcode
570*fae548d3Szrj // (defined in the yyscript.h file generated from yyscript.y).
571*fae548d3Szrj // Otherwise return 0.
572*fae548d3Szrj 
573*fae548d3Szrj inline int
two_char_operator(char c1,char c2)574*fae548d3Szrj Lex::two_char_operator(char c1, char c2)
575*fae548d3Szrj {
576*fae548d3Szrj   switch (c1)
577*fae548d3Szrj     {
578*fae548d3Szrj     case '=':
579*fae548d3Szrj       if (c2 == '=')
580*fae548d3Szrj 	return EQ;
581*fae548d3Szrj       break;
582*fae548d3Szrj     case '!':
583*fae548d3Szrj       if (c2 == '=')
584*fae548d3Szrj 	return NE;
585*fae548d3Szrj       break;
586*fae548d3Szrj     case '+':
587*fae548d3Szrj       if (c2 == '=')
588*fae548d3Szrj 	return PLUSEQ;
589*fae548d3Szrj       break;
590*fae548d3Szrj     case '-':
591*fae548d3Szrj       if (c2 == '=')
592*fae548d3Szrj 	return MINUSEQ;
593*fae548d3Szrj       break;
594*fae548d3Szrj     case '*':
595*fae548d3Szrj       if (c2 == '=')
596*fae548d3Szrj 	return MULTEQ;
597*fae548d3Szrj       break;
598*fae548d3Szrj     case '/':
599*fae548d3Szrj       if (c2 == '=')
600*fae548d3Szrj 	return DIVEQ;
601*fae548d3Szrj       break;
602*fae548d3Szrj     case '|':
603*fae548d3Szrj       if (c2 == '=')
604*fae548d3Szrj 	return OREQ;
605*fae548d3Szrj       if (c2 == '|')
606*fae548d3Szrj 	return OROR;
607*fae548d3Szrj       break;
608*fae548d3Szrj     case '&':
609*fae548d3Szrj       if (c2 == '=')
610*fae548d3Szrj 	return ANDEQ;
611*fae548d3Szrj       if (c2 == '&')
612*fae548d3Szrj 	return ANDAND;
613*fae548d3Szrj       break;
614*fae548d3Szrj     case '>':
615*fae548d3Szrj       if (c2 == '=')
616*fae548d3Szrj 	return GE;
617*fae548d3Szrj       if (c2 == '>')
618*fae548d3Szrj 	return RSHIFT;
619*fae548d3Szrj       break;
620*fae548d3Szrj     case '<':
621*fae548d3Szrj       if (c2 == '=')
622*fae548d3Szrj 	return LE;
623*fae548d3Szrj       if (c2 == '<')
624*fae548d3Szrj 	return LSHIFT;
625*fae548d3Szrj       break;
626*fae548d3Szrj     default:
627*fae548d3Szrj       break;
628*fae548d3Szrj     }
629*fae548d3Szrj   return 0;
630*fae548d3Szrj }
631*fae548d3Szrj 
632*fae548d3Szrj // If C1 is a valid operator, return the opcode.  Otherwise return 0.
633*fae548d3Szrj 
634*fae548d3Szrj inline int
one_char_operator(char c1)635*fae548d3Szrj Lex::one_char_operator(char c1)
636*fae548d3Szrj {
637*fae548d3Szrj   switch (c1)
638*fae548d3Szrj     {
639*fae548d3Szrj     case '+':
640*fae548d3Szrj     case '-':
641*fae548d3Szrj     case '*':
642*fae548d3Szrj     case '/':
643*fae548d3Szrj     case '%':
644*fae548d3Szrj     case '!':
645*fae548d3Szrj     case '&':
646*fae548d3Szrj     case '|':
647*fae548d3Szrj     case '^':
648*fae548d3Szrj     case '~':
649*fae548d3Szrj     case '<':
650*fae548d3Szrj     case '>':
651*fae548d3Szrj     case '=':
652*fae548d3Szrj     case '?':
653*fae548d3Szrj     case ',':
654*fae548d3Szrj     case '(':
655*fae548d3Szrj     case ')':
656*fae548d3Szrj     case '{':
657*fae548d3Szrj     case '}':
658*fae548d3Szrj     case '[':
659*fae548d3Szrj     case ']':
660*fae548d3Szrj     case ':':
661*fae548d3Szrj     case ';':
662*fae548d3Szrj       return c1;
663*fae548d3Szrj     default:
664*fae548d3Szrj       return 0;
665*fae548d3Szrj     }
666*fae548d3Szrj }
667*fae548d3Szrj 
668*fae548d3Szrj // Skip a C style comment.  *PP points to just after the "/*".  Return
669*fae548d3Szrj // false if the comment did not end.
670*fae548d3Szrj 
671*fae548d3Szrj bool
skip_c_comment(const char ** pp)672*fae548d3Szrj Lex::skip_c_comment(const char** pp)
673*fae548d3Szrj {
674*fae548d3Szrj   const char* p = *pp;
675*fae548d3Szrj   while (p[0] != '*' || p[1] != '/')
676*fae548d3Szrj     {
677*fae548d3Szrj       if (*p == '\0')
678*fae548d3Szrj 	{
679*fae548d3Szrj 	  *pp = p;
680*fae548d3Szrj 	  return false;
681*fae548d3Szrj 	}
682*fae548d3Szrj 
683*fae548d3Szrj       if (*p == '\n')
684*fae548d3Szrj 	{
685*fae548d3Szrj 	  ++this->lineno_;
686*fae548d3Szrj 	  this->linestart_ = p + 1;
687*fae548d3Szrj 	}
688*fae548d3Szrj       ++p;
689*fae548d3Szrj     }
690*fae548d3Szrj 
691*fae548d3Szrj   *pp = p + 2;
692*fae548d3Szrj   return true;
693*fae548d3Szrj }
694*fae548d3Szrj 
695*fae548d3Szrj // Skip a line # comment.  Return false if there was no newline.
696*fae548d3Szrj 
697*fae548d3Szrj bool
skip_line_comment(const char ** pp)698*fae548d3Szrj Lex::skip_line_comment(const char** pp)
699*fae548d3Szrj {
700*fae548d3Szrj   const char* p = *pp;
701*fae548d3Szrj   size_t skip = strcspn(p, "\n");
702*fae548d3Szrj   if (p[skip] == '\0')
703*fae548d3Szrj     {
704*fae548d3Szrj       *pp = p + skip;
705*fae548d3Szrj       return false;
706*fae548d3Szrj     }
707*fae548d3Szrj 
708*fae548d3Szrj   p += skip + 1;
709*fae548d3Szrj   ++this->lineno_;
710*fae548d3Szrj   this->linestart_ = p;
711*fae548d3Szrj   *pp = p;
712*fae548d3Szrj 
713*fae548d3Szrj   return true;
714*fae548d3Szrj }
715*fae548d3Szrj 
716*fae548d3Szrj // Build a token CLASSIFICATION from all characters that match
717*fae548d3Szrj // CAN_CONTINUE_FN.  Update *PP.
718*fae548d3Szrj 
719*fae548d3Szrj inline Token
gather_token(Token::Classification classification,const char * (Lex::* can_continue_fn)(const char *),const char * start,const char * match,const char ** pp)720*fae548d3Szrj Lex::gather_token(Token::Classification classification,
721*fae548d3Szrj 		  const char* (Lex::*can_continue_fn)(const char*),
722*fae548d3Szrj 		  const char* start,
723*fae548d3Szrj 		  const char* match,
724*fae548d3Szrj 		  const char** pp)
725*fae548d3Szrj {
726*fae548d3Szrj   const char* new_match = NULL;
727*fae548d3Szrj   while ((new_match = (this->*can_continue_fn)(match)) != NULL)
728*fae548d3Szrj     match = new_match;
729*fae548d3Szrj 
730*fae548d3Szrj   // A special case: integers may be followed by a single M or K,
731*fae548d3Szrj   // case-insensitive.
732*fae548d3Szrj   if (classification == Token::TOKEN_INTEGER
733*fae548d3Szrj       && (*match == 'm' || *match == 'M' || *match == 'k' || *match == 'K'))
734*fae548d3Szrj     ++match;
735*fae548d3Szrj 
736*fae548d3Szrj   *pp = match;
737*fae548d3Szrj   return this->make_token(classification, start, match - start, start);
738*fae548d3Szrj }
739*fae548d3Szrj 
740*fae548d3Szrj // Build a token from a quoted string.
741*fae548d3Szrj 
742*fae548d3Szrj Token
gather_quoted_string(const char ** pp)743*fae548d3Szrj Lex::gather_quoted_string(const char** pp)
744*fae548d3Szrj {
745*fae548d3Szrj   const char* start = *pp;
746*fae548d3Szrj   const char* p = start;
747*fae548d3Szrj   ++p;
748*fae548d3Szrj   size_t skip = strcspn(p, "\"\n");
749*fae548d3Szrj   if (p[skip] != '"')
750*fae548d3Szrj     return this->make_invalid_token(start);
751*fae548d3Szrj   *pp = p + skip + 1;
752*fae548d3Szrj   return this->make_token(Token::TOKEN_QUOTED_STRING, p, skip, start);
753*fae548d3Szrj }
754*fae548d3Szrj 
755*fae548d3Szrj // Return the next token at *PP.  Update *PP.  General guideline: we
756*fae548d3Szrj // require linker scripts to be simple ASCII.  No unicode linker
757*fae548d3Szrj // scripts.  In particular we can assume that any '\0' is the end of
758*fae548d3Szrj // the input.
759*fae548d3Szrj 
760*fae548d3Szrj Token
get_token(const char ** pp)761*fae548d3Szrj Lex::get_token(const char** pp)
762*fae548d3Szrj {
763*fae548d3Szrj   const char* p = *pp;
764*fae548d3Szrj 
765*fae548d3Szrj   while (true)
766*fae548d3Szrj     {
767*fae548d3Szrj       // Skip whitespace quickly.
768*fae548d3Szrj       while (*p == ' ' || *p == '\t' || *p == '\r')
769*fae548d3Szrj 	++p;
770*fae548d3Szrj 
771*fae548d3Szrj       if (*p == '\n')
772*fae548d3Szrj 	{
773*fae548d3Szrj 	  ++p;
774*fae548d3Szrj 	  ++this->lineno_;
775*fae548d3Szrj 	  this->linestart_ = p;
776*fae548d3Szrj 	  continue;
777*fae548d3Szrj 	}
778*fae548d3Szrj 
779*fae548d3Szrj       char c0 = *p;
780*fae548d3Szrj 
781*fae548d3Szrj       if (c0 == '\0')
782*fae548d3Szrj 	{
783*fae548d3Szrj 	  *pp = p;
784*fae548d3Szrj 	  return this->make_eof_token(p);
785*fae548d3Szrj 	}
786*fae548d3Szrj 
787*fae548d3Szrj       char c1 = p[1];
788*fae548d3Szrj 
789*fae548d3Szrj       // Skip C style comments.
790*fae548d3Szrj       if (c0 == '/' && c1 == '*')
791*fae548d3Szrj 	{
792*fae548d3Szrj 	  int lineno = this->lineno_;
793*fae548d3Szrj 	  int charpos = p - this->linestart_ + 1;
794*fae548d3Szrj 
795*fae548d3Szrj 	  *pp = p + 2;
796*fae548d3Szrj 	  if (!this->skip_c_comment(pp))
797*fae548d3Szrj 	    return Token(Token::TOKEN_INVALID, lineno, charpos);
798*fae548d3Szrj 	  p = *pp;
799*fae548d3Szrj 
800*fae548d3Szrj 	  continue;
801*fae548d3Szrj 	}
802*fae548d3Szrj 
803*fae548d3Szrj       // Skip line comments.
804*fae548d3Szrj       if (c0 == '#')
805*fae548d3Szrj 	{
806*fae548d3Szrj 	  *pp = p + 1;
807*fae548d3Szrj 	  if (!this->skip_line_comment(pp))
808*fae548d3Szrj 	    return this->make_eof_token(p);
809*fae548d3Szrj 	  p = *pp;
810*fae548d3Szrj 	  continue;
811*fae548d3Szrj 	}
812*fae548d3Szrj 
813*fae548d3Szrj       // Check for a name.
814*fae548d3Szrj       if (this->can_start_name(c0, c1))
815*fae548d3Szrj 	return this->gather_token(Token::TOKEN_STRING,
816*fae548d3Szrj 				  &Lex::can_continue_name,
817*fae548d3Szrj 				  p, p + 1, pp);
818*fae548d3Szrj 
819*fae548d3Szrj       // We accept any arbitrary name in double quotes, as long as it
820*fae548d3Szrj       // does not cross a line boundary.
821*fae548d3Szrj       if (*p == '"')
822*fae548d3Szrj 	{
823*fae548d3Szrj 	  *pp = p;
824*fae548d3Szrj 	  return this->gather_quoted_string(pp);
825*fae548d3Szrj 	}
826*fae548d3Szrj 
827*fae548d3Szrj       // Be careful not to lookahead past the end of the buffer.
828*fae548d3Szrj       char c2 = (c1 == '\0' ? '\0' : p[2]);
829*fae548d3Szrj 
830*fae548d3Szrj       // Check for a number.
831*fae548d3Szrj 
832*fae548d3Szrj       if (this->can_start_hex(c0, c1, c2))
833*fae548d3Szrj 	return this->gather_token(Token::TOKEN_INTEGER,
834*fae548d3Szrj 				  &Lex::can_continue_hex,
835*fae548d3Szrj 				  p, p + 3, pp);
836*fae548d3Szrj 
837*fae548d3Szrj       if (Lex::can_start_number(c0))
838*fae548d3Szrj 	return this->gather_token(Token::TOKEN_INTEGER,
839*fae548d3Szrj 				  &Lex::can_continue_number,
840*fae548d3Szrj 				  p, p + 1, pp);
841*fae548d3Szrj 
842*fae548d3Szrj       // Check for operators.
843*fae548d3Szrj 
844*fae548d3Szrj       int opcode = Lex::three_char_operator(c0, c1, c2);
845*fae548d3Szrj       if (opcode != 0)
846*fae548d3Szrj 	{
847*fae548d3Szrj 	  *pp = p + 3;
848*fae548d3Szrj 	  return this->make_token(opcode, p);
849*fae548d3Szrj 	}
850*fae548d3Szrj 
851*fae548d3Szrj       opcode = Lex::two_char_operator(c0, c1);
852*fae548d3Szrj       if (opcode != 0)
853*fae548d3Szrj 	{
854*fae548d3Szrj 	  *pp = p + 2;
855*fae548d3Szrj 	  return this->make_token(opcode, p);
856*fae548d3Szrj 	}
857*fae548d3Szrj 
858*fae548d3Szrj       opcode = Lex::one_char_operator(c0);
859*fae548d3Szrj       if (opcode != 0)
860*fae548d3Szrj 	{
861*fae548d3Szrj 	  *pp = p + 1;
862*fae548d3Szrj 	  return this->make_token(opcode, p);
863*fae548d3Szrj 	}
864*fae548d3Szrj 
865*fae548d3Szrj       return this->make_token(Token::TOKEN_INVALID, p);
866*fae548d3Szrj     }
867*fae548d3Szrj }
868*fae548d3Szrj 
869*fae548d3Szrj // Return the next token.
870*fae548d3Szrj 
871*fae548d3Szrj const Token*
next_token()872*fae548d3Szrj Lex::next_token()
873*fae548d3Szrj {
874*fae548d3Szrj   // The first token is special.
875*fae548d3Szrj   if (this->first_token_ != 0)
876*fae548d3Szrj     {
877*fae548d3Szrj       this->token_ = Token(this->first_token_, 0, 0);
878*fae548d3Szrj       this->first_token_ = 0;
879*fae548d3Szrj       return &this->token_;
880*fae548d3Szrj     }
881*fae548d3Szrj 
882*fae548d3Szrj   this->token_ = this->get_token(&this->current_);
883*fae548d3Szrj 
884*fae548d3Szrj   // Don't let an early null byte fool us into thinking that we've
885*fae548d3Szrj   // reached the end of the file.
886*fae548d3Szrj   if (this->token_.is_eof()
887*fae548d3Szrj       && (static_cast<size_t>(this->current_ - this->input_string_)
888*fae548d3Szrj 	  < this->input_length_))
889*fae548d3Szrj     this->token_ = this->make_invalid_token(this->current_);
890*fae548d3Szrj 
891*fae548d3Szrj   return &this->token_;
892*fae548d3Szrj }
893*fae548d3Szrj 
894*fae548d3Szrj // class Symbol_assignment.
895*fae548d3Szrj 
896*fae548d3Szrj // Add the symbol to the symbol table.  This makes sure the symbol is
897*fae548d3Szrj // there and defined.  The actual value is stored later.  We can't
898*fae548d3Szrj // determine the actual value at this point, because we can't
899*fae548d3Szrj // necessarily evaluate the expression until all ordinary symbols have
900*fae548d3Szrj // been finalized.
901*fae548d3Szrj 
902*fae548d3Szrj // The GNU linker lets symbol assignments in the linker script
903*fae548d3Szrj // silently override defined symbols in object files.  We are
904*fae548d3Szrj // compatible.  FIXME: Should we issue a warning?
905*fae548d3Szrj 
906*fae548d3Szrj void
add_to_table(Symbol_table * symtab)907*fae548d3Szrj Symbol_assignment::add_to_table(Symbol_table* symtab)
908*fae548d3Szrj {
909*fae548d3Szrj   elfcpp::STV vis = this->hidden_ ? elfcpp::STV_HIDDEN : elfcpp::STV_DEFAULT;
910*fae548d3Szrj   this->sym_ = symtab->define_as_constant(this->name_.c_str(),
911*fae548d3Szrj 					  NULL, // version
912*fae548d3Szrj 					  (this->is_defsym_
913*fae548d3Szrj 					   ? Symbol_table::DEFSYM
914*fae548d3Szrj 					   : Symbol_table::SCRIPT),
915*fae548d3Szrj 					  0, // value
916*fae548d3Szrj 					  0, // size
917*fae548d3Szrj 					  elfcpp::STT_NOTYPE,
918*fae548d3Szrj 					  elfcpp::STB_GLOBAL,
919*fae548d3Szrj 					  vis,
920*fae548d3Szrj 					  0, // nonvis
921*fae548d3Szrj 					  this->provide_,
922*fae548d3Szrj                                           true); // force_override
923*fae548d3Szrj }
924*fae548d3Szrj 
925*fae548d3Szrj // Finalize a symbol value.
926*fae548d3Szrj 
927*fae548d3Szrj void
finalize(Symbol_table * symtab,const Layout * layout)928*fae548d3Szrj Symbol_assignment::finalize(Symbol_table* symtab, const Layout* layout)
929*fae548d3Szrj {
930*fae548d3Szrj   this->finalize_maybe_dot(symtab, layout, false, 0, NULL);
931*fae548d3Szrj }
932*fae548d3Szrj 
933*fae548d3Szrj // Finalize a symbol value which can refer to the dot symbol.
934*fae548d3Szrj 
935*fae548d3Szrj void
finalize_with_dot(Symbol_table * symtab,const Layout * layout,uint64_t dot_value,Output_section * dot_section)936*fae548d3Szrj Symbol_assignment::finalize_with_dot(Symbol_table* symtab,
937*fae548d3Szrj 				     const Layout* layout,
938*fae548d3Szrj 				     uint64_t dot_value,
939*fae548d3Szrj 				     Output_section* dot_section)
940*fae548d3Szrj {
941*fae548d3Szrj   this->finalize_maybe_dot(symtab, layout, true, dot_value, dot_section);
942*fae548d3Szrj }
943*fae548d3Szrj 
944*fae548d3Szrj // Finalize a symbol value, internal version.
945*fae548d3Szrj 
946*fae548d3Szrj void
finalize_maybe_dot(Symbol_table * symtab,const Layout * layout,bool is_dot_available,uint64_t dot_value,Output_section * dot_section)947*fae548d3Szrj Symbol_assignment::finalize_maybe_dot(Symbol_table* symtab,
948*fae548d3Szrj 				      const Layout* layout,
949*fae548d3Szrj 				      bool is_dot_available,
950*fae548d3Szrj 				      uint64_t dot_value,
951*fae548d3Szrj 				      Output_section* dot_section)
952*fae548d3Szrj {
953*fae548d3Szrj   // If we were only supposed to provide this symbol, the sym_ field
954*fae548d3Szrj   // will be NULL if the symbol was not referenced.
955*fae548d3Szrj   if (this->sym_ == NULL)
956*fae548d3Szrj     {
957*fae548d3Szrj       gold_assert(this->provide_);
958*fae548d3Szrj       return;
959*fae548d3Szrj     }
960*fae548d3Szrj 
961*fae548d3Szrj   if (parameters->target().get_size() == 32)
962*fae548d3Szrj     {
963*fae548d3Szrj #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
964*fae548d3Szrj       this->sized_finalize<32>(symtab, layout, is_dot_available, dot_value,
965*fae548d3Szrj 			       dot_section);
966*fae548d3Szrj #else
967*fae548d3Szrj       gold_unreachable();
968*fae548d3Szrj #endif
969*fae548d3Szrj     }
970*fae548d3Szrj   else if (parameters->target().get_size() == 64)
971*fae548d3Szrj     {
972*fae548d3Szrj #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
973*fae548d3Szrj       this->sized_finalize<64>(symtab, layout, is_dot_available, dot_value,
974*fae548d3Szrj 			       dot_section);
975*fae548d3Szrj #else
976*fae548d3Szrj       gold_unreachable();
977*fae548d3Szrj #endif
978*fae548d3Szrj     }
979*fae548d3Szrj   else
980*fae548d3Szrj     gold_unreachable();
981*fae548d3Szrj }
982*fae548d3Szrj 
983*fae548d3Szrj template<int size>
984*fae548d3Szrj void
sized_finalize(Symbol_table * symtab,const Layout * layout,bool is_dot_available,uint64_t dot_value,Output_section * dot_section)985*fae548d3Szrj Symbol_assignment::sized_finalize(Symbol_table* symtab, const Layout* layout,
986*fae548d3Szrj 				  bool is_dot_available, uint64_t dot_value,
987*fae548d3Szrj 				  Output_section* dot_section)
988*fae548d3Szrj {
989*fae548d3Szrj   Output_section* section;
990*fae548d3Szrj   elfcpp::STT type = elfcpp::STT_NOTYPE;
991*fae548d3Szrj   elfcpp::STV vis = elfcpp::STV_DEFAULT;
992*fae548d3Szrj   unsigned char nonvis = 0;
993*fae548d3Szrj   uint64_t final_val = this->val_->eval_maybe_dot(symtab, layout, true,
994*fae548d3Szrj 						  is_dot_available,
995*fae548d3Szrj 						  dot_value, dot_section,
996*fae548d3Szrj 						  &section, NULL, &type,
997*fae548d3Szrj 						  &vis, &nonvis, false, NULL);
998*fae548d3Szrj   Sized_symbol<size>* ssym = symtab->get_sized_symbol<size>(this->sym_);
999*fae548d3Szrj   ssym->set_value(final_val);
1000*fae548d3Szrj   ssym->set_type(type);
1001*fae548d3Szrj   ssym->set_visibility(vis);
1002*fae548d3Szrj   ssym->set_nonvis(nonvis);
1003*fae548d3Szrj   if (section != NULL)
1004*fae548d3Szrj     ssym->set_output_section(section);
1005*fae548d3Szrj }
1006*fae548d3Szrj 
1007*fae548d3Szrj // Set the symbol value if the expression yields an absolute value or
1008*fae548d3Szrj // a value relative to DOT_SECTION.
1009*fae548d3Szrj 
1010*fae548d3Szrj void
set_if_absolute(Symbol_table * symtab,const Layout * layout,bool is_dot_available,uint64_t dot_value,Output_section * dot_section)1011*fae548d3Szrj Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout,
1012*fae548d3Szrj 				   bool is_dot_available, uint64_t dot_value,
1013*fae548d3Szrj 				   Output_section* dot_section)
1014*fae548d3Szrj {
1015*fae548d3Szrj   if (this->sym_ == NULL)
1016*fae548d3Szrj     return;
1017*fae548d3Szrj 
1018*fae548d3Szrj   Output_section* val_section;
1019*fae548d3Szrj   bool is_valid;
1020*fae548d3Szrj   uint64_t val = this->val_->eval_maybe_dot(symtab, layout, false,
1021*fae548d3Szrj 					    is_dot_available, dot_value,
1022*fae548d3Szrj 					    dot_section, &val_section, NULL,
1023*fae548d3Szrj 					    NULL, NULL, NULL, false, &is_valid);
1024*fae548d3Szrj   if (!is_valid || (val_section != NULL && val_section != dot_section))
1025*fae548d3Szrj     return;
1026*fae548d3Szrj 
1027*fae548d3Szrj   if (parameters->target().get_size() == 32)
1028*fae548d3Szrj     {
1029*fae548d3Szrj #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
1030*fae548d3Szrj       Sized_symbol<32>* ssym = symtab->get_sized_symbol<32>(this->sym_);
1031*fae548d3Szrj       ssym->set_value(val);
1032*fae548d3Szrj #else
1033*fae548d3Szrj       gold_unreachable();
1034*fae548d3Szrj #endif
1035*fae548d3Szrj     }
1036*fae548d3Szrj   else if (parameters->target().get_size() == 64)
1037*fae548d3Szrj     {
1038*fae548d3Szrj #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
1039*fae548d3Szrj       Sized_symbol<64>* ssym = symtab->get_sized_symbol<64>(this->sym_);
1040*fae548d3Szrj       ssym->set_value(val);
1041*fae548d3Szrj #else
1042*fae548d3Szrj       gold_unreachable();
1043*fae548d3Szrj #endif
1044*fae548d3Szrj     }
1045*fae548d3Szrj   else
1046*fae548d3Szrj     gold_unreachable();
1047*fae548d3Szrj   if (val_section != NULL)
1048*fae548d3Szrj     this->sym_->set_output_section(val_section);
1049*fae548d3Szrj }
1050*fae548d3Szrj 
1051*fae548d3Szrj // Print for debugging.
1052*fae548d3Szrj 
1053*fae548d3Szrj void
print(FILE * f) const1054*fae548d3Szrj Symbol_assignment::print(FILE* f) const
1055*fae548d3Szrj {
1056*fae548d3Szrj   if (this->provide_ && this->hidden_)
1057*fae548d3Szrj     fprintf(f, "PROVIDE_HIDDEN(");
1058*fae548d3Szrj   else if (this->provide_)
1059*fae548d3Szrj     fprintf(f, "PROVIDE(");
1060*fae548d3Szrj   else if (this->hidden_)
1061*fae548d3Szrj     gold_unreachable();
1062*fae548d3Szrj 
1063*fae548d3Szrj   fprintf(f, "%s = ", this->name_.c_str());
1064*fae548d3Szrj   this->val_->print(f);
1065*fae548d3Szrj 
1066*fae548d3Szrj   if (this->provide_ || this->hidden_)
1067*fae548d3Szrj     fprintf(f, ")");
1068*fae548d3Szrj 
1069*fae548d3Szrj   fprintf(f, "\n");
1070*fae548d3Szrj }
1071*fae548d3Szrj 
1072*fae548d3Szrj // Class Script_assertion.
1073*fae548d3Szrj 
1074*fae548d3Szrj // Check the assertion.
1075*fae548d3Szrj 
1076*fae548d3Szrj void
check(const Symbol_table * symtab,const Layout * layout)1077*fae548d3Szrj Script_assertion::check(const Symbol_table* symtab, const Layout* layout)
1078*fae548d3Szrj {
1079*fae548d3Szrj   if (!this->check_->eval(symtab, layout, true))
1080*fae548d3Szrj     gold_error("%s", this->message_.c_str());
1081*fae548d3Szrj }
1082*fae548d3Szrj 
1083*fae548d3Szrj // Print for debugging.
1084*fae548d3Szrj 
1085*fae548d3Szrj void
print(FILE * f) const1086*fae548d3Szrj Script_assertion::print(FILE* f) const
1087*fae548d3Szrj {
1088*fae548d3Szrj   fprintf(f, "ASSERT(");
1089*fae548d3Szrj   this->check_->print(f);
1090*fae548d3Szrj   fprintf(f, ", \"%s\")\n", this->message_.c_str());
1091*fae548d3Szrj }
1092*fae548d3Szrj 
1093*fae548d3Szrj // Class Script_options.
1094*fae548d3Szrj 
Script_options()1095*fae548d3Szrj Script_options::Script_options()
1096*fae548d3Szrj   : entry_(), symbol_assignments_(), symbol_definitions_(),
1097*fae548d3Szrj     symbol_references_(), version_script_info_(), script_sections_()
1098*fae548d3Szrj {
1099*fae548d3Szrj }
1100*fae548d3Szrj 
1101*fae548d3Szrj // Returns true if NAME is on the list of symbol assignments waiting
1102*fae548d3Szrj // to be processed.
1103*fae548d3Szrj 
1104*fae548d3Szrj bool
is_pending_assignment(const char * name)1105*fae548d3Szrj Script_options::is_pending_assignment(const char* name)
1106*fae548d3Szrj {
1107*fae548d3Szrj   for (Symbol_assignments::iterator p = this->symbol_assignments_.begin();
1108*fae548d3Szrj        p != this->symbol_assignments_.end();
1109*fae548d3Szrj        ++p)
1110*fae548d3Szrj     if ((*p)->name() == name)
1111*fae548d3Szrj       return true;
1112*fae548d3Szrj   return false;
1113*fae548d3Szrj }
1114*fae548d3Szrj 
1115*fae548d3Szrj // Populates the set with symbols defined in defsym LHS.
1116*fae548d3Szrj 
find_defsym_defs(Unordered_set<std::string> & defsym_set)1117*fae548d3Szrj void Script_options::find_defsym_defs(Unordered_set<std::string>& defsym_set)
1118*fae548d3Szrj {
1119*fae548d3Szrj   for (Symbol_assignments::const_iterator p = this->symbol_assignments_.begin();
1120*fae548d3Szrj        p != this->symbol_assignments_.end();
1121*fae548d3Szrj        ++p)
1122*fae548d3Szrj     {
1123*fae548d3Szrj       defsym_set.insert((*p)->name());
1124*fae548d3Szrj     }
1125*fae548d3Szrj }
1126*fae548d3Szrj 
1127*fae548d3Szrj void
set_defsym_uses_in_real_elf(Symbol_table * symtab) const1128*fae548d3Szrj Script_options::set_defsym_uses_in_real_elf(Symbol_table* symtab) const
1129*fae548d3Szrj {
1130*fae548d3Szrj   for (Symbol_assignments::const_iterator p = this->symbol_assignments_.begin();
1131*fae548d3Szrj        p != this->symbol_assignments_.end();
1132*fae548d3Szrj        ++p)
1133*fae548d3Szrj     {
1134*fae548d3Szrj       (*p)->value()->set_expr_sym_in_real_elf(symtab);
1135*fae548d3Szrj     }
1136*fae548d3Szrj }
1137*fae548d3Szrj 
1138*fae548d3Szrj // Add a symbol to be defined.
1139*fae548d3Szrj 
1140*fae548d3Szrj void
add_symbol_assignment(const char * name,size_t length,bool is_defsym,Expression * value,bool provide,bool hidden)1141*fae548d3Szrj Script_options::add_symbol_assignment(const char* name, size_t length,
1142*fae548d3Szrj 				      bool is_defsym, Expression* value,
1143*fae548d3Szrj 				      bool provide, bool hidden)
1144*fae548d3Szrj {
1145*fae548d3Szrj   if (length != 1 || name[0] != '.')
1146*fae548d3Szrj     {
1147*fae548d3Szrj       if (this->script_sections_.in_sections_clause())
1148*fae548d3Szrj 	{
1149*fae548d3Szrj 	  gold_assert(!is_defsym);
1150*fae548d3Szrj 	  this->script_sections_.add_symbol_assignment(name, length, value,
1151*fae548d3Szrj 						       provide, hidden);
1152*fae548d3Szrj 	}
1153*fae548d3Szrj       else
1154*fae548d3Szrj 	{
1155*fae548d3Szrj 	  Symbol_assignment* p = new Symbol_assignment(name, length, is_defsym,
1156*fae548d3Szrj 						       value, provide, hidden);
1157*fae548d3Szrj 	  this->symbol_assignments_.push_back(p);
1158*fae548d3Szrj 	}
1159*fae548d3Szrj 
1160*fae548d3Szrj       if (!provide)
1161*fae548d3Szrj 	{
1162*fae548d3Szrj 	  std::string n(name, length);
1163*fae548d3Szrj 	  this->symbol_definitions_.insert(n);
1164*fae548d3Szrj 	  this->symbol_references_.erase(n);
1165*fae548d3Szrj 	}
1166*fae548d3Szrj     }
1167*fae548d3Szrj   else
1168*fae548d3Szrj     {
1169*fae548d3Szrj       if (provide || hidden)
1170*fae548d3Szrj 	gold_error(_("invalid use of PROVIDE for dot symbol"));
1171*fae548d3Szrj 
1172*fae548d3Szrj       // The GNU linker permits assignments to dot outside of SECTIONS
1173*fae548d3Szrj       // clauses and treats them as occurring inside, so we don't
1174*fae548d3Szrj       // check in_sections_clause here.
1175*fae548d3Szrj       this->script_sections_.add_dot_assignment(value);
1176*fae548d3Szrj     }
1177*fae548d3Szrj }
1178*fae548d3Szrj 
1179*fae548d3Szrj // Add a reference to a symbol.
1180*fae548d3Szrj 
1181*fae548d3Szrj void
add_symbol_reference(const char * name,size_t length)1182*fae548d3Szrj Script_options::add_symbol_reference(const char* name, size_t length)
1183*fae548d3Szrj {
1184*fae548d3Szrj   if (length != 1 || name[0] != '.')
1185*fae548d3Szrj     {
1186*fae548d3Szrj       std::string n(name, length);
1187*fae548d3Szrj       if (this->symbol_definitions_.find(n) == this->symbol_definitions_.end())
1188*fae548d3Szrj 	this->symbol_references_.insert(n);
1189*fae548d3Szrj     }
1190*fae548d3Szrj }
1191*fae548d3Szrj 
1192*fae548d3Szrj // Add an assertion.
1193*fae548d3Szrj 
1194*fae548d3Szrj void
add_assertion(Expression * check,const char * message,size_t messagelen)1195*fae548d3Szrj Script_options::add_assertion(Expression* check, const char* message,
1196*fae548d3Szrj 			      size_t messagelen)
1197*fae548d3Szrj {
1198*fae548d3Szrj   if (this->script_sections_.in_sections_clause())
1199*fae548d3Szrj     this->script_sections_.add_assertion(check, message, messagelen);
1200*fae548d3Szrj   else
1201*fae548d3Szrj     {
1202*fae548d3Szrj       Script_assertion* p = new Script_assertion(check, message, messagelen);
1203*fae548d3Szrj       this->assertions_.push_back(p);
1204*fae548d3Szrj     }
1205*fae548d3Szrj }
1206*fae548d3Szrj 
1207*fae548d3Szrj // Create sections required by any linker scripts.
1208*fae548d3Szrj 
1209*fae548d3Szrj void
create_script_sections(Layout * layout)1210*fae548d3Szrj Script_options::create_script_sections(Layout* layout)
1211*fae548d3Szrj {
1212*fae548d3Szrj   if (this->saw_sections_clause())
1213*fae548d3Szrj     this->script_sections_.create_sections(layout);
1214*fae548d3Szrj }
1215*fae548d3Szrj 
1216*fae548d3Szrj // Add any symbols we are defining to the symbol table.
1217*fae548d3Szrj 
1218*fae548d3Szrj void
add_symbols_to_table(Symbol_table * symtab)1219*fae548d3Szrj Script_options::add_symbols_to_table(Symbol_table* symtab)
1220*fae548d3Szrj {
1221*fae548d3Szrj   for (Symbol_assignments::iterator p = this->symbol_assignments_.begin();
1222*fae548d3Szrj        p != this->symbol_assignments_.end();
1223*fae548d3Szrj        ++p)
1224*fae548d3Szrj     (*p)->add_to_table(symtab);
1225*fae548d3Szrj   this->script_sections_.add_symbols_to_table(symtab);
1226*fae548d3Szrj }
1227*fae548d3Szrj 
1228*fae548d3Szrj // Finalize symbol values.  Also check assertions.
1229*fae548d3Szrj 
1230*fae548d3Szrj void
finalize_symbols(Symbol_table * symtab,const Layout * layout)1231*fae548d3Szrj Script_options::finalize_symbols(Symbol_table* symtab, const Layout* layout)
1232*fae548d3Szrj {
1233*fae548d3Szrj   // We finalize the symbols defined in SECTIONS first, because they
1234*fae548d3Szrj   // are the ones which may have changed.  This way if symbol outside
1235*fae548d3Szrj   // SECTIONS are defined in terms of symbols inside SECTIONS, they
1236*fae548d3Szrj   // will get the right value.
1237*fae548d3Szrj   this->script_sections_.finalize_symbols(symtab, layout);
1238*fae548d3Szrj 
1239*fae548d3Szrj   for (Symbol_assignments::iterator p = this->symbol_assignments_.begin();
1240*fae548d3Szrj        p != this->symbol_assignments_.end();
1241*fae548d3Szrj        ++p)
1242*fae548d3Szrj     (*p)->finalize(symtab, layout);
1243*fae548d3Szrj 
1244*fae548d3Szrj   for (Assertions::iterator p = this->assertions_.begin();
1245*fae548d3Szrj        p != this->assertions_.end();
1246*fae548d3Szrj        ++p)
1247*fae548d3Szrj     (*p)->check(symtab, layout);
1248*fae548d3Szrj }
1249*fae548d3Szrj 
1250*fae548d3Szrj // Set section addresses.  We set all the symbols which have absolute
1251*fae548d3Szrj // values.  Then we let the SECTIONS clause do its thing.  This
1252*fae548d3Szrj // returns the segment which holds the file header and segment
1253*fae548d3Szrj // headers, if any.
1254*fae548d3Szrj 
1255*fae548d3Szrj Output_segment*
set_section_addresses(Symbol_table * symtab,Layout * layout)1256*fae548d3Szrj Script_options::set_section_addresses(Symbol_table* symtab, Layout* layout)
1257*fae548d3Szrj {
1258*fae548d3Szrj   for (Symbol_assignments::iterator p = this->symbol_assignments_.begin();
1259*fae548d3Szrj        p != this->symbol_assignments_.end();
1260*fae548d3Szrj        ++p)
1261*fae548d3Szrj     (*p)->set_if_absolute(symtab, layout, false, 0, NULL);
1262*fae548d3Szrj 
1263*fae548d3Szrj   return this->script_sections_.set_section_addresses(symtab, layout);
1264*fae548d3Szrj }
1265*fae548d3Szrj 
1266*fae548d3Szrj // This class holds data passed through the parser to the lexer and to
1267*fae548d3Szrj // the parser support functions.  This avoids global variables.  We
1268*fae548d3Szrj // can't use global variables because we need not be called by a
1269*fae548d3Szrj // singleton thread.
1270*fae548d3Szrj 
1271*fae548d3Szrj class Parser_closure
1272*fae548d3Szrj {
1273*fae548d3Szrj  public:
Parser_closure(const char * filename,const Position_dependent_options & posdep_options,bool parsing_defsym,bool in_group,bool is_in_sysroot,Command_line * command_line,Script_options * script_options,Lex * lex,bool skip_on_incompatible_target,Script_info * script_info)1274*fae548d3Szrj   Parser_closure(const char* filename,
1275*fae548d3Szrj 		 const Position_dependent_options& posdep_options,
1276*fae548d3Szrj 		 bool parsing_defsym, bool in_group, bool is_in_sysroot,
1277*fae548d3Szrj                  Command_line* command_line,
1278*fae548d3Szrj 		 Script_options* script_options,
1279*fae548d3Szrj 		 Lex* lex,
1280*fae548d3Szrj 		 bool skip_on_incompatible_target,
1281*fae548d3Szrj 		 Script_info* script_info)
1282*fae548d3Szrj     : filename_(filename), posdep_options_(posdep_options),
1283*fae548d3Szrj       parsing_defsym_(parsing_defsym), in_group_(in_group),
1284*fae548d3Szrj       is_in_sysroot_(is_in_sysroot),
1285*fae548d3Szrj       skip_on_incompatible_target_(skip_on_incompatible_target),
1286*fae548d3Szrj       found_incompatible_target_(false),
1287*fae548d3Szrj       command_line_(command_line), script_options_(script_options),
1288*fae548d3Szrj       version_script_info_(script_options->version_script_info()),
1289*fae548d3Szrj       lex_(lex), lineno_(0), charpos_(0), lex_mode_stack_(), inputs_(NULL),
1290*fae548d3Szrj       script_info_(script_info)
1291*fae548d3Szrj   {
1292*fae548d3Szrj     // We start out processing C symbols in the default lex mode.
1293*fae548d3Szrj     this->language_stack_.push_back(Version_script_info::LANGUAGE_C);
1294*fae548d3Szrj     this->lex_mode_stack_.push_back(lex->mode());
1295*fae548d3Szrj   }
1296*fae548d3Szrj 
1297*fae548d3Szrj   // Return the file name.
1298*fae548d3Szrj   const char*
filename() const1299*fae548d3Szrj   filename() const
1300*fae548d3Szrj   { return this->filename_; }
1301*fae548d3Szrj 
1302*fae548d3Szrj   // Return the position dependent options.  The caller may modify
1303*fae548d3Szrj   // this.
1304*fae548d3Szrj   Position_dependent_options&
position_dependent_options()1305*fae548d3Szrj   position_dependent_options()
1306*fae548d3Szrj   { return this->posdep_options_; }
1307*fae548d3Szrj 
1308*fae548d3Szrj   // Whether we are parsing a --defsym.
1309*fae548d3Szrj   bool
parsing_defsym() const1310*fae548d3Szrj   parsing_defsym() const
1311*fae548d3Szrj   { return this->parsing_defsym_; }
1312*fae548d3Szrj 
1313*fae548d3Szrj   // Return whether this script is being run in a group.
1314*fae548d3Szrj   bool
in_group() const1315*fae548d3Szrj   in_group() const
1316*fae548d3Szrj   { return this->in_group_; }
1317*fae548d3Szrj 
1318*fae548d3Szrj   // Return whether this script was found using a directory in the
1319*fae548d3Szrj   // sysroot.
1320*fae548d3Szrj   bool
is_in_sysroot() const1321*fae548d3Szrj   is_in_sysroot() const
1322*fae548d3Szrj   { return this->is_in_sysroot_; }
1323*fae548d3Szrj 
1324*fae548d3Szrj   // Whether to skip to the next file with the same name if we find an
1325*fae548d3Szrj   // incompatible target in an OUTPUT_FORMAT statement.
1326*fae548d3Szrj   bool
skip_on_incompatible_target() const1327*fae548d3Szrj   skip_on_incompatible_target() const
1328*fae548d3Szrj   { return this->skip_on_incompatible_target_; }
1329*fae548d3Szrj 
1330*fae548d3Szrj   // Stop skipping to the next file on an incompatible target.  This
1331*fae548d3Szrj   // is called when we make some unrevocable change to the data
1332*fae548d3Szrj   // structures.
1333*fae548d3Szrj   void
clear_skip_on_incompatible_target()1334*fae548d3Szrj   clear_skip_on_incompatible_target()
1335*fae548d3Szrj   { this->skip_on_incompatible_target_ = false; }
1336*fae548d3Szrj 
1337*fae548d3Szrj   // Whether we found an incompatible target in an OUTPUT_FORMAT
1338*fae548d3Szrj   // statement.
1339*fae548d3Szrj   bool
found_incompatible_target() const1340*fae548d3Szrj   found_incompatible_target() const
1341*fae548d3Szrj   { return this->found_incompatible_target_; }
1342*fae548d3Szrj 
1343*fae548d3Szrj   // Note that we found an incompatible target.
1344*fae548d3Szrj   void
set_found_incompatible_target()1345*fae548d3Szrj   set_found_incompatible_target()
1346*fae548d3Szrj   { this->found_incompatible_target_ = true; }
1347*fae548d3Szrj 
1348*fae548d3Szrj   // Returns the Command_line structure passed in at constructor time.
1349*fae548d3Szrj   // This value may be NULL.  The caller may modify this, which modifies
1350*fae548d3Szrj   // the passed-in Command_line object (not a copy).
1351*fae548d3Szrj   Command_line*
command_line()1352*fae548d3Szrj   command_line()
1353*fae548d3Szrj   { return this->command_line_; }
1354*fae548d3Szrj 
1355*fae548d3Szrj   // Return the options which may be set by a script.
1356*fae548d3Szrj   Script_options*
script_options()1357*fae548d3Szrj   script_options()
1358*fae548d3Szrj   { return this->script_options_; }
1359*fae548d3Szrj 
1360*fae548d3Szrj   // Return the object in which version script information should be stored.
1361*fae548d3Szrj   Version_script_info*
version_script()1362*fae548d3Szrj   version_script()
1363*fae548d3Szrj   { return this->version_script_info_; }
1364*fae548d3Szrj 
1365*fae548d3Szrj   // Return the next token, and advance.
1366*fae548d3Szrj   const Token*
next_token()1367*fae548d3Szrj   next_token()
1368*fae548d3Szrj   {
1369*fae548d3Szrj     const Token* token = this->lex_->next_token();
1370*fae548d3Szrj     this->lineno_ = token->lineno();
1371*fae548d3Szrj     this->charpos_ = token->charpos();
1372*fae548d3Szrj     return token;
1373*fae548d3Szrj   }
1374*fae548d3Szrj 
1375*fae548d3Szrj   // Set a new lexer mode, pushing the current one.
1376*fae548d3Szrj   void
push_lex_mode(Lex::Mode mode)1377*fae548d3Szrj   push_lex_mode(Lex::Mode mode)
1378*fae548d3Szrj   {
1379*fae548d3Szrj     this->lex_mode_stack_.push_back(this->lex_->mode());
1380*fae548d3Szrj     this->lex_->set_mode(mode);
1381*fae548d3Szrj   }
1382*fae548d3Szrj 
1383*fae548d3Szrj   // Pop the lexer mode.
1384*fae548d3Szrj   void
pop_lex_mode()1385*fae548d3Szrj   pop_lex_mode()
1386*fae548d3Szrj   {
1387*fae548d3Szrj     gold_assert(!this->lex_mode_stack_.empty());
1388*fae548d3Szrj     this->lex_->set_mode(this->lex_mode_stack_.back());
1389*fae548d3Szrj     this->lex_mode_stack_.pop_back();
1390*fae548d3Szrj   }
1391*fae548d3Szrj 
1392*fae548d3Szrj   // Return the current lexer mode.
1393*fae548d3Szrj   Lex::Mode
lex_mode() const1394*fae548d3Szrj   lex_mode() const
1395*fae548d3Szrj   { return this->lex_mode_stack_.back(); }
1396*fae548d3Szrj 
1397*fae548d3Szrj   // Return the line number of the last token.
1398*fae548d3Szrj   int
lineno() const1399*fae548d3Szrj   lineno() const
1400*fae548d3Szrj   { return this->lineno_; }
1401*fae548d3Szrj 
1402*fae548d3Szrj   // Return the character position in the line of the last token.
1403*fae548d3Szrj   int
charpos() const1404*fae548d3Szrj   charpos() const
1405*fae548d3Szrj   { return this->charpos_; }
1406*fae548d3Szrj 
1407*fae548d3Szrj   // Return the list of input files, creating it if necessary.  This
1408*fae548d3Szrj   // is a space leak--we never free the INPUTS_ pointer.
1409*fae548d3Szrj   Input_arguments*
inputs()1410*fae548d3Szrj   inputs()
1411*fae548d3Szrj   {
1412*fae548d3Szrj     if (this->inputs_ == NULL)
1413*fae548d3Szrj       this->inputs_ = new Input_arguments();
1414*fae548d3Szrj     return this->inputs_;
1415*fae548d3Szrj   }
1416*fae548d3Szrj 
1417*fae548d3Szrj   // Return whether we saw any input files.
1418*fae548d3Szrj   bool
saw_inputs() const1419*fae548d3Szrj   saw_inputs() const
1420*fae548d3Szrj   { return this->inputs_ != NULL && !this->inputs_->empty(); }
1421*fae548d3Szrj 
1422*fae548d3Szrj   // Return the current language being processed in a version script
1423*fae548d3Szrj   // (eg, "C++").  The empty string represents unmangled C names.
1424*fae548d3Szrj   Version_script_info::Language
get_current_language() const1425*fae548d3Szrj   get_current_language() const
1426*fae548d3Szrj   { return this->language_stack_.back(); }
1427*fae548d3Szrj 
1428*fae548d3Szrj   // Push a language onto the stack when entering an extern block.
1429*fae548d3Szrj   void
push_language(Version_script_info::Language lang)1430*fae548d3Szrj   push_language(Version_script_info::Language lang)
1431*fae548d3Szrj   { this->language_stack_.push_back(lang); }
1432*fae548d3Szrj 
1433*fae548d3Szrj   // Pop a language off of the stack when exiting an extern block.
1434*fae548d3Szrj   void
pop_language()1435*fae548d3Szrj   pop_language()
1436*fae548d3Szrj   {
1437*fae548d3Szrj     gold_assert(!this->language_stack_.empty());
1438*fae548d3Szrj     this->language_stack_.pop_back();
1439*fae548d3Szrj   }
1440*fae548d3Szrj 
1441*fae548d3Szrj   // Return a pointer to the incremental info.
1442*fae548d3Szrj   Script_info*
script_info()1443*fae548d3Szrj   script_info()
1444*fae548d3Szrj   { return this->script_info_; }
1445*fae548d3Szrj 
1446*fae548d3Szrj  private:
1447*fae548d3Szrj   // The name of the file we are reading.
1448*fae548d3Szrj   const char* filename_;
1449*fae548d3Szrj   // The position dependent options.
1450*fae548d3Szrj   Position_dependent_options posdep_options_;
1451*fae548d3Szrj   // True if we are parsing a --defsym.
1452*fae548d3Szrj   bool parsing_defsym_;
1453*fae548d3Szrj   // Whether we are currently in a --start-group/--end-group.
1454*fae548d3Szrj   bool in_group_;
1455*fae548d3Szrj   // Whether the script was found in a sysrooted directory.
1456*fae548d3Szrj   bool is_in_sysroot_;
1457*fae548d3Szrj   // If this is true, then if we find an OUTPUT_FORMAT with an
1458*fae548d3Szrj   // incompatible target, then we tell the parser to abort so that we
1459*fae548d3Szrj   // can search for the next file with the same name.
1460*fae548d3Szrj   bool skip_on_incompatible_target_;
1461*fae548d3Szrj   // True if we found an OUTPUT_FORMAT with an incompatible target.
1462*fae548d3Szrj   bool found_incompatible_target_;
1463*fae548d3Szrj   // May be NULL if the user chooses not to pass one in.
1464*fae548d3Szrj   Command_line* command_line_;
1465*fae548d3Szrj   // Options which may be set from any linker script.
1466*fae548d3Szrj   Script_options* script_options_;
1467*fae548d3Szrj   // Information parsed from a version script.
1468*fae548d3Szrj   Version_script_info* version_script_info_;
1469*fae548d3Szrj   // The lexer.
1470*fae548d3Szrj   Lex* lex_;
1471*fae548d3Szrj   // The line number of the last token returned by next_token.
1472*fae548d3Szrj   int lineno_;
1473*fae548d3Szrj   // The column number of the last token returned by next_token.
1474*fae548d3Szrj   int charpos_;
1475*fae548d3Szrj   // A stack of lexer modes.
1476*fae548d3Szrj   std::vector<Lex::Mode> lex_mode_stack_;
1477*fae548d3Szrj   // A stack of which extern/language block we're inside. Can be C++,
1478*fae548d3Szrj   // java, or empty for C.
1479*fae548d3Szrj   std::vector<Version_script_info::Language> language_stack_;
1480*fae548d3Szrj   // New input files found to add to the link.
1481*fae548d3Szrj   Input_arguments* inputs_;
1482*fae548d3Szrj   // Pointer to incremental linking info.
1483*fae548d3Szrj   Script_info* script_info_;
1484*fae548d3Szrj };
1485*fae548d3Szrj 
1486*fae548d3Szrj // FILE was found as an argument on the command line.  Try to read it
1487*fae548d3Szrj // as a script.  Return true if the file was handled.
1488*fae548d3Szrj 
1489*fae548d3Szrj bool
read_input_script(Workqueue * workqueue,Symbol_table * symtab,Layout * layout,Dirsearch * dirsearch,int dirindex,Input_objects * input_objects,Mapfile * mapfile,Input_group * input_group,const Input_argument * input_argument,Input_file * input_file,Task_token * next_blocker,bool * used_next_blocker)1490*fae548d3Szrj read_input_script(Workqueue* workqueue, Symbol_table* symtab, Layout* layout,
1491*fae548d3Szrj 		  Dirsearch* dirsearch, int dirindex,
1492*fae548d3Szrj 		  Input_objects* input_objects, Mapfile* mapfile,
1493*fae548d3Szrj 		  Input_group* input_group,
1494*fae548d3Szrj 		  const Input_argument* input_argument,
1495*fae548d3Szrj 		  Input_file* input_file, Task_token* next_blocker,
1496*fae548d3Szrj 		  bool* used_next_blocker)
1497*fae548d3Szrj {
1498*fae548d3Szrj   *used_next_blocker = false;
1499*fae548d3Szrj 
1500*fae548d3Szrj   std::string input_string;
1501*fae548d3Szrj   Lex::read_file(input_file, &input_string);
1502*fae548d3Szrj 
1503*fae548d3Szrj   Lex lex(input_string.c_str(), input_string.length(), PARSING_LINKER_SCRIPT);
1504*fae548d3Szrj 
1505*fae548d3Szrj   Script_info* script_info = NULL;
1506*fae548d3Szrj   if (layout->incremental_inputs() != NULL)
1507*fae548d3Szrj     {
1508*fae548d3Szrj       const std::string& filename = input_file->filename();
1509*fae548d3Szrj       Timespec mtime = input_file->file().get_mtime();
1510*fae548d3Szrj       unsigned int arg_serial = input_argument->file().arg_serial();
1511*fae548d3Szrj       script_info = new Script_info(filename);
1512*fae548d3Szrj       layout->incremental_inputs()->report_script(script_info, arg_serial,
1513*fae548d3Szrj 						  mtime);
1514*fae548d3Szrj     }
1515*fae548d3Szrj 
1516*fae548d3Szrj   Parser_closure closure(input_file->filename().c_str(),
1517*fae548d3Szrj 			 input_argument->file().options(),
1518*fae548d3Szrj 			 false,
1519*fae548d3Szrj 			 input_group != NULL,
1520*fae548d3Szrj 			 input_file->is_in_sysroot(),
1521*fae548d3Szrj                          NULL,
1522*fae548d3Szrj 			 layout->script_options(),
1523*fae548d3Szrj 			 &lex,
1524*fae548d3Szrj 			 input_file->will_search_for(),
1525*fae548d3Szrj 			 script_info);
1526*fae548d3Szrj 
1527*fae548d3Szrj   bool old_saw_sections_clause =
1528*fae548d3Szrj     layout->script_options()->saw_sections_clause();
1529*fae548d3Szrj 
1530*fae548d3Szrj   if (yyparse(&closure) != 0)
1531*fae548d3Szrj     {
1532*fae548d3Szrj       if (closure.found_incompatible_target())
1533*fae548d3Szrj 	{
1534*fae548d3Szrj 	  Read_symbols::incompatible_warning(input_argument, input_file);
1535*fae548d3Szrj 	  Read_symbols::requeue(workqueue, input_objects, symtab, layout,
1536*fae548d3Szrj 				dirsearch, dirindex, mapfile, input_argument,
1537*fae548d3Szrj 				input_group, next_blocker);
1538*fae548d3Szrj 	  return true;
1539*fae548d3Szrj 	}
1540*fae548d3Szrj       return false;
1541*fae548d3Szrj     }
1542*fae548d3Szrj 
1543*fae548d3Szrj   if (!old_saw_sections_clause
1544*fae548d3Szrj       && layout->script_options()->saw_sections_clause()
1545*fae548d3Szrj       && layout->have_added_input_section())
1546*fae548d3Szrj     gold_error(_("%s: SECTIONS seen after other input files; try -T/--script"),
1547*fae548d3Szrj 	       input_file->filename().c_str());
1548*fae548d3Szrj 
1549*fae548d3Szrj   if (!closure.saw_inputs())
1550*fae548d3Szrj     return true;
1551*fae548d3Szrj 
1552*fae548d3Szrj   Task_token* this_blocker = NULL;
1553*fae548d3Szrj   for (Input_arguments::const_iterator p = closure.inputs()->begin();
1554*fae548d3Szrj        p != closure.inputs()->end();
1555*fae548d3Szrj        ++p)
1556*fae548d3Szrj     {
1557*fae548d3Szrj       Task_token* nb;
1558*fae548d3Szrj       if (p + 1 == closure.inputs()->end())
1559*fae548d3Szrj 	nb = next_blocker;
1560*fae548d3Szrj       else
1561*fae548d3Szrj 	{
1562*fae548d3Szrj 	  nb = new Task_token(true);
1563*fae548d3Szrj 	  nb->add_blocker();
1564*fae548d3Szrj 	}
1565*fae548d3Szrj       workqueue->queue_soon(new Read_symbols(input_objects, symtab,
1566*fae548d3Szrj 					     layout, dirsearch, 0, mapfile, &*p,
1567*fae548d3Szrj 					     input_group, NULL, this_blocker, nb));
1568*fae548d3Szrj       this_blocker = nb;
1569*fae548d3Szrj     }
1570*fae548d3Szrj 
1571*fae548d3Szrj   *used_next_blocker = true;
1572*fae548d3Szrj 
1573*fae548d3Szrj   return true;
1574*fae548d3Szrj }
1575*fae548d3Szrj 
1576*fae548d3Szrj // Helper function for read_version_script(), read_commandline_script() and
1577*fae548d3Szrj // script_include_directive().  Processes the given file in the mode indicated
1578*fae548d3Szrj // by first_token and lex_mode.
1579*fae548d3Szrj 
1580*fae548d3Szrj static bool
read_script_file(const char * filename,Command_line * cmdline,Script_options * script_options,int first_token,Lex::Mode lex_mode)1581*fae548d3Szrj read_script_file(const char* filename, Command_line* cmdline,
1582*fae548d3Szrj                  Script_options* script_options,
1583*fae548d3Szrj                  int first_token, Lex::Mode lex_mode)
1584*fae548d3Szrj {
1585*fae548d3Szrj   Dirsearch dirsearch;
1586*fae548d3Szrj   std::string name = filename;
1587*fae548d3Szrj 
1588*fae548d3Szrj   // If filename is a relative filename, search for it manually using "." +
1589*fae548d3Szrj   // cmdline->options()->library_path() -- not dirsearch.
1590*fae548d3Szrj   if (!IS_ABSOLUTE_PATH(filename))
1591*fae548d3Szrj     {
1592*fae548d3Szrj       const General_options::Dir_list& search_path =
1593*fae548d3Szrj           cmdline->options().library_path();
1594*fae548d3Szrj       name = Dirsearch::find_file_in_dir_list(name, search_path, ".");
1595*fae548d3Szrj     }
1596*fae548d3Szrj 
1597*fae548d3Szrj   // The file locking code wants to record a Task, but we haven't
1598*fae548d3Szrj   // started the workqueue yet.  This is only for debugging purposes,
1599*fae548d3Szrj   // so we invent a fake value.
1600*fae548d3Szrj   const Task* task = reinterpret_cast<const Task*>(-1);
1601*fae548d3Szrj 
1602*fae548d3Szrj   // We don't want this file to be opened in binary mode.
1603*fae548d3Szrj   Position_dependent_options posdep = cmdline->position_dependent_options();
1604*fae548d3Szrj   if (posdep.format_enum() == General_options::OBJECT_FORMAT_BINARY)
1605*fae548d3Szrj     posdep.set_format_enum(General_options::OBJECT_FORMAT_ELF);
1606*fae548d3Szrj   Input_file_argument input_argument(name.c_str(),
1607*fae548d3Szrj 				     Input_file_argument::INPUT_FILE_TYPE_FILE,
1608*fae548d3Szrj 				     "", false, posdep);
1609*fae548d3Szrj   Input_file input_file(&input_argument);
1610*fae548d3Szrj   int dummy = 0;
1611*fae548d3Szrj   if (!input_file.open(dirsearch, task, &dummy))
1612*fae548d3Szrj     return false;
1613*fae548d3Szrj 
1614*fae548d3Szrj   std::string input_string;
1615*fae548d3Szrj   Lex::read_file(&input_file, &input_string);
1616*fae548d3Szrj 
1617*fae548d3Szrj   Lex lex(input_string.c_str(), input_string.length(), first_token);
1618*fae548d3Szrj   lex.set_mode(lex_mode);
1619*fae548d3Szrj 
1620*fae548d3Szrj   Parser_closure closure(filename,
1621*fae548d3Szrj 			 cmdline->position_dependent_options(),
1622*fae548d3Szrj 			 first_token == Lex::DYNAMIC_LIST,
1623*fae548d3Szrj 			 false,
1624*fae548d3Szrj 			 input_file.is_in_sysroot(),
1625*fae548d3Szrj                          cmdline,
1626*fae548d3Szrj 			 script_options,
1627*fae548d3Szrj 			 &lex,
1628*fae548d3Szrj 			 false,
1629*fae548d3Szrj 			 NULL);
1630*fae548d3Szrj   if (yyparse(&closure) != 0)
1631*fae548d3Szrj     {
1632*fae548d3Szrj       input_file.file().unlock(task);
1633*fae548d3Szrj       return false;
1634*fae548d3Szrj     }
1635*fae548d3Szrj 
1636*fae548d3Szrj   input_file.file().unlock(task);
1637*fae548d3Szrj 
1638*fae548d3Szrj   gold_assert(!closure.saw_inputs());
1639*fae548d3Szrj 
1640*fae548d3Szrj   return true;
1641*fae548d3Szrj }
1642*fae548d3Szrj 
1643*fae548d3Szrj // FILENAME was found as an argument to --script (-T).
1644*fae548d3Szrj // Read it as a script, and execute its contents immediately.
1645*fae548d3Szrj 
1646*fae548d3Szrj bool
read_commandline_script(const char * filename,Command_line * cmdline)1647*fae548d3Szrj read_commandline_script(const char* filename, Command_line* cmdline)
1648*fae548d3Szrj {
1649*fae548d3Szrj   return read_script_file(filename, cmdline, &cmdline->script_options(),
1650*fae548d3Szrj                           PARSING_LINKER_SCRIPT, Lex::LINKER_SCRIPT);
1651*fae548d3Szrj }
1652*fae548d3Szrj 
1653*fae548d3Szrj // FILENAME was found as an argument to --version-script.  Read it as
1654*fae548d3Szrj // a version script, and store its contents in
1655*fae548d3Szrj // cmdline->script_options()->version_script_info().
1656*fae548d3Szrj 
1657*fae548d3Szrj bool
read_version_script(const char * filename,Command_line * cmdline)1658*fae548d3Szrj read_version_script(const char* filename, Command_line* cmdline)
1659*fae548d3Szrj {
1660*fae548d3Szrj   return read_script_file(filename, cmdline, &cmdline->script_options(),
1661*fae548d3Szrj                           PARSING_VERSION_SCRIPT, Lex::VERSION_SCRIPT);
1662*fae548d3Szrj }
1663*fae548d3Szrj 
1664*fae548d3Szrj // FILENAME was found as an argument to --dynamic-list.  Read it as a
1665*fae548d3Szrj // list of symbols, and store its contents in DYNAMIC_LIST.
1666*fae548d3Szrj 
1667*fae548d3Szrj bool
read_dynamic_list(const char * filename,Command_line * cmdline,Script_options * dynamic_list)1668*fae548d3Szrj read_dynamic_list(const char* filename, Command_line* cmdline,
1669*fae548d3Szrj                   Script_options* dynamic_list)
1670*fae548d3Szrj {
1671*fae548d3Szrj   return read_script_file(filename, cmdline, dynamic_list,
1672*fae548d3Szrj                           PARSING_DYNAMIC_LIST, Lex::DYNAMIC_LIST);
1673*fae548d3Szrj }
1674*fae548d3Szrj 
1675*fae548d3Szrj // Implement the --defsym option on the command line.  Return true if
1676*fae548d3Szrj // all is well.
1677*fae548d3Szrj 
1678*fae548d3Szrj bool
define_symbol(const char * definition)1679*fae548d3Szrj Script_options::define_symbol(const char* definition)
1680*fae548d3Szrj {
1681*fae548d3Szrj   Lex lex(definition, strlen(definition), PARSING_DEFSYM);
1682*fae548d3Szrj   lex.set_mode(Lex::EXPRESSION);
1683*fae548d3Szrj 
1684*fae548d3Szrj   // Dummy value.
1685*fae548d3Szrj   Position_dependent_options posdep_options;
1686*fae548d3Szrj 
1687*fae548d3Szrj   Parser_closure closure("command line", posdep_options, true,
1688*fae548d3Szrj 			 false, false, NULL, this, &lex, false, NULL);
1689*fae548d3Szrj 
1690*fae548d3Szrj   if (yyparse(&closure) != 0)
1691*fae548d3Szrj     return false;
1692*fae548d3Szrj 
1693*fae548d3Szrj   gold_assert(!closure.saw_inputs());
1694*fae548d3Szrj 
1695*fae548d3Szrj   return true;
1696*fae548d3Szrj }
1697*fae548d3Szrj 
1698*fae548d3Szrj // Print the script to F for debugging.
1699*fae548d3Szrj 
1700*fae548d3Szrj void
print(FILE * f) const1701*fae548d3Szrj Script_options::print(FILE* f) const
1702*fae548d3Szrj {
1703*fae548d3Szrj   fprintf(f, "%s: Dumping linker script\n", program_name);
1704*fae548d3Szrj 
1705*fae548d3Szrj   if (!this->entry_.empty())
1706*fae548d3Szrj     fprintf(f, "ENTRY(%s)\n", this->entry_.c_str());
1707*fae548d3Szrj 
1708*fae548d3Szrj   for (Symbol_assignments::const_iterator p =
1709*fae548d3Szrj 	 this->symbol_assignments_.begin();
1710*fae548d3Szrj        p != this->symbol_assignments_.end();
1711*fae548d3Szrj        ++p)
1712*fae548d3Szrj     (*p)->print(f);
1713*fae548d3Szrj 
1714*fae548d3Szrj   for (Assertions::const_iterator p = this->assertions_.begin();
1715*fae548d3Szrj        p != this->assertions_.end();
1716*fae548d3Szrj        ++p)
1717*fae548d3Szrj     (*p)->print(f);
1718*fae548d3Szrj 
1719*fae548d3Szrj   this->script_sections_.print(f);
1720*fae548d3Szrj 
1721*fae548d3Szrj   this->version_script_info_.print(f);
1722*fae548d3Szrj }
1723*fae548d3Szrj 
1724*fae548d3Szrj // Manage mapping from keywords to the codes expected by the bison
1725*fae548d3Szrj // parser.  We construct one global object for each lex mode with
1726*fae548d3Szrj // keywords.
1727*fae548d3Szrj 
1728*fae548d3Szrj class Keyword_to_parsecode
1729*fae548d3Szrj {
1730*fae548d3Szrj  public:
1731*fae548d3Szrj   // The structure which maps keywords to parsecodes.
1732*fae548d3Szrj   struct Keyword_parsecode
1733*fae548d3Szrj   {
1734*fae548d3Szrj     // Keyword.
1735*fae548d3Szrj     const char* keyword;
1736*fae548d3Szrj     // Corresponding parsecode.
1737*fae548d3Szrj     int parsecode;
1738*fae548d3Szrj   };
1739*fae548d3Szrj 
Keyword_to_parsecode(const Keyword_parsecode * keywords,int keyword_count)1740*fae548d3Szrj   Keyword_to_parsecode(const Keyword_parsecode* keywords,
1741*fae548d3Szrj                        int keyword_count)
1742*fae548d3Szrj       : keyword_parsecodes_(keywords), keyword_count_(keyword_count)
1743*fae548d3Szrj   { }
1744*fae548d3Szrj 
1745*fae548d3Szrj   // Return the parsecode corresponding KEYWORD, or 0 if it is not a
1746*fae548d3Szrj   // keyword.
1747*fae548d3Szrj   int
1748*fae548d3Szrj   keyword_to_parsecode(const char* keyword, size_t len) const;
1749*fae548d3Szrj 
1750*fae548d3Szrj  private:
1751*fae548d3Szrj   const Keyword_parsecode* keyword_parsecodes_;
1752*fae548d3Szrj   const int keyword_count_;
1753*fae548d3Szrj };
1754*fae548d3Szrj 
1755*fae548d3Szrj // Mapping from keyword string to keyword parsecode.  This array must
1756*fae548d3Szrj // be kept in sorted order.  Parsecodes are looked up using bsearch.
1757*fae548d3Szrj // This array must correspond to the list of parsecodes in yyscript.y.
1758*fae548d3Szrj 
1759*fae548d3Szrj static const Keyword_to_parsecode::Keyword_parsecode
1760*fae548d3Szrj script_keyword_parsecodes[] =
1761*fae548d3Szrj {
1762*fae548d3Szrj   { "ABSOLUTE", ABSOLUTE },
1763*fae548d3Szrj   { "ADDR", ADDR },
1764*fae548d3Szrj   { "ALIGN", ALIGN_K },
1765*fae548d3Szrj   { "ALIGNOF", ALIGNOF },
1766*fae548d3Szrj   { "ASSERT", ASSERT_K },
1767*fae548d3Szrj   { "AS_NEEDED", AS_NEEDED },
1768*fae548d3Szrj   { "AT", AT },
1769*fae548d3Szrj   { "BIND", BIND },
1770*fae548d3Szrj   { "BLOCK", BLOCK },
1771*fae548d3Szrj   { "BYTE", BYTE },
1772*fae548d3Szrj   { "CONSTANT", CONSTANT },
1773*fae548d3Szrj   { "CONSTRUCTORS", CONSTRUCTORS },
1774*fae548d3Szrj   { "COPY", COPY },
1775*fae548d3Szrj   { "CREATE_OBJECT_SYMBOLS", CREATE_OBJECT_SYMBOLS },
1776*fae548d3Szrj   { "DATA_SEGMENT_ALIGN", DATA_SEGMENT_ALIGN },
1777*fae548d3Szrj   { "DATA_SEGMENT_END", DATA_SEGMENT_END },
1778*fae548d3Szrj   { "DATA_SEGMENT_RELRO_END", DATA_SEGMENT_RELRO_END },
1779*fae548d3Szrj   { "DEFINED", DEFINED },
1780*fae548d3Szrj   { "DSECT", DSECT },
1781*fae548d3Szrj   { "ENTRY", ENTRY },
1782*fae548d3Szrj   { "EXCLUDE_FILE", EXCLUDE_FILE },
1783*fae548d3Szrj   { "EXTERN", EXTERN },
1784*fae548d3Szrj   { "FILL", FILL },
1785*fae548d3Szrj   { "FLOAT", FLOAT },
1786*fae548d3Szrj   { "FORCE_COMMON_ALLOCATION", FORCE_COMMON_ALLOCATION },
1787*fae548d3Szrj   { "GROUP", GROUP },
1788*fae548d3Szrj   { "HIDDEN", HIDDEN },
1789*fae548d3Szrj   { "HLL", HLL },
1790*fae548d3Szrj   { "INCLUDE", INCLUDE },
1791*fae548d3Szrj   { "INFO", INFO },
1792*fae548d3Szrj   { "INHIBIT_COMMON_ALLOCATION", INHIBIT_COMMON_ALLOCATION },
1793*fae548d3Szrj   { "INPUT", INPUT },
1794*fae548d3Szrj   { "KEEP", KEEP },
1795*fae548d3Szrj   { "LENGTH", LENGTH },
1796*fae548d3Szrj   { "LOADADDR", LOADADDR },
1797*fae548d3Szrj   { "LONG", LONG },
1798*fae548d3Szrj   { "MAP", MAP },
1799*fae548d3Szrj   { "MAX", MAX_K },
1800*fae548d3Szrj   { "MEMORY", MEMORY },
1801*fae548d3Szrj   { "MIN", MIN_K },
1802*fae548d3Szrj   { "NEXT", NEXT },
1803*fae548d3Szrj   { "NOCROSSREFS", NOCROSSREFS },
1804*fae548d3Szrj   { "NOFLOAT", NOFLOAT },
1805*fae548d3Szrj   { "NOLOAD", NOLOAD },
1806*fae548d3Szrj   { "ONLY_IF_RO", ONLY_IF_RO },
1807*fae548d3Szrj   { "ONLY_IF_RW", ONLY_IF_RW },
1808*fae548d3Szrj   { "OPTION", OPTION },
1809*fae548d3Szrj   { "ORIGIN", ORIGIN },
1810*fae548d3Szrj   { "OUTPUT", OUTPUT },
1811*fae548d3Szrj   { "OUTPUT_ARCH", OUTPUT_ARCH },
1812*fae548d3Szrj   { "OUTPUT_FORMAT", OUTPUT_FORMAT },
1813*fae548d3Szrj   { "OVERLAY", OVERLAY },
1814*fae548d3Szrj   { "PHDRS", PHDRS },
1815*fae548d3Szrj   { "PROVIDE", PROVIDE },
1816*fae548d3Szrj   { "PROVIDE_HIDDEN", PROVIDE_HIDDEN },
1817*fae548d3Szrj   { "QUAD", QUAD },
1818*fae548d3Szrj   { "SEARCH_DIR", SEARCH_DIR },
1819*fae548d3Szrj   { "SECTIONS", SECTIONS },
1820*fae548d3Szrj   { "SEGMENT_START", SEGMENT_START },
1821*fae548d3Szrj   { "SHORT", SHORT },
1822*fae548d3Szrj   { "SIZEOF", SIZEOF },
1823*fae548d3Szrj   { "SIZEOF_HEADERS", SIZEOF_HEADERS },
1824*fae548d3Szrj   { "SORT", SORT_BY_NAME },
1825*fae548d3Szrj   { "SORT_BY_ALIGNMENT", SORT_BY_ALIGNMENT },
1826*fae548d3Szrj   { "SORT_BY_INIT_PRIORITY", SORT_BY_INIT_PRIORITY },
1827*fae548d3Szrj   { "SORT_BY_NAME", SORT_BY_NAME },
1828*fae548d3Szrj   { "SPECIAL", SPECIAL },
1829*fae548d3Szrj   { "SQUAD", SQUAD },
1830*fae548d3Szrj   { "STARTUP", STARTUP },
1831*fae548d3Szrj   { "SUBALIGN", SUBALIGN },
1832*fae548d3Szrj   { "SYSLIB", SYSLIB },
1833*fae548d3Szrj   { "TARGET", TARGET_K },
1834*fae548d3Szrj   { "TRUNCATE", TRUNCATE },
1835*fae548d3Szrj   { "VERSION", VERSIONK },
1836*fae548d3Szrj   { "global", GLOBAL },
1837*fae548d3Szrj   { "l", LENGTH },
1838*fae548d3Szrj   { "len", LENGTH },
1839*fae548d3Szrj   { "local", LOCAL },
1840*fae548d3Szrj   { "o", ORIGIN },
1841*fae548d3Szrj   { "org", ORIGIN },
1842*fae548d3Szrj   { "sizeof_headers", SIZEOF_HEADERS },
1843*fae548d3Szrj };
1844*fae548d3Szrj 
1845*fae548d3Szrj static const Keyword_to_parsecode
1846*fae548d3Szrj script_keywords(&script_keyword_parsecodes[0],
1847*fae548d3Szrj                 (sizeof(script_keyword_parsecodes)
1848*fae548d3Szrj                  / sizeof(script_keyword_parsecodes[0])));
1849*fae548d3Szrj 
1850*fae548d3Szrj static const Keyword_to_parsecode::Keyword_parsecode
1851*fae548d3Szrj version_script_keyword_parsecodes[] =
1852*fae548d3Szrj {
1853*fae548d3Szrj   { "extern", EXTERN },
1854*fae548d3Szrj   { "global", GLOBAL },
1855*fae548d3Szrj   { "local", LOCAL },
1856*fae548d3Szrj };
1857*fae548d3Szrj 
1858*fae548d3Szrj static const Keyword_to_parsecode
1859*fae548d3Szrj version_script_keywords(&version_script_keyword_parsecodes[0],
1860*fae548d3Szrj                         (sizeof(version_script_keyword_parsecodes)
1861*fae548d3Szrj                          / sizeof(version_script_keyword_parsecodes[0])));
1862*fae548d3Szrj 
1863*fae548d3Szrj static const Keyword_to_parsecode::Keyword_parsecode
1864*fae548d3Szrj dynamic_list_keyword_parsecodes[] =
1865*fae548d3Szrj {
1866*fae548d3Szrj   { "extern", EXTERN },
1867*fae548d3Szrj };
1868*fae548d3Szrj 
1869*fae548d3Szrj static const Keyword_to_parsecode
1870*fae548d3Szrj dynamic_list_keywords(&dynamic_list_keyword_parsecodes[0],
1871*fae548d3Szrj                       (sizeof(dynamic_list_keyword_parsecodes)
1872*fae548d3Szrj                        / sizeof(dynamic_list_keyword_parsecodes[0])));
1873*fae548d3Szrj 
1874*fae548d3Szrj 
1875*fae548d3Szrj 
1876*fae548d3Szrj // Comparison function passed to bsearch.
1877*fae548d3Szrj 
1878*fae548d3Szrj extern "C"
1879*fae548d3Szrj {
1880*fae548d3Szrj 
1881*fae548d3Szrj struct Ktt_key
1882*fae548d3Szrj {
1883*fae548d3Szrj   const char* str;
1884*fae548d3Szrj   size_t len;
1885*fae548d3Szrj };
1886*fae548d3Szrj 
1887*fae548d3Szrj static int
ktt_compare(const void * keyv,const void * kttv)1888*fae548d3Szrj ktt_compare(const void* keyv, const void* kttv)
1889*fae548d3Szrj {
1890*fae548d3Szrj   const Ktt_key* key = static_cast<const Ktt_key*>(keyv);
1891*fae548d3Szrj   const Keyword_to_parsecode::Keyword_parsecode* ktt =
1892*fae548d3Szrj     static_cast<const Keyword_to_parsecode::Keyword_parsecode*>(kttv);
1893*fae548d3Szrj   int i = strncmp(key->str, ktt->keyword, key->len);
1894*fae548d3Szrj   if (i != 0)
1895*fae548d3Szrj     return i;
1896*fae548d3Szrj   if (ktt->keyword[key->len] != '\0')
1897*fae548d3Szrj     return -1;
1898*fae548d3Szrj   return 0;
1899*fae548d3Szrj }
1900*fae548d3Szrj 
1901*fae548d3Szrj } // End extern "C".
1902*fae548d3Szrj 
1903*fae548d3Szrj int
keyword_to_parsecode(const char * keyword,size_t len) const1904*fae548d3Szrj Keyword_to_parsecode::keyword_to_parsecode(const char* keyword,
1905*fae548d3Szrj                                            size_t len) const
1906*fae548d3Szrj {
1907*fae548d3Szrj   Ktt_key key;
1908*fae548d3Szrj   key.str = keyword;
1909*fae548d3Szrj   key.len = len;
1910*fae548d3Szrj   void* kttv = bsearch(&key,
1911*fae548d3Szrj                        this->keyword_parsecodes_,
1912*fae548d3Szrj                        this->keyword_count_,
1913*fae548d3Szrj                        sizeof(this->keyword_parsecodes_[0]),
1914*fae548d3Szrj                        ktt_compare);
1915*fae548d3Szrj   if (kttv == NULL)
1916*fae548d3Szrj     return 0;
1917*fae548d3Szrj   Keyword_parsecode* ktt = static_cast<Keyword_parsecode*>(kttv);
1918*fae548d3Szrj   return ktt->parsecode;
1919*fae548d3Szrj }
1920*fae548d3Szrj 
1921*fae548d3Szrj // The following structs are used within the VersionInfo class as well
1922*fae548d3Szrj // as in the bison helper functions.  They store the information
1923*fae548d3Szrj // parsed from the version script.
1924*fae548d3Szrj 
1925*fae548d3Szrj // A single version expression.
1926*fae548d3Szrj // For example, pattern="std::map*" and language="C++".
1927*fae548d3Szrj struct Version_expression
1928*fae548d3Szrj {
Version_expressiongold::Version_expression1929*fae548d3Szrj   Version_expression(const std::string& a_pattern,
1930*fae548d3Szrj 		     Version_script_info::Language a_language,
1931*fae548d3Szrj                      bool a_exact_match)
1932*fae548d3Szrj     : pattern(a_pattern), language(a_language), exact_match(a_exact_match),
1933*fae548d3Szrj       was_matched_by_symbol(false)
1934*fae548d3Szrj   { }
1935*fae548d3Szrj 
1936*fae548d3Szrj   std::string pattern;
1937*fae548d3Szrj   Version_script_info::Language language;
1938*fae548d3Szrj   // If false, we use glob() to match pattern.  If true, we use strcmp().
1939*fae548d3Szrj   bool exact_match;
1940*fae548d3Szrj   // True if --no-undefined-version is in effect and we found this
1941*fae548d3Szrj   // version in get_symbol_version.  We use mutable because this
1942*fae548d3Szrj   // struct is generally not modifiable after it has been created.
1943*fae548d3Szrj   mutable bool was_matched_by_symbol;
1944*fae548d3Szrj };
1945*fae548d3Szrj 
1946*fae548d3Szrj // A list of expressions.
1947*fae548d3Szrj struct Version_expression_list
1948*fae548d3Szrj {
1949*fae548d3Szrj   std::vector<struct Version_expression> expressions;
1950*fae548d3Szrj };
1951*fae548d3Szrj 
1952*fae548d3Szrj // A list of which versions upon which another version depends.
1953*fae548d3Szrj // Strings should be from the Stringpool.
1954*fae548d3Szrj struct Version_dependency_list
1955*fae548d3Szrj {
1956*fae548d3Szrj   std::vector<std::string> dependencies;
1957*fae548d3Szrj };
1958*fae548d3Szrj 
1959*fae548d3Szrj // The total definition of a version.  It includes the tag for the
1960*fae548d3Szrj // version, its global and local expressions, and any dependencies.
1961*fae548d3Szrj struct Version_tree
1962*fae548d3Szrj {
Version_treegold::Version_tree1963*fae548d3Szrj   Version_tree()
1964*fae548d3Szrj       : tag(), global(NULL), local(NULL), dependencies(NULL)
1965*fae548d3Szrj   { }
1966*fae548d3Szrj 
1967*fae548d3Szrj   std::string tag;
1968*fae548d3Szrj   const struct Version_expression_list* global;
1969*fae548d3Szrj   const struct Version_expression_list* local;
1970*fae548d3Szrj   const struct Version_dependency_list* dependencies;
1971*fae548d3Szrj };
1972*fae548d3Szrj 
1973*fae548d3Szrj // Helper class that calls cplus_demangle when needed and takes care of freeing
1974*fae548d3Szrj // the result.
1975*fae548d3Szrj 
1976*fae548d3Szrj class Lazy_demangler
1977*fae548d3Szrj {
1978*fae548d3Szrj  public:
Lazy_demangler(const char * symbol,int options)1979*fae548d3Szrj   Lazy_demangler(const char* symbol, int options)
1980*fae548d3Szrj     : symbol_(symbol), options_(options), demangled_(NULL), did_demangle_(false)
1981*fae548d3Szrj   { }
1982*fae548d3Szrj 
~Lazy_demangler()1983*fae548d3Szrj   ~Lazy_demangler()
1984*fae548d3Szrj   { free(this->demangled_); }
1985*fae548d3Szrj 
1986*fae548d3Szrj   // Return the demangled name. The actual demangling happens on the first call,
1987*fae548d3Szrj   // and the result is later cached.
1988*fae548d3Szrj   inline char*
1989*fae548d3Szrj   get();
1990*fae548d3Szrj 
1991*fae548d3Szrj  private:
1992*fae548d3Szrj   // The symbol to demangle.
1993*fae548d3Szrj   const char* symbol_;
1994*fae548d3Szrj   // Option flags to pass to cplus_demagle.
1995*fae548d3Szrj   const int options_;
1996*fae548d3Szrj   // The cached demangled value, or NULL if demangling didn't happen yet or
1997*fae548d3Szrj   // failed.
1998*fae548d3Szrj   char* demangled_;
1999*fae548d3Szrj   // Whether we already called cplus_demangle
2000*fae548d3Szrj   bool did_demangle_;
2001*fae548d3Szrj };
2002*fae548d3Szrj 
2003*fae548d3Szrj // Return the demangled name. The actual demangling happens on the first call,
2004*fae548d3Szrj // and the result is later cached. Returns NULL if the symbol cannot be
2005*fae548d3Szrj // demangled.
2006*fae548d3Szrj 
2007*fae548d3Szrj inline char*
get()2008*fae548d3Szrj Lazy_demangler::get()
2009*fae548d3Szrj {
2010*fae548d3Szrj   if (!this->did_demangle_)
2011*fae548d3Szrj     {
2012*fae548d3Szrj       this->demangled_ = cplus_demangle(this->symbol_, this->options_);
2013*fae548d3Szrj       this->did_demangle_ = true;
2014*fae548d3Szrj     }
2015*fae548d3Szrj   return this->demangled_;
2016*fae548d3Szrj }
2017*fae548d3Szrj 
2018*fae548d3Szrj // Class Version_script_info.
2019*fae548d3Szrj 
Version_script_info()2020*fae548d3Szrj Version_script_info::Version_script_info()
2021*fae548d3Szrj   : dependency_lists_(), expression_lists_(), version_trees_(), globs_(),
2022*fae548d3Szrj     default_version_(NULL), default_is_global_(false), is_finalized_(false)
2023*fae548d3Szrj {
2024*fae548d3Szrj   for (int i = 0; i < LANGUAGE_COUNT; ++i)
2025*fae548d3Szrj     this->exact_[i] = NULL;
2026*fae548d3Szrj }
2027*fae548d3Szrj 
~Version_script_info()2028*fae548d3Szrj Version_script_info::~Version_script_info()
2029*fae548d3Szrj {
2030*fae548d3Szrj }
2031*fae548d3Szrj 
2032*fae548d3Szrj // Forget all the known version script information.
2033*fae548d3Szrj 
2034*fae548d3Szrj void
clear()2035*fae548d3Szrj Version_script_info::clear()
2036*fae548d3Szrj {
2037*fae548d3Szrj   for (size_t k = 0; k < this->dependency_lists_.size(); ++k)
2038*fae548d3Szrj     delete this->dependency_lists_[k];
2039*fae548d3Szrj   this->dependency_lists_.clear();
2040*fae548d3Szrj   for (size_t k = 0; k < this->version_trees_.size(); ++k)
2041*fae548d3Szrj     delete this->version_trees_[k];
2042*fae548d3Szrj   this->version_trees_.clear();
2043*fae548d3Szrj   for (size_t k = 0; k < this->expression_lists_.size(); ++k)
2044*fae548d3Szrj     delete this->expression_lists_[k];
2045*fae548d3Szrj   this->expression_lists_.clear();
2046*fae548d3Szrj }
2047*fae548d3Szrj 
2048*fae548d3Szrj // Finalize the version script information.
2049*fae548d3Szrj 
2050*fae548d3Szrj void
finalize()2051*fae548d3Szrj Version_script_info::finalize()
2052*fae548d3Szrj {
2053*fae548d3Szrj   if (!this->is_finalized_)
2054*fae548d3Szrj     {
2055*fae548d3Szrj       this->build_lookup_tables();
2056*fae548d3Szrj       this->is_finalized_ = true;
2057*fae548d3Szrj     }
2058*fae548d3Szrj }
2059*fae548d3Szrj 
2060*fae548d3Szrj // Return all the versions.
2061*fae548d3Szrj 
2062*fae548d3Szrj std::vector<std::string>
get_versions() const2063*fae548d3Szrj Version_script_info::get_versions() const
2064*fae548d3Szrj {
2065*fae548d3Szrj   std::vector<std::string> ret;
2066*fae548d3Szrj   for (size_t j = 0; j < this->version_trees_.size(); ++j)
2067*fae548d3Szrj     if (!this->version_trees_[j]->tag.empty())
2068*fae548d3Szrj       ret.push_back(this->version_trees_[j]->tag);
2069*fae548d3Szrj   return ret;
2070*fae548d3Szrj }
2071*fae548d3Szrj 
2072*fae548d3Szrj // Return the dependencies of VERSION.
2073*fae548d3Szrj 
2074*fae548d3Szrj std::vector<std::string>
get_dependencies(const char * version) const2075*fae548d3Szrj Version_script_info::get_dependencies(const char* version) const
2076*fae548d3Szrj {
2077*fae548d3Szrj   std::vector<std::string> ret;
2078*fae548d3Szrj   for (size_t j = 0; j < this->version_trees_.size(); ++j)
2079*fae548d3Szrj     if (this->version_trees_[j]->tag == version)
2080*fae548d3Szrj       {
2081*fae548d3Szrj         const struct Version_dependency_list* deps =
2082*fae548d3Szrj           this->version_trees_[j]->dependencies;
2083*fae548d3Szrj         if (deps != NULL)
2084*fae548d3Szrj           for (size_t k = 0; k < deps->dependencies.size(); ++k)
2085*fae548d3Szrj             ret.push_back(deps->dependencies[k]);
2086*fae548d3Szrj         return ret;
2087*fae548d3Szrj       }
2088*fae548d3Szrj   return ret;
2089*fae548d3Szrj }
2090*fae548d3Szrj 
2091*fae548d3Szrj // A version script essentially maps a symbol name to a version tag
2092*fae548d3Szrj // and an indication of whether symbol is global or local within that
2093*fae548d3Szrj // version tag.  Each symbol maps to at most one version tag.
2094*fae548d3Szrj // Unfortunately, in practice, version scripts are ambiguous, and list
2095*fae548d3Szrj // symbols multiple times.  Thus, we have to document the matching
2096*fae548d3Szrj // process.
2097*fae548d3Szrj 
2098*fae548d3Szrj // This is a description of what the GNU linker does as of 2010-01-11.
2099*fae548d3Szrj // It walks through the version tags in the order in which they appear
2100*fae548d3Szrj // in the version script.  For each tag, it first walks through the
2101*fae548d3Szrj // global patterns for that tag, then the local patterns.  When
2102*fae548d3Szrj // looking at a single pattern, it first applies any language specific
2103*fae548d3Szrj // demangling as specified for the pattern, and then matches the
2104*fae548d3Szrj // resulting symbol name to the pattern.  If it finds an exact match
2105*fae548d3Szrj // for a literal pattern (a pattern enclosed in quotes or with no
2106*fae548d3Szrj // wildcard characters), then that is the match that it uses.  If
2107*fae548d3Szrj // finds a match with a wildcard pattern, then it saves it and
2108*fae548d3Szrj // continues searching.  Wildcard patterns that are exactly "*" are
2109*fae548d3Szrj // saved separately.
2110*fae548d3Szrj 
2111*fae548d3Szrj // If no exact match with a literal pattern is ever found, then if a
2112*fae548d3Szrj // wildcard match with a global pattern was found it is used,
2113*fae548d3Szrj // otherwise if a wildcard match with a local pattern was found it is
2114*fae548d3Szrj // used.
2115*fae548d3Szrj 
2116*fae548d3Szrj // This is the result:
2117*fae548d3Szrj //   * If there is an exact match, then we use the first tag in the
2118*fae548d3Szrj //     version script where it matches.
2119*fae548d3Szrj //     + If the exact match in that tag is global, it is used.
2120*fae548d3Szrj //     + Otherwise the exact match in that tag is local, and is used.
2121*fae548d3Szrj //   * Otherwise, if there is any match with a global wildcard pattern:
2122*fae548d3Szrj //     + If there is any match with a wildcard pattern which is not
2123*fae548d3Szrj //       "*", then we use the tag in which the *last* such pattern
2124*fae548d3Szrj //       appears.
2125*fae548d3Szrj //     + Otherwise, we matched "*".  If there is no match with a local
2126*fae548d3Szrj //       wildcard pattern which is not "*", then we use the *last*
2127*fae548d3Szrj //       match with a global "*".  Otherwise, continue.
2128*fae548d3Szrj //   * Otherwise, if there is any match with a local wildcard pattern:
2129*fae548d3Szrj //     + If there is any match with a wildcard pattern which is not
2130*fae548d3Szrj //       "*", then we use the tag in which the *last* such pattern
2131*fae548d3Szrj //       appears.
2132*fae548d3Szrj //     + Otherwise, we matched "*", and we use the tag in which the
2133*fae548d3Szrj //       *last* such match occurred.
2134*fae548d3Szrj 
2135*fae548d3Szrj // There is an additional wrinkle.  When the GNU linker finds a symbol
2136*fae548d3Szrj // with a version defined in an object file due to a .symver
2137*fae548d3Szrj // directive, it looks up that symbol name in that version tag.  If it
2138*fae548d3Szrj // finds it, it matches the symbol name against the patterns for that
2139*fae548d3Szrj // version.  If there is no match with a global pattern, but there is
2140*fae548d3Szrj // a match with a local pattern, then the GNU linker marks the symbol
2141*fae548d3Szrj // as local.
2142*fae548d3Szrj 
2143*fae548d3Szrj // We want gold to be generally compatible, but we also want gold to
2144*fae548d3Szrj // be fast.  These are the rules that gold implements:
2145*fae548d3Szrj //   * If there is an exact match for the mangled name, we use it.
2146*fae548d3Szrj //     + If there is more than one exact match, we give a warning, and
2147*fae548d3Szrj //       we use the first tag in the script which matches.
2148*fae548d3Szrj //     + If a symbol has an exact match as both global and local for
2149*fae548d3Szrj //       the same version tag, we give an error.
2150*fae548d3Szrj //   * Otherwise, we look for an extern C++ or an extern Java exact
2151*fae548d3Szrj //     match.  If we find an exact match, we use it.
2152*fae548d3Szrj //     + If there is more than one exact match, we give a warning, and
2153*fae548d3Szrj //       we use the first tag in the script which matches.
2154*fae548d3Szrj //     + If a symbol has an exact match as both global and local for
2155*fae548d3Szrj //       the same version tag, we give an error.
2156*fae548d3Szrj //   * Otherwise, we look through the wildcard patterns, ignoring "*"
2157*fae548d3Szrj //     patterns.  We look through the version tags in reverse order.
2158*fae548d3Szrj //     For each version tag, we look through the global patterns and
2159*fae548d3Szrj //     then the local patterns.  We use the first match we find (i.e.,
2160*fae548d3Szrj //     the last matching version tag in the file).
2161*fae548d3Szrj //   * Otherwise, we use the "*" pattern if there is one.  We give an
2162*fae548d3Szrj //     error if there are multiple "*" patterns.
2163*fae548d3Szrj 
2164*fae548d3Szrj // At least for now, gold does not look up the version tag for a
2165*fae548d3Szrj // symbol version found in an object file to see if it should be
2166*fae548d3Szrj // forced local.  There are other ways to force a symbol to be local,
2167*fae548d3Szrj // and I don't understand why this one is useful.
2168*fae548d3Szrj 
2169*fae548d3Szrj // Build a set of fast lookup tables for a version script.
2170*fae548d3Szrj 
2171*fae548d3Szrj void
build_lookup_tables()2172*fae548d3Szrj Version_script_info::build_lookup_tables()
2173*fae548d3Szrj {
2174*fae548d3Szrj   size_t size = this->version_trees_.size();
2175*fae548d3Szrj   for (size_t j = 0; j < size; ++j)
2176*fae548d3Szrj     {
2177*fae548d3Szrj       const Version_tree* v = this->version_trees_[j];
2178*fae548d3Szrj       this->build_expression_list_lookup(v->local, v, false);
2179*fae548d3Szrj       this->build_expression_list_lookup(v->global, v, true);
2180*fae548d3Szrj     }
2181*fae548d3Szrj }
2182*fae548d3Szrj 
2183*fae548d3Szrj // If a pattern has backlashes but no unquoted wildcard characters,
2184*fae548d3Szrj // then we apply backslash unquoting and look for an exact match.
2185*fae548d3Szrj // Otherwise we treat it as a wildcard pattern.  This function returns
2186*fae548d3Szrj // true for a wildcard pattern.  Otherwise, it does backslash
2187*fae548d3Szrj // unquoting on *PATTERN and returns false.  If this returns true,
2188*fae548d3Szrj // *PATTERN may have been partially unquoted.
2189*fae548d3Szrj 
2190*fae548d3Szrj bool
unquote(std::string * pattern) const2191*fae548d3Szrj Version_script_info::unquote(std::string* pattern) const
2192*fae548d3Szrj {
2193*fae548d3Szrj   bool saw_backslash = false;
2194*fae548d3Szrj   size_t len = pattern->length();
2195*fae548d3Szrj   size_t j = 0;
2196*fae548d3Szrj   for (size_t i = 0; i < len; ++i)
2197*fae548d3Szrj     {
2198*fae548d3Szrj       if (saw_backslash)
2199*fae548d3Szrj 	saw_backslash = false;
2200*fae548d3Szrj       else
2201*fae548d3Szrj 	{
2202*fae548d3Szrj 	  switch ((*pattern)[i])
2203*fae548d3Szrj 	    {
2204*fae548d3Szrj 	    case '?': case '[': case '*':
2205*fae548d3Szrj 	      return true;
2206*fae548d3Szrj 	    case '\\':
2207*fae548d3Szrj 	      saw_backslash = true;
2208*fae548d3Szrj 	      continue;
2209*fae548d3Szrj 	    default:
2210*fae548d3Szrj 	      break;
2211*fae548d3Szrj 	    }
2212*fae548d3Szrj 	}
2213*fae548d3Szrj 
2214*fae548d3Szrj       if (i != j)
2215*fae548d3Szrj 	(*pattern)[j] = (*pattern)[i];
2216*fae548d3Szrj       ++j;
2217*fae548d3Szrj     }
2218*fae548d3Szrj   return false;
2219*fae548d3Szrj }
2220*fae548d3Szrj 
2221*fae548d3Szrj // Add an exact match for MATCH to *PE.  The result of the match is
2222*fae548d3Szrj // V/IS_GLOBAL.
2223*fae548d3Szrj 
2224*fae548d3Szrj void
add_exact_match(const std::string & match,const Version_tree * v,bool is_global,const Version_expression * ve,Exact * pe)2225*fae548d3Szrj Version_script_info::add_exact_match(const std::string& match,
2226*fae548d3Szrj 				     const Version_tree* v, bool is_global,
2227*fae548d3Szrj 				     const Version_expression* ve,
2228*fae548d3Szrj 				     Exact* pe)
2229*fae548d3Szrj {
2230*fae548d3Szrj   std::pair<Exact::iterator, bool> ins =
2231*fae548d3Szrj     pe->insert(std::make_pair(match, Version_tree_match(v, is_global, ve)));
2232*fae548d3Szrj   if (ins.second)
2233*fae548d3Szrj     {
2234*fae548d3Szrj       // This is the first time we have seen this match.
2235*fae548d3Szrj       return;
2236*fae548d3Szrj     }
2237*fae548d3Szrj 
2238*fae548d3Szrj   Version_tree_match& vtm(ins.first->second);
2239*fae548d3Szrj   if (vtm.real->tag != v->tag)
2240*fae548d3Szrj     {
2241*fae548d3Szrj       // This is an ambiguous match.  We still return the
2242*fae548d3Szrj       // first version that we found in the script, but we
2243*fae548d3Szrj       // record the new version to issue a warning if we
2244*fae548d3Szrj       // wind up looking up this symbol.
2245*fae548d3Szrj       if (vtm.ambiguous == NULL)
2246*fae548d3Szrj 	vtm.ambiguous = v;
2247*fae548d3Szrj     }
2248*fae548d3Szrj   else if (is_global != vtm.is_global)
2249*fae548d3Szrj     {
2250*fae548d3Szrj       // We have a match for both the global and local entries for a
2251*fae548d3Szrj       // version tag.  That's got to be wrong.
2252*fae548d3Szrj       gold_error(_("'%s' appears as both a global and a local symbol "
2253*fae548d3Szrj 		   "for version '%s' in script"),
2254*fae548d3Szrj 		 match.c_str(), v->tag.c_str());
2255*fae548d3Szrj     }
2256*fae548d3Szrj }
2257*fae548d3Szrj 
2258*fae548d3Szrj // Build fast lookup information for EXPLIST and store it in LOOKUP.
2259*fae548d3Szrj // All matches go to V, and IS_GLOBAL is true if they are global
2260*fae548d3Szrj // matches.
2261*fae548d3Szrj 
2262*fae548d3Szrj void
build_expression_list_lookup(const Version_expression_list * explist,const Version_tree * v,bool is_global)2263*fae548d3Szrj Version_script_info::build_expression_list_lookup(
2264*fae548d3Szrj     const Version_expression_list* explist,
2265*fae548d3Szrj     const Version_tree* v,
2266*fae548d3Szrj     bool is_global)
2267*fae548d3Szrj {
2268*fae548d3Szrj   if (explist == NULL)
2269*fae548d3Szrj     return;
2270*fae548d3Szrj   size_t size = explist->expressions.size();
2271*fae548d3Szrj   for (size_t i = 0; i < size; ++i)
2272*fae548d3Szrj     {
2273*fae548d3Szrj       const Version_expression& exp(explist->expressions[i]);
2274*fae548d3Szrj 
2275*fae548d3Szrj       if (exp.pattern.length() == 1 && exp.pattern[0] == '*')
2276*fae548d3Szrj 	{
2277*fae548d3Szrj 	  if (this->default_version_ != NULL
2278*fae548d3Szrj 	      && this->default_version_->tag != v->tag)
2279*fae548d3Szrj 	    gold_warning(_("wildcard match appears in both version '%s' "
2280*fae548d3Szrj 			   "and '%s' in script"),
2281*fae548d3Szrj 			 this->default_version_->tag.c_str(), v->tag.c_str());
2282*fae548d3Szrj 	  else if (this->default_version_ != NULL
2283*fae548d3Szrj 		   && this->default_is_global_ != is_global)
2284*fae548d3Szrj 	    gold_error(_("wildcard match appears as both global and local "
2285*fae548d3Szrj 			 "in version '%s' in script"),
2286*fae548d3Szrj 		       v->tag.c_str());
2287*fae548d3Szrj 	  this->default_version_ = v;
2288*fae548d3Szrj 	  this->default_is_global_ = is_global;
2289*fae548d3Szrj 	  continue;
2290*fae548d3Szrj 	}
2291*fae548d3Szrj 
2292*fae548d3Szrj       std::string pattern = exp.pattern;
2293*fae548d3Szrj       if (!exp.exact_match)
2294*fae548d3Szrj 	{
2295*fae548d3Szrj 	  if (this->unquote(&pattern))
2296*fae548d3Szrj 	    {
2297*fae548d3Szrj 	      this->globs_.push_back(Glob(&exp, v, is_global));
2298*fae548d3Szrj 	      continue;
2299*fae548d3Szrj 	    }
2300*fae548d3Szrj 	}
2301*fae548d3Szrj 
2302*fae548d3Szrj       if (this->exact_[exp.language] == NULL)
2303*fae548d3Szrj 	this->exact_[exp.language] = new Exact();
2304*fae548d3Szrj       this->add_exact_match(pattern, v, is_global, &exp,
2305*fae548d3Szrj 			    this->exact_[exp.language]);
2306*fae548d3Szrj     }
2307*fae548d3Szrj }
2308*fae548d3Szrj 
2309*fae548d3Szrj // Return the name to match given a name, a language code, and two
2310*fae548d3Szrj // lazy demanglers.
2311*fae548d3Szrj 
2312*fae548d3Szrj const char*
get_name_to_match(const char * name,int language,Lazy_demangler * cpp_demangler,Lazy_demangler * java_demangler) const2313*fae548d3Szrj Version_script_info::get_name_to_match(const char* name,
2314*fae548d3Szrj 				       int language,
2315*fae548d3Szrj 				       Lazy_demangler* cpp_demangler,
2316*fae548d3Szrj 				       Lazy_demangler* java_demangler) const
2317*fae548d3Szrj {
2318*fae548d3Szrj   switch (language)
2319*fae548d3Szrj     {
2320*fae548d3Szrj     case LANGUAGE_C:
2321*fae548d3Szrj       return name;
2322*fae548d3Szrj     case LANGUAGE_CXX:
2323*fae548d3Szrj       return cpp_demangler->get();
2324*fae548d3Szrj     case LANGUAGE_JAVA:
2325*fae548d3Szrj       return java_demangler->get();
2326*fae548d3Szrj     default:
2327*fae548d3Szrj       gold_unreachable();
2328*fae548d3Szrj     }
2329*fae548d3Szrj }
2330*fae548d3Szrj 
2331*fae548d3Szrj // Look up SYMBOL_NAME in the list of versions.  Return true if the
2332*fae548d3Szrj // symbol is found, false if not.  If the symbol is found, then if
2333*fae548d3Szrj // PVERSION is not NULL, set *PVERSION to the version tag, and if
2334*fae548d3Szrj // P_IS_GLOBAL is not NULL, set *P_IS_GLOBAL according to whether the
2335*fae548d3Szrj // symbol is global or not.
2336*fae548d3Szrj 
2337*fae548d3Szrj bool
get_symbol_version(const char * symbol_name,std::string * pversion,bool * p_is_global) const2338*fae548d3Szrj Version_script_info::get_symbol_version(const char* symbol_name,
2339*fae548d3Szrj 					std::string* pversion,
2340*fae548d3Szrj 					bool* p_is_global) const
2341*fae548d3Szrj {
2342*fae548d3Szrj   Lazy_demangler cpp_demangled_name(symbol_name, DMGL_ANSI | DMGL_PARAMS);
2343*fae548d3Szrj   Lazy_demangler java_demangled_name(symbol_name,
2344*fae548d3Szrj 				     DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
2345*fae548d3Szrj 
2346*fae548d3Szrj   gold_assert(this->is_finalized_);
2347*fae548d3Szrj   for (int i = 0; i < LANGUAGE_COUNT; ++i)
2348*fae548d3Szrj     {
2349*fae548d3Szrj       Exact* exact = this->exact_[i];
2350*fae548d3Szrj       if (exact == NULL)
2351*fae548d3Szrj 	continue;
2352*fae548d3Szrj 
2353*fae548d3Szrj       const char* name_to_match = this->get_name_to_match(symbol_name, i,
2354*fae548d3Szrj 							  &cpp_demangled_name,
2355*fae548d3Szrj 							  &java_demangled_name);
2356*fae548d3Szrj       if (name_to_match == NULL)
2357*fae548d3Szrj 	{
2358*fae548d3Szrj 	  // If the name can not be demangled, the GNU linker goes
2359*fae548d3Szrj 	  // ahead and tries to match it anyhow.  That does not
2360*fae548d3Szrj 	  // make sense to me and I have not implemented it.
2361*fae548d3Szrj 	  continue;
2362*fae548d3Szrj 	}
2363*fae548d3Szrj 
2364*fae548d3Szrj       Exact::const_iterator pe = exact->find(name_to_match);
2365*fae548d3Szrj       if (pe != exact->end())
2366*fae548d3Szrj 	{
2367*fae548d3Szrj 	  const Version_tree_match& vtm(pe->second);
2368*fae548d3Szrj 	  if (vtm.ambiguous != NULL)
2369*fae548d3Szrj 	    gold_warning(_("using '%s' as version for '%s' which is also "
2370*fae548d3Szrj 			   "named in version '%s' in script"),
2371*fae548d3Szrj 			 vtm.real->tag.c_str(), name_to_match,
2372*fae548d3Szrj 			 vtm.ambiguous->tag.c_str());
2373*fae548d3Szrj 
2374*fae548d3Szrj 	  if (pversion != NULL)
2375*fae548d3Szrj 	    *pversion = vtm.real->tag;
2376*fae548d3Szrj 	  if (p_is_global != NULL)
2377*fae548d3Szrj 	    *p_is_global = vtm.is_global;
2378*fae548d3Szrj 
2379*fae548d3Szrj 	  // If we are using --no-undefined-version, and this is a
2380*fae548d3Szrj 	  // global symbol, we have to record that we have found this
2381*fae548d3Szrj 	  // symbol, so that we don't warn about it.  We have to do
2382*fae548d3Szrj 	  // this now, because otherwise we have no way to get from a
2383*fae548d3Szrj 	  // non-C language back to the demangled name that we
2384*fae548d3Szrj 	  // matched.
2385*fae548d3Szrj 	  if (p_is_global != NULL && vtm.is_global)
2386*fae548d3Szrj 	    vtm.expression->was_matched_by_symbol = true;
2387*fae548d3Szrj 
2388*fae548d3Szrj 	  return true;
2389*fae548d3Szrj 	}
2390*fae548d3Szrj     }
2391*fae548d3Szrj 
2392*fae548d3Szrj   // Look through the glob patterns in reverse order.
2393*fae548d3Szrj 
2394*fae548d3Szrj   for (Globs::const_reverse_iterator p = this->globs_.rbegin();
2395*fae548d3Szrj        p != this->globs_.rend();
2396*fae548d3Szrj        ++p)
2397*fae548d3Szrj     {
2398*fae548d3Szrj       int language = p->expression->language;
2399*fae548d3Szrj       const char* name_to_match = this->get_name_to_match(symbol_name,
2400*fae548d3Szrj 							  language,
2401*fae548d3Szrj 							  &cpp_demangled_name,
2402*fae548d3Szrj 							  &java_demangled_name);
2403*fae548d3Szrj       if (name_to_match == NULL)
2404*fae548d3Szrj 	continue;
2405*fae548d3Szrj 
2406*fae548d3Szrj       if (fnmatch(p->expression->pattern.c_str(), name_to_match,
2407*fae548d3Szrj 		  FNM_NOESCAPE) == 0)
2408*fae548d3Szrj 	{
2409*fae548d3Szrj 	  if (pversion != NULL)
2410*fae548d3Szrj 	    *pversion = p->version->tag;
2411*fae548d3Szrj 	  if (p_is_global != NULL)
2412*fae548d3Szrj 	    *p_is_global = p->is_global;
2413*fae548d3Szrj 	  return true;
2414*fae548d3Szrj 	}
2415*fae548d3Szrj     }
2416*fae548d3Szrj 
2417*fae548d3Szrj   // Finally, there may be a wildcard.
2418*fae548d3Szrj   if (this->default_version_ != NULL)
2419*fae548d3Szrj     {
2420*fae548d3Szrj       if (pversion != NULL)
2421*fae548d3Szrj 	*pversion = this->default_version_->tag;
2422*fae548d3Szrj       if (p_is_global != NULL)
2423*fae548d3Szrj 	*p_is_global = this->default_is_global_;
2424*fae548d3Szrj       return true;
2425*fae548d3Szrj     }
2426*fae548d3Szrj 
2427*fae548d3Szrj   return false;
2428*fae548d3Szrj }
2429*fae548d3Szrj 
2430*fae548d3Szrj // Give an error if any exact symbol names (not wildcards) appear in a
2431*fae548d3Szrj // version script, but there is no such symbol.
2432*fae548d3Szrj 
2433*fae548d3Szrj void
check_unmatched_names(const Symbol_table * symtab) const2434*fae548d3Szrj Version_script_info::check_unmatched_names(const Symbol_table* symtab) const
2435*fae548d3Szrj {
2436*fae548d3Szrj   for (size_t i = 0; i < this->version_trees_.size(); ++i)
2437*fae548d3Szrj     {
2438*fae548d3Szrj       const Version_tree* vt = this->version_trees_[i];
2439*fae548d3Szrj       if (vt->global == NULL)
2440*fae548d3Szrj 	continue;
2441*fae548d3Szrj       for (size_t j = 0; j < vt->global->expressions.size(); ++j)
2442*fae548d3Szrj 	{
2443*fae548d3Szrj 	  const Version_expression& expression(vt->global->expressions[j]);
2444*fae548d3Szrj 
2445*fae548d3Szrj 	  // Ignore cases where we used the version because we saw a
2446*fae548d3Szrj 	  // symbol that we looked up.  Note that
2447*fae548d3Szrj 	  // WAS_MATCHED_BY_SYMBOL will be true even if the symbol was
2448*fae548d3Szrj 	  // not a definition.  That's OK as in that case we most
2449*fae548d3Szrj 	  // likely gave an undefined symbol error anyhow.
2450*fae548d3Szrj 	  if (expression.was_matched_by_symbol)
2451*fae548d3Szrj 	    continue;
2452*fae548d3Szrj 
2453*fae548d3Szrj 	  // Just ignore names which are in languages other than C.
2454*fae548d3Szrj 	  // We have no way to look them up in the symbol table.
2455*fae548d3Szrj 	  if (expression.language != LANGUAGE_C)
2456*fae548d3Szrj 	    continue;
2457*fae548d3Szrj 
2458*fae548d3Szrj 	  // Remove backslash quoting, and ignore wildcard patterns.
2459*fae548d3Szrj 	  std::string pattern = expression.pattern;
2460*fae548d3Szrj 	  if (!expression.exact_match)
2461*fae548d3Szrj 	    {
2462*fae548d3Szrj 	      if (this->unquote(&pattern))
2463*fae548d3Szrj 		continue;
2464*fae548d3Szrj 	    }
2465*fae548d3Szrj 
2466*fae548d3Szrj 	  if (symtab->lookup(pattern.c_str(), vt->tag.c_str()) == NULL)
2467*fae548d3Szrj 	    gold_error(_("version script assignment of %s to symbol %s "
2468*fae548d3Szrj 			 "failed: symbol not defined"),
2469*fae548d3Szrj 		       vt->tag.c_str(), pattern.c_str());
2470*fae548d3Szrj 	}
2471*fae548d3Szrj     }
2472*fae548d3Szrj }
2473*fae548d3Szrj 
2474*fae548d3Szrj struct Version_dependency_list*
allocate_dependency_list()2475*fae548d3Szrj Version_script_info::allocate_dependency_list()
2476*fae548d3Szrj {
2477*fae548d3Szrj   dependency_lists_.push_back(new Version_dependency_list);
2478*fae548d3Szrj   return dependency_lists_.back();
2479*fae548d3Szrj }
2480*fae548d3Szrj 
2481*fae548d3Szrj struct Version_expression_list*
allocate_expression_list()2482*fae548d3Szrj Version_script_info::allocate_expression_list()
2483*fae548d3Szrj {
2484*fae548d3Szrj   expression_lists_.push_back(new Version_expression_list);
2485*fae548d3Szrj   return expression_lists_.back();
2486*fae548d3Szrj }
2487*fae548d3Szrj 
2488*fae548d3Szrj struct Version_tree*
allocate_version_tree()2489*fae548d3Szrj Version_script_info::allocate_version_tree()
2490*fae548d3Szrj {
2491*fae548d3Szrj   version_trees_.push_back(new Version_tree);
2492*fae548d3Szrj   return version_trees_.back();
2493*fae548d3Szrj }
2494*fae548d3Szrj 
2495*fae548d3Szrj // Print for debugging.
2496*fae548d3Szrj 
2497*fae548d3Szrj void
print(FILE * f) const2498*fae548d3Szrj Version_script_info::print(FILE* f) const
2499*fae548d3Szrj {
2500*fae548d3Szrj   if (this->empty())
2501*fae548d3Szrj     return;
2502*fae548d3Szrj 
2503*fae548d3Szrj   fprintf(f, "VERSION {");
2504*fae548d3Szrj 
2505*fae548d3Szrj   for (size_t i = 0; i < this->version_trees_.size(); ++i)
2506*fae548d3Szrj     {
2507*fae548d3Szrj       const Version_tree* vt = this->version_trees_[i];
2508*fae548d3Szrj 
2509*fae548d3Szrj       if (vt->tag.empty())
2510*fae548d3Szrj 	fprintf(f, "  {\n");
2511*fae548d3Szrj       else
2512*fae548d3Szrj 	fprintf(f, "  %s {\n", vt->tag.c_str());
2513*fae548d3Szrj 
2514*fae548d3Szrj       if (vt->global != NULL)
2515*fae548d3Szrj 	{
2516*fae548d3Szrj 	  fprintf(f, "    global :\n");
2517*fae548d3Szrj 	  this->print_expression_list(f, vt->global);
2518*fae548d3Szrj 	}
2519*fae548d3Szrj 
2520*fae548d3Szrj       if (vt->local != NULL)
2521*fae548d3Szrj 	{
2522*fae548d3Szrj 	  fprintf(f, "    local :\n");
2523*fae548d3Szrj 	  this->print_expression_list(f, vt->local);
2524*fae548d3Szrj 	}
2525*fae548d3Szrj 
2526*fae548d3Szrj       fprintf(f, "  }");
2527*fae548d3Szrj       if (vt->dependencies != NULL)
2528*fae548d3Szrj 	{
2529*fae548d3Szrj 	  const Version_dependency_list* deps = vt->dependencies;
2530*fae548d3Szrj 	  for (size_t j = 0; j < deps->dependencies.size(); ++j)
2531*fae548d3Szrj 	    {
2532*fae548d3Szrj 	      if (j < deps->dependencies.size() - 1)
2533*fae548d3Szrj 		fprintf(f, "\n");
2534*fae548d3Szrj 	      fprintf(f, "    %s", deps->dependencies[j].c_str());
2535*fae548d3Szrj 	    }
2536*fae548d3Szrj 	}
2537*fae548d3Szrj       fprintf(f, ";\n");
2538*fae548d3Szrj     }
2539*fae548d3Szrj 
2540*fae548d3Szrj   fprintf(f, "}\n");
2541*fae548d3Szrj }
2542*fae548d3Szrj 
2543*fae548d3Szrj void
print_expression_list(FILE * f,const Version_expression_list * vel) const2544*fae548d3Szrj Version_script_info::print_expression_list(
2545*fae548d3Szrj     FILE* f,
2546*fae548d3Szrj     const Version_expression_list* vel) const
2547*fae548d3Szrj {
2548*fae548d3Szrj   Version_script_info::Language current_language = LANGUAGE_C;
2549*fae548d3Szrj   for (size_t i = 0; i < vel->expressions.size(); ++i)
2550*fae548d3Szrj     {
2551*fae548d3Szrj       const Version_expression& ve(vel->expressions[i]);
2552*fae548d3Szrj 
2553*fae548d3Szrj       if (ve.language != current_language)
2554*fae548d3Szrj 	{
2555*fae548d3Szrj 	  if (current_language != LANGUAGE_C)
2556*fae548d3Szrj 	    fprintf(f, "      }\n");
2557*fae548d3Szrj 	  switch (ve.language)
2558*fae548d3Szrj 	    {
2559*fae548d3Szrj 	    case LANGUAGE_C:
2560*fae548d3Szrj 	      break;
2561*fae548d3Szrj 	    case LANGUAGE_CXX:
2562*fae548d3Szrj 	      fprintf(f, "      extern \"C++\" {\n");
2563*fae548d3Szrj 	      break;
2564*fae548d3Szrj 	    case LANGUAGE_JAVA:
2565*fae548d3Szrj 	      fprintf(f, "      extern \"Java\" {\n");
2566*fae548d3Szrj 	      break;
2567*fae548d3Szrj 	    default:
2568*fae548d3Szrj 	      gold_unreachable();
2569*fae548d3Szrj 	    }
2570*fae548d3Szrj 	  current_language = ve.language;
2571*fae548d3Szrj 	}
2572*fae548d3Szrj 
2573*fae548d3Szrj       fprintf(f, "      ");
2574*fae548d3Szrj       if (current_language != LANGUAGE_C)
2575*fae548d3Szrj 	fprintf(f, "  ");
2576*fae548d3Szrj 
2577*fae548d3Szrj       if (ve.exact_match)
2578*fae548d3Szrj 	fprintf(f, "\"");
2579*fae548d3Szrj       fprintf(f, "%s", ve.pattern.c_str());
2580*fae548d3Szrj       if (ve.exact_match)
2581*fae548d3Szrj 	fprintf(f, "\"");
2582*fae548d3Szrj 
2583*fae548d3Szrj       fprintf(f, "\n");
2584*fae548d3Szrj     }
2585*fae548d3Szrj 
2586*fae548d3Szrj   if (current_language != LANGUAGE_C)
2587*fae548d3Szrj     fprintf(f, "      }\n");
2588*fae548d3Szrj }
2589*fae548d3Szrj 
2590*fae548d3Szrj } // End namespace gold.
2591*fae548d3Szrj 
2592*fae548d3Szrj // The remaining functions are extern "C", so it's clearer to not put
2593*fae548d3Szrj // them in namespace gold.
2594*fae548d3Szrj 
2595*fae548d3Szrj using namespace gold;
2596*fae548d3Szrj 
2597*fae548d3Szrj // This function is called by the bison parser to return the next
2598*fae548d3Szrj // token.
2599*fae548d3Szrj 
2600*fae548d3Szrj extern "C" int
yylex(YYSTYPE * lvalp,void * closurev)2601*fae548d3Szrj yylex(YYSTYPE* lvalp, void* closurev)
2602*fae548d3Szrj {
2603*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2604*fae548d3Szrj   const Token* token = closure->next_token();
2605*fae548d3Szrj   switch (token->classification())
2606*fae548d3Szrj     {
2607*fae548d3Szrj     default:
2608*fae548d3Szrj       gold_unreachable();
2609*fae548d3Szrj 
2610*fae548d3Szrj     case Token::TOKEN_INVALID:
2611*fae548d3Szrj       yyerror(closurev, "invalid character");
2612*fae548d3Szrj       return 0;
2613*fae548d3Szrj 
2614*fae548d3Szrj     case Token::TOKEN_EOF:
2615*fae548d3Szrj       return 0;
2616*fae548d3Szrj 
2617*fae548d3Szrj     case Token::TOKEN_STRING:
2618*fae548d3Szrj       {
2619*fae548d3Szrj 	// This is either a keyword or a STRING.
2620*fae548d3Szrj 	size_t len;
2621*fae548d3Szrj 	const char* str = token->string_value(&len);
2622*fae548d3Szrj 	int parsecode = 0;
2623*fae548d3Szrj         switch (closure->lex_mode())
2624*fae548d3Szrj           {
2625*fae548d3Szrj           case Lex::LINKER_SCRIPT:
2626*fae548d3Szrj             parsecode = script_keywords.keyword_to_parsecode(str, len);
2627*fae548d3Szrj             break;
2628*fae548d3Szrj           case Lex::VERSION_SCRIPT:
2629*fae548d3Szrj             parsecode = version_script_keywords.keyword_to_parsecode(str, len);
2630*fae548d3Szrj             break;
2631*fae548d3Szrj           case Lex::DYNAMIC_LIST:
2632*fae548d3Szrj             parsecode = dynamic_list_keywords.keyword_to_parsecode(str, len);
2633*fae548d3Szrj             break;
2634*fae548d3Szrj           default:
2635*fae548d3Szrj             break;
2636*fae548d3Szrj           }
2637*fae548d3Szrj 	if (parsecode != 0)
2638*fae548d3Szrj 	  return parsecode;
2639*fae548d3Szrj 	lvalp->string.value = str;
2640*fae548d3Szrj 	lvalp->string.length = len;
2641*fae548d3Szrj 	return STRING;
2642*fae548d3Szrj       }
2643*fae548d3Szrj 
2644*fae548d3Szrj     case Token::TOKEN_QUOTED_STRING:
2645*fae548d3Szrj       lvalp->string.value = token->string_value(&lvalp->string.length);
2646*fae548d3Szrj       return QUOTED_STRING;
2647*fae548d3Szrj 
2648*fae548d3Szrj     case Token::TOKEN_OPERATOR:
2649*fae548d3Szrj       return token->operator_value();
2650*fae548d3Szrj 
2651*fae548d3Szrj     case Token::TOKEN_INTEGER:
2652*fae548d3Szrj       lvalp->integer = token->integer_value();
2653*fae548d3Szrj       return INTEGER;
2654*fae548d3Szrj     }
2655*fae548d3Szrj }
2656*fae548d3Szrj 
2657*fae548d3Szrj // This function is called by the bison parser to report an error.
2658*fae548d3Szrj 
2659*fae548d3Szrj extern "C" void
yyerror(void * closurev,const char * message)2660*fae548d3Szrj yyerror(void* closurev, const char* message)
2661*fae548d3Szrj {
2662*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2663*fae548d3Szrj   gold_error(_("%s:%d:%d: %s"), closure->filename(), closure->lineno(),
2664*fae548d3Szrj 	     closure->charpos(), message);
2665*fae548d3Szrj }
2666*fae548d3Szrj 
2667*fae548d3Szrj // Called by the bison parser to add an external symbol to the link.
2668*fae548d3Szrj 
2669*fae548d3Szrj extern "C" void
script_add_extern(void * closurev,const char * name,size_t length)2670*fae548d3Szrj script_add_extern(void* closurev, const char* name, size_t length)
2671*fae548d3Szrj {
2672*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2673*fae548d3Szrj   closure->script_options()->add_symbol_reference(name, length);
2674*fae548d3Szrj }
2675*fae548d3Szrj 
2676*fae548d3Szrj // Called by the bison parser to add a file to the link.
2677*fae548d3Szrj 
2678*fae548d3Szrj extern "C" void
script_add_file(void * closurev,const char * name,size_t length)2679*fae548d3Szrj script_add_file(void* closurev, const char* name, size_t length)
2680*fae548d3Szrj {
2681*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2682*fae548d3Szrj 
2683*fae548d3Szrj   // If this is an absolute path, and we found the script in the
2684*fae548d3Szrj   // sysroot, then we want to prepend the sysroot to the file name.
2685*fae548d3Szrj   // For example, this is how we handle a cross link to the x86_64
2686*fae548d3Szrj   // libc.so, which refers to /lib/libc.so.6.
2687*fae548d3Szrj   std::string name_string(name, length);
2688*fae548d3Szrj   const char* extra_search_path = ".";
2689*fae548d3Szrj   std::string script_directory;
2690*fae548d3Szrj   if (IS_ABSOLUTE_PATH(name_string.c_str()))
2691*fae548d3Szrj     {
2692*fae548d3Szrj       if (closure->is_in_sysroot())
2693*fae548d3Szrj 	{
2694*fae548d3Szrj 	  const std::string& sysroot(parameters->options().sysroot());
2695*fae548d3Szrj 	  gold_assert(!sysroot.empty());
2696*fae548d3Szrj 	  name_string = sysroot + name_string;
2697*fae548d3Szrj 	}
2698*fae548d3Szrj     }
2699*fae548d3Szrj   else
2700*fae548d3Szrj     {
2701*fae548d3Szrj       // In addition to checking the normal library search path, we
2702*fae548d3Szrj       // also want to check in the script-directory.
2703*fae548d3Szrj       const char* slash = strrchr(closure->filename(), '/');
2704*fae548d3Szrj       if (slash != NULL)
2705*fae548d3Szrj 	{
2706*fae548d3Szrj 	  script_directory.assign(closure->filename(),
2707*fae548d3Szrj 				  slash - closure->filename() + 1);
2708*fae548d3Szrj 	  extra_search_path = script_directory.c_str();
2709*fae548d3Szrj 	}
2710*fae548d3Szrj     }
2711*fae548d3Szrj 
2712*fae548d3Szrj   Input_file_argument file(name_string.c_str(),
2713*fae548d3Szrj 			   Input_file_argument::INPUT_FILE_TYPE_FILE,
2714*fae548d3Szrj 			   extra_search_path, false,
2715*fae548d3Szrj 			   closure->position_dependent_options());
2716*fae548d3Szrj   Input_argument& arg = closure->inputs()->add_file(file);
2717*fae548d3Szrj   arg.set_script_info(closure->script_info());
2718*fae548d3Szrj }
2719*fae548d3Szrj 
2720*fae548d3Szrj // Called by the bison parser to add a library to the link.
2721*fae548d3Szrj 
2722*fae548d3Szrj extern "C" void
script_add_library(void * closurev,const char * name,size_t length)2723*fae548d3Szrj script_add_library(void* closurev, const char* name, size_t length)
2724*fae548d3Szrj {
2725*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2726*fae548d3Szrj   std::string name_string(name, length);
2727*fae548d3Szrj 
2728*fae548d3Szrj   if (name_string[0] != 'l')
2729*fae548d3Szrj     gold_error(_("library name must be prefixed with -l"));
2730*fae548d3Szrj 
2731*fae548d3Szrj   Input_file_argument file(name_string.c_str() + 1,
2732*fae548d3Szrj 			   Input_file_argument::INPUT_FILE_TYPE_LIBRARY,
2733*fae548d3Szrj 			   "", false,
2734*fae548d3Szrj 			   closure->position_dependent_options());
2735*fae548d3Szrj   Input_argument& arg = closure->inputs()->add_file(file);
2736*fae548d3Szrj   arg.set_script_info(closure->script_info());
2737*fae548d3Szrj }
2738*fae548d3Szrj 
2739*fae548d3Szrj // Called by the bison parser to start a group.  If we are already in
2740*fae548d3Szrj // a group, that means that this script was invoked within a
2741*fae548d3Szrj // --start-group --end-group sequence on the command line, or that
2742*fae548d3Szrj // this script was found in a GROUP of another script.  In that case,
2743*fae548d3Szrj // we simply continue the existing group, rather than starting a new
2744*fae548d3Szrj // one.  It is possible to construct a case in which this will do
2745*fae548d3Szrj // something other than what would happen if we did a recursive group,
2746*fae548d3Szrj // but it's hard to imagine why the different behaviour would be
2747*fae548d3Szrj // useful for a real program.  Avoiding recursive groups is simpler
2748*fae548d3Szrj // and more efficient.
2749*fae548d3Szrj 
2750*fae548d3Szrj extern "C" void
script_start_group(void * closurev)2751*fae548d3Szrj script_start_group(void* closurev)
2752*fae548d3Szrj {
2753*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2754*fae548d3Szrj   if (!closure->in_group())
2755*fae548d3Szrj     closure->inputs()->start_group();
2756*fae548d3Szrj }
2757*fae548d3Szrj 
2758*fae548d3Szrj // Called by the bison parser at the end of a group.
2759*fae548d3Szrj 
2760*fae548d3Szrj extern "C" void
script_end_group(void * closurev)2761*fae548d3Szrj script_end_group(void* closurev)
2762*fae548d3Szrj {
2763*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2764*fae548d3Szrj   if (!closure->in_group())
2765*fae548d3Szrj     closure->inputs()->end_group();
2766*fae548d3Szrj }
2767*fae548d3Szrj 
2768*fae548d3Szrj // Called by the bison parser to start an AS_NEEDED list.
2769*fae548d3Szrj 
2770*fae548d3Szrj extern "C" void
script_start_as_needed(void * closurev)2771*fae548d3Szrj script_start_as_needed(void* closurev)
2772*fae548d3Szrj {
2773*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2774*fae548d3Szrj   closure->position_dependent_options().set_as_needed(true);
2775*fae548d3Szrj }
2776*fae548d3Szrj 
2777*fae548d3Szrj // Called by the bison parser at the end of an AS_NEEDED list.
2778*fae548d3Szrj 
2779*fae548d3Szrj extern "C" void
script_end_as_needed(void * closurev)2780*fae548d3Szrj script_end_as_needed(void* closurev)
2781*fae548d3Szrj {
2782*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2783*fae548d3Szrj   closure->position_dependent_options().set_as_needed(false);
2784*fae548d3Szrj }
2785*fae548d3Szrj 
2786*fae548d3Szrj // Called by the bison parser to set the entry symbol.
2787*fae548d3Szrj 
2788*fae548d3Szrj extern "C" void
script_set_entry(void * closurev,const char * entry,size_t length)2789*fae548d3Szrj script_set_entry(void* closurev, const char* entry, size_t length)
2790*fae548d3Szrj {
2791*fae548d3Szrj   // We'll parse this exactly the same as --entry=ENTRY on the commandline
2792*fae548d3Szrj   // TODO(csilvers): FIXME -- call set_entry directly.
2793*fae548d3Szrj   std::string arg("--entry=");
2794*fae548d3Szrj   arg.append(entry, length);
2795*fae548d3Szrj   script_parse_option(closurev, arg.c_str(), arg.size());
2796*fae548d3Szrj }
2797*fae548d3Szrj 
2798*fae548d3Szrj // Called by the bison parser to set whether to define common symbols.
2799*fae548d3Szrj 
2800*fae548d3Szrj extern "C" void
script_set_common_allocation(void * closurev,int set)2801*fae548d3Szrj script_set_common_allocation(void* closurev, int set)
2802*fae548d3Szrj {
2803*fae548d3Szrj   const char* arg = set != 0 ? "--define-common" : "--no-define-common";
2804*fae548d3Szrj   script_parse_option(closurev, arg, strlen(arg));
2805*fae548d3Szrj }
2806*fae548d3Szrj 
2807*fae548d3Szrj // Called by the bison parser to refer to a symbol.
2808*fae548d3Szrj 
2809*fae548d3Szrj extern "C" Expression*
script_symbol(void * closurev,const char * name,size_t length)2810*fae548d3Szrj script_symbol(void* closurev, const char* name, size_t length)
2811*fae548d3Szrj {
2812*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2813*fae548d3Szrj   if (length != 1 || name[0] != '.')
2814*fae548d3Szrj     closure->script_options()->add_symbol_reference(name, length);
2815*fae548d3Szrj   return script_exp_string(name, length);
2816*fae548d3Szrj }
2817*fae548d3Szrj 
2818*fae548d3Szrj // Called by the bison parser to define a symbol.
2819*fae548d3Szrj 
2820*fae548d3Szrj extern "C" void
script_set_symbol(void * closurev,const char * name,size_t length,Expression * value,int providei,int hiddeni)2821*fae548d3Szrj script_set_symbol(void* closurev, const char* name, size_t length,
2822*fae548d3Szrj 		  Expression* value, int providei, int hiddeni)
2823*fae548d3Szrj {
2824*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2825*fae548d3Szrj   const bool provide = providei != 0;
2826*fae548d3Szrj   const bool hidden = hiddeni != 0;
2827*fae548d3Szrj   closure->script_options()->add_symbol_assignment(name, length,
2828*fae548d3Szrj 						   closure->parsing_defsym(),
2829*fae548d3Szrj 						   value, provide, hidden);
2830*fae548d3Szrj   closure->clear_skip_on_incompatible_target();
2831*fae548d3Szrj }
2832*fae548d3Szrj 
2833*fae548d3Szrj // Called by the bison parser to add an assertion.
2834*fae548d3Szrj 
2835*fae548d3Szrj extern "C" void
script_add_assertion(void * closurev,Expression * check,const char * message,size_t messagelen)2836*fae548d3Szrj script_add_assertion(void* closurev, Expression* check, const char* message,
2837*fae548d3Szrj 		     size_t messagelen)
2838*fae548d3Szrj {
2839*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2840*fae548d3Szrj   closure->script_options()->add_assertion(check, message, messagelen);
2841*fae548d3Szrj   closure->clear_skip_on_incompatible_target();
2842*fae548d3Szrj }
2843*fae548d3Szrj 
2844*fae548d3Szrj // Called by the bison parser to parse an OPTION.
2845*fae548d3Szrj 
2846*fae548d3Szrj extern "C" void
script_parse_option(void * closurev,const char * option,size_t length)2847*fae548d3Szrj script_parse_option(void* closurev, const char* option, size_t length)
2848*fae548d3Szrj {
2849*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2850*fae548d3Szrj   // We treat the option as a single command-line option, even if
2851*fae548d3Szrj   // it has internal whitespace.
2852*fae548d3Szrj   if (closure->command_line() == NULL)
2853*fae548d3Szrj     {
2854*fae548d3Szrj       // There are some options that we could handle here--e.g.,
2855*fae548d3Szrj       // -lLIBRARY.  Should we bother?
2856*fae548d3Szrj       gold_warning(_("%s:%d:%d: ignoring command OPTION; OPTION is only valid"
2857*fae548d3Szrj 		     " for scripts specified via -T/--script"),
2858*fae548d3Szrj 		   closure->filename(), closure->lineno(), closure->charpos());
2859*fae548d3Szrj     }
2860*fae548d3Szrj   else
2861*fae548d3Szrj     {
2862*fae548d3Szrj       bool past_a_double_dash_option = false;
2863*fae548d3Szrj       const char* mutable_option = strndup(option, length);
2864*fae548d3Szrj       gold_assert(mutable_option != NULL);
2865*fae548d3Szrj       closure->command_line()->process_one_option(1, &mutable_option, 0,
2866*fae548d3Szrj                                                   &past_a_double_dash_option);
2867*fae548d3Szrj       // The General_options class will quite possibly store a pointer
2868*fae548d3Szrj       // into mutable_option, so we can't free it.  In cases the class
2869*fae548d3Szrj       // does not store such a pointer, this is a memory leak.  Alas. :(
2870*fae548d3Szrj     }
2871*fae548d3Szrj   closure->clear_skip_on_incompatible_target();
2872*fae548d3Szrj }
2873*fae548d3Szrj 
2874*fae548d3Szrj // Called by the bison parser to handle OUTPUT_FORMAT.  OUTPUT_FORMAT
2875*fae548d3Szrj // takes either one or three arguments.  In the three argument case,
2876*fae548d3Szrj // the format depends on the endianness option, which we don't
2877*fae548d3Szrj // currently support (FIXME).  If we see an OUTPUT_FORMAT for the
2878*fae548d3Szrj // wrong format, then we want to search for a new file.  Returning 0
2879*fae548d3Szrj // here will cause the parser to immediately abort.
2880*fae548d3Szrj 
2881*fae548d3Szrj extern "C" int
script_check_output_format(void * closurev,const char * default_name,size_t default_length,const char *,size_t,const char *,size_t)2882*fae548d3Szrj script_check_output_format(void* closurev,
2883*fae548d3Szrj 			   const char* default_name, size_t default_length,
2884*fae548d3Szrj 			   const char*, size_t, const char*, size_t)
2885*fae548d3Szrj {
2886*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2887*fae548d3Szrj   std::string name(default_name, default_length);
2888*fae548d3Szrj   Target* target = select_target_by_bfd_name(name.c_str());
2889*fae548d3Szrj   if (target == NULL || !parameters->is_compatible_target(target))
2890*fae548d3Szrj     {
2891*fae548d3Szrj       if (closure->skip_on_incompatible_target())
2892*fae548d3Szrj 	{
2893*fae548d3Szrj 	  closure->set_found_incompatible_target();
2894*fae548d3Szrj 	  return 0;
2895*fae548d3Szrj 	}
2896*fae548d3Szrj       // FIXME: Should we warn about the unknown target?
2897*fae548d3Szrj     }
2898*fae548d3Szrj   return 1;
2899*fae548d3Szrj }
2900*fae548d3Szrj 
2901*fae548d3Szrj // Called by the bison parser to handle TARGET.
2902*fae548d3Szrj 
2903*fae548d3Szrj extern "C" void
script_set_target(void * closurev,const char * target,size_t len)2904*fae548d3Szrj script_set_target(void* closurev, const char* target, size_t len)
2905*fae548d3Szrj {
2906*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2907*fae548d3Szrj   std::string s(target, len);
2908*fae548d3Szrj   General_options::Object_format format_enum;
2909*fae548d3Szrj   format_enum = General_options::string_to_object_format(s.c_str());
2910*fae548d3Szrj   closure->position_dependent_options().set_format_enum(format_enum);
2911*fae548d3Szrj }
2912*fae548d3Szrj 
2913*fae548d3Szrj // Called by the bison parser to handle SEARCH_DIR.  This is handled
2914*fae548d3Szrj // exactly like a -L option.
2915*fae548d3Szrj 
2916*fae548d3Szrj extern "C" void
script_add_search_dir(void * closurev,const char * option,size_t length)2917*fae548d3Szrj script_add_search_dir(void* closurev, const char* option, size_t length)
2918*fae548d3Szrj {
2919*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2920*fae548d3Szrj   if (closure->command_line() == NULL)
2921*fae548d3Szrj     gold_warning(_("%s:%d:%d: ignoring SEARCH_DIR; SEARCH_DIR is only valid"
2922*fae548d3Szrj 		   " for scripts specified via -T/--script"),
2923*fae548d3Szrj 		 closure->filename(), closure->lineno(), closure->charpos());
2924*fae548d3Szrj   else if (!closure->command_line()->options().nostdlib())
2925*fae548d3Szrj     {
2926*fae548d3Szrj       std::string s = "-L" + std::string(option, length);
2927*fae548d3Szrj       script_parse_option(closurev, s.c_str(), s.size());
2928*fae548d3Szrj     }
2929*fae548d3Szrj }
2930*fae548d3Szrj 
2931*fae548d3Szrj /* Called by the bison parser to push the lexer into expression
2932*fae548d3Szrj    mode.  */
2933*fae548d3Szrj 
2934*fae548d3Szrj extern "C" void
script_push_lex_into_expression_mode(void * closurev)2935*fae548d3Szrj script_push_lex_into_expression_mode(void* closurev)
2936*fae548d3Szrj {
2937*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2938*fae548d3Szrj   closure->push_lex_mode(Lex::EXPRESSION);
2939*fae548d3Szrj }
2940*fae548d3Szrj 
2941*fae548d3Szrj /* Called by the bison parser to push the lexer into version
2942*fae548d3Szrj    mode.  */
2943*fae548d3Szrj 
2944*fae548d3Szrj extern "C" void
script_push_lex_into_version_mode(void * closurev)2945*fae548d3Szrj script_push_lex_into_version_mode(void* closurev)
2946*fae548d3Szrj {
2947*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2948*fae548d3Szrj   if (closure->version_script()->is_finalized())
2949*fae548d3Szrj     gold_error(_("%s:%d:%d: invalid use of VERSION in input file"),
2950*fae548d3Szrj 	       closure->filename(), closure->lineno(), closure->charpos());
2951*fae548d3Szrj   closure->push_lex_mode(Lex::VERSION_SCRIPT);
2952*fae548d3Szrj }
2953*fae548d3Szrj 
2954*fae548d3Szrj /* Called by the bison parser to pop the lexer mode.  */
2955*fae548d3Szrj 
2956*fae548d3Szrj extern "C" void
script_pop_lex_mode(void * closurev)2957*fae548d3Szrj script_pop_lex_mode(void* closurev)
2958*fae548d3Szrj {
2959*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2960*fae548d3Szrj   closure->pop_lex_mode();
2961*fae548d3Szrj }
2962*fae548d3Szrj 
2963*fae548d3Szrj // Register an entire version node. For example:
2964*fae548d3Szrj //
2965*fae548d3Szrj // GLIBC_2.1 {
2966*fae548d3Szrj //   global: foo;
2967*fae548d3Szrj // } GLIBC_2.0;
2968*fae548d3Szrj //
2969*fae548d3Szrj // - tag is "GLIBC_2.1"
2970*fae548d3Szrj // - tree contains the information "global: foo"
2971*fae548d3Szrj // - deps contains "GLIBC_2.0"
2972*fae548d3Szrj 
2973*fae548d3Szrj extern "C" void
script_register_vers_node(void *,const char * tag,int taglen,struct Version_tree * tree,struct Version_dependency_list * deps)2974*fae548d3Szrj script_register_vers_node(void*,
2975*fae548d3Szrj 			  const char* tag,
2976*fae548d3Szrj 			  int taglen,
2977*fae548d3Szrj 			  struct Version_tree* tree,
2978*fae548d3Szrj 			  struct Version_dependency_list* deps)
2979*fae548d3Szrj {
2980*fae548d3Szrj   gold_assert(tree != NULL);
2981*fae548d3Szrj   tree->dependencies = deps;
2982*fae548d3Szrj   if (tag != NULL)
2983*fae548d3Szrj     tree->tag = std::string(tag, taglen);
2984*fae548d3Szrj }
2985*fae548d3Szrj 
2986*fae548d3Szrj // Add a dependencies to the list of existing dependencies, if any,
2987*fae548d3Szrj // and return the expanded list.
2988*fae548d3Szrj 
2989*fae548d3Szrj extern "C" struct Version_dependency_list*
script_add_vers_depend(void * closurev,struct Version_dependency_list * all_deps,const char * depend_to_add,int deplen)2990*fae548d3Szrj script_add_vers_depend(void* closurev,
2991*fae548d3Szrj 		       struct Version_dependency_list* all_deps,
2992*fae548d3Szrj 		       const char* depend_to_add, int deplen)
2993*fae548d3Szrj {
2994*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
2995*fae548d3Szrj   if (all_deps == NULL)
2996*fae548d3Szrj     all_deps = closure->version_script()->allocate_dependency_list();
2997*fae548d3Szrj   all_deps->dependencies.push_back(std::string(depend_to_add, deplen));
2998*fae548d3Szrj   return all_deps;
2999*fae548d3Szrj }
3000*fae548d3Szrj 
3001*fae548d3Szrj // Add a pattern expression to an existing list of expressions, if any.
3002*fae548d3Szrj 
3003*fae548d3Szrj extern "C" struct Version_expression_list*
script_new_vers_pattern(void * closurev,struct Version_expression_list * expressions,const char * pattern,int patlen,int exact_match)3004*fae548d3Szrj script_new_vers_pattern(void* closurev,
3005*fae548d3Szrj 			struct Version_expression_list* expressions,
3006*fae548d3Szrj 			const char* pattern, int patlen, int exact_match)
3007*fae548d3Szrj {
3008*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3009*fae548d3Szrj   if (expressions == NULL)
3010*fae548d3Szrj     expressions = closure->version_script()->allocate_expression_list();
3011*fae548d3Szrj   expressions->expressions.push_back(
3012*fae548d3Szrj       Version_expression(std::string(pattern, patlen),
3013*fae548d3Szrj                          closure->get_current_language(),
3014*fae548d3Szrj                          static_cast<bool>(exact_match)));
3015*fae548d3Szrj   return expressions;
3016*fae548d3Szrj }
3017*fae548d3Szrj 
3018*fae548d3Szrj // Attaches b to the end of a, and clears b.  So a = a + b and b = {}.
3019*fae548d3Szrj 
3020*fae548d3Szrj extern "C" struct Version_expression_list*
script_merge_expressions(struct Version_expression_list * a,struct Version_expression_list * b)3021*fae548d3Szrj script_merge_expressions(struct Version_expression_list* a,
3022*fae548d3Szrj                          struct Version_expression_list* b)
3023*fae548d3Szrj {
3024*fae548d3Szrj   a->expressions.insert(a->expressions.end(),
3025*fae548d3Szrj                         b->expressions.begin(), b->expressions.end());
3026*fae548d3Szrj   // We could delete b and remove it from expressions_lists_, but
3027*fae548d3Szrj   // that's a lot of work.  This works just as well.
3028*fae548d3Szrj   b->expressions.clear();
3029*fae548d3Szrj   return a;
3030*fae548d3Szrj }
3031*fae548d3Szrj 
3032*fae548d3Szrj // Combine the global and local expressions into a a Version_tree.
3033*fae548d3Szrj 
3034*fae548d3Szrj extern "C" struct Version_tree*
script_new_vers_node(void * closurev,struct Version_expression_list * global,struct Version_expression_list * local)3035*fae548d3Szrj script_new_vers_node(void* closurev,
3036*fae548d3Szrj 		     struct Version_expression_list* global,
3037*fae548d3Szrj 		     struct Version_expression_list* local)
3038*fae548d3Szrj {
3039*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3040*fae548d3Szrj   Version_tree* tree = closure->version_script()->allocate_version_tree();
3041*fae548d3Szrj   tree->global = global;
3042*fae548d3Szrj   tree->local = local;
3043*fae548d3Szrj   return tree;
3044*fae548d3Szrj }
3045*fae548d3Szrj 
3046*fae548d3Szrj // Handle a transition in language, such as at the
3047*fae548d3Szrj // start or end of 'extern "C++"'
3048*fae548d3Szrj 
3049*fae548d3Szrj extern "C" void
version_script_push_lang(void * closurev,const char * lang,int langlen)3050*fae548d3Szrj version_script_push_lang(void* closurev, const char* lang, int langlen)
3051*fae548d3Szrj {
3052*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3053*fae548d3Szrj   std::string language(lang, langlen);
3054*fae548d3Szrj   Version_script_info::Language code;
3055*fae548d3Szrj   if (language.empty() || language == "C")
3056*fae548d3Szrj     code = Version_script_info::LANGUAGE_C;
3057*fae548d3Szrj   else if (language == "C++")
3058*fae548d3Szrj     code = Version_script_info::LANGUAGE_CXX;
3059*fae548d3Szrj   else if (language == "Java")
3060*fae548d3Szrj     code = Version_script_info::LANGUAGE_JAVA;
3061*fae548d3Szrj   else
3062*fae548d3Szrj     {
3063*fae548d3Szrj       char* buf = new char[langlen + 100];
3064*fae548d3Szrj       snprintf(buf, langlen + 100,
3065*fae548d3Szrj 	       _("unrecognized version script language '%s'"),
3066*fae548d3Szrj 	       language.c_str());
3067*fae548d3Szrj       yyerror(closurev, buf);
3068*fae548d3Szrj       delete[] buf;
3069*fae548d3Szrj       code = Version_script_info::LANGUAGE_C;
3070*fae548d3Szrj     }
3071*fae548d3Szrj   closure->push_language(code);
3072*fae548d3Szrj }
3073*fae548d3Szrj 
3074*fae548d3Szrj extern "C" void
version_script_pop_lang(void * closurev)3075*fae548d3Szrj version_script_pop_lang(void* closurev)
3076*fae548d3Szrj {
3077*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3078*fae548d3Szrj   closure->pop_language();
3079*fae548d3Szrj }
3080*fae548d3Szrj 
3081*fae548d3Szrj // Called by the bison parser to start a SECTIONS clause.
3082*fae548d3Szrj 
3083*fae548d3Szrj extern "C" void
script_start_sections(void * closurev)3084*fae548d3Szrj script_start_sections(void* closurev)
3085*fae548d3Szrj {
3086*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3087*fae548d3Szrj   closure->script_options()->script_sections()->start_sections();
3088*fae548d3Szrj   closure->clear_skip_on_incompatible_target();
3089*fae548d3Szrj }
3090*fae548d3Szrj 
3091*fae548d3Szrj // Called by the bison parser to finish a SECTIONS clause.
3092*fae548d3Szrj 
3093*fae548d3Szrj extern "C" void
script_finish_sections(void * closurev)3094*fae548d3Szrj script_finish_sections(void* closurev)
3095*fae548d3Szrj {
3096*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3097*fae548d3Szrj   closure->script_options()->script_sections()->finish_sections();
3098*fae548d3Szrj }
3099*fae548d3Szrj 
3100*fae548d3Szrj // Start processing entries for an output section.
3101*fae548d3Szrj 
3102*fae548d3Szrj extern "C" void
script_start_output_section(void * closurev,const char * name,size_t namelen,const struct Parser_output_section_header * header)3103*fae548d3Szrj script_start_output_section(void* closurev, const char* name, size_t namelen,
3104*fae548d3Szrj 			    const struct Parser_output_section_header* header)
3105*fae548d3Szrj {
3106*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3107*fae548d3Szrj   closure->script_options()->script_sections()->start_output_section(name,
3108*fae548d3Szrj 								     namelen,
3109*fae548d3Szrj 								     header);
3110*fae548d3Szrj }
3111*fae548d3Szrj 
3112*fae548d3Szrj // Finish processing entries for an output section.
3113*fae548d3Szrj 
3114*fae548d3Szrj extern "C" void
script_finish_output_section(void * closurev,const struct Parser_output_section_trailer * trail)3115*fae548d3Szrj script_finish_output_section(void* closurev,
3116*fae548d3Szrj 			     const struct Parser_output_section_trailer* trail)
3117*fae548d3Szrj {
3118*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3119*fae548d3Szrj   closure->script_options()->script_sections()->finish_output_section(trail);
3120*fae548d3Szrj }
3121*fae548d3Szrj 
3122*fae548d3Szrj // Add a data item (e.g., "WORD (0)") to the current output section.
3123*fae548d3Szrj 
3124*fae548d3Szrj extern "C" void
script_add_data(void * closurev,int data_token,Expression * val)3125*fae548d3Szrj script_add_data(void* closurev, int data_token, Expression* val)
3126*fae548d3Szrj {
3127*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3128*fae548d3Szrj   int size;
3129*fae548d3Szrj   bool is_signed = true;
3130*fae548d3Szrj   switch (data_token)
3131*fae548d3Szrj     {
3132*fae548d3Szrj     case QUAD:
3133*fae548d3Szrj       size = 8;
3134*fae548d3Szrj       is_signed = false;
3135*fae548d3Szrj       break;
3136*fae548d3Szrj     case SQUAD:
3137*fae548d3Szrj       size = 8;
3138*fae548d3Szrj       break;
3139*fae548d3Szrj     case LONG:
3140*fae548d3Szrj       size = 4;
3141*fae548d3Szrj       break;
3142*fae548d3Szrj     case SHORT:
3143*fae548d3Szrj       size = 2;
3144*fae548d3Szrj       break;
3145*fae548d3Szrj     case BYTE:
3146*fae548d3Szrj       size = 1;
3147*fae548d3Szrj       break;
3148*fae548d3Szrj     default:
3149*fae548d3Szrj       gold_unreachable();
3150*fae548d3Szrj     }
3151*fae548d3Szrj   closure->script_options()->script_sections()->add_data(size, is_signed, val);
3152*fae548d3Szrj }
3153*fae548d3Szrj 
3154*fae548d3Szrj // Add a clause setting the fill value to the current output section.
3155*fae548d3Szrj 
3156*fae548d3Szrj extern "C" void
script_add_fill(void * closurev,Expression * val)3157*fae548d3Szrj script_add_fill(void* closurev, Expression* val)
3158*fae548d3Szrj {
3159*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3160*fae548d3Szrj   closure->script_options()->script_sections()->add_fill(val);
3161*fae548d3Szrj }
3162*fae548d3Szrj 
3163*fae548d3Szrj // Add a new input section specification to the current output
3164*fae548d3Szrj // section.
3165*fae548d3Szrj 
3166*fae548d3Szrj extern "C" void
script_add_input_section(void * closurev,const struct Input_section_spec * spec,int keepi)3167*fae548d3Szrj script_add_input_section(void* closurev,
3168*fae548d3Szrj 			 const struct Input_section_spec* spec,
3169*fae548d3Szrj 			 int keepi)
3170*fae548d3Szrj {
3171*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3172*fae548d3Szrj   bool keep = keepi != 0;
3173*fae548d3Szrj   closure->script_options()->script_sections()->add_input_section(spec, keep);
3174*fae548d3Szrj }
3175*fae548d3Szrj 
3176*fae548d3Szrj // When we see DATA_SEGMENT_ALIGN we record that following output
3177*fae548d3Szrj // sections may be relro.
3178*fae548d3Szrj 
3179*fae548d3Szrj extern "C" void
script_data_segment_align(void * closurev)3180*fae548d3Szrj script_data_segment_align(void* closurev)
3181*fae548d3Szrj {
3182*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3183*fae548d3Szrj   if (!closure->script_options()->saw_sections_clause())
3184*fae548d3Szrj     gold_error(_("%s:%d:%d: DATA_SEGMENT_ALIGN not in SECTIONS clause"),
3185*fae548d3Szrj 	       closure->filename(), closure->lineno(), closure->charpos());
3186*fae548d3Szrj   else
3187*fae548d3Szrj     closure->script_options()->script_sections()->data_segment_align();
3188*fae548d3Szrj }
3189*fae548d3Szrj 
3190*fae548d3Szrj // When we see DATA_SEGMENT_RELRO_END we know that all output sections
3191*fae548d3Szrj // since DATA_SEGMENT_ALIGN should be relro.
3192*fae548d3Szrj 
3193*fae548d3Szrj extern "C" void
script_data_segment_relro_end(void * closurev)3194*fae548d3Szrj script_data_segment_relro_end(void* closurev)
3195*fae548d3Szrj {
3196*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3197*fae548d3Szrj   if (!closure->script_options()->saw_sections_clause())
3198*fae548d3Szrj     gold_error(_("%s:%d:%d: DATA_SEGMENT_ALIGN not in SECTIONS clause"),
3199*fae548d3Szrj 	       closure->filename(), closure->lineno(), closure->charpos());
3200*fae548d3Szrj   else
3201*fae548d3Szrj     closure->script_options()->script_sections()->data_segment_relro_end();
3202*fae548d3Szrj }
3203*fae548d3Szrj 
3204*fae548d3Szrj // Create a new list of string/sort pairs.
3205*fae548d3Szrj 
3206*fae548d3Szrj extern "C" String_sort_list_ptr
script_new_string_sort_list(const struct Wildcard_section * string_sort)3207*fae548d3Szrj script_new_string_sort_list(const struct Wildcard_section* string_sort)
3208*fae548d3Szrj {
3209*fae548d3Szrj   return new String_sort_list(1, *string_sort);
3210*fae548d3Szrj }
3211*fae548d3Szrj 
3212*fae548d3Szrj // Add an entry to a list of string/sort pairs.  The way the parser
3213*fae548d3Szrj // works permits us to simply modify the first parameter, rather than
3214*fae548d3Szrj // copy the vector.
3215*fae548d3Szrj 
3216*fae548d3Szrj extern "C" String_sort_list_ptr
script_string_sort_list_add(String_sort_list_ptr pv,const struct Wildcard_section * string_sort)3217*fae548d3Szrj script_string_sort_list_add(String_sort_list_ptr pv,
3218*fae548d3Szrj 			    const struct Wildcard_section* string_sort)
3219*fae548d3Szrj {
3220*fae548d3Szrj   if (pv == NULL)
3221*fae548d3Szrj     return script_new_string_sort_list(string_sort);
3222*fae548d3Szrj   else
3223*fae548d3Szrj     {
3224*fae548d3Szrj       pv->push_back(*string_sort);
3225*fae548d3Szrj       return pv;
3226*fae548d3Szrj     }
3227*fae548d3Szrj }
3228*fae548d3Szrj 
3229*fae548d3Szrj // Create a new list of strings.
3230*fae548d3Szrj 
3231*fae548d3Szrj extern "C" String_list_ptr
script_new_string_list(const char * str,size_t len)3232*fae548d3Szrj script_new_string_list(const char* str, size_t len)
3233*fae548d3Szrj {
3234*fae548d3Szrj   return new String_list(1, std::string(str, len));
3235*fae548d3Szrj }
3236*fae548d3Szrj 
3237*fae548d3Szrj // Add an element to a list of strings.  The way the parser works
3238*fae548d3Szrj // permits us to simply modify the first parameter, rather than copy
3239*fae548d3Szrj // the vector.
3240*fae548d3Szrj 
3241*fae548d3Szrj extern "C" String_list_ptr
script_string_list_push_back(String_list_ptr pv,const char * str,size_t len)3242*fae548d3Szrj script_string_list_push_back(String_list_ptr pv, const char* str, size_t len)
3243*fae548d3Szrj {
3244*fae548d3Szrj   if (pv == NULL)
3245*fae548d3Szrj     return script_new_string_list(str, len);
3246*fae548d3Szrj   else
3247*fae548d3Szrj     {
3248*fae548d3Szrj       pv->push_back(std::string(str, len));
3249*fae548d3Szrj       return pv;
3250*fae548d3Szrj     }
3251*fae548d3Szrj }
3252*fae548d3Szrj 
3253*fae548d3Szrj // Concatenate two string lists.  Either or both may be NULL.  The way
3254*fae548d3Szrj // the parser works permits us to modify the parameters, rather than
3255*fae548d3Szrj // copy the vector.
3256*fae548d3Szrj 
3257*fae548d3Szrj extern "C" String_list_ptr
script_string_list_append(String_list_ptr pv1,String_list_ptr pv2)3258*fae548d3Szrj script_string_list_append(String_list_ptr pv1, String_list_ptr pv2)
3259*fae548d3Szrj {
3260*fae548d3Szrj   if (pv1 == NULL)
3261*fae548d3Szrj     return pv2;
3262*fae548d3Szrj   if (pv2 == NULL)
3263*fae548d3Szrj     return pv1;
3264*fae548d3Szrj   pv1->insert(pv1->end(), pv2->begin(), pv2->end());
3265*fae548d3Szrj   return pv1;
3266*fae548d3Szrj }
3267*fae548d3Szrj 
3268*fae548d3Szrj // Add a new program header.
3269*fae548d3Szrj 
3270*fae548d3Szrj extern "C" void
script_add_phdr(void * closurev,const char * name,size_t namelen,unsigned int type,const Phdr_info * info)3271*fae548d3Szrj script_add_phdr(void* closurev, const char* name, size_t namelen,
3272*fae548d3Szrj 		unsigned int type, const Phdr_info* info)
3273*fae548d3Szrj {
3274*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3275*fae548d3Szrj   bool includes_filehdr = info->includes_filehdr != 0;
3276*fae548d3Szrj   bool includes_phdrs = info->includes_phdrs != 0;
3277*fae548d3Szrj   bool is_flags_valid = info->is_flags_valid != 0;
3278*fae548d3Szrj   Script_sections* ss = closure->script_options()->script_sections();
3279*fae548d3Szrj   ss->add_phdr(name, namelen, type, includes_filehdr, includes_phdrs,
3280*fae548d3Szrj 	       is_flags_valid, info->flags, info->load_address);
3281*fae548d3Szrj   closure->clear_skip_on_incompatible_target();
3282*fae548d3Szrj }
3283*fae548d3Szrj 
3284*fae548d3Szrj // Convert a program header string to a type.
3285*fae548d3Szrj 
3286*fae548d3Szrj #define PHDR_TYPE(NAME) { #NAME, sizeof(#NAME) - 1, elfcpp::NAME }
3287*fae548d3Szrj 
3288*fae548d3Szrj static struct
3289*fae548d3Szrj {
3290*fae548d3Szrj   const char* name;
3291*fae548d3Szrj   size_t namelen;
3292*fae548d3Szrj   unsigned int val;
3293*fae548d3Szrj } phdr_type_names[] =
3294*fae548d3Szrj {
3295*fae548d3Szrj   PHDR_TYPE(PT_NULL),
3296*fae548d3Szrj   PHDR_TYPE(PT_LOAD),
3297*fae548d3Szrj   PHDR_TYPE(PT_DYNAMIC),
3298*fae548d3Szrj   PHDR_TYPE(PT_INTERP),
3299*fae548d3Szrj   PHDR_TYPE(PT_NOTE),
3300*fae548d3Szrj   PHDR_TYPE(PT_SHLIB),
3301*fae548d3Szrj   PHDR_TYPE(PT_PHDR),
3302*fae548d3Szrj   PHDR_TYPE(PT_TLS),
3303*fae548d3Szrj   PHDR_TYPE(PT_GNU_EH_FRAME),
3304*fae548d3Szrj   PHDR_TYPE(PT_GNU_STACK),
3305*fae548d3Szrj   PHDR_TYPE(PT_GNU_RELRO)
3306*fae548d3Szrj };
3307*fae548d3Szrj 
3308*fae548d3Szrj extern "C" unsigned int
script_phdr_string_to_type(void * closurev,const char * name,size_t namelen)3309*fae548d3Szrj script_phdr_string_to_type(void* closurev, const char* name, size_t namelen)
3310*fae548d3Szrj {
3311*fae548d3Szrj   for (unsigned int i = 0;
3312*fae548d3Szrj        i < sizeof(phdr_type_names) / sizeof(phdr_type_names[0]);
3313*fae548d3Szrj        ++i)
3314*fae548d3Szrj     if (namelen == phdr_type_names[i].namelen
3315*fae548d3Szrj 	&& strncmp(name, phdr_type_names[i].name, namelen) == 0)
3316*fae548d3Szrj       return phdr_type_names[i].val;
3317*fae548d3Szrj   yyerror(closurev, _("unknown PHDR type (try integer)"));
3318*fae548d3Szrj   return elfcpp::PT_NULL;
3319*fae548d3Szrj }
3320*fae548d3Szrj 
3321*fae548d3Szrj extern "C" void
script_saw_segment_start_expression(void * closurev)3322*fae548d3Szrj script_saw_segment_start_expression(void* closurev)
3323*fae548d3Szrj {
3324*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3325*fae548d3Szrj   Script_sections* ss = closure->script_options()->script_sections();
3326*fae548d3Szrj   ss->set_saw_segment_start_expression(true);
3327*fae548d3Szrj }
3328*fae548d3Szrj 
3329*fae548d3Szrj extern "C" void
script_set_section_region(void * closurev,const char * name,size_t namelen,int set_vma)3330*fae548d3Szrj script_set_section_region(void* closurev, const char* name, size_t namelen,
3331*fae548d3Szrj 			  int set_vma)
3332*fae548d3Szrj {
3333*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3334*fae548d3Szrj   if (!closure->script_options()->saw_sections_clause())
3335*fae548d3Szrj     {
3336*fae548d3Szrj       gold_error(_("%s:%d:%d: MEMORY region '%.*s' referred to outside of "
3337*fae548d3Szrj 		   "SECTIONS clause"),
3338*fae548d3Szrj 		 closure->filename(), closure->lineno(), closure->charpos(),
3339*fae548d3Szrj 		 static_cast<int>(namelen), name);
3340*fae548d3Szrj       return;
3341*fae548d3Szrj     }
3342*fae548d3Szrj 
3343*fae548d3Szrj   Script_sections* ss = closure->script_options()->script_sections();
3344*fae548d3Szrj   Memory_region* mr = ss->find_memory_region(name, namelen);
3345*fae548d3Szrj   if (mr == NULL)
3346*fae548d3Szrj     {
3347*fae548d3Szrj       gold_error(_("%s:%d:%d: MEMORY region '%.*s' not declared"),
3348*fae548d3Szrj 		 closure->filename(), closure->lineno(), closure->charpos(),
3349*fae548d3Szrj 		 static_cast<int>(namelen), name);
3350*fae548d3Szrj       return;
3351*fae548d3Szrj     }
3352*fae548d3Szrj 
3353*fae548d3Szrj   ss->set_memory_region(mr, set_vma);
3354*fae548d3Szrj }
3355*fae548d3Szrj 
3356*fae548d3Szrj extern "C" void
script_add_memory(void * closurev,const char * name,size_t namelen,unsigned int attrs,Expression * origin,Expression * length)3357*fae548d3Szrj script_add_memory(void* closurev, const char* name, size_t namelen,
3358*fae548d3Szrj 		  unsigned int attrs, Expression* origin, Expression* length)
3359*fae548d3Szrj {
3360*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3361*fae548d3Szrj   Script_sections* ss = closure->script_options()->script_sections();
3362*fae548d3Szrj   ss->add_memory_region(name, namelen, attrs, origin, length);
3363*fae548d3Szrj }
3364*fae548d3Szrj 
3365*fae548d3Szrj extern "C" unsigned int
script_parse_memory_attr(void * closurev,const char * attrs,size_t attrlen,int invert)3366*fae548d3Szrj script_parse_memory_attr(void* closurev, const char* attrs, size_t attrlen,
3367*fae548d3Szrj 			 int invert)
3368*fae548d3Szrj {
3369*fae548d3Szrj   int attributes = 0;
3370*fae548d3Szrj 
3371*fae548d3Szrj   while (attrlen--)
3372*fae548d3Szrj     switch (*attrs++)
3373*fae548d3Szrj       {
3374*fae548d3Szrj       case 'R':
3375*fae548d3Szrj       case 'r':
3376*fae548d3Szrj 	attributes |= MEM_READABLE; break;
3377*fae548d3Szrj       case 'W':
3378*fae548d3Szrj       case 'w':
3379*fae548d3Szrj 	attributes |= MEM_READABLE | MEM_WRITEABLE; break;
3380*fae548d3Szrj       case 'X':
3381*fae548d3Szrj       case 'x':
3382*fae548d3Szrj 	attributes |= MEM_EXECUTABLE; break;
3383*fae548d3Szrj       case 'A':
3384*fae548d3Szrj       case 'a':
3385*fae548d3Szrj 	attributes |= MEM_ALLOCATABLE; break;
3386*fae548d3Szrj       case 'I':
3387*fae548d3Szrj       case 'i':
3388*fae548d3Szrj       case 'L':
3389*fae548d3Szrj       case 'l':
3390*fae548d3Szrj 	attributes |= MEM_INITIALIZED; break;
3391*fae548d3Szrj       default:
3392*fae548d3Szrj 	yyerror(closurev, _("unknown MEMORY attribute"));
3393*fae548d3Szrj       }
3394*fae548d3Szrj 
3395*fae548d3Szrj   if (invert)
3396*fae548d3Szrj     attributes = (~ attributes) & MEM_ATTR_MASK;
3397*fae548d3Szrj 
3398*fae548d3Szrj   return attributes;
3399*fae548d3Szrj }
3400*fae548d3Szrj 
3401*fae548d3Szrj extern "C" void
script_include_directive(int first_token,void * closurev,const char * filename,size_t length)3402*fae548d3Szrj script_include_directive(int first_token, void* closurev,
3403*fae548d3Szrj 			 const char* filename, size_t length)
3404*fae548d3Szrj {
3405*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3406*fae548d3Szrj   std::string name(filename, length);
3407*fae548d3Szrj   Command_line* cmdline = closure->command_line();
3408*fae548d3Szrj   read_script_file(name.c_str(), cmdline, &cmdline->script_options(),
3409*fae548d3Szrj                    first_token, Lex::LINKER_SCRIPT);
3410*fae548d3Szrj }
3411*fae548d3Szrj 
3412*fae548d3Szrj // Functions for memory regions.
3413*fae548d3Szrj 
3414*fae548d3Szrj extern "C" Expression*
script_exp_function_origin(void * closurev,const char * name,size_t namelen)3415*fae548d3Szrj script_exp_function_origin(void* closurev, const char* name, size_t namelen)
3416*fae548d3Szrj {
3417*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3418*fae548d3Szrj   Script_sections* ss = closure->script_options()->script_sections();
3419*fae548d3Szrj   Expression* origin = ss->find_memory_region_origin(name, namelen);
3420*fae548d3Szrj 
3421*fae548d3Szrj   if (origin == NULL)
3422*fae548d3Szrj     {
3423*fae548d3Szrj       gold_error(_("undefined memory region '%s' referenced "
3424*fae548d3Szrj 		   "in ORIGIN expression"),
3425*fae548d3Szrj 		 name);
3426*fae548d3Szrj       // Create a dummy expression to prevent crashes later on.
3427*fae548d3Szrj       origin = script_exp_integer(0);
3428*fae548d3Szrj     }
3429*fae548d3Szrj 
3430*fae548d3Szrj   return origin;
3431*fae548d3Szrj }
3432*fae548d3Szrj 
3433*fae548d3Szrj extern "C" Expression*
script_exp_function_length(void * closurev,const char * name,size_t namelen)3434*fae548d3Szrj script_exp_function_length(void* closurev, const char* name, size_t namelen)
3435*fae548d3Szrj {
3436*fae548d3Szrj   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
3437*fae548d3Szrj   Script_sections* ss = closure->script_options()->script_sections();
3438*fae548d3Szrj   Expression* length = ss->find_memory_region_length(name, namelen);
3439*fae548d3Szrj 
3440*fae548d3Szrj   if (length == NULL)
3441*fae548d3Szrj     {
3442*fae548d3Szrj       gold_error(_("undefined memory region '%s' referenced "
3443*fae548d3Szrj 		   "in LENGTH expression"),
3444*fae548d3Szrj 		 name);
3445*fae548d3Szrj       // Create a dummy expression to prevent crashes later on.
3446*fae548d3Szrj       length = script_exp_integer(0);
3447*fae548d3Szrj     }
3448*fae548d3Szrj 
3449*fae548d3Szrj   return length;
3450*fae548d3Szrj }
3451