gdb.python/py-evthreads.exp: add missing $
[deliverable/binutils-gdb.git] / gold / script.cc
index 659a0d2ee65f3e6018a80bc420c5f31d009b7b55..7df0c9e9dcc297b41fbcb84c002536b5ee57e2cd 100644 (file)
@@ -1,6 +1,6 @@
 // script.cc -- handle linker scripts for gold.
 
-// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -146,13 +146,7 @@ class Token
   }
 
   uint64_t
-  integer_value() const
-  {
-    gold_assert(this->classification_ == TOKEN_INTEGER);
-    // Null terminate.
-    std::string s(this->value_, this->value_length_);
-    return strtoull(s.c_str(), NULL, 0);
-  }
+  integer_value() const;
 
  private:
   // The token classification.
@@ -171,6 +165,35 @@ class Token
   int charpos_;
 };
 
+// Return the value of a TOKEN_INTEGER.
+
+uint64_t
+Token::integer_value() const
+{
+  gold_assert(this->classification_ == TOKEN_INTEGER);
+
+  size_t len = this->value_length_;
+
+  uint64_t multiplier = 1;
+  char last = this->value_[len - 1];
+  if (last == 'm' || last == 'M')
+    {
+      multiplier = 1024 * 1024;
+      --len;
+    }
+  else if (last == 'k' || last == 'K')
+    {
+      multiplier = 1024;
+      --len;
+    }
+
+  char *end;
+  uint64_t ret = strtoull(this->value_, &end, 0);
+  gold_assert(static_cast<size_t>(end - this->value_) == len);
+
+  return ret * multiplier;
+}
+
 // This class handles lexing a file into a sequence of tokens.
 
 class Lex
@@ -474,9 +497,7 @@ Lex::can_continue_name(const char* c)
 // For a number we accept 0x followed by hex digits, or any sequence
 // of digits.  The old linker accepts leading '$' for hex, and
 // trailing HXBOD.  Those are for MRI compatibility and we don't
-// accept them.  The old linker also accepts trailing MK for mega or
-// kilo.  FIXME: Those are mentioned in the documentation, and we
-// should accept them.
+// accept them.
 
 // Return whether C1 C2 C3 can start a hex number.
 
@@ -703,8 +724,15 @@ Lex::gather_token(Token::Classification classification,
                  const char** pp)
 {
   const char* new_match = NULL;
-  while ((new_match = (this->*can_continue_fn)(match)))
+  while ((new_match = (this->*can_continue_fn)(match)) != NULL)
     match = new_match;
+
+  // A special case: integers may be followed by a single M or K,
+  // case-insensitive.
+  if (classification == Token::TOKEN_INTEGER
+      && (*match == 'm' || *match == 'M' || *match == 'k' || *match == 'K'))
+    ++match;
+
   *pp = match;
   return this->make_token(classification, start, match - start, start);
 }
@@ -1206,7 +1234,8 @@ class Parser_closure
                  Command_line* command_line,
                 Script_options* script_options,
                 Lex* lex,
-                bool skip_on_incompatible_target)
+                bool skip_on_incompatible_target,
+                Script_info* script_info)
     : filename_(filename), posdep_options_(posdep_options),
       parsing_defsym_(parsing_defsym), in_group_(in_group),
       is_in_sysroot_(is_in_sysroot),
@@ -1214,7 +1243,8 @@ class Parser_closure
       found_incompatible_target_(false),
       command_line_(command_line), script_options_(script_options),
       version_script_info_(script_options->version_script_info()),
-      lex_(lex), lineno_(0), charpos_(0), lex_mode_stack_(), inputs_(NULL)
+      lex_(lex), lineno_(0), charpos_(0), lex_mode_stack_(), inputs_(NULL),
+      script_info_(script_info)
   {
     // We start out processing C symbols in the default lex mode.
     this->language_stack_.push_back(Version_script_info::LANGUAGE_C);
@@ -1365,6 +1395,11 @@ class Parser_closure
     this->language_stack_.pop_back();
   }
 
+  // Return a pointer to the incremental info.
+  Script_info*
+  script_info()
+  { return this->script_info_; }
+
  private:
   // The name of the file we are reading.
   const char* filename_;
