<div dir="ltr">Thanks!<div><br></div><div>btw, in the future it would be nice to mention the PR (PR25188) in the commit message.</div><div><br></div><div>-- Sean Silva</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Oct 15, 2015 at 10:11 AM, Rui Ueyama via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: ruiu<br>
Date: Thu Oct 15 12:11:03 2015<br>
New Revision: 250432<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=250432&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=250432&view=rev</a><br>
Log:<br>
ELF2: Implement __start_SECNAME and __stop_SECNAME.<br>
<br>
If a section name is valid as a C identifier (which is rare because of<br>
the leading '.'), linkers are expected to define __start_<secname> and<br>
__stop_<secname> symbols. They are at beginning and end of the section,<br>
respectively. This is not requested by the ELF standard, but GNU ld and<br>
gold provide this feature.<br>
<br>
Added:<br>
    lld/trunk/test/elf2/startstop.s<br>
Modified:<br>
    lld/trunk/ELF/SymbolTable.cpp<br>
    lld/trunk/ELF/SymbolTable.h<br>
    lld/trunk/ELF/Writer.cpp<br>
<br>
Modified: lld/trunk/ELF/SymbolTable.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=250432&r1=250431&r2=250432&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=250432&r1=250431&r2=250432&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/SymbolTable.cpp (original)<br>
+++ lld/trunk/ELF/SymbolTable.cpp Thu Oct 15 12:11:03 2015<br>
@@ -88,6 +88,12 @@ template <class ELFT> void SymbolTable<E<br>
   resolve(Sym);<br>
 }<br>
<br>
+template <class ELFT> bool SymbolTable<ELFT>::isUndefined(StringRef Name) {<br>
+  if (SymbolBody *Sym = find(Name))<br>
+    return Sym->isUndefined();<br>
+  return false;<br>
+}<br>
+<br>
 template <class ELFT><br>
 void SymbolTable<ELFT>::addELFFile(ELFFileBase<ELFT> *File) {<br>
   if (auto *O = dyn_cast<ObjectFile<ELFT>>(File))<br>
<br>
Modified: lld/trunk/ELF/SymbolTable.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=250432&r1=250431&r2=250432&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=250432&r1=250431&r2=250432&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/SymbolTable.h (original)<br>
+++ lld/trunk/ELF/SymbolTable.h Thu Oct 15 12:11:03 2015<br>
@@ -54,6 +54,7 @@ public:<br>
                        OutputSectionBase<ELFT::Is64Bits> &Section,<br>
                        typename llvm::object::ELFFile<ELFT>::uintX_t Value);<br>
   void addIgnoredSym(StringRef Name);<br>
+  bool isUndefined(StringRef Name);<br>
   void scanShlibUndefined();<br>
<br>
 private:<br>
<br>
Modified: lld/trunk/ELF/Writer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=250432&r1=250431&r2=250432&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=250432&r1=250431&r2=250432&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Writer.cpp (original)<br>
+++ lld/trunk/ELF/Writer.cpp Thu Oct 15 12:11:03 2015<br>
@@ -16,6 +16,7 @@<br>
 #include "llvm/ADT/SmallPtrSet.h"<br>
 #include "llvm/ADT/StringSwitch.h"<br>
 #include "llvm/Support/FileOutputBuffer.h"<br>
+#include "llvm/Support/StringSaver.h"<br>
<br>
 using namespace llvm;<br>
 using namespace llvm::ELF;<br>
@@ -70,9 +71,11 @@ private:<br>
   std::unique_ptr<llvm::FileOutputBuffer> Buffer;<br>
<br>
   SpecificBumpPtrAllocator<OutputSection<ELFT>> SecAlloc;<br>
+  BumpPtrAllocator Alloc;<br>
   std::vector<OutputSectionBase<ELFT::Is64Bits> *> OutputSections;<br>
   unsigned getNumSections() const { return OutputSections.size() + 1; }<br>
<br>
+  void addStartStopSymbols(OutputSection<ELFT> *Sec);<br>
   void setPhdr(Elf_Phdr *PH, uint32_t Type, uint32_t Flags, uintX_t FileOff,<br>
                uintX_t VA, uintX_t Align);<br>
   void copyPhdr(Elf_Phdr *PH, OutputSectionBase<ELFT::Is64Bits> *From);<br>
@@ -400,6 +403,8 @@ template <class ELFT> void Writer<ELFT>:<br>
   if (!isOutputDynamic())<br>
     Symtab.addIgnoredSym("__tls_get_addr");<br>
<br>
+  std::vector<OutputSection<ELFT> *> RegularSections;<br>
+<br>
   for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab.getObjectFiles()) {<br>
     for (InputSection<ELFT> *C : F->getSections()) {<br>
       if (!C || C == &InputSection<ELFT>::Discarded)<br>
@@ -413,12 +418,16 @@ template <class ELFT> void Writer<ELFT>:<br>
         Sec = new (SecAlloc.Allocate())<br>
             OutputSection<ELFT>(Key.Name, Key.Type, Key.Flags);<br>
         OutputSections.push_back(Sec);<br>
+        RegularSections.push_back(Sec);<br>
       }<br>
       Sec->addSection(C);<br>
       scanRelocs(*C);<br>
     }<br>
   }<br>
