gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gold / copy-relocs.cc
index ce019c4265ea498fc0ea09120885a77716380cdd..bb824b6a9fac312bf4688da02e4fca38c616cf30 100644 (file)
@@ -1,6 +1,6 @@
 // copy-relocs.cc -- handle COPY relocations for gold.
 
-// Copyright (C) 2006-2016 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.
@@ -141,6 +141,7 @@ Copy_relocs<sh_type, size, big_endian>::make_copy_reloc(
   unsigned int shndx = sym->shndx(&is_ordinary);
   gold_assert(is_ordinary);
   typename elfcpp::Elf_types<size>::Elf_WXword addralign;
+  bool is_readonly = false;
 
   {
     // Lock the object so we can read from it.  This is only called
@@ -150,6 +151,17 @@ Copy_relocs<sh_type, size, big_endian>::make_copy_reloc(
     Object* obj = sym->object();
     Task_lock_obj<Object> tl(dummy_task, obj);
     addralign = obj->section_addralign(shndx);
+    if (parameters->options().relro())
+      {
+       if ((obj->section_flags(shndx) & elfcpp::SHF_WRITE) == 0)
+         is_readonly = true;
+       else
+         {
+           // Symbols in .data.rel.ro should also be treated as read-only.
+           if (obj->section_name(shndx) == ".data.rel.ro")
+             is_readonly = true;
+         }
+      }
   }
 
   typename Sized_symbol<size>::Value_type value = sym->value();
@@ -159,16 +171,32 @@ Copy_relocs<sh_type, size, big_endian>::make_copy_reloc(
   // Mark the dynamic object as needed for the --as-needed option.
   sym->object()->set_is_needed();
 
-  if (this->dynbss_ == NULL)
+  Output_data_space* dynbss;
+
+  if (is_readonly)
     {
-      this->dynbss_ = new Output_data_space(addralign, "** dynbss");
-      layout->add_output_section_data(".bss",
-                                     elfcpp::SHT_NOBITS,
-                                     elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
-                                     this->dynbss_, ORDER_BSS, false);
+      if (this->dynrelro_ == NULL)
+       {
+         this->dynrelro_ = new Output_data_space(addralign, "** dynrelro");
+         layout->add_output_section_data(".data.rel.ro",
+                                         elfcpp::SHT_PROGBITS,
+                                         elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
+                                         this->dynrelro_, ORDER_RELRO, false);
+       }
+      dynbss = this->dynrelro_;
+    }
+  else
+    {
+      if (this->dynbss_ == NULL)
+       {
+         this->dynbss_ = new Output_data_space(addralign, "** dynbss");
+         layout->add_output_section_data(".bss",
+                                         elfcpp::SHT_NOBITS,
+                                         elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
+                                         this->dynbss_, ORDER_BSS, false);
+       }
+      dynbss = this->dynbss_;
     }
-
-  Output_data_space* dynbss = this->dynbss_;
 
   if (addralign > dynbss->addralign())
     dynbss->set_space_alignment(addralign);
This page took 0.025877 seconds and 4 git commands to generate.