227 changes: 185 additions & 42 deletions lld/lib/ReaderWriter/ELF/Mips/MipsRelocationPass.cpp

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions lld/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ template <class ELFT> void MipsReginfoSection<ELFT>::finalize() {
this->_outputSection->setType(this->_type);
}

template class MipsReginfoSection<ELF32BE>;
template class MipsReginfoSection<ELF32LE>;
template class MipsReginfoSection<ELF64BE>;
template class MipsReginfoSection<ELF64LE>;

template <class ELFT>
Expand Down Expand Up @@ -85,7 +87,9 @@ template <class ELFT> void MipsOptionsSection<ELFT>::finalize() {
this->_outputSection->setType(this->_type);
}

template class MipsOptionsSection<ELF32BE>;
template class MipsOptionsSection<ELF32LE>;
template class MipsOptionsSection<ELF64BE>;
template class MipsOptionsSection<ELF64LE>;

template <class ELFT>
Expand Down Expand Up @@ -116,7 +120,9 @@ template <class ELFT> void MipsAbiFlagsSection<ELFT>::finalize() {
this->_outputSection->setType(this->_type);
}

template class MipsAbiFlagsSection<ELF32BE>;
template class MipsAbiFlagsSection<ELF32LE>;
template class MipsAbiFlagsSection<ELF64BE>;
template class MipsAbiFlagsSection<ELF64LE>;

template <class ELFT>
Expand Down Expand Up @@ -175,7 +181,9 @@ const AtomLayout *MipsGOTSection<ELFT>::appendAtom(const Atom *atom) {
return AtomSection<ELFT>::appendAtom(atom);
}

template class MipsGOTSection<ELF32BE>;
template class MipsGOTSection<ELF32LE>;
template class MipsGOTSection<ELF64BE>;
template class MipsGOTSection<ELF64LE>;

template <class ELFT>
Expand Down Expand Up @@ -208,7 +216,9 @@ const AtomLayout *MipsPLTSection<ELFT>::appendAtom(const Atom *atom) {
return layout;
}

template class MipsPLTSection<ELF32BE>;
template class MipsPLTSection<ELF32LE>;
template class MipsPLTSection<ELF64BE>;
template class MipsPLTSection<ELF64LE>;

template <class ELFT> static bool isMips64EL() {
Expand Down Expand Up @@ -245,7 +255,9 @@ void MipsRelocationTable<ELFT>::writeRel(ELFWriter *writer, Elf_Rel &r,
r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
}

template class MipsRelocationTable<ELF32BE>;
template class MipsRelocationTable<ELF32LE>;
template class MipsRelocationTable<ELF64BE>;
template class MipsRelocationTable<ELF64LE>;

} // elf
Expand Down
6 changes: 6 additions & 0 deletions lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ std::unique_ptr<Writer> MipsTargetHandler<ELFT>::getWriter() {
}
}

template class MipsTargetHandler<ELF32BE>;
template class MipsTargetHandler<ELF32LE>;
template class MipsTargetHandler<ELF64BE>;
template class MipsTargetHandler<ELF64LE>;

template <class ELFT>
Expand Down Expand Up @@ -95,7 +97,9 @@ template <class ELFT> void MipsSymbolTable<ELFT>::finalize(bool sort) {
}
}

template class MipsSymbolTable<ELF32BE>;
template class MipsSymbolTable<ELF32LE>;
template class MipsSymbolTable<ELF64BE>;
template class MipsSymbolTable<ELF64LE>;

template <class ELFT>
Expand Down Expand Up @@ -149,7 +153,9 @@ template <class ELFT> void MipsDynamicSymbolTable<ELFT>::finalize() {
}
}

template class MipsDynamicSymbolTable<ELF32BE>;
template class MipsDynamicSymbolTable<ELF32LE>;
template class MipsDynamicSymbolTable<ELF64BE>;
template class MipsDynamicSymbolTable<ELF64LE>;

}
Expand Down
2 changes: 2 additions & 0 deletions lld/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ template <class ELFT> void MipsTargetLayout<ELFT>::sortSegments() {
this->_segments.insert(outIt, abiSeg);
}