<br>
+  for (OutputSection<ELFT> *Sec : RegularSections)<br>
+    addStartStopSymbols(Sec);<br>
+<br>
   Out<ELFT>::Dynamic->PreInitArraySec =<br>
       Map.lookup({".preinit_array", SHT_PREINIT_ARRAY, SHF_WRITE | SHF_ALLOC});<br>
   Out<ELFT>::Dynamic->InitArraySec =<br>
@@ -501,6 +510,38 @@ template <class ELFT> void Writer<ELFT>:<br>
   Out<ELFT>::Opd = Map.lookup({".opd", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC});<br>
 }<br>
<br>
+static bool isAlpha(char C) {<br>
+  return ('a' <= C && C <= 'z') || ('A' <= C && C <= 'Z') || C == '_';<br>
+}<br>
+<br>
+static bool isAlnum(char C) { return isAlpha(C) || ('0' <= C && C <= '9'); }<br>
+<br>
+// Returns true if S is valid as a C language identifier.<br>
+static bool isValidCIdentifier(StringRef S) {<br>
+  if (S.empty() || !isAlpha(S[0]))<br>
+    return false;<br>
+  return std::all_of(S.begin() + 1, S.end(), isAlnum);<br>
+}<br>
+<br>
+// If a section name is valid as a C identifier (which is rare because of<br>
+// the leading '.'), linkers are expected to define __start_<secname> and<br>
+// __stop_<secname> symbols. They are at beginning and end of the section,<br>
+// respectively. This is not requested by the ELF standard, but GNU ld and<br>
+// gold provide the feature, and used by many programs.<br>
+template <class ELFT><br>
+void Writer<ELFT>::addStartStopSymbols(OutputSection<ELFT> *Sec) {<br>
+  StringRef S = Sec->getName();<br>
+  if (!isValidCIdentifier(S))<br>
+    return;<br>
+  StringSaver Saver(Alloc);<br>
+  StringRef Start = Saver.save("__start_" + S);<br>
+  StringRef Stop = Saver.save("__stop_" + S);<br>
+  if (Symtab.isUndefined(Start))<br>
+    Symtab.addSyntheticSym(Start, *Sec, 0);<br>
+  if (Symtab.isUndefined(Stop))<br>
+    Symtab.addSyntheticSym(Stop, *Sec, Sec->getSize());<br>
+}<br>
+<br>
 template <class ELFT><br>
 static bool needsPhdr(OutputSectionBase<ELFT::Is64Bits> *Sec) {<br>
   return Sec->getFlags() & SHF_ALLOC;<br>
<br>
Added: lld/trunk/test/elf2/startstop.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/startstop.s?rev=250432&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/startstop.s?rev=250432&view=auto</a><br>
==============================================================================<br>
--- lld/trunk/test/elf2/startstop.s (added)<br>
+++ lld/trunk/test/elf2/startstop.s Thu Oct 15 12:11:03 2015<br>
@@ -0,0 +1,54 @@<br>
+// REQUIRES: x86<br>
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t<br>
+// RUN: ld.lld2 %t -o %tout<br>
+// RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s<br>
+// RUN: llvm-readobj -symbols %tout | FileCheck -check-prefix=SYMBOL %s<br>
+<br>
+// DISASM: _start:<br>
+// DISASM:    11000:       e8 0a 00 00 00  callq   10<br>
+// DISASM:    11005:       e8 08 00 00 00  callq   8<br>
+// DISASM:    1100a:       e8 03 00 00 00  callq   3<br>
+// DISASM: Disassembly of section foo:<br>
+// DISASM: __start_foo:<br>
+// DISASM:    1100f:       90      nop<br>
+// DISASM:    11010:       90      nop<br>
+// DISASM:    11011:       90      nop<br>
+// DISASM: Disassembly of section bar:<br>
+// DISASM: __start_bar:<br>
+// DISASM:    11012:       90      nop<br>
+// DISASM:    11013:       90      nop<br>
+// DISASM:    11014:       90      nop<br>
+<br>
+// SYMBOL: Symbol {<br>
+// SYMBOL:   Name: __start_bar<br>
+// SYMBOL:   Value: 0x11012<br>
+// SYMBOL:   Section: bar<br>
+// SYMBOL: }<br>
+// SYMBOL-NOT:   Section: __stop_bar<br>
+// SYMBOL: Symbol {<br>
+// SYMBOL:   Name: __start_foo<br>
+// SYMBOL:   Value: 0x1100F<br>
+// SYMBOL:   Section: foo<br>
+// SYMBOL: }<br>
+// SYMBOL: Symbol {<br>
+// SYMBOL:   Name: __stop_foo<br>
+// SYMBOL:   Value: 0x11012<br>
+// SYMBOL:   Section: foo (0x2)<br>
+// SYMBOL: }<br>
+<br>
+.global _start<br>
+.text<br>
+_start:<br>
+       call __start_foo<br>
+       call __stop_foo<br>
+       call __start_bar<br>
+<br>
+.section foo,"ax"<br>
+       nop<br>
+       nop<br>
+       nop<br>
+<br>
+.section bar,"ax"<br>
+       nop<br>
+       nop<br>
+       nop<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>