Index: lld/trunk/ELF/InputSection.cpp =================================================================== --- lld/trunk/ELF/InputSection.cpp +++ lld/trunk/ELF/InputSection.cpp @@ -71,14 +71,32 @@ this->Alignment = V; } +// 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 InputSectionBase::InputSectionBase(elf::ObjectFile *File, const typename ELFT::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) { // We reject object files having insanely large alignments even though // they are allowed by the spec. I think 4GB is a reasonable limitation. // We might want to relax this in the future. Index: lld/trunk/test/ELF/init-fini-progbits.s =================================================================== --- lld/trunk/test/ELF/init-fini-progbits.s +++ lld/trunk/test/ELF/init-fini-progbits.s @@ -0,0 +1,19 @@ +// 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