template class MipsTargetLayout<ELF32BE>;
template class MipsTargetLayout<ELF32LE>;
template class MipsTargetLayout<ELF64BE>;
template class MipsTargetLayout<ELF64LE>;

} // end namespace elf
Expand Down
60 changes: 60 additions & 0 deletions lld/test/elf/Mips/exe-fileheader-be-64.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Check ELF Header for non-pic big-endian 64-bit executable file.

# RUN: yaml2obj -format=elf %s > %t.o
# RUN: lld -flavor gnu -target mips64 -o %t.exe %t.o
# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s

# CHECK: Format: ELF64-mips
# CHECK: Arch: mips64
# CHECK: AddressSize: 64bit
# CHECK: LoadName:
# CHECK: ElfHeader {
# CHECK: Ident {
# CHECK: Magic: (7F 45 4C 46)
# CHECK: Class: 64-bit (0x2)
# CHECK: DataEncoding: BigEndian (0x2)
# CHECK: FileVersion: 1
# CHECK: OS/ABI: SystemV (0x0)
# CHECK: ABIVersion: 0
# CHECK: Unused: (00 00 00 00 00 00 00)
# CHECK: }
# CHECK: Type: Executable (0x2)
# CHECK: Machine: EM_MIPS (0x8)
# CHECK: Version: 1
# CHECK: Entry: 0x{{[0-9A-F]+}}
# CHECK: ProgramHeaderOffset: 0x{{[0-9A-F]+}}
# CHECK: SectionHeaderOffset: 0x{{[0-9A-F]+}}
# CHECK: Flags [ (0x60000007)
# CHECK: EF_MIPS_ARCH_64 (0x60000000)
# CHECK: EF_MIPS_CPIC (0x4)
# CHECK: EF_MIPS_NOREORDER (0x1)
# CHECK: EF_MIPS_PIC (0x2)
# CHECK: ]
# CHECK: HeaderSize: 64
# CHECK: ProgramHeaderEntrySize: 56
# CHECK: ProgramHeaderCount: {{[0-9]+}}
# CHECK: SectionHeaderEntrySize: 64
# CHECK: SectionHeaderCount: {{[0-9]+}}
# CHECK: StringTableSectionIndex: {{[0-9]+}}
# CHECK: }

---
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2MSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_NOREORDER, EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ARCH_64]

Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 4
Size: 8

Symbols:
Global:
- Name: __start
Section: .text
...
60 changes: 60 additions & 0 deletions lld/test/elf/Mips/exe-fileheader-be.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Check ELF Header for non-pic big-endian 32-bit executable file.

# RUN: yaml2obj -format=elf %s > %t.o
# RUN: lld -flavor gnu -target mips -o %t.exe %t.o
# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s

# CHECK: Format: ELF32-mips
# CHECK: Arch: mips
# CHECK: AddressSize: 32bit
# CHECK: LoadName:
# CHECK: ElfHeader {
# CHECK: Ident {
# CHECK: Magic: (7F 45 4C 46)
# CHECK: Class: 32-bit (0x1)
# CHECK: DataEncoding: BigEndian (0x2)
# CHECK: FileVersion: 1
# CHECK: OS/ABI: SystemV (0x0)
# CHECK: ABIVersion: 1
# CHECK: Unused: (00 00 00 00 00 00 00)
# CHECK: }
# CHECK: Type: Executable (0x2)
# CHECK: Machine: EM_MIPS (0x8)
# CHECK: Version: 1
# CHECK: Entry: 0x{{[0-9A-F]+}}
# CHECK: ProgramHeaderOffset: 0x{{[0-9A-F]+}}
# CHECK: SectionHeaderOffset: 0x{{[0-9A-F]+}}
# CHECK: Flags [ (0x50001005)
# CHECK: EF_MIPS_ABI_O32 (0x1000)
# CHECK: EF_MIPS_ARCH_32 (0x50000000)
# CHECK: EF_MIPS_CPIC (0x4)
# CHECK: EF_MIPS_NOREORDER (0x1)
# CHECK: ]
# CHECK: HeaderSize: 52
# CHECK: ProgramHeaderEntrySize: 32
# CHECK: ProgramHeaderCount: {{[0-9]+}}
# CHECK: SectionHeaderEntrySize: 40
# CHECK: SectionHeaderCount: {{[0-9]+}}
# CHECK: StringTableSectionIndex: {{[0-9]+}}
# CHECK: }

