Index: lld/ELF/Writer.cpp =================================================================== --- lld/ELF/Writer.cpp +++ lld/ELF/Writer.cpp @@ -60,7 +60,8 @@ std::vector createPhdrs(); void removeEmptyPTLoad(); - void addPtArmExid(std::vector &Phdrs); + void addPhdrForSection(std::vector &Phdrs, unsigned ShType, + unsigned PType, unsigned PFlags); void assignFileOffsets(); void assignFileOffsetsBinary(); void setPhdrs(); @@ -1761,7 +1762,16 @@ // image base and the dynamic section on mips includes the image base. if (!Config->Relocatable && !Config->OFormatBinary) { Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs() : createPhdrs(); - addPtArmExid(Phdrs); + if (Config->EMachine == EM_ARM) { + // PT_ARM_EXIDX is the ARM EHABI equivalent of PT_GNU_EH_FRAME + addPhdrForSection(Phdrs, SHT_ARM_EXIDX, PT_ARM_EXIDX, PF_R); + } + if (Config->EMachine == EM_MIPS) { + // Add separate segments for MIPS-specific sections. + addPhdrForSection(Phdrs, SHT_MIPS_REGINFO, PT_MIPS_REGINFO, PF_R); + addPhdrForSection(Phdrs, SHT_MIPS_OPTIONS, PT_MIPS_OPTIONS, PF_R); + addPhdrForSection(Phdrs, SHT_MIPS_ABIFLAGS, PT_MIPS_ABIFLAGS, PF_R); + } Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size(); // Find the TLS segment. This happens before the section layout loop so that @@ -2057,19 +2067,17 @@ } template -void Writer::addPtArmExid(std::vector &Phdrs) { - if (Config->EMachine != EM_ARM) - return; - auto I = llvm::find_if(OutputSections, [](OutputSection *Cmd) { - return Cmd->Type == SHT_ARM_EXIDX; - }); +void Writer::addPhdrForSection(std::vector &Phdrs, + unsigned ShType, unsigned PType, + unsigned PFlags) { + auto I = llvm::find_if( + OutputSections, [=](OutputSection *Cmd) { return Cmd->Type == ShType; }); if (I == OutputSections.end()) return; - // PT_ARM_EXIDX is the ARM EHABI equivalent of PT_GNU_EH_FRAME - PhdrEntry *ARMExidx = make(PT_ARM_EXIDX, PF_R); - ARMExidx->add(*I); - Phdrs.push_back(ARMExidx); + PhdrEntry *Entry = make(PType, PFlags); + Entry->add(*I); + Phdrs.push_back(Entry); } // The first section of each PT_LOAD, the first section in PT_GNU_RELRO and the Index: lld/test/ELF/basic-mips.s =================================================================== --- lld/test/ELF/basic-mips.s +++ lld/test/ELF/basic-mips.s @@ -34,7 +34,7 @@ # CHECK-NEXT: ] # CHECK-NEXT: HeaderSize: 52 # CHECK-NEXT: ProgramHeaderEntrySize: 32 -# CHECK-NEXT: ProgramHeaderCount: 5 +# CHECK-NEXT: ProgramHeaderCount: 7 # CHECK-NEXT: SectionHeaderEntrySize: 40 # CHECK-NEXT: SectionHeaderCount: 11 # CHECK-NEXT: StringTableSectionIndex: 9 @@ -61,8 +61,8 @@ # CHECK-NEXT: Flags [ (0x2) # CHECK-NEXT: SHF_ALLOC (0x2) # CHECK-NEXT: ] -# CHECK-NEXT: Address: 0x100D8 -# CHECK-NEXT: Offset: 0xD8 +# CHECK-NEXT: Address: 0x10118 +# CHECK-NEXT: Offset: 0x118 # CHECK-NEXT: Size: 24 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -76,8 +76,8 @@ # CHECK-NEXT: Flags [ (0x2) # CHECK-NEXT: SHF_ALLOC (0x2) # CHECK-NEXT: ] -# CHECK-NEXT: Address: 0x100F0 -# CHECK-NEXT: Offset: 0xF0 +# CHECK-NEXT: Address: 0x10130 +# CHECK-NEXT: Offset: 0x130 # CHECK-NEXT: Size: 24 # CHECK-NEXT: Link: 0 # CHECK-NEXT: Info: 0 @@ -245,8 +245,8 @@ # CHECK-NEXT: Offset: 0x34 # CHECK-NEXT: VirtualAddress: 0x10034 # CHECK-NEXT: PhysicalAddress: 0x10034 -# CHECK-NEXT: FileSize: 160 -# CHECK-NEXT: MemSize: 160 +# CHECK-NEXT: FileSize: 224 +# CHECK-NEXT: MemSize: 224 # CHECK-NEXT: Flags [ (0x4) # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: ] @@ -257,8 +257,8 @@ # CHECK-NEXT: Offset: 0x0 # CHECK-NEXT: VirtualAddress: 0x10000 # CHECK-NEXT: PhysicalAddress: 0x10000 -# CHECK-NEXT: FileSize: 264 -# CHECK-NEXT: MemSize: 264 +# CHECK-NEXT: FileSize: 328 +# CHECK-NEXT: MemSize: 328 # CHECK-NEXT: Flags [ (0x4) # CHECK-NEXT: PF_R (0x4) # CHECK-NEXT: ] @@ -303,4 +303,28 @@ # CHECK-NEXT: ] # CHECK-NEXT: Alignment: 0 # CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_MIPS_REGINFO +# CHECK-NEXT: Offset: 0x130 +# CHECK-NEXT: VirtualAddress: 0x10130 +# CHECK-NEXT: PhysicalAddress: 0x10130 +# CHECK-NEXT: FileSize: 24 +# CHECK-NEXT: MemSize: 24 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_MIPS_ABIFLAGS +# CHECK-NEXT: Offset: 0x118 +# CHECK-NEXT: VirtualAddress: 0x10118 +# CHECK-NEXT: PhysicalAddress: 0x10118 +# CHECK-NEXT: FileSize: 24 +# CHECK-NEXT: MemSize: 24 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: } # CHECK-NEXT: ] Index: lld/test/ELF/mips-got-string.s =================================================================== --- lld/test/ELF/mips-got-string.s +++ lld/test/ELF/mips-got-string.s @@ -7,7 +7,7 @@ # CHECK: Symbol { # CHECK: Name: $.str -# CHECK-NEXT: Value: 0x1B1 +# CHECK-NEXT: Value: 0x1F1 # CHECK: } # CHECK: Local entries [ Index: lld/test/ELF/mips-options.s =================================================================== --- lld/test/ELF/mips-options.s +++ lld/test/ELF/mips-options.s @@ -8,7 +8,7 @@ # RUN: . = 0x100000000; \ # RUN: .got : { *(.got) } }" > %t.rel.script # RUN: ld.lld %t1.o %t2.o --gc-sections --script %t.rel.script -shared -o %t.so -# RUN: llvm-readobj -symbols -mips-options %t.so | FileCheck %s +# RUN: llvm-readobj -program-headers -symbols -mips-options %t.so | FileCheck %s .text .globl __start @@ -18,6 +18,19 @@ # CHECK: Name: _gp # CHECK-NEXT: Value: 0x[[GP:[0-9A-F]+]] +# CHECK: ProgramHeader { +# CHECK: Type: PT_MIPS_OPTIONS +# CHECK-NEXT: Offset: +# CHECK-NEXT: VirtualAddress: +# CHECK-NEXT: PhysicalAddress: +# CHECK-NEXT: FileSize: +# CHECK-NEXT: MemSize: +# CHECK-NEXT: Flags [ +# CHECK-NEXT: PF_R +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: } + # CHECK: MIPS Options { # CHECK-NEXT: ODK_REGINFO { # CHECK-NEXT: GP: 0x[[GP]]