Rework section mapping algorithm to handle .data.rel.ro sections.
authorIan Lance Taylor <iant@google.com>
Thu, 18 Oct 2007 19:56:12 +0000 (19:56 +0000)
committerIan Lance Taylor <iant@google.com>
Thu, 18 Oct 2007 19:56:12 +0000 (19:56 +0000)
gold/layout.cc

index 8fafdcbaabf11305cf1be7f24b8e73ad4e8fdfbb..727b335097e4ac05638f14e2a1539773e970a605 100644 (file)
@@ -1514,41 +1514,68 @@ Layout::output_section_name(const char* name, size_t* plen)
       return Layout::linkonce_output_name(name, plen);
     }
 
-  // If the section name has no '.', or only an initial '.', we use
-  // the name unchanged (i.e., ".text" is unchanged).
-
-  // Otherwise, if the section name does not include ".rel", we drop
-  // the last '.'  and everything that follows (i.e., ".text.XXX"
-  // becomes ".text").
-
-  // Otherwise, if the section name has zero or one '.' after the
-  // ".rel", we use the name unchanged (i.e., ".rel.text" is
-  // unchanged).
-
-  // Otherwise, we drop the last '.' and everything that follows
-  // (i.e., ".rel.text.XXX" becomes ".rel.text").
+  // gcc 4.3 generates the following sorts of section names when it
+  // needs a section name specific to a function:
+  //   .text.FN
+  //   .rodata.FN
+  //   .sdata2.FN
+  //   .data.FN
+  //   .data.rel.FN
+  //   .data.rel.local.FN
+  //   .data.rel.ro.FN
+  //   .data.rel.ro.local.FN
+  //   .sdata.FN
+  //   .bss.FN
+  //   .sbss.FN
+  //   .tdata.FN
+  //   .tbss.FN
+
+  // The GNU linker maps all of those to the part before the .FN,
+  // except that .data.rel.local.FN is mapped to .data, and
+  // .data.rel.ro.local.FN is mapped to .data.rel.ro.  The sections
+  // beginning with .data.rel.ro.local are grouped together.
+
+  // For an anonymous namespace, the string FN can contain a '.'.
+
+  // Also of interest: .rodata.strN.N, .rodata.cstN, both of which the
+  // GNU linker maps to .rodata.
+
+  // The .data.rel.ro sections enable a security feature triggered by
+  // the -z relro option.  Section which need to be relocated at
+  // program startup time but which may be readonly after startup are
+  // grouped into .data.rel.ro.  They are then put into a PT_GNU_RELRO
+  // segment.  The dynamic linker will make that segment writable,
+  // perform relocations, and then make it read-only.  FIXME: We do
+  // not yet implement this optimization.
+
+  // It is hard to handle this in a principled way.
+
+  // These are the rules we follow:
+
+  // If the section name has no initial '.', or no dot other than an
+  // initial '.', we use the name unchanged (i.e., "mysection" and
+  // ".text" are unchanged).
+
+  // If the name starts with ".data.rel.ro" we use ".data.rel.ro".
+
+  // Otherwise, we drop the second '.' and everything that comes after
+  // it (i.e., ".text.XXX" becomes ".text").
 
   const char* s = name;
-  if (*s == '.')
-    ++s;
+  if (*s != '.')
+    return name;
+  ++s;
   const char* sdot = strchr(s, '.');
   if (sdot == NULL)
     return name;
 
-  const char* srel = strstr(s, ".rel");
-  if (srel == NULL)
+  const char* const data_rel_ro = ".data.rel.ro";
+  if (strncmp(name, data_rel_ro, strlen(data_rel_ro)) == 0)
     {
-      *plen = sdot - name;
-      return name;
+      *plen = strlen(data_rel_ro);
+      return data_rel_ro;
     }
 
-  sdot = strchr(srel + 1, '.');
-  if (sdot == NULL)
-    return name;
-  sdot = strchr(sdot + 1, '.');
-  if (sdot == NULL)
-    return name;
-
   *plen = sdot - name;
   return name;
 }