---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2MSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_NOREORDER, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]

Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 4
Size: 8

Symbols:
Global:
- Name: __start
Section: .text
...
113 changes: 113 additions & 0 deletions lld/test/elf/Mips/la25-stub-be.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# REQUIRES: mips

# Check LA25 stubs creation in the big-endian case.

# RUN: yaml2obj -format=elf -docnum 1 %s > %t-npic.o
# RUN: yaml2obj -format=elf -docnum 2 %s > %t-pic.o
# RUN: yaml2obj -format=elf -docnum 3 %s > %t-main.o
# RUN: lld -flavor gnu -target mips -o %t.exe %t-npic.o %t-pic.o %t-main.o

# RUN: llvm-objdump -disassemble %t.exe | FileCheck %s

# CHECK: 400150: 3c 19 00 40 lui $25, 64
# CHECK-NEXT: 400154: 08 10 00 48 j 4194592
# CHECK-NEXT: 400158: 27 39 01 20 addiu $25, $25, 288
# CHECK-NEXT: 40015c: 00 00 00 00 nop

# npic.o
---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2MSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_CPIC]

Sections:
- Name: .text
Type: SHT_PROGBITS
Size: 4
AddressAlign: 16
Flags: [SHF_EXECINSTR, SHF_ALLOC]

Symbols:
Global:
- Name: T1N
Section: .text
Type: STT_FUNC
Value: 0
Size: 4

# pic.o
---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2MSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_CPIC, EF_MIPS_PIC]

Sections:
- Name: .text
Type: SHT_PROGBITS
Size: 4
AddressAlign: 16
Flags: [SHF_EXECINSTR, SHF_ALLOC]

Symbols:
Global:
- Name: T1
Section: .text
Type: STT_FUNC
Value: 0
Size: 4

# main.o
---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2MSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32, EF_MIPS_CPIC]

Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 4
Size: 40

- Name: .rel.text
Type: SHT_REL
Link: .symtab
AddressAlign: 4
Info: .text
Relocations:
- Offset: 8
Symbol: .text
Type: R_MIPS_26
- Offset: 16
Symbol: __start
Type: R_MIPS_26
- Offset: 24
Symbol: T1N
Type: R_MIPS_26
- Offset: 32
Symbol: T1
Type: R_MIPS_26

Symbols:
Local:
- Name: loc
Section: .text
Value: 16
- Name: .text
Type: STT_SECTION
Section: .text
Global:
- Name: __start
Section: .text
- Name: T1
- Name: T1N
...
121 changes: 121 additions & 0 deletions lld/test/elf/Mips/la25-stub-micro-be.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# REQUIRES: mips

# Check LA25 stubs creation in the big-endian case.

# RUN: yaml2obj -format=elf -docnum 1 %s > %t-npic.o
# RUN: yaml2obj -format=elf -docnum 2 %s > %t-pic.o
# RUN: yaml2obj -format=elf -docnum 3 %s > %t-main.o
# RUN: lld -flavor gnu -target mips -o %t.exe %t-npic.o %t-pic.o %t-main.o

# RUN: llvm-objdump -disassemble -mattr=micromips %t.exe | FileCheck %s

# CHECK: 400150: 41 be 00 40 lui $fp, 64
# CHECK-NEXT: 400154: d4 20 00 90 j 4194592
# CHECK-NEXT: 400158: 33 39 01 21 addiu $25, $25, 289
# CHECK-NEXT: 40015c: 00 00 00 00 nop

---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2MSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2,
EF_MIPS_CPIC, EF_MIPS_MICROMIPS]

Sections:
- Name: .text
Type: SHT_PROGBITS
Size: 4
AddressAlign: 16
Flags: [SHF_EXECINSTR, SHF_ALLOC]

Symbols:
Global:
- Name: T1N
Section: .text
Type: STT_FUNC
Value: 0
Size: 4
Other: [ STO_MIPS_MICROMIPS ]

# pic.o
---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2MSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2,
EF_MIPS_CPIC, EF_MIPS_PIC, EF_MIPS_MICROMIPS]

