// script.cc -- handle linker scripts for gold.
-// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2006-2020 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
while (true)
{
- if (*p == '\0')
- {
- *pp = p;
- return this->make_eof_token(p);
- }
-
// Skip whitespace quickly.
while (*p == ' ' || *p == '\t' || *p == '\r')
++p;
continue;
}
+ char c0 = *p;
+
+ if (c0 == '\0')
+ {
+ *pp = p;
+ return this->make_eof_token(p);
+ }
+
+ char c1 = p[1];
+
// Skip C style comments.
- if (p[0] == '/' && p[1] == '*')
+ if (c0 == '/' && c1 == '*')
{
int lineno = this->lineno_;
int charpos = p - this->linestart_ + 1;
}
// Skip line comments.
- if (*p == '#')
+ if (c0 == '#')
{
*pp = p + 1;
if (!this->skip_line_comment(pp))
}
// Check for a name.
- if (this->can_start_name(p[0], p[1]))
+ if (this->can_start_name(c0, c1))
return this->gather_token(Token::TOKEN_STRING,
&Lex::can_continue_name,
p, p + 1, pp);
return this->gather_quoted_string(pp);
}
+ // Be careful not to lookahead past the end of the buffer.
+ char c2 = (c1 == '\0' ? '\0' : p[2]);
+
// Check for a number.
- if (this->can_start_hex(p[0], p[1], p[2]))
+ if (this->can_start_hex(c0, c1, c2))
return this->gather_token(Token::TOKEN_INTEGER,
&Lex::can_continue_hex,
p, p + 3, pp);
- if (Lex::can_start_number(p[0]))
+ if (Lex::can_start_number(c0))
return this->gather_token(Token::TOKEN_INTEGER,
&Lex::can_continue_number,
p, p + 1, pp);
// Check for operators.
- int opcode = Lex::three_char_operator(p[0], p[1], p[2]);
+ int opcode = Lex::three_char_operator(c0, c1, c2);
if (opcode != 0)
{
*pp = p + 3;
return this->make_token(opcode, p);
}
- opcode = Lex::two_char_operator(p[0], p[1]);
+ opcode = Lex::two_char_operator(c0, c1);
if (opcode != 0)
{
*pp = p + 2;
return this->make_token(opcode, p);
}
- opcode = Lex::one_char_operator(p[0]);
+ opcode = Lex::one_char_operator(c0);
if (opcode != 0)
{
*pp = p + 1;
Output_section* dot_section)
{
Output_section* section;
+ elfcpp::STT type = elfcpp::STT_NOTYPE;
+ elfcpp::STV vis = elfcpp::STV_DEFAULT;
+ unsigned char nonvis = 0;
uint64_t final_val = this->val_->eval_maybe_dot(symtab, layout, true,
is_dot_available,
dot_value, dot_section,
- §ion, NULL, false);
+ §ion, NULL, &type,
+ &vis, &nonvis, false, NULL);
Sized_symbol<size>* ssym = symtab->get_sized_symbol<size>(this->sym_);
ssym->set_value(final_val);
+ ssym->set_type(type);
+ ssym->set_visibility(vis);
+ ssym->set_nonvis(nonvis);
if (section != NULL)
ssym->set_output_section(section);
}
return;
Output_section* val_section;
+ bool is_valid;
uint64_t val = this->val_->eval_maybe_dot(symtab, layout, false,
is_dot_available, dot_value,
dot_section, &val_section, NULL,
- false);
- if (val_section != NULL && val_section != dot_section)
+ NULL, NULL, NULL, false, &is_valid);
+ if (!is_valid || (val_section != NULL && val_section != dot_section))
return;
if (parameters->target().get_size() == 32)
return false;
}
+// Populates the set with symbols defined in defsym LHS.
+
+void Script_options::find_defsym_defs(Unordered_set<std::string>& defsym_set)
+{
+ for (Symbol_assignments::const_iterator p = this->symbol_assignments_.begin();
+ p != this->symbol_assignments_.end();
+ ++p)
+ {
+ defsym_set.insert((*p)->name());
+ }
+}
+
+void
+Script_options::set_defsym_uses_in_real_elf(Symbol_table* symtab) const
+{
+ for (Symbol_assignments::const_iterator p = this->symbol_assignments_.begin();
+ p != this->symbol_assignments_.end();
+ ++p)
+ {
+ (*p)->value()->set_expr_sym_in_real_elf(symtab);
+ }
+}
+
// Add a symbol to be defined.
void
return true;
}
-// Helper function for read_version_script() and
-// read_commandline_script(). Processes the given file in the mode
-// indicated by first_token and lex_mode.
+// Helper function for read_version_script(), read_commandline_script() and
+// script_include_directive(). Processes the given file in the mode indicated
+// by first_token and lex_mode.
static bool
read_script_file(const char* filename, Command_line* cmdline,
Script_options* script_options,
int first_token, Lex::Mode lex_mode)
{
- // TODO: if filename is a relative filename, search for it manually
- // using "." + cmdline->options()->search_path() -- not dirsearch.
Dirsearch dirsearch;
+ std::string name = filename;
+
+ // If filename is a relative filename, search for it manually using "." +
+ // cmdline->options()->library_path() -- not dirsearch.
+ if (!IS_ABSOLUTE_PATH(filename))
+ {
+ const General_options::Dir_list& search_path =
+ cmdline->options().library_path();
+ name = Dirsearch::find_file_in_dir_list(name, search_path, ".");
+ }
// The file locking code wants to record a Task, but we haven't
// started the workqueue yet. This is only for debugging purposes,
Position_dependent_options posdep = cmdline->position_dependent_options();
if (posdep.format_enum() == General_options::OBJECT_FORMAT_BINARY)
posdep.set_format_enum(General_options::OBJECT_FORMAT_ELF);
- Input_file_argument input_argument(filename,
+ Input_file_argument input_argument(name.c_str(),
Input_file_argument::INPUT_FILE_TYPE_FILE,
"", false, posdep);
Input_file input_file(&input_argument);
{ "FLOAT", FLOAT },
{ "FORCE_COMMON_ALLOCATION", FORCE_COMMON_ALLOCATION },
{ "GROUP", GROUP },
+ { "HIDDEN", HIDDEN },
{ "HLL", HLL },
{ "INCLUDE", INCLUDE },
{ "INFO", INFO },
{ "SIZEOF_HEADERS", SIZEOF_HEADERS },
{ "SORT", SORT_BY_NAME },
{ "SORT_BY_ALIGNMENT", SORT_BY_ALIGNMENT },
+ { "SORT_BY_INIT_PRIORITY", SORT_BY_INIT_PRIORITY },
{ "SORT_BY_NAME", SORT_BY_NAME },
{ "SPECIAL", SPECIAL },
{ "SQUAD", SQUAD },
if (name_string[0] != 'l')
gold_error(_("library name must be prefixed with -l"));
-
+
Input_file_argument file(name_string.c_str() + 1,
Input_file_argument::INPUT_FILE_TYPE_LIBRARY,
"", false,
}
extern "C" void
-script_include_directive(void* closurev, const char*, size_t)
+script_include_directive(int first_token, void* closurev,
+ const char* filename, size_t length)
{
- // FIXME: Implement ?
- yyerror (closurev, _("GOLD does not currently support INCLUDE directives"));
+ Parser_closure* closure = static_cast<Parser_closure*>(closurev);
+ std::string name(filename, length);
+ Command_line* cmdline = closure->command_line();
+ read_script_file(name.c_str(), cmdline, &cmdline->script_options(),
+ first_token, Lex::LINKER_SCRIPT);
}
// Functions for memory regions.