From: Rui Ueyama Date: Thu, 23 Mar 2017 01:00:41 +0000 (+0000) Subject: Force @{init,fini}_array if section name starts with ".{init,fini}_array.". X-Git-Tag: llvmorg-5.0.0-rc1~9379 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=34e3d50d18fa8ad9f63d98731cb585d91d2349ca;p=platform%2Fupstream%2Fllvm.git Force @{init,fini}_array if section name starts with ".{init,fini}_array.". Fixes https://bugs.llvm.org/show_bug.cgi?id=32307. Differential Revision: https://reviews.llvm.org/D31255 llvm-svn: 298569 --- diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 92b2e57..7d542db 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -71,14 +71,32 @@ InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags, 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. diff --git a/lld/test/ELF/init-fini-progbits.s b/lld/test/ELF/init-fini-progbits.s new file mode 100644 index 0000000..a874944 --- /dev/null +++ b/lld/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