Commit 75bcf62c authored by Rui Ueyama's avatar Rui Ueyama
Browse files

Merge r298569: Force @{init,fini}_array if section name starts with ".{init,fini}_array.".

Related bug: http://bugs.llvm.org/show_bug.cgi?id=32599

llvm-svn: 301447
parent 3c833140
Loading
Loading
Loading
Loading
+22 −4
Original line number Diff line number Diff line
@@ -84,14 +84,32 @@ InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File,
    this->Flags &= ~(SHF_MERGE | SHF_STRINGS);
}

// GNU assembler 2.24 and LLVM 4.0.0's MC (the newest release as of
// March 2017) fail to infer section types for sections starting with
// ".init_array." or ".fini_array.". They set SHT_PROGBITS instead of
// SHF_INIT_ARRAY. As a result, the following assembler directive
// creates ".init_array.100" with SHT_PROGBITS, for example.
//
//   .section .init_array.100, "aw"
//
// This function forces SHT_{INIT,FINI}_ARRAY so that we can handle
// incorrect inputs as if they were correct from the beginning.
static uint64_t getType(uint64_t Type, StringRef Name) {
  if (Type == SHT_PROGBITS && Name.startswith(".init_array."))
    return SHT_INIT_ARRAY;
  if (Type == SHT_PROGBITS && Name.startswith(".fini_array."))
    return SHT_FINI_ARRAY;
  return Type;
}

template <class ELFT>
InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File,
                                         const Elf_Shdr *Hdr, StringRef Name,
                                         Kind SectionKind)
    : InputSectionBase(File, Hdr->sh_flags & ~SHF_INFO_LINK, Hdr->sh_type,
                       Hdr->sh_entsize, Hdr->sh_link, Hdr->sh_info,
                       Hdr->sh_addralign, getSectionContents(File, Hdr), Name,
                       SectionKind) {
    : InputSectionBase(File, Hdr->sh_flags & ~SHF_INFO_LINK,
                       getType(Hdr->sh_type, Name), Hdr->sh_entsize,
                       Hdr->sh_link, Hdr->sh_info, Hdr->sh_addralign,
                       getSectionContents(File, Hdr), Name, SectionKind) {
  this->Offset = Hdr->sh_offset;
}

+19 −0
Original line number Diff line number Diff line
// REQUIRES: x86

// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
// RUN: ld.lld %t -o %t.exe
// RUN: llvm-readobj -sections %t.exe | FileCheck %s

// CHECK:      Name: .init_array
// CHECK-NEXT: Type: SHT_INIT_ARRAY
// CHECK:      Name: .fini_array
// CHECK-NEXT: Type: SHT_FINI_ARRAY

.globl _start
_start:
  nop

.section .init_array.100, "aw", @progbits
  .byte 0
.section .fini_array.100, "aw", @progbits
  .byte 0