2010-04-09 Doug Kwan <dougkwan@google.com>
[external/binutils.git] / gold / script-sections.cc
index 9daf9ec..24b9103 100644 (file)
@@ -85,6 +85,8 @@ class Orphan_section_placement
     PLACE_TEXT,
     PLACE_RODATA,
     PLACE_DATA,
+    PLACE_TLS,
+    PLACE_TLS_BSS,
     PLACE_BSS,
     PLACE_REL,
     PLACE_INTERP,
@@ -122,6 +124,8 @@ Orphan_section_placement::Orphan_section_placement()
   this->initialize_place(PLACE_TEXT, ".text");
   this->initialize_place(PLACE_RODATA, ".rodata");
   this->initialize_place(PLACE_DATA, ".data");
+  this->initialize_place(PLACE_TLS, NULL);
+  this->initialize_place(PLACE_TLS_BSS, NULL);
   this->initialize_place(PLACE_BSS, ".bss");
   this->initialize_place(PLACE_REL, NULL);
   this->initialize_place(PLACE_INTERP, ".interp");
@@ -232,6 +236,13 @@ Orphan_section_placement::find_place(Output_section* os,
     index = PLACE_LAST;
   else if (type == elfcpp::SHT_NOTE)
     index = PLACE_INTERP;
+  else if ((flags & elfcpp::SHF_TLS) != 0)
+    {
+      if (type == elfcpp::SHT_NOBITS)
+       index = PLACE_TLS_BSS;
+      else
+       index = PLACE_TLS;
+    }
   else if (type == elfcpp::SHT_NOBITS)
     index = PLACE_BSS;
   else if ((flags & elfcpp::SHF_WRITE) != 0)
@@ -265,6 +276,14 @@ Orphan_section_placement::find_place(Output_section* os,
        case PLACE_INTERP:
          follow = PLACE_TEXT;
          break;
+       case PLACE_TLS:
+         follow = PLACE_DATA;
+         break;
+       case PLACE_TLS_BSS:
+         follow = PLACE_TLS;
+         if (!this->places_[PLACE_TLS].have_location)
+           follow = PLACE_DATA;
+         break;
        }
       if (follow != PLACE_MAX && this->places_[follow].have_location)
        {
@@ -337,7 +356,8 @@ class Sections_element
   // section name.  This only real implementation is in
   // Output_section_definition.
   virtual const char*
-  output_section_name(const char*, const char*, Output_section***)
+  output_section_name(const char*, const char*, Output_section***,
+                     Script_sections::Section_type*)
   { return NULL; }
 
   // Initialize OSP with an output section.
@@ -406,7 +426,7 @@ class Sections_element_assignment : public Sections_element
  public:
   Sections_element_assignment(const char* name, size_t namelen,
                              Expression* val, bool provide, bool hidden)
-    : assignment_(name, namelen, val, provide, hidden)
+    : assignment_(name, namelen, false, val, provide, hidden)
   { }
 
   // Add the symbol to the symbol table.
@@ -524,7 +544,7 @@ class Output_section_element
 {
  public:
   // A list of input sections.
-  typedef std::list<std::pair<Relobj*, unsigned int> > Input_section_list;
+  typedef std::list<Output_section::Simple_input_section> Input_section_list;
 
   Output_section_element()
   { }
@@ -593,7 +613,7 @@ class Output_section_element_assignment : public Output_section_element
   Output_section_element_assignment(const char* name, size_t namelen,
                                    Expression* val, bool provide,
                                    bool hidden)
-    : assignment_(name, namelen, val, provide, hidden)
+    : assignment_(name, namelen, false, val, provide, hidden)
   { }
 
   // Add the symbol to the symbol table.
@@ -701,6 +721,7 @@ Output_section_element_dot_assignment::set_section_addresses(
          posd = new Output_data_const(this_fill, 0);
        }
       output_section->add_output_section_data(posd);
+      layout->new_output_section_data_from_script(posd);
     }
   *dot_value = next_dot;
 }
@@ -736,7 +757,7 @@ class Output_data_expression : public Output_section_data
   Output_data_expression(int size, bool is_signed, Expression* val,
                         const Symbol_table* symtab, const Layout* layout,
                         uint64_t dot_value, Output_section* dot_section)
-    : Output_section_data(size, 0),
+    : Output_section_data(size, 0, true),
       is_signed_(is_signed), val_(val), symtab_(symtab),
       layout_(layout), dot_value_(dot_value), dot_section_(dot_section)
   { }
@@ -877,13 +898,11 @@ Output_section_element_data::set_section_addresses(
     Input_section_list*)
 {
   gold_assert(os != NULL);
-  os->add_output_section_data(new Output_data_expression(this->size_,
-                                                        this->is_signed_,
-                                                        this->val_,
-                                                        symtab,
-                                                        layout,
-                                                        *dot_value,
-                                                        *dot_section));
+  Output_data_expression* expression =
+    new Output_data_expression(this->size_, this->is_signed_, this->val_,
+                              symtab, layout, *dot_value, *dot_section);
+  os->add_output_section_data(expression);
+  layout->new_output_section_data_from_script(expression);
   *dot_value += this->size_;
 }
 
@@ -1169,13 +1188,68 @@ Output_section_element_input::match_name(const char* file_name,
 
 // Information we use to sort the input sections.
 
-struct Input_section_info
+class Input_section_info
 {
-  Relobj* relobj;
-  unsigned int shndx;
-  std::string section_name;
-  uint64_t size;
-  uint64_t addralign;
+ public:
+  Input_section_info(const Output_section::Simple_input_section& input_section)
+    : input_section_(input_section), section_name_(),
+      size_(0), addralign_(1)
+  { }
+
+  // Return the simple input section.
+  const Output_section::Simple_input_section&
+  input_section() const
+  { return this->input_section_; }
+
+  // Return the object.
+  Relobj*
+  relobj() const
+  { return this->input_section_.relobj(); }
+
+  // Return the section index.
+  unsigned int
+  shndx()
+  { return this->input_section_.shndx(); }
+
+  // Return the section name.
+  const std::string&
+  section_name() const
+  { return this->section_name_; }
+
+  // Set the section name.
+  void
+  set_section_name(const std::string name)
+  { this->section_name_ = name; }
+
+  // Return the section size.
+  uint64_t
+  size() const
+  { return this->size_; }
+
+  // Set the section size.
+  void
+  set_size(uint64_t size)
+  { this->size_ = size; }
+
+  // Return the address alignment.
+  uint64_t
+  addralign() const
+  { return this->addralign_; }
+
+  // Set the address alignment.
+  void
+  set_addralign(uint64_t addralign)
+  { this->addralign_ = addralign; }
+
+ private:
+  // Input section, can be a relaxed section.
+  Output_section::Simple_input_section input_section_;
+  // Name of the section. 
+  std::string section_name_;
+  // Section size.
+  uint64_t size_;
+  // Address alignment.
+  uint64_t addralign_;
 };
 
 // A class to sort the input sections.
@@ -1202,22 +1276,22 @@ Input_section_sorter::operator()(const Input_section_info& isi1,
   if (this->section_sort_ == SORT_WILDCARD_BY_NAME
       || this->section_sort_ == SORT_WILDCARD_BY_NAME_BY_ALIGNMENT
       || (this->section_sort_ == SORT_WILDCARD_BY_ALIGNMENT_BY_NAME
-         && isi1.addralign == isi2.addralign))
+         && isi1.addralign() == isi2.addralign()))
     {
-      if (isi1.section_name != isi2.section_name)
-       return isi1.section_name < isi2.section_name;
+      if (isi1.section_name() != isi2.section_name())
+       return isi1.section_name() < isi2.section_name();
     }
   if (this->section_sort_ == SORT_WILDCARD_BY_ALIGNMENT
       || this->section_sort_ == SORT_WILDCARD_BY_NAME_BY_ALIGNMENT
       || this->section_sort_ == SORT_WILDCARD_BY_ALIGNMENT_BY_NAME)
     {
-      if (isi1.addralign != isi2.addralign)
-       return isi1.addralign < isi2.addralign;
+      if (isi1.addralign() != isi2.addralign())
+       return isi1.addralign() < isi2.addralign();
     }
   if (this->filename_sort_ == SORT_WILDCARD_BY_NAME)
     {
-      if (isi1.relobj->name() != isi2.relobj->name())
-       return isi1.relobj->name() < isi2.relobj->name();
+      if (isi1.relobj()->name() != isi2.relobj()->name())
+       return (isi1.relobj()->name() < isi2.relobj()->name());
     }
 
   // Otherwise we leave them in the same order.
@@ -1231,7 +1305,7 @@ Input_section_sorter::operator()(const Input_section_info& isi1,
 void
 Output_section_element_input::set_section_addresses(
     Symbol_table*,
-    Layout*,
+    Layout* layout,
     Output_section* output_section,
     uint64_t subalign,
     uint64_t* dot_value,
@@ -1255,25 +1329,36 @@ Output_section_element_input::set_section_addresses(
   Input_section_list::iterator p = input_sections->begin();
   while (p != input_sections->end())
     {
+      Relobj* relobj = p->relobj();
+      unsigned int shndx = p->shndx();      
+      Input_section_info isi(*p);
+
       // Calling section_name and section_addralign is not very
       // efficient.
-      Input_section_info isi;
-      isi.relobj = p->first;
-      isi.shndx = p->second;
 
       // Lock the object so that we can get information about the
       // section.  This is OK since we know we are single-threaded
       // here.
       {
        const Task* task = reinterpret_cast<const Task*>(-1);
-       Task_lock_obj<Object> tl(task, p->first);
-
-       isi.section_name = p->first->section_name(p->second);
-       isi.size = p->first->section_size(p->second);
-       isi.addralign = p->first->section_addralign(p->second);
+       Task_lock_obj<Object> tl(task, relobj);
+
+       isi.set_section_name(relobj->section_name(shndx));
+       if (p->is_relaxed_input_section())
+         {
+           // We use current data size because relxed section sizes may not
+           // have finalized yet.
+           isi.set_size(p->relaxed_input_section()->current_data_size());
+           isi.set_addralign(p->relaxed_input_section()->addralign());
+         }
+       else
+         {
+           isi.set_size(relobj->section_size(shndx));
+           isi.set_addralign(relobj->section_addralign(shndx));
+         }
       }
 
-      if (!this->match_file_name(isi.relobj->name().c_str()))
+      if (!this->match_file_name(relobj->name().c_str()))
        ++p;
       else if (this->input_section_patterns_.empty())
        {
@@ -1287,7 +1372,7 @@ Output_section_element_input::set_section_addresses(
            {
              const Input_section_pattern&
                isp(this->input_section_patterns_[i]);
-             if (match(isi.section_name.c_str(), isp.pattern.c_str(),
+             if (match(isi.section_name().c_str(), isp.pattern.c_str(),
                        isp.pattern_is_wildcard))
                break;
            }
@@ -1307,6 +1392,7 @@ Output_section_element_input::set_section_addresses(
   // sections are otherwise equal.  Add each input section to the
   // output section.
 
+  uint64_t dot = *dot_value;
   for (size_t i = 0; i < input_pattern_count; ++i)
     {
       if (matching_sections[i].empty())
@@ -1327,30 +1413,37 @@ Output_section_element_input::set_section_addresses(
           p != matching_sections[i].end();
           ++p)
        {
-         uint64_t this_subalign = p->addralign;
+         uint64_t this_subalign = p->addralign();
          if (this_subalign < subalign)
            this_subalign = subalign;
 
-         uint64_t address = align_address(*dot_value, this_subalign);
+         uint64_t address = align_address(dot, this_subalign);
 
-         if (address > *dot_value && !fill->empty())
+         if (address > dot && !fill->empty())
            {
              section_size_type length =
-               convert_to_section_size_type(address - *dot_value);
+               convert_to_section_size_type(address - dot);
              std::string this_fill = this->get_fill_string(fill, length);
              Output_section_data* posd = new Output_data_const(this_fill, 0);
              output_section->add_output_section_data(posd);
+             layout->new_output_section_data_from_script(posd);
            }
 
-         output_section->add_input_section_for_script(p->relobj,
-                                                      p->shndx,
-                                                      p->size,
-                                                      this_subalign);
+         output_section->add_simple_input_section(p->input_section(),
+                                                  p->size(),
+                                                  this_subalign);
 
-         *dot_value = address + p->size;
+         dot = address + p->size();
        }
     }
 
+  // An SHF_TLS/SHT_NOBITS section does not take up any
+  // address space.
+  if (output_section == NULL
+      || (output_section->flags() & elfcpp::SHF_TLS) == 0
+      || output_section->type() != elfcpp::SHT_NOBITS)
+    *dot_value = dot;
+
   this->final_dot_value_ = *dot_value;
   this->final_dot_section_ = *dot_section;
 }
@@ -1525,7 +1618,7 @@ class Output_section_definition : public Sections_element
   // section name.
   const char*
   output_section_name(const char* file_name, const char* section_name,
-                     Output_section***);
+                     Output_section***, Script_sections::Section_type*);
 
   // Initialize OSP with an output section.
   void
@@ -1573,7 +1666,14 @@ class Output_section_definition : public Sections_element
   void
   print(FILE*) const;
 
+  // Return the output section type if specified or Script_sections::ST_NONE.
+  Script_sections::Section_type
+  section_type() const;
+
  private:
+  static const char*
+  script_section_type_name(Script_section_type);
+
   typedef std::vector<Output_section_element*> Output_section_elements;
 
   // The output section name.
@@ -1606,6 +1706,8 @@ class Output_section_definition : public Sections_element
   uint64_t evaluated_addralign_;
   // The output section is relro.
   bool is_relro_;
+  // The output section type if specified.
+  enum Script_section_type script_section_type_;
 };
 
 // Constructor.
@@ -1627,7 +1729,8 @@ Output_section_definition::Output_section_definition(
     evaluated_address_(0),
     evaluated_load_address_(0),
     evaluated_addralign_(0),
-    is_relro_(false)
+    is_relro_(false),
+    script_section_type_(header->section_type)
 {
 }
 
@@ -1723,7 +1826,8 @@ Output_section_definition::create_sections(Layout* layout)
       if ((*p)->needs_output_section())
        {
          const char* name = this->name_.c_str();
-         this->output_section_ = layout->make_output_section_for_script(name);
+         this->output_section_ =
+           layout->make_output_section_for_script(name, this->section_type());
          return;
        }
     }
@@ -1781,9 +1885,11 @@ Output_section_definition::finalize_symbols(Symbol_table* symtab,
 // Return the output section name to use for an input section name.
 
 const char*
-Output_section_definition::output_section_name(const char* file_name,
-                                              const char* section_name,
-                                              Output_section*** slot)
+Output_section_definition::output_section_name(
+    const char* file_name,
+    const char* section_name,
+    Output_section*** slot,
+    Script_sections::Section_type *psection_type)
 {
   // Ask each element whether it matches NAME.
   for (Output_section_elements::const_iterator p = this->elements_.begin();
@@ -1795,6 +1901,7 @@ Output_section_definition::output_section_name(const char* file_name,
          // We found a match for NAME, which means that it should go
          // into this output section.
          *slot = &this->output_section_;
+         *psection_type = this->section_type();
          return this->name_.c_str();
        }
     }
@@ -1814,6 +1921,9 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
                                                  uint64_t* load_address)
 {
   uint64_t address;
+  uint64_t old_dot_value = *dot_value;
+  uint64_t old_load_address = *load_address;
+
   if (this->address_ == NULL)
     address = *dot_value;
   else
@@ -1849,10 +1959,11 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
 
   *dot_value = address;
 
-  // The address of non-SHF_ALLOC sections is forced to zero,
-  // regardless of what the linker script wants.
+  // Except for NOLOAD sections, the address of non-SHF_ALLOC sections is
+  // forced to zero, regardless of what the linker script wants.
   if (this->output_section_ != NULL
-      && (this->output_section_->flags() & elfcpp::SHF_ALLOC) != 0)
+      && ((this->output_section_->flags() & elfcpp::SHF_ALLOC) != 0
+         || this->output_section_->is_noload()))
     this->output_section_->set_address(address);
 
   this->evaluated_address_ = address;
@@ -1863,12 +1974,12 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
   else
     {
       Output_section* dummy;
-      uint64_t load_address =
+      uint64_t laddr =
        this->load_address_->eval_with_dot(symtab, layout, true, *dot_value,
                                           this->output_section_, &dummy);
       if (this->output_section_ != NULL)
-        this->output_section_->set_load_address(load_address);
-      this->evaluated_load_address_ = load_address;
+        this->output_section_->set_load_address(laddr);
+      this->evaluated_load_address_ = laddr;
     }
 
   uint64_t subalign;
@@ -1937,6 +2048,13 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
        this->output_section_->set_is_relro();
       else
        this->output_section_->clear_is_relro();
+
+      // If this is a NOLOAD section, keep dot and load address unchanged.
+      if (this->output_section_->is_noload())
+       {
+         *dot_value = old_dot_value;
+         *load_address = old_load_address;
+       }
     }
 }
 
@@ -2094,6 +2212,10 @@ Output_section_definition::print(FILE* f) const
       fprintf(f, " ");
     }
 
+  if (this->script_section_type_ != SCRIPT_SECTION_TYPE_NONE)
+      fprintf(f, "(%s) ",
+             this->script_section_type_name(this->script_section_type_));
+
   fprintf(f, ": ");
 
   if (this->load_address_ != NULL)
@@ -2143,6 +2265,52 @@ Output_section_definition::print(FILE* f) const
   fprintf(f, "\n");
 }
 
+Script_sections::Section_type
+Output_section_definition::section_type() const
+{
+  switch (this->script_section_type_)
+    {
+    case SCRIPT_SECTION_TYPE_NONE:
+      return Script_sections::ST_NONE;
+    case SCRIPT_SECTION_TYPE_NOLOAD:
+      return Script_sections::ST_NOLOAD;
+    case SCRIPT_SECTION_TYPE_COPY:
+    case SCRIPT_SECTION_TYPE_DSECT:
+    case SCRIPT_SECTION_TYPE_INFO:
+    case SCRIPT_SECTION_TYPE_OVERLAY:
+      // There are not really support so we treat them as ST_NONE.  The
+      // parse should have issued errors for them already.
+      return Script_sections::ST_NONE;
+    default:
+      gold_unreachable();
+    }
+}
+
+// Return the name of a script section type.
+
+const char*
+Output_section_definition::script_section_type_name (
+    Script_section_type script_section_type)
+{
+  switch (script_section_type)
+    {
+    case SCRIPT_SECTION_TYPE_NONE:
+      return "NONE";
+    case SCRIPT_SECTION_TYPE_NOLOAD:
+      return "NOLOAD";
+    case SCRIPT_SECTION_TYPE_DSECT:
+      return "DSECT";
+    case SCRIPT_SECTION_TYPE_COPY:
+      return "COPY";
+    case SCRIPT_SECTION_TYPE_INFO:
+      return "INFO";
+    case SCRIPT_SECTION_TYPE_OVERLAY:
+      return "OVERLAY";
+    default:
+      gold_unreachable();
+    }
+}
+
 // An output section created to hold orphaned input sections.  These
 // do not actually appear in linker scripts.  However, for convenience
 // when setting the output section addresses, we put a marker to these
@@ -2202,7 +2370,7 @@ Orphan_output_section::set_section_addresses(Symbol_table*, Layout*,
                                             uint64_t* dot_value,
                                              uint64_t* load_address)
 {
-  typedef std::list<std::pair<Relobj*, unsigned int> > Input_section_list;
+  typedef std::list<Output_section::Simple_input_section> Input_section_list;
 
   bool have_load_address = *load_address != *dot_value;
 
@@ -2227,27 +2395,37 @@ Orphan_output_section::set_section_addresses(Symbol_table*, Layout*,
       uint64_t addralign;
       uint64_t size;
 
-      // We know what are single-threaded, so it is OK to lock the
+      // We know we are single-threaded, so it is OK to lock the
       // object.
       {
        const Task* task = reinterpret_cast<const Task*>(-1);
-       Task_lock_obj<Object> tl(task, p->first);
-       addralign = p->first->section_addralign(p->second);
-       size = p->first->section_size(p->second);
+       Task_lock_obj<Object> tl(task, p->relobj());
+       addralign = p->relobj()->section_addralign(p->shndx());
+       if (p->is_relaxed_input_section())
+         // We use current data size because relxed section sizes may not
+         // have finalized yet.
+         size = p->relaxed_input_section()->current_data_size();
+       else
+         size = p->relobj()->section_size(p->shndx());
       }
 
       address = align_address(address, addralign);
-      this->os_->add_input_section_for_script(p->first, p->second, size,
-                                              addralign);
+      this->os_->add_simple_input_section(*p, size, addralign);
       address += size;
     }
 
-  if (!have_load_address)
-    *load_address = address;
-  else
-    *load_address += address - *dot_value;
+  // An SHF_TLS/SHT_NOBITS section does not take up any address space.
+  if (this->os_ == NULL
+      || (this->os_->flags() & elfcpp::SHF_TLS) == 0
+      || this->os_->type() != elfcpp::SHT_NOBITS)
+    {
+      if (!have_load_address)
+       *load_address = address;
+      else
+       *load_address += address - *dot_value;
 
-  *dot_value = address;
+      *dot_value = address;
+    }
 }
 
 // Get the list of segments to use for an allocated section when using
@@ -2333,6 +2511,11 @@ class Phdrs_element
   segment()
   { return this->segment_; }
 
+  // Release the segment.
+  void
+  release_segment()
+  { this->segment_ = NULL; }
+
   // Set the segment flags if appropriate.
   void
   set_flags_if_valid()
@@ -2399,7 +2582,8 @@ Script_sections::Script_sections()
     orphan_section_placement_(NULL),
     data_segment_align_start_(),
     saw_data_segment_align_(false),
-    saw_relro_end_(false)
+    saw_relro_end_(false),
+    saw_segment_start_expression_(false)
 {
 }
 
@@ -2452,6 +2636,15 @@ Script_sections::add_dot_assignment(Expression* val)
     this->output_section_->add_dot_assignment(val);
   else
     {
+      // The GNU linker permits assignments to . to appears outside of
+      // a SECTIONS clause, and treats it as appearing inside, so
+      // sections_elements_ may be NULL here.
+      if (this->sections_elements_ == NULL)
+       {
+         this->sections_elements_ = new Sections_elements;
+         this->saw_sections_clause_ = true;
+       }
+
       Sections_element* p = new Sections_element_dot_assignment(val);
       this->sections_elements_->push_back(p);
     }
@@ -2607,16 +2800,19 @@ Script_sections::finalize_symbols(Symbol_table* symtab, const Layout* layout)
 // and section name.
 
 const char*
-Script_sections::output_section_name(const char* file_name,
-                                    const char* section_name,
-                                    Output_section*** output_section_slot)
+Script_sections::output_section_name(
+    const char* file_name,
+    const char* section_name,
+    Output_section*** output_section_slot,
+    Script_sections::Section_type *psection_type)
 {
   for (Sections_elements::const_iterator p = this->sections_elements_->begin();
        p != this->sections_elements_->end();
        ++p)
     {
       const char* ret = (*p)->output_section_name(file_name, section_name,
-                                                 output_section_slot);
+                                                 output_section_slot,
+                                                 psection_type);
 
       if (ret != NULL)
        {
@@ -2625,6 +2821,7 @@ Script_sections::output_section_name(const char* file_name,
          if (strcmp(ret, "/DISCARD/") == 0)
            {
              *output_section_slot = NULL;
+             *psection_type = Script_sections::ST_NONE;
              return NULL;
            }
          return ret;
@@ -2635,6 +2832,7 @@ Script_sections::output_section_name(const char* file_name,
   // gets the name of the input section.
 
   *output_section_slot = NULL;
+  *psection_type = Script_sections::ST_NONE;
 
   return section_name;
 }
@@ -2753,10 +2951,52 @@ Script_sections::set_section_addresses(Symbol_table* symtab, Layout* layout)
   // For a relocatable link, we implicitly set dot to zero.
   uint64_t dot_value = 0;
   uint64_t load_address = 0;
+
+  // Check to see if we want to use any of -Ttext, -Tdata and -Tbss options
+  // to set section addresses.  If the script has any SEGMENT_START
+  // expression, we do not set the section addresses.
+  bool use_tsection_options =
+    (!this->saw_segment_start_expression_
+     && (parameters->options().user_set_Ttext()
+        || parameters->options().user_set_Tdata()
+        || parameters->options().user_set_Tbss()));
+
   for (Sections_elements::iterator p = this->sections_elements_->begin();
        p != this->sections_elements_->end();
        ++p)
-    (*p)->set_section_addresses(symtab, layout, &dot_value, &load_address);
+    {
+      Output_section* os = (*p)->get_output_section();
+
+      // Handle -Ttext, -Tdata and -Tbss options.  We do this by looking for
+      // the special sections by names and doing dot assignments. 
+      if (use_tsection_options
+         && os != NULL
+         && (os->flags() & elfcpp::SHF_ALLOC) != 0)
+       {
+         uint64_t new_dot_value = dot_value;
+
+         if (parameters->options().user_set_Ttext()
+             && strcmp(os->name(), ".text") == 0)
+           new_dot_value = parameters->options().Ttext();
+         else if (parameters->options().user_set_Tdata()
+             && strcmp(os->name(), ".data") == 0)
+           new_dot_value = parameters->options().Tdata();
+         else if (parameters->options().user_set_Tbss()
+             && strcmp(os->name(), ".bss") == 0)
+           new_dot_value = parameters->options().Tbss();
+
+         // Update dot and load address if necessary.
+         if (new_dot_value < dot_value)
+           gold_error(_("dot may not move backward"));
+         else if (new_dot_value != dot_value)
+           {
+             dot_value = new_dot_value;
+             load_address = new_dot_value;
+           }
+       }
+
+      (*p)->set_section_addresses(symtab, layout, &dot_value, &load_address);
+    } 
 
   if (this->phdrs_elements_ != NULL)
     {
@@ -2808,6 +3048,12 @@ Sort_output_sections::operator()(const Output_section* os1,
   if (os1->type() == elfcpp::SHT_NOBITS && os2->type() == elfcpp::SHT_PROGBITS)
     return false;
 
+  // Sort non-NOLOAD before NOLOAD.
+  if (os1->is_noload() && !os2->is_noload())
+    return true;
+  if (!os1->is_noload() && os2->is_noload())
+    return true;
+  
   // Otherwise we don't care.
   return false;
 }
@@ -2954,7 +3200,7 @@ Script_sections::create_segments(Layout* layout)
          is_current_seg_readonly = true;
        }
 
-      current_seg->add_output_section(*p, seg_flags);
+      current_seg->add_output_section(*p, seg_flags, false);
 
       if (((*p)->flags() & elfcpp::SHF_WRITE) != 0)
        is_current_seg_readonly = false;
@@ -2981,6 +3227,11 @@ Script_sections::create_segments(Layout* layout)
   if (first_seg == NULL)
     return NULL;
 
+  // -n or -N mean that the program is not demand paged and there is
+  // no need to put the program headers in a PT_LOAD segment.
+  if (parameters->options().nmagic() || parameters->options().omagic())
+    return NULL;
+
   size_t sizeof_headers = this->total_header_size(layout);
 
   uint64_t vma = first_seg->vaddr();
@@ -3028,7 +3279,7 @@ Script_sections::create_note_and_tls_segments(
            Layout::section_flags_to_segment((*p)->flags());
          Output_segment* oseg = layout->make_output_segment(elfcpp::PT_NOTE,
                                                             seg_flags);
-         oseg->add_output_section(*p, seg_flags);
+         oseg->add_output_section(*p, seg_flags, false);
 
          // Incorporate any subsequent SHT_NOTE sections, in the
          // hopes that the script is sensible.
@@ -3037,7 +3288,7 @@ Script_sections::create_note_and_tls_segments(
                 && (*pnext)->type() == elfcpp::SHT_NOTE)
            {
              seg_flags = Layout::section_flags_to_segment((*pnext)->flags());
-             oseg->add_output_section(*pnext, seg_flags);
+             oseg->add_output_section(*pnext, seg_flags, false);
              p = pnext;
              ++pnext;
            }
@@ -3052,14 +3303,14 @@ Script_sections::create_note_and_tls_segments(
            Layout::section_flags_to_segment((*p)->flags());
          Output_segment* oseg = layout->make_output_segment(elfcpp::PT_TLS,
                                                             seg_flags);
-         oseg->add_output_section(*p, seg_flags);
+         oseg->add_output_section(*p, seg_flags, false);
 
          Layout::Section_list::const_iterator pnext = p + 1;
          while (pnext != sections->end()
                 && ((*pnext)->flags() & elfcpp::SHF_TLS) != 0)
            {
              seg_flags = Layout::section_flags_to_segment((*pnext)->flags());
-             oseg->add_output_section(*pnext, seg_flags);
+             oseg->add_output_section(*pnext, seg_flags, false);
              p = pnext;
              ++pnext;
            }
@@ -3071,7 +3322,7 @@ Script_sections::create_note_and_tls_segments(
 
 // Add a program header.  The PHDRS clause is syntactically distinct
 // from the SECTIONS clause, but we implement it with the SECTIONS
-// support becauase PHDRS is useless if there is no SECTIONS clause.
+// support because PHDRS is useless if there is no SECTIONS clause.
 
 void
 Script_sections::add_phdr(const char* name, size_t namelen, unsigned int type,
@@ -3160,12 +3411,15 @@ Script_sections::attach_sections_using_phdrs_clause(Layout* layout)
   // Output sections in the script which do not list segments are
   // attached to the same set of segments as the immediately preceding
   // output section.
+  
   String_list* phdr_names = NULL;
+  bool load_segments_only = false;
   for (Sections_elements::const_iterator p = this->sections_elements_->begin();
        p != this->sections_elements_->end();
        ++p)
     {
       bool orphan;
+      String_list* old_phdr_names = phdr_names;
       Output_section* os = (*p)->allocate_to_segment(&phdr_names, &orphan);
       if (os == NULL)
        continue;
@@ -3176,6 +3430,11 @@ Script_sections::attach_sections_using_phdrs_clause(Layout* layout)
          continue;
        }
 
+      // We see a list of segments names.  Disable PT_LOAD segment only
+      // filtering.
+      if (old_phdr_names != phdr_names)
+       load_segments_only = false;
+               
       // If this is an orphan section--one that was not explicitly
       // mentioned in the linker script--then it should not inherit
       // any segment type other than PT_LOAD.  Otherwise, e.g., the
@@ -3184,17 +3443,9 @@ Script_sections::attach_sections_using_phdrs_clause(Layout* layout)
       // we trust the linker script.
       if (orphan)
        {
-         String_list::iterator q = phdr_names->begin();
-         while (q != phdr_names->end())
-           {
-             Name_to_segment::const_iterator r = name_to_segment.find(*q);
-             // We give errors about unknown segments below.
-             if (r == name_to_segment.end()
-                 || r->second->type() == elfcpp::PT_LOAD)
-               ++q;
-             else
-               q = phdr_names->erase(q);
-           }
+         // Enable PT_LOAD segments only filtering until we see another
+         // list of segment names.
+         load_segments_only = true;
        }
 
       bool in_load_segment = false;
@@ -3207,9 +3458,13 @@ Script_sections::attach_sections_using_phdrs_clause(Layout* layout)
            gold_error(_("no segment %s"), q->c_str());
          else
            {
+             if (load_segments_only
+                 && r->second->type() != elfcpp::PT_LOAD)
+               continue;
+
              elfcpp::Elf_Word seg_flags =
                Layout::section_flags_to_segment(os->flags());
-             r->second->add_output_section(os, seg_flags);
+             r->second->add_output_section(os, seg_flags, false);
 
              if (r->second->type() == elfcpp::PT_LOAD)
                {
@@ -3361,6 +3616,21 @@ Script_sections::get_output_section_info(const char* name, uint64_t* address,
   return false;
 }
 
+// Release all Output_segments.  This remove all pointers to all
+// Output_segments.
+
+void
+Script_sections::release_segments()
+{
+  if (this->saw_phdrs_clause())
+    {
+      for (Phdrs_elements::const_iterator p = this->phdrs_elements_->begin();
+          p != this->phdrs_elements_->end();
+          ++p)
+       (*p)->release_segment();
+    }
+}
+
 // Print the SECTIONS clause to F for debugging.
 
 void