@@ -1401,6 +1436,8 @@ class Parser_closure
   std::vector<Version_script_info::Language> language_stack_;
   // New input files found to add to the link.
   Input_arguments* inputs_;
+  // Pointer to incremental linking info.
+  Script_info* script_info_;
 };
 
 // FILE was found as an argument on the command line.  Try to read it
@@ -1422,6 +1459,17 @@ read_input_script(Workqueue* workqueue, Symbol_table* symtab, Layout* layout,
 
   Lex lex(input_string.c_str(), input_string.length(), PARSING_LINKER_SCRIPT);
 
+  Script_info* script_info = NULL;
+  if (layout->incremental_inputs() != NULL)
+    {
+      const std::string& filename = input_file->filename();
+      Timespec mtime = input_file->file().get_mtime();
+      unsigned int arg_serial = input_argument->file().arg_serial();
+      script_info = new Script_info(filename);
+      layout->incremental_inputs()->report_script(script_info, arg_serial,
+                                                 mtime);
+    }
+
   Parser_closure closure(input_file->filename().c_str(),
                         input_argument->file().options(),
                         false,
@@ -1430,7 +1478,8 @@ read_input_script(Workqueue* workqueue, Symbol_table* symtab, Layout* layout,
                          NULL,
                         layout->script_options(),
                         &lex,
-                        input_file->will_search_for());
+                        input_file->will_search_for(),
+                        script_info);
 
   bool old_saw_sections_clause =
     layout->script_options()->saw_sections_clause();
@@ -1476,16 +1525,6 @@ read_input_script(Workqueue* workqueue, Symbol_table* symtab, Layout* layout,
       this_blocker = nb;
     }
 
-  if (layout->incremental_inputs() != NULL)
-    {
-      // Like new Read_symbols(...) above, we rely on closure.inputs()
-      // getting leaked by closure.
-      const std::string& filename = input_file->filename();
-      Script_info* info = new Script_info(closure.inputs());
-      Timespec mtime = input_file->file().get_mtime();
-      layout->incremental_inputs()->report_script(filename, info, mtime);
-    }
-
   *used_next_blocker = true;
 
   return true;
@@ -1535,7 +1574,8 @@ read_script_file(const char* filename, Command_line* cmdline,
                          cmdline,
                         script_options,
                         &lex,
-                        false);
+                        false,
+                        NULL);
   if (yyparse(&closure) != 0)
     {
       input_file.file().unlock(task);
@@ -1594,7 +1634,7 @@ Script_options::define_symbol(const char* definition)
   Position_dependent_options posdep_options;
 
   Parser_closure closure("command line", posdep_options, true,
-                        false, false, NULL, this, &lex, false);
+                        false, false, NULL, this, &lex, false, NULL);
 
   if (yyparse(&closure) != 0)
     return false;
@@ -2620,7 +2660,8 @@ script_add_file(void* closurev, const char* name, size_t length)
                           Input_file_argument::INPUT_FILE_TYPE_FILE,
                           extra_search_path, false,
                           closure->position_dependent_options());
-  closure->inputs()->add_file(file);
+  Input_argument& arg = closure->inputs()->add_file(file);
+  arg.set_script_info(closure->script_info());
 }
 
 // Called by the bison parser to add a library to the link.
@@ -2638,7 +2679,8 @@ script_add_library(void* closurev, const char* name, size_t length)
                           Input_file_argument::INPUT_FILE_TYPE_LIBRARY,
                           "", false,
                           closure->position_dependent_options());
-  closure->inputs()->add_file(file);
+  Input_argument& arg = closure->inputs()->add_file(file);
+  arg.set_script_info(closure->script_info());
 }
 
 // Called by the bison parser to start a group.  If we are already in
@@ -2790,7 +2832,7 @@ script_check_output_format(void* closurev,
 {
   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
   std::string name(default_name, default_length);
-  Target* target = select_target_by_name(name.c_str());
+  Target* target = select_target_by_bfd_name(name.c_str());
   if (target == NULL || !parameters->is_compatible_target(target))
     {
       if (closure->skip_on_incompatible_target())
This page took 0.026701 seconds and 4 git commands to generate.