diff --git a/lld/lib/ReaderWriter/ELF/Atoms.h b/lld/lib/ReaderWriter/ELF/Atoms.h index d995f97f4d0e..735297f638b8 100644 --- a/lld/lib/ReaderWriter/ELF/Atoms.h +++ b/lld/lib/ReaderWriter/ELF/Atoms.h @@ -326,6 +326,7 @@ public: ret = typeZeroFill; break; case llvm::ELF::SHT_INIT_ARRAY: + case llvm::ELF::SHT_FINI_ARRAY: ret = typeData; break; } @@ -432,6 +433,7 @@ public: return _permissions = permRW_; case llvm::ELF::SHT_INIT_ARRAY: + case llvm::ELF::SHT_FINI_ARRAY: return _permissions = permRW_; default: diff --git a/lld/lib/ReaderWriter/ELF/DefaultLayout.h b/lld/lib/ReaderWriter/ELF/DefaultLayout.h index c3734061a383..cb18e0ce48b2 100644 --- a/lld/lib/ReaderWriter/ELF/DefaultLayout.h +++ b/lld/lib/ReaderWriter/ELF/DefaultLayout.h @@ -329,6 +329,7 @@ Layout::SectionOrder DefaultLayout::getSectionOrder( case DefinedAtom::typeDataFast: return llvm::StringSwitch(name) .StartsWith(".init_array", ORDER_INIT_ARRAY) + .StartsWith(".fini_array", ORDER_FINI_ARRAY) .Default(ORDER_DATA); case DefinedAtom::typeZeroFill: diff --git a/lld/lib/ReaderWriter/ELF/File.h b/lld/lib/ReaderWriter/ELF/File.h index 0c2c3b80fe57..33d925067b2a 100644 --- a/lld/lib/ReaderWriter/ELF/File.h +++ b/lld/lib/ReaderWriter/ELF/File.h @@ -181,7 +181,9 @@ public: } // Create a sectionSymbols entry for every progbits section. - if (section->sh_type == llvm::ELF::SHT_PROGBITS) + if ((section->sh_type == llvm::ELF::SHT_PROGBITS) || + (section->sh_type == llvm::ELF::SHT_INIT_ARRAY) || + (section->sh_type == llvm::ELF::SHT_FINI_ARRAY)) _sectionSymbols[section]; if (section->sh_type == llvm::ELF::SHT_RELA) { diff --git a/lld/test/elf/X86_64/Inputs/initfini.c b/lld/test/elf/X86_64/Inputs/initfini.c new file mode 100644 index 000000000000..9427a86b6c9b --- /dev/null +++ b/lld/test/elf/X86_64/Inputs/initfini.c @@ -0,0 +1,14 @@ +#include + +void __attribute__ ((constructor)) constructor() { + printf("%s\n", __FUNCTION__); +} + +void __attribute__ ((destructor)) destructor() { + printf("%s\n", __FUNCTION__); +} + +int main() { + return 0; +} + diff --git a/lld/test/elf/X86_64/Inputs/initfini.o b/lld/test/elf/X86_64/Inputs/initfini.o new file mode 100644 index 000000000000..f0e55a90b8b6 Binary files /dev/null and b/lld/test/elf/X86_64/Inputs/initfini.o differ diff --git a/lld/test/elf/X86_64/initfini.test b/lld/test/elf/X86_64/initfini.test new file mode 100644 index 000000000000..08a65a5f4531 --- /dev/null +++ b/lld/test/elf/X86_64/initfini.test @@ -0,0 +1,23 @@ +# This tests the functionality that lld is able to read +# init_array/fini_array sections in the input ELF. This +# corresponds to the the .init_array/.fini_array sections +# in the output ELF. + +RUN: lld -flavor gnu -target x86_64-linux %p/Inputs/initfini.o \ +RUN: --noinhibit-exec -emit-yaml -o %t +RUN: FileCheck %s < %t + +CHECK: - type: data +CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ] +CHECK: section-name: .init_array +CHECK: references: +CHECK: - kind: R_X86_64_64 +CHECK: offset: 0 +CHECK: target: constructor +CHECK: - type: data +CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ] +CHECK: section-name: .fini_array +CHECK: references: +CHECK: - kind: R_X86_64_64 +CHECK: offset: 0 +CHECK: target: destructor