Index: lld/trunk/ELF/SymbolTable.cpp =================================================================== --- lld/trunk/ELF/SymbolTable.cpp +++ lld/trunk/ELF/SymbolTable.cpp @@ -47,6 +47,8 @@ return new AArch64TargetInfo(); case EM_ARM: return new ARMTargetInfo(); + case EM_MIPS: + return new MipsTargetInfo(); case EM_PPC: return new PPCTargetInfo(); case EM_PPC64: @@ -72,7 +74,8 @@ Target.reset(createTarget(EMachine)); if (Config->Shared) return; - EntrySym = new (Alloc) Undefined("_start", Undefined::Synthetic); + EntrySym = new (Alloc) + Undefined(Target->getDefaultEntry(), Undefined::Synthetic); resolve(EntrySym); // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol is magical Index: lld/trunk/ELF/Target.h =================================================================== --- lld/trunk/ELF/Target.h +++ lld/trunk/ELF/Target.h @@ -10,6 +10,8 @@ #ifndef LLD_ELF_TARGET_H #define LLD_ELF_TARGET_H +#include "llvm/ADT/StringRef.h" + #include namespace lld { @@ -18,6 +20,7 @@ class TargetInfo { public: + llvm::StringRef getDefaultEntry() const { return DefaultEntry; } unsigned getPCRelReloc() const { return PCRelReloc; } unsigned getGotReloc() const { return GotReloc; } virtual void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, @@ -32,6 +35,7 @@ protected: unsigned PCRelReloc; unsigned GotReloc; + llvm::StringRef DefaultEntry = "_start"; }; class X86TargetInfo final : public TargetInfo { @@ -100,6 +104,17 @@ uint64_t BaseAddr, uint64_t SymVA) const override; }; +class MipsTargetInfo final : public TargetInfo { +public: + MipsTargetInfo(); + void writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const override; + bool relocNeedsGot(uint32_t Type) const override; + bool relocNeedsPlt(uint32_t Type) const override; + void relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type, + uint64_t BaseAddr, uint64_t SymVA) const override; +}; + extern std::unique_ptr Target; } } Index: lld/trunk/ELF/Target.cpp =================================================================== --- lld/trunk/ELF/Target.cpp +++ lld/trunk/ELF/Target.cpp @@ -252,5 +252,21 @@ break; } } + +MipsTargetInfo::MipsTargetInfo() { + // PCRelReloc = FIXME + // GotReloc = FIXME + DefaultEntry = "__start"; +} + +void MipsTargetInfo::writePltEntry(uint8_t *Buf, uint64_t GotEntryAddr, + uint64_t PltEntryAddr) const {} + +bool MipsTargetInfo::relocNeedsGot(uint32_t Type) const { return false; } + +bool MipsTargetInfo::relocNeedsPlt(uint32_t Type) const { return false; } + +void MipsTargetInfo::relocateOne(uint8_t *Buf, const void *RelP, uint32_t Type, + uint64_t BaseAddr, uint64_t SymVA) const {} } } Index: lld/trunk/test/elf2/basic-mips.s =================================================================== --- lld/trunk/test/elf2/basic-mips.s +++ lld/trunk/test/elf2/basic-mips.s @@ -0,0 +1,220 @@ +# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t.o +# RUN: lld -flavor gnu2 %t.o -o %t.exe +# RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t.exe \ +# RUN: | FileCheck %s + +# REQUIRES: mips + +# Exits with return code 1 on Linux. + .globl __start +__start: + li $a0,1 + li $v0,4001 + syscall + +# CHECK: ElfHeader { +# CHECK-NEXT: Ident { +# CHECK-NEXT: Magic: (7F 45 4C 46) +# CHECK-NEXT: Class: 32-bit (0x1) +# CHECK-NEXT: DataEncoding: LittleEndian (0x1) +# CHECK-NEXT: FileVersion: 1 +# CHECK-NEXT: OS/ABI: SystemV (0x0) +# CHECK-NEXT: ABIVersion: 0 +# CHECK-NEXT: Unused: (00 00 00 00 00 00 00) +# CHECK-NEXT: } +# CHECK-NEXT: Type: Executable (0x2) +# CHECK-NEXT: Machine: EM_MIPS (0x8) +# CHECK-NEXT: Version: 1 +# CHECK-NEXT: Entry: 0x11000 +# CHECK-NEXT: ProgramHeaderOffset: 0x34 +# CHECK-NEXT: SectionHeaderOffset: 0x2094 +# CHECK-NEXT: Flags [ (0x0) +# CHECK-NEXT: ] +# CHECK-NEXT: HeaderSize: 52 +# CHECK-NEXT: ProgramHeaderEntrySize: 32 +# CHECK-NEXT: ProgramHeaderCount: 3 +# CHECK-NEXT: SectionHeaderEntrySize: 40 +# CHECK-NEXT: SectionHeaderCount: 8 +# CHECK-NEXT: StringTableSectionIndex: 7 +# CHECK-NEXT: } +# CHECK-NEXT: Sections [ +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 0 +# CHECK-NEXT: Name: (0) +# CHECK-NEXT: Type: SHT_NULL (0x0) +# CHECK-NEXT: Flags [ (0x0) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 0 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 1 +# CHECK-NEXT: Name: .bss (15) +# CHECK-NEXT: Type: SHT_NOBITS (0x8) +# CHECK-NEXT: Flags [ (0x3) +# CHECK-NEXT: SHF_ALLOC (0x2) +# CHECK-NEXT: SHF_WRITE (0x1) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x11000 +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 16 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 2 +# CHECK-NEXT: Name: .text (1) +# CHECK-NEXT: Type: SHT_PROGBITS (0x1) +# CHECK-NEXT: Flags [ (0x6) +# CHECK-NEXT: SHF_ALLOC (0x2) +# CHECK-NEXT: SHF_EXECINSTR (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x11000 +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: Size: 12 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 16 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 3 +# CHECK-NEXT: Name: .data (60) +# CHECK-NEXT: Type: SHT_PROGBITS (0x1) +# CHECK-NEXT: Flags [ (0x3) +# CHECK-NEXT: SHF_ALLOC (0x2) +# CHECK-NEXT: SHF_WRITE (0x1) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x11010 +# CHECK-NEXT: Offset: 0x1010 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 16 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 4 +# CHECK-NEXT: Name: .reginfo (35) +# CHECK-NEXT: Type: SHT_MIPS_REGINFO (0x70000006) +# CHECK-NEXT: Flags [ (0x2) +# CHECK-NEXT: SHF_ALLOC (0x2) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x12000 +# CHECK-NEXT: Offset: 0x2000 +# CHECK-NEXT: Size: 24 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 4 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 5 +# CHECK-NEXT: Name: .MIPS.abiflags (20) +# CHECK-NEXT: Type: SHT_MIPS_ABIFLAGS (0x7000002A) +# CHECK-NEXT: Flags [ (0x2) +# CHECK-NEXT: SHF_ALLOC (0x2) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x12018 +# CHECK-NEXT: Offset: 0x2018 +# CHECK-NEXT: Size: 24 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 8 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 6 +# CHECK-NEXT: Name: .symtab (52) +# CHECK-NEXT: Type: SHT_SYMTAB (0x2) +# CHECK-NEXT: Flags [ (0x0) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Offset: 0x2030 +# CHECK-NEXT: Size: 32 +# CHECK-NEXT: Link: 7 +# CHECK-NEXT: Info: 1 +# CHECK-NEXT: AddressAlignment: 4 +# CHECK-NEXT: EntrySize: 16 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 7 +# CHECK-NEXT: Name: .strtab (44) +# CHECK-NEXT: Type: SHT_STRTAB (0x3) +# CHECK-NEXT: Flags [ (0x0) +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Offset: 0x2050 +# CHECK-NEXT: Size: 66 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 1 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: Symbols [ +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: (0) +# CHECK-NEXT: Value: 0x0 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Local (0x0) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: Undefined (0x0) +# CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: __start (7) +# CHECK-NEXT: Value: 0x11000 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global (0x1) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .text (0x2) +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK-NEXT: ProgramHeaders [ +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: VirtualAddress: 0x10000 +# CHECK-NEXT: PhysicalAddress: 0x10000 +# CHECK-NEXT: FileSize: 148 +# CHECK-NEXT: MemSize: 148 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x11000 +# CHECK-NEXT: PhysicalAddress: 0x11000 +# CHECK-NEXT: FileSize: 16 +# CHECK-NEXT: MemSize: 16 +# CHECK-NEXT: Flags [ (0x5) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: PF_X (0x1) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x2000 +# CHECK-NEXT: VirtualAddress: 0x12000 +# CHECK-NEXT: PhysicalAddress: 0x12000 +# CHECK-NEXT: FileSize: 48 +# CHECK-NEXT: MemSize: 48 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } +# CHECK-NEXT: ]