From a8c0a468c9e1adfe02c584dbc28ca733cd5b5171 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 18 Oct 2007 19:56:12 +0000 Subject: [PATCH] Rework section mapping algorithm to handle .data.rel.ro sections. --- gold/layout.cc | 79 +++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 26 deletions(-) diff --git a/gold/layout.cc b/gold/layout.cc index 8fafdcbaab..727b335097 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -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; } -- 2.11.0