Sections:
- Name: .text
Type: SHT_PROGBITS
Size: 4
AddressAlign: 16
Flags: [SHF_EXECINSTR, SHF_ALLOC]

Symbols:
Global:
- Name: T1
Section: .text
Type: STT_FUNC
Value: 0
Size: 4
Other: [ STO_MIPS_MICROMIPS ]

# main.o
---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2MSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2,
EF_MIPS_CPIC, EF_MIPS_MICROMIPS]

Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 4
Content: '0000000000000000f400000000000000f400000000000000f400000000000000f400000000000000'
# jal loc jal glob jal T1N jal T1
- Name: .rel.text
Type: SHT_REL
Link: .symtab
AddressAlign: 4
Info: .text
Relocations:
- Offset: 8
Symbol: .text
Type: R_MICROMIPS_26_S1
- Offset: 16
Symbol: glob
Type: R_MICROMIPS_26_S1
- Offset: 24
Symbol: T1N
Type: R_MICROMIPS_26_S1
- Offset: 32
Symbol: T1
Type: R_MICROMIPS_26_S1

Symbols:
Local:
- Name: loc
Section: .text
Value: 16
Size: 24
Other: [ STO_MIPS_MICROMIPS ]
- Name: .text
Type: STT_SECTION
Section: .text
Global:
- Name: __start
Section: .text
Size: 16
Other: [ STO_MIPS_MICROMIPS ]
- Name: T1
- Name: T1N
...
109 changes: 109 additions & 0 deletions lld/test/elf/Mips/plt-entry-r6-be.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# REQUIRES: mips

# Check generation of PLT entries in case of R6 big-endian target ABI.

# Build shared library
# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o
# RUN: lld -flavor gnu -target mips -shared -o %t.so %t-so.o

# Build executable
# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
# RUN: lld -flavor gnu -target mips -e T0 -o %t.exe %t-o.o %t.so
# RUN: llvm-objdump -d %t.exe | FileCheck %s

# CHECK: Disassembly of section .plt:
# CHECK-NEXT: .plt:
# CHECK-NEXT: 400160: 3c 1c 00 40 lui $gp, 64
# CHECK-NEXT: 400164: 8f 99 20 00 lw $25, 8192($gp)
# CHECK-NEXT: 400168: 27 9c 20 00 addiu $gp, $gp, 8192
# CHECK-NEXT: 40016c: 03 1c c0 23 subu $24, $24, $gp
# CHECK-NEXT: 400170: 03 e0 78 21 move $15, $ra
# CHECK-NEXT: 400174: 00 18 c0 82 srl $24, $24, 2
# CHECK-NEXT: 400178: 03 20 f8 09 jalr $25
# CHECK-NEXT: 40017c: 27 18 ff fe addiu $24, $24, -2
# CHECK-NEXT: 400180: 3c 0f 00 40 lui $15, 64
# CHECK-NEXT: 400184: 8d f9 20 08 lw $25, 8200($15)
# CHECK-NEXT: 400188: 03 20 00 09 jr $25
# CHECK-NEXT: 40018c: 25 f8 20 08 addiu $24, $15, 8200

# so.o
---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2MSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R6]

Sections:
- Name: .text
Type: SHT_PROGBITS
Size: 0x0C
AddressAlign: 16
Flags: [SHF_EXECINSTR, SHF_ALLOC]

Symbols:
Global:
- Name: T1
Section: .text
Type: STT_FUNC
Value: 0x0
Size: 4

# o.o
---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2MSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R6]

Sections:
- Name: .text
Type: SHT_PROGBITS
Content: "0C00000000000000"
AddressAlign: 16
Flags: [SHF_EXECINSTR, SHF_ALLOC]

- Name: .data
Type: SHT_PROGBITS
Size: 0x08
AddressAlign: 16
Flags: [SHF_WRITE, SHF_ALLOC]

- Name: .rel.text
Type: SHT_REL
Info: .text
AddressAlign: 4
Relocations:
- Offset: 0x0
Symbol: T1
Type: R_MIPS_26

