diff options
-rw-r--r-- | lld/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h | 20 | ||||
-rw-r--r-- | lld/test/elf/ARM/entry-point.test | 77 |
2 files changed, 97 insertions, 0 deletions
diff --git a/lld/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h b/lld/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h index 4e475e50bcd..19311d516e4 100644 --- a/lld/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h +++ b/lld/lib/ReaderWriter/ELF/ARM/ARMExecutableWriter.h @@ -42,6 +42,10 @@ protected: void processUndefinedSymbol(StringRef symName, RuntimeFile<ELFT> &file) const override; + + // Setup the ELF header. + std::error_code setELFHeader() override; + private: ARMLinkingContext &_context; ARMTargetLayout<ELFT> &_armLayout; @@ -95,6 +99,22 @@ void ARMExecutableWriter<ELFT>::processUndefinedSymbol( } } +template <class ELFT> +std::error_code ARMExecutableWriter<ELFT>::setELFHeader() { + if (std::error_code ec = ExecutableWriter<ELFT>::setELFHeader()) + return ec; + + // Fixup entry point for Thumb code. + StringRef entryName = _context.entrySymbolName(); + if (const AtomLayout *al = _armLayout.findAtomLayoutByName(entryName)) { + const auto *ea = dyn_cast<DefinedAtom>(al->_atom); + if (ea && ea->codeModel() == DefinedAtom::codeARMThumb) + this->_elfHeader->e_entry(al->_virtualAddr | 0x1); + } + + return std::error_code(); +} + } // namespace elf } // namespace lld diff --git a/lld/test/elf/ARM/entry-point.test b/lld/test/elf/ARM/entry-point.test new file mode 100644 index 00000000000..d168bb6463c --- /dev/null +++ b/lld/test/elf/ARM/entry-point.test @@ -0,0 +1,77 @@ +# 1. Check entry point address for ARM code - should be even. +# RUN: yaml2obj -format=elf -docnum 1 %s > %t-arm.o +# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \ +# RUN: --noinhibit-exec %t-arm.o -o %t-arm +# RUN: llvm-readobj -file-headers %t-arm | FileCheck -check-prefix=ARM-ENTRY %s +# +# ARM-ENTRY: Entry: 0x400074 + +# 2. Check entry point address for Thumb code - should be odd. +# RUN: yaml2obj -format=elf -docnum 2 %s > %t-thm.o +# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \ +# RUN: --noinhibit-exec %t-thm.o -o %t-thm +# RUN: llvm-readobj -file-headers %t-thm | FileCheck -check-prefix=THM-ENTRY %s +# +# THM-ENTRY: Entry: 0x400075 + +# arm.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_ARM + Flags: [ EF_ARM_EABI_VER5 ] +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000004 + Content: 04B02DE500B08DE20030A0E30300A0E100D04BE204B09DE41EFF2FE1 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000001 + Content: '' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000001 + Content: '' +Symbols: + Global: + - Name: _start + Type: STT_FUNC + Section: .text + +# thm.o +--- +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_ARM + Flags: [ EF_ARM_EABI_VER5 ] +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000004 + Content: 80B400AF00231846BD465DF8047B7047 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000001 + Content: '' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000001 + Content: '' +Symbols: + Global: + - Name: _start + Type: STT_FUNC + Section: .text + Value: 0x0000000000000001 +... |