[lld] r260460 - ELF: Implement __attribute__((init_priority(N)) support.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 10 16:10:46 PST 2016


Clang actually seems to use .{init,fini}_array on x86_64-unknown-linux, but
it indeed produces .[cd]tors for x86_64-scei-ps4. I'll add that with a test.

On Wed, Feb 10, 2016 at 4:07 PM, Sean Silva <chisophugis at gmail.com> wrote:

>
>
> On Wed, Feb 10, 2016 at 3:42 PM, Rui Ueyama <ruiu at google.com> wrote:
>
>> Are .[cd]tors still in use?
>>
>
> .[cd]tors are the default on most places I think. E.g. clang uses them on
> x86_64-unknown-linux and x86_64-scei-ps4. (haven't tried on other
> architectures).
>
> -- Sean Silva
>
>
>>
>> On Wed, Feb 10, 2016 at 3:38 PM, Sean Silva <chisophugis at gmail.com>
>> wrote:
>>
>>> Did you intend to add .[cd]tors support also? That was part of PR26538.
>>>
>>> -- Sean Silva
>>>
>>> On Wed, Feb 10, 2016 at 3:20 PM, Rui Ueyama via llvm-commits <
>>> llvm-commits at lists.llvm.org> wrote:
>>>
>>>> Author: ruiu
>>>> Date: Wed Feb 10 17:20:42 2016
>>>> New Revision: 260460
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=260460&view=rev
>>>> Log:
>>>> ELF: Implement __attribute__((init_priority(N)) support.
>>>>
>>>> Added:
>>>>     lld/trunk/test/ELF/init_fini_priority.s
>>>> Modified:
>>>>     lld/trunk/ELF/OutputSections.cpp
>>>>     lld/trunk/ELF/OutputSections.h
>>>>     lld/trunk/ELF/Writer.cpp
>>>>
>>>> Modified: lld/trunk/ELF/OutputSections.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=260460&r1=260459&r2=260460&view=diff
>>>>
>>>> ==============================================================================
>>>> --- lld/trunk/ELF/OutputSections.cpp (original)
>>>> +++ lld/trunk/ELF/OutputSections.cpp Wed Feb 10 17:20:42 2016
>>>> @@ -750,6 +750,44 @@ void OutputSection<ELFT>::addSection(Inp
>>>>    this->Header.sh_size = Off;
>>>>  }
>>>>
>>>> +// If an input string is in the form of "foo.N" where N is a number,
>>>> +// return N. Otherwise, returns 65536, which is one greater than the
>>>> +// lowest priority.
>>>> +static int getPriority(StringRef S) {
>>>> +  size_t Pos = S.rfind('.');
>>>> +  if (Pos == StringRef::npos)
>>>> +    return 65536;
>>>> +  int V;
>>>> +  if (S.substr(Pos + 1).getAsInteger(10, V))
>>>> +    return 65536;
>>>> +  return V;
>>>> +}
>>>> +
>>>> +// Sorts input sections by section name suffixes, so that .foo.N comes
>>>> +// before .foo.M if N < M. Used to sort .{init,fini}_array.N sections.
>>>> +// For more detail, read the section of the GCC's manual about
>>>> init_priority.
>>>> +template <class ELFT> void OutputSection<ELFT>::sortByPriority() {
>>>> +  // Sort sections by priority.
>>>> +  typedef std::pair<int, InputSection<ELFT> *> Pair;
>>>> +  std::vector<Pair> V;
>>>> +  for (InputSection<ELFT> *S : Sections)
>>>> +    V.push_back({getPriority(S->getSectionName()), S});
>>>> +  std::sort(V.begin(), V.end(),
>>>> +            [](const Pair &A, const Pair &B) { return A.first <
>>>> B.first; });
>>>> +  Sections.clear();
>>>> +  for (Pair &P : V)
>>>> +    Sections.push_back(P.second);
>>>> +
>>>> +  // Reassign section addresses.
>>>> +  uintX_t Off = 0;
>>>> +  for (InputSection<ELFT> *S : Sections) {
>>>> +    Off = alignTo(Off, S->getAlign());
>>>> +    S->OutSecOff = Off;
>>>> +    Off += S->getSize();
>>>> +  }
>>>> +  this->Header.sh_size = Off;
>>>> +}
>>>> +
>>>>  // Returns a VA which a relocatin RI refers to. Used only for local
>>>> symbols.
>>>>  // For non-local symbols, use SymbolBody::getVA instead.
>>>>  template <class ELFT, bool IsRela>
>>>>
>>>> Modified: lld/trunk/ELF/OutputSections.h
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=260460&r1=260459&r2=260460&view=diff
>>>>
>>>> ==============================================================================
>>>> --- lld/trunk/ELF/OutputSections.h (original)
>>>> +++ lld/trunk/ELF/OutputSections.h Wed Feb 10 17:20:42 2016
>>>> @@ -279,6 +279,7 @@ public:
>>>>    typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
>>>>    OutputSection(StringRef Name, uint32_t sh_type, uintX_t sh_flags);
>>>>    void addSection(InputSectionBase<ELFT> *C) override;
>>>> +  void sortByPriority();
>>>>    void writeTo(uint8_t *Buf) override;
>>>>
>>>>  private:
>>>>
>>>> Modified: lld/trunk/ELF/Writer.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=260460&r1=260459&r2=260460&view=diff
>>>>
>>>> ==============================================================================
>>>> --- lld/trunk/ELF/Writer.cpp (original)
>>>> +++ lld/trunk/ELF/Writer.cpp Wed Feb 10 17:20:42 2016
>>>> @@ -735,6 +735,10 @@ StringRef Writer<ELFT>::getOutputSection
>>>>      return ".data";
>>>>    if (S.startswith(".bss."))
>>>>      return ".bss";
>>>> +  if (S.startswith(".init_array."))
>>>> +    return ".init_array";
>>>> +  if (S.startswith(".fini_array."))
>>>> +    return ".fini_array";
>>>>    return S;
>>>>  }
>>>>
>>>> @@ -915,6 +919,13 @@ template <class ELFT> void Writer<ELFT>:
>>>>        Symtab.addAbsolute("end", ElfSym<ELFT>::End);
>>>>  }
>>>>
>>>> +// Sort input sections by section name suffixes for
>>>> +// __attribute__((init_priority(N))).
>>>> +template <class ELFT> static void
>>>> sortByPriority(OutputSectionBase<ELFT> *S) {
>>>> +  if (S)
>>>> +    reinterpret_cast<OutputSection<ELFT> *>(S)->sortByPriority();
>>>> +}
>>>> +
>>>>  // Create output section objects and add them to OutputSections.
>>>>  template <class ELFT> bool Writer<ELFT>::createSections() {
>>>>    OutputSections.push_back(Out<ELFT>::ElfHeader);
>>>> @@ -962,6 +973,10 @@ template <class ELFT> bool Writer<ELFT>:
>>>>    Out<ELFT>::Dynamic->FiniArraySec =
>>>>        Factory.lookup(".fini_array", SHT_FINI_ARRAY, SHF_WRITE |
>>>> SHF_ALLOC);
>>>>
>>>> +  // Sort section contents for __attribute__((init_priority(N)).
>>>> +  sortByPriority(Out<ELFT>::Dynamic->InitArraySec);
>>>> +  sortByPriority(Out<ELFT>::Dynamic->FiniArraySec);
>>>> +
>>>>    // The linker needs to define SECNAME_start, SECNAME_end and
>>>> SECNAME_stop
>>>>    // symbols for sections, so that the runtime can get the start and
>>>> end
>>>>    // addresses of each section by section name. Add such symbols.
>>>>
>>>> Added: lld/trunk/test/ELF/init_fini_priority.s
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/init_fini_priority.s?rev=260460&view=auto
>>>>
>>>> ==============================================================================
>>>> --- lld/trunk/test/ELF/init_fini_priority.s (added)
>>>> +++ lld/trunk/test/ELF/init_fini_priority.s Wed Feb 10 17:20:42 2016
>>>> @@ -0,0 +1,29 @@
>>>> +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
>>>> +// RUN: ld.lld %t -o %t.exe
>>>> +// RUN: llvm-objdump -s %t.exe | FileCheck %s
>>>> +// REQUIRES: x86
>>>> +
>>>> +.globl _start
>>>> +_start:
>>>> +  nop
>>>> +
>>>> +.section .init_array, "aw", @init_array
>>>> +  .align 8
>>>> +  .byte 1
>>>> +.section .init_array.100, "aw", @init_array
>>>> +  .long 2
>>>> +.section .init_array.5, "aw", @init_array
>>>> +  .byte 3
>>>> +
>>>> +.section .fini_array, "aw", @fini_array
>>>> +  .align 8
>>>> +  .byte 4
>>>> +.section .fini_array.100, "aw", @fini_array
>>>> +  .long 5
>>>> +.section .fini_array.5, "aw", @fini_array
>>>> +  .byte 6
>>>> +
>>>> +// CHECK:      Contents of section .init_array:
>>>> +// CHECK-NEXT: 03020000 00000000 01
>>>> +// CHECK:      Contents of section .fini_array:
>>>> +// CHECK-NEXT: 06050000 00000000 04
>>>>
>>>>
>>>> _______________________________________________
>>>> llvm-commits mailing list
>>>> llvm-commits at lists.llvm.org
>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>>
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160210/b8d554fc/attachment.html>


More information about the llvm-commits mailing list