- Name: .rel.data
Type: SHT_REL
Info: .data
AddressAlign: 4
Relocations:
- Offset: 0x00
Symbol: T1
Type: R_MIPS_HI16
- Offset: 0x00
Symbol: T1
Type: R_MIPS_LO16

Symbols:
Global:
- Name: T0
Section: .text
Type: STT_FUNC
Value: 0x0
Size: 0x8
- Name: D0
Section: .data
Type: STT_OBJECT
Value: 0x0
Size: 8
- Name: T1
...
104 changes: 104 additions & 0 deletions lld/test/elf/Mips/plt-header-be.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# REQUIRES: mips

# Check initialization of big-endian .plt header entries.

# Build shared library
# RUN: yaml2obj -format=elf -docnum 1 %s > %t-so.o
# RUN: lld -flavor gnu -target mips -shared -o %t.so %t-so.o

# Build executable
# RUN: yaml2obj -format=elf -docnum 2 %s > %t-o.o
# RUN: lld -flavor gnu -target mips -o %t.exe %t-o.o %t.so
# RUN: llvm-objdump -section-headers -disassemble %t.exe | FileCheck %s

# CHECK: Disassembly of section .plt:
# CHECK-NEXT: .plt:
# CHECK-NEXT: 400160: 3c 1c 00 40 lui $gp, 64
# CHECK-NEXT: 400164: 8f 99 20 00 lw $25, 8192($gp)
# CHECK-NEXT: 400168: 27 9c 20 00 addiu $gp, $gp, 8192
# CHECK-NEXT: 40016c: 03 1c c0 23 subu $24, $24, $gp
# CHECK-NEXT: 400170: 03 e0 78 21 move $15, $ra
# CHECK-NEXT: 400174: 00 18 c0 82 srl $24, $24, 2
# CHECK-NEXT: 400178: 03 20 f8 09 jalr $25
# CHECK-NEXT: 40017c: 27 18 ff fe addiu $24, $24, -2

# CHECK-NEXT: 400180: 3c 0f 00 40 lui $15, 64
# CHECK-NEXT: 400184: 8d f9 20 08 lw $25, 8200($15)
# CHECK-NEXT: 400188: 03 20 00 08 jr $25
# CHECK-NEXT: 40018c: 25 f8 20 08 addiu $24, $15, 8200

# CHECK: Sections:
# CHECK: Idx Name Size Address Type
# CHECK: 6 .plt 00000030 0000000000400160 TEXT DATA
# CHECK: 10 .got.plt 0000000c 0000000000402000 DATA

# so.o
---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2MSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]

Sections:
- Name: .text
Type: SHT_PROGBITS
Size: 12
AddressAlign: 16
Flags: [SHF_EXECINSTR, SHF_ALLOC]

Symbols:
Global:
- Name: T1
Section: .text
Type: STT_FUNC
Value: 0
Size: 4

# o.o
---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2MSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]

Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 4
Size: 32

- Name: .rel.text
Type: SHT_REL
Link: .symtab
AddressAlign: 4
Info: .text
Relocations:
- Offset: 8
Symbol: .text
Type: R_MIPS_26
- Offset: 16
Symbol: __start
Type: R_MIPS_26
- Offset: 24
Symbol: T1
Type: R_MIPS_26

Symbols:
Local:
- Name: loc
Section: .text
Value: 16
- Name: .text
Type: STT_SECTION
Section: .text

Global:
- Name: __start
Section: .text
- Name: T1
...
105 changes: 105 additions & 0 deletions lld/test/elf/Mips/plt-header-micro-be.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# REQUIRES: mips

# Check initialization of .plt header entries
# if all PLT entries use microMIPS big-endian encoding.

# RUN: yaml2obj -format=elf -docnum 1 %s > %t1.o
# RUN: lld -flavor gnu -target mips -shared -o %t.so %t1.o
# RUN: yaml2obj -format=elf -docnum 2 %s > %t2.o
# RUN: lld -flavor gnu -target mips -o %t.exe %t2.o %t.so
# RUN: llvm-objdump -section-headers -d -mattr=micromips %t.exe | FileCheck %s

