From a4cde9d2e22308381cefeda7e8e8ccd4a48fc19d Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Fri, 23 Feb 2018 11:28:57 +0000 Subject: [PATCH] [ELF][MIPS] Set EI_ABIVERSION flag accordingly to MIPS ABIs requirement MIPS ABIs require that if an executable file uses non-PIC model, the EI_ABIVERSION entry in the ELF header should be incremented from 0 to 1. That allows obsoleted / limited dynamic linkers refuse to link them. llvm-svn: 325890 --- lld/ELF/Writer.cpp | 11 +++++++++++ lld/test/ELF/basic-mips.s | 2 +- lld/test/ELF/emulation.s | 4 ++-- lld/test/ELF/mips-elf-abi.s | 23 +++++++++++++++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 lld/test/ELF/mips-elf-abi.s diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index df03f8a..111a19d 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -2069,6 +2069,16 @@ static uint16_t getELFType() { return ET_EXEC; } +static uint8_t getAbiVersion() { + if (Config->EMachine == EM_MIPS) { + // Increment the ABI version for non-PIC executable files. + if (getELFType() == ET_EXEC && + (Config->EFlags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC) + return 1; + } + return 0; +} + template void Writer::writeHeader() { uint8_t *Buf = Buffer->getBufferStart(); memcpy(Buf, "\177ELF", 4); @@ -2079,6 +2089,7 @@ template void Writer::writeHeader() { EHdr->e_ident[EI_DATA] = Config->IsLE ? ELFDATA2LSB : ELFDATA2MSB; EHdr->e_ident[EI_VERSION] = EV_CURRENT; EHdr->e_ident[EI_OSABI] = Config->OSABI; + EHdr->e_ident[EI_ABIVERSION] = getAbiVersion(); EHdr->e_type = getELFType(); EHdr->e_machine = Config->EMachine; EHdr->e_version = EV_CURRENT; diff --git a/lld/test/ELF/basic-mips.s b/lld/test/ELF/basic-mips.s index a193529..edc91b4 100644 --- a/lld/test/ELF/basic-mips.s +++ b/lld/test/ELF/basic-mips.s @@ -19,7 +19,7 @@ __start: # CHECK-NEXT: DataEncoding: LittleEndian (0x1) # CHECK-NEXT: FileVersion: 1 # CHECK-NEXT: OS/ABI: SystemV (0x0) -# CHECK-NEXT: ABIVersion: 0 +# CHECK-NEXT: ABIVersion: 1 # CHECK-NEXT: Unused: (00 00 00 00 00 00 00) # CHECK-NEXT: } # CHECK-NEXT: Type: Executable (0x2) diff --git a/lld/test/ELF/emulation.s b/lld/test/ELF/emulation.s index 05efd0b..b3d0434 100644 --- a/lld/test/ELF/emulation.s +++ b/lld/test/ELF/emulation.s @@ -230,7 +230,7 @@ # MIPS-NEXT: DataEncoding: BigEndian (0x2) # MIPS-NEXT: FileVersion: 1 # MIPS-NEXT: OS/ABI: SystemV (0x0) -# MIPS-NEXT: ABIVersion: 0 +# MIPS-NEXT: ABIVersion: 1 # MIPS-NEXT: Unused: (00 00 00 00 00 00 00) # MIPS-NEXT: } # MIPS-NEXT: Type: Executable (0x2) @@ -259,7 +259,7 @@ # MIPSEL-NEXT: DataEncoding: LittleEndian (0x1) # MIPSEL-NEXT: FileVersion: 1 # MIPSEL-NEXT: OS/ABI: SystemV (0x0) -# MIPSEL-NEXT: ABIVersion: 0 +# MIPSEL-NEXT: ABIVersion: 1 # MIPSEL-NEXT: Unused: (00 00 00 00 00 00 00) # MIPSEL-NEXT: } # MIPSEL-NEXT: Type: Executable (0x2) diff --git a/lld/test/ELF/mips-elf-abi.s b/lld/test/ELF/mips-elf-abi.s new file mode 100644 index 0000000..8721b48 --- /dev/null +++ b/lld/test/ELF/mips-elf-abi.s @@ -0,0 +1,23 @@ +# Check EI_ABIVERSION flags + +# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o +# RUN: ld.lld -shared -o %t.so %t.o +# RUN: llvm-readobj -h %t.so | FileCheck -check-prefix=DSO %s +# RUN: ld.lld -o %t.exe %t.o +# RUN: llvm-readobj -h %t.exe | FileCheck -check-prefix=EXE %s +# RUN: ld.lld -pie -o %t.pie %t.o +# RUN: llvm-readobj -h %t.pie | FileCheck -check-prefix=PIE %s +# RUN: ld.lld -r -o %t.rel %t.o +# RUN: llvm-readobj -h %t.rel | FileCheck -check-prefix=REL %s + +# REQUIRES: mips + +# DSO: ABIVersion: 0 +# EXE: ABIVersion: 1 +# PIE: ABIVersion: 0 +# REL: ABIVersion: 0 + + .global __start + .text +__start: + nop -- 2.7.4