[lld] r300176 - Add comments for the RELRO segment.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 12 22:40:08 PDT 2017


Author: ruiu
Date: Thu Apr 13 00:40:07 2017
New Revision: 300176

URL: http://llvm.org/viewvc/llvm-project?rev=300176&view=rev
Log:
Add comments for the RELRO segment.

RELRO is a feature to make segments read-only after dynamic relocations
are applied. It is different from read-only segments because RELRO is
initially writable. And of course RELRO is different from writable
segments.

RELRO is not a very well known feature. We have a series of checks to
make a decision whether a section should be in a RELRO segment or not,
but we didn't describe why. This patch adds comments to explain how
that decision is made.

Modified:
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=300176&r1=300175&r2=300176&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Apr 13 00:40:07 2017
@@ -586,25 +586,63 @@ template <class ELFT> bool elf::isRelroS
     return false;
 
   uint64_t Flags = Sec->Flags;
+
+  // Non-allocatable or non-writable sections don't need RELRO because
+  // they are not writable or not even mapped to memory in the first place.
+  // RELRO is for sections that are essentially read-only but need to
+  // be writable only at process startup to allow dynamic linker to
+  // apply relocations.
   if (!(Flags & SHF_ALLOC) || !(Flags & SHF_WRITE))
     return false;
+
+  // Once initialized, TLS data segments are used as data templates
+  // for a thread-local storage. For each new thread, runtime
+  // allocates memory for a TLS and copy templates there. No thread
+  // are supposed to use templates directly. Thus, it can be in RELRO.
   if (Flags & SHF_TLS)
     return true;
 
+  // .init_array, .preinit_array and .fini_array contain pointers to
+  // functions that are executed on process startup or exit. These
+  // pointers are set by the static linker, and they are not expected
+  // to change at runtime. But if you are an attacker, you could do
+  // interesting things by manipulating pointers in .fini_array, for
+  // example. So they are put into RELRO.
   uint32_t Type = Sec->Type;
   if (Type == SHT_INIT_ARRAY || Type == SHT_FINI_ARRAY ||
       Type == SHT_PREINIT_ARRAY)
     return true;
 
+  // .got contains pointers to external symbols. They are resolved by
+  // the dynamic linker when a module is loaded into memory, and after
+  // that they are not expected to change. So, it can be in RELRO.
+  if (In<ELFT>::Got && Sec == In<ELFT>::Got->OutSec)
+    return true;
+
+  // .got.plt contains pointers to external function symbols. They are
+  // by default resolved lazily, so we usually cannot put it into RELRO.
+  // However, if "-z now" is given, the lazy symbol resolution is
+  // disabled, which enables us to put it into RELRO.
   if (Sec == In<ELFT>::GotPlt->OutSec)
     return Config->ZNow;
+
+  // .dynamic section contains data for the dynamic linker, and
+  // there's no need to write to it at runtime, so it's better to put
+  // it into RELRO.
   if (Sec == In<ELFT>::Dynamic->OutSec)
     return true;
-  if (In<ELFT>::Got && Sec == In<ELFT>::Got->OutSec)
-    return true;
+
+  // .bss.rel.ro is used for copy relocations for read-only symbols.
+  // Since the dynamic linker needs to process copy relocations, the
+  // section cannot be read-only, but once initialized, they shouldn't
+  // change.
   if (Sec == In<ELFT>::BssRelRo->OutSec)
     return true;
 
+  // Sections with some special names are put into RELRO. This is a
+  // bit unfortunate because section names shouldn't be significant in
+  // ELF in spirit. But in reality many linker features depend on
+  // magic section names.
   StringRef S = Sec->Name;
   return S == ".data.rel.ro" || S == ".ctors" || S == ".dtors" || S == ".jcr" ||
          S == ".eh_frame" || S == ".openbsd.randomdata";




More information about the llvm-commits mailing list