# CHECK: Disassembly of section .plt:
# CHECK-NEXT: .plt:
# CHECK-NEXT: 400170: 79 80 07 a4 addiupc $3, 7824
# CHECK-NEXT: 400174: ff 23 00 00 lw $25, 0($3)
# CHECK-NEXT: 400178: 05 35 subu16 $2, $2, $3
# CHECK-NEXT: 40017a: 25 25 srl16 $2, $2, 2
# CHECK-NEXT: 40017c: 33 02 ff fe addiu $24, $2, -2
# CHECK-NEXT: 400180: 0d ff move $15, $ra
# CHECK-NEXT: 400182: 45 f9 jalrs16 $25
# CHECK-NEXT: 400184: 0f 83 move $gp, $3
# CHECK-NEXT: 400186: 0c 00 nop

# CHECK-NEXT: 400188: 79 00 07 a0 addiupc $2, 7808
# CHECK-NEXT: 40018c: ff 22 00 00 lw $25, 0($2)
# CHECK-NEXT: 400190: 45 99 jr16 $25
# CHECK-NEXT: 400192: 0f 02 move $24, $2

# CHECK: Sections:
# CHECK: Idx Name Size Address Type
# CHECK: 6 .plt 00000024 0000000000400170 TEXT DATA
# CHECK: 10 .got.plt 0000000c 0000000000402000 DATA

# so.o
---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2MSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]

Sections:
- Name: .text
Type: SHT_PROGBITS
Size: 12
AddressAlign: 16
Flags: [SHF_EXECINSTR, SHF_ALLOC]

Symbols:
Global:
- Name: T1
Section: .text
Type: STT_FUNC
Value: 0
Size: 4

# o.o
---
FileHeader:
Class: ELFCLASS32
Data: ELFDATA2MSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32,
EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS]

Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x04
Content: '0000000000000000f40000000000000000000000f400000000000000f4000000'
# jal .text jal __start jal T1
- Name: .rel.text
Type: SHT_REL
Link: .symtab
AddressAlign: 4
Info: .text
Relocations:
- Offset: 8
Symbol: .text
Type: R_MICROMIPS_26_S1
- Offset: 20
Symbol: __start
Type: R_MICROMIPS_26_S1
- Offset: 28
Symbol: T1
Type: R_MICROMIPS_26_S1

Symbols:
Local:
- Name: loc
Section: .text
Value: 16
Other: [ STO_MIPS_MICROMIPS ]
- Name: .text
Type: STT_SECTION
Section: .text
Global:
- Name: __start
Section: .text
Other: [ STO_MIPS_MICROMIPS ]
- Name: T1
...
60 changes: 60 additions & 0 deletions lld/test/elf/Mips/rel-32-be.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Check handling of R_MIPS_32 relocation in the big-endian case.

# RUN: yaml2obj -format=elf %s > %t.o
# RUN: lld -flavor gnu -target mips -o %t.exe %t.o
# RUN: llvm-objdump -s -t %t.exe | FileCheck %s

# CHECK: Contents of section .data:
# CHECK-NEXT: 402000 00000000 01402088 01402084
# ^^ D2 + 0x1000080 = 0x1402088
# ^^ D1 + 0x1000080 = 0x1402084
# CHECK: SYMBOL TABLE:
# CHECK: 00402004 g .data 00000004 D1
# CHECK: 00402008 g .data 00000004 D2

FileHeader:
Class: ELFCLASS32
Data: ELFDATA2MSB
Type: ET_REL
Machine: EM_MIPS
Flags: [EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]

Sections:
- Name: .text
Type: SHT_PROGBITS
AddressAlign: 16
Flags: [SHF_ALLOC]
Size: 4

- Name: .data
Type: SHT_PROGBITS
AddressAlign: 16
Flags: [SHF_ALLOC, SHF_WRITE]
Content: "000000000100008001000080"

- Name: .rel.data
Type: SHT_REL
Info: .data
AddressAlign: 4
Relocations:
- Offset: 4
Symbol: D2
Type: R_MIPS_32
- Offset: 8
Symbol: D1
Type: R_MIPS_32

Symbols:
Global:
- Name: __start
Section: .text
Value: 0
Size: 4
- Name: D1
Section: .data
Value: 4
Size: 4
- Name: D2
Section: .data
Value: 8
Size: 4