diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 09cffcec718f..4cc8e7729ed9 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -57,6 +57,10 @@ static std::pair parseEmulation(StringRef S) { return {ELF32BEKind, EM_MIPS}; if (S == "elf32ltsmip") return {ELF32LEKind, EM_MIPS}; + if (S == "elf64btsmip") + return {ELF64BEKind, EM_MIPS}; + if (S == "elf64ltsmip") + return {ELF64LEKind, EM_MIPS}; if (S == "elf32ppc") return {ELF32BEKind, EM_PPC}; if (S == "elf64ppc") @@ -312,6 +316,9 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { Config->Emulation = S; } + if (Config->EMachine == EM_MIPS && Config->EKind == ELF64LEKind) + Config->Mips64EL = true; + Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition); Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic); Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions); diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 957f5d8725b1..578d5a29fe6f 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -616,6 +616,8 @@ static std::unique_ptr createELFFileAux(MemoryBufferRef MB) { if (Config->EKind == ELFNoneKind) { Config->EKind = Ret->getELFKind(); Config->EMachine = Ret->getEMachine(); + if (Config->EMachine == EM_MIPS && Config->EKind == ELF64LEKind) + Config->Mips64EL = true; } return std::move(Ret); diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index 9746b4f7c7c9..565171bf5040 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -198,6 +198,10 @@ TargetInfo *createTarget() { return new MipsTargetInfo(); case ELF32BEKind: return new MipsTargetInfo(); + case ELF64LEKind: + return new MipsTargetInfo(); + case ELF64BEKind: + return new MipsTargetInfo(); default: fatal("unsupported MIPS target"); } diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 514b21a58267..86915f31beb3 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1760,10 +1760,13 @@ template void Writer::setPhdrs() { } } -static uint32_t getMipsEFlags() { +static uint32_t getMipsEFlags(bool Is64Bits) { // FIXME: In fact ELF flags depends on ELF flags of input object files // and selected emulation. For now just use hard coded values. - uint32_t V = EF_MIPS_ABI_O32 | EF_MIPS_CPIC | EF_MIPS_ARCH_32R2; + if (Is64Bits) + return EF_MIPS_CPIC | EF_MIPS_PIC | EF_MIPS_ARCH_64R2; + + uint32_t V = EF_MIPS_CPIC | EF_MIPS_ABI_O32 | EF_MIPS_ARCH_32R2; if (Config->Shared) V |= EF_MIPS_PIC; return V; @@ -1844,7 +1847,7 @@ template void Writer::writeHeader() { EHdr->e_shstrndx = Out::ShStrTab->SectionIndex; if (Config->EMachine == EM_MIPS) - EHdr->e_flags = getMipsEFlags(); + EHdr->e_flags = getMipsEFlags(ELFT::Is64Bits); if (!Config->Relocatable) { EHdr->e_phoff = sizeof(Elf_Ehdr); diff --git a/lld/test/ELF/emulation.s b/lld/test/ELF/emulation.s index eaeab546266f..f61ca95fecbf 100644 --- a/lld/test/ELF/emulation.s +++ b/lld/test/ELF/emulation.s @@ -178,6 +178,60 @@ # MIPSEL-NEXT: EF_MIPS_CPIC # MIPSEL-NEXT: ] +# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %tmips64 +# RUN: ld.lld -m elf64btsmip -e _start %tmips64 -o %t2mips64 +# RUN: llvm-readobj -file-headers %t2mips64 | FileCheck --check-prefix=MIPS64 %s +# RUN: ld.lld %tmips64 -e _start -o %t3mips64 +# RUN: llvm-readobj -file-headers %t3mips64 | FileCheck --check-prefix=MIPS64 %s +# MIPS64: ElfHeader { +# MIPS64-NEXT: Ident { +# MIPS64-NEXT: Magic: (7F 45 4C 46) +# MIPS64-NEXT: Class: 64-bit (0x2) +# MIPS64-NEXT: DataEncoding: BigEndian (0x2) +# MIPS64-NEXT: FileVersion: 1 +# MIPS64-NEXT: OS/ABI: SystemV (0x0) +# MIPS64-NEXT: ABIVersion: 0 +# MIPS64-NEXT: Unused: (00 00 00 00 00 00 00) +# MIPS64-NEXT: } +# MIPS64-NEXT: Type: Executable (0x2) +# MIPS64-NEXT: Machine: EM_MIPS (0x8) +# MIPS64-NEXT: Version: 1 +# MIPS64-NEXT: Entry: +# MIPS64-NEXT: ProgramHeaderOffset: 0x40 +# MIPS64-NEXT: SectionHeaderOffset: +# MIPS64-NEXT: Flags [ +# MIPS64-NEXT: EF_MIPS_ARCH_64R2 +# MIPS64-NEXT: EF_MIPS_CPIC +# MIPS64-NEXT: EF_MIPS_PIC +# MIPS64-NEXT: ] + +# RUN: llvm-mc -filetype=obj -triple=mips64el-unknown-linux %s -o %tmips64el +# RUN: ld.lld -m elf64ltsmip -e _start %tmips64el -o %t2mips64el +# RUN: llvm-readobj -file-headers %t2mips64el | FileCheck --check-prefix=MIPS64EL %s +# RUN: ld.lld %tmips64el -e _start -o %t3mips64el +# RUN: llvm-readobj -file-headers %t3mips64el | FileCheck --check-prefix=MIPS64EL %s +# MIPS64EL: ElfHeader { +# MIPS64EL-NEXT: Ident { +# MIPS64EL-NEXT: Magic: (7F 45 4C 46) +# MIPS64EL-NEXT: Class: 64-bit (0x2) +# MIPS64EL-NEXT: DataEncoding: LittleEndian (0x1) +# MIPS64EL-NEXT: FileVersion: 1 +# MIPS64EL-NEXT: OS/ABI: SystemV (0x0) +# MIPS64EL-NEXT: ABIVersion: 0 +# MIPS64EL-NEXT: Unused: (00 00 00 00 00 00 00) +# MIPS64EL-NEXT: } +# MIPS64EL-NEXT: Type: Executable (0x2) +# MIPS64EL-NEXT: Machine: EM_MIPS (0x8) +# MIPS64EL-NEXT: Version: 1 +# MIPS64EL-NEXT: Entry: +# MIPS64EL-NEXT: ProgramHeaderOffset: 0x40 +# MIPS64EL-NEXT: SectionHeaderOffset: +# MIPS64EL-NEXT: Flags [ +# MIPS64EL-NEXT: EF_MIPS_ARCH_64R2 +# MIPS64EL-NEXT: EF_MIPS_CPIC +# MIPS64EL-NEXT: EF_MIPS_PIC +# MIPS64EL-NEXT: ] + # RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %taarch64 # RUN: ld.lld -m aarch64linux %taarch64 -o %t2aarch64 # RUN: llvm-readobj -file-headers %t2aarch64 | FileCheck --check-prefix=AARCH64 %s