diff --git a/llvm/test/tools/llvm-objcopy/ELF/mips64el.test b/llvm/test/tools/llvm-objcopy/ELF/mips64el.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/ELF/mips64el.test @@ -0,0 +1,48 @@ +# RUN: yaml2obj %s -DENDIANNESS=ELFDATA2LSB -o %t +# RUN: llvm-objcopy %t %t2 +# RUN: llvm-readobj --relocations %t2 | FileCheck %s + +# RUN: yaml2obj %s -DENDIANNESS=ELFDATA2MSB -o %t +# RUN: llvm-objcopy %t %t2 +# RUN: llvm-readobj --relocations %t2 | FileCheck %s + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: [[ENDIANNESS]] + Type: ET_REL + Machine: EM_MIPS +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x10 + Content: 0000000000000000 + - Name: .rela.text + Type: SHT_RELA + Flags: [ SHF_INFO_LINK ] + Link: .symtab + AddressAlign: 0x8 + Info: .text + Relocations: + - Offset: 8 + Symbol: foo + Type: R_MIPS_JALR +Symbols: + - Name: foo + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Size: 8 + - Name: bar + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 8 + Size: 8 + +# CHECK: Relocations [ +# CHECK-NEXT: Section (2) .rela.text { +# CHECK-NEXT: 0x8 R_MIPS_JALR/R_MIPS_NONE/R_MIPS_NONE foo 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] diff --git a/llvm/tools/llvm-objcopy/ELF/Object.h b/llvm/tools/llvm-objcopy/ELF/Object.h --- a/llvm/tools/llvm-objcopy/ELF/Object.h +++ b/llvm/tools/llvm-objcopy/ELF/Object.h @@ -783,6 +783,7 @@ MAKE_SEC_WRITER_FRIEND std::vector Relocations; + bool IsObjMips64EL = false; public: void addRelocation(Relocation Rel) { Relocations.push_back(Rel); } @@ -795,6 +796,8 @@ void markSymbols() override; void replaceSectionReferences( const DenseMap &FromTo) override; + bool IsMips64EL() const { return IsObjMips64EL; } + void SetMips64EL(bool value) { IsObjMips64EL = value; } static bool classof(const SectionBase *S) { if (S->OriginalFlags & ELF::SHF_ALLOC) diff --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/tools/llvm-objcopy/ELF/Object.cpp --- a/llvm/tools/llvm-objcopy/ELF/Object.cpp +++ b/llvm/tools/llvm-objcopy/ELF/Object.cpp @@ -978,12 +978,12 @@ } template -static void writeRel(const RelRange &Relocations, T *Buf) { +static void writeRel(const RelRange &Relocations, T *Buf, bool IsMips64EL) { for (const auto &Reloc : Relocations) { Buf->r_offset = Reloc.Offset; setAddend(*Buf, Reloc.Addend); Buf->setSymbolAndType(Reloc.RelocSymbol ? Reloc.RelocSymbol->Index : 0, - Reloc.Type, false); + Reloc.Type, IsMips64EL); ++Buf; } } @@ -992,9 +992,11 @@ Error ELFSectionWriter::visit(const RelocationSection &Sec) { uint8_t *Buf = reinterpret_cast(Out.getBufferStart()) + Sec.Offset; if (Sec.Type == SHT_REL) - writeRel(Sec.Relocations, reinterpret_cast(Buf)); + writeRel(Sec.Relocations, reinterpret_cast(Buf), + Sec.IsMips64EL()); else - writeRel(Sec.Relocations, reinterpret_cast(Buf)); + writeRel(Sec.Relocations, reinterpret_cast(Buf), + Sec.IsMips64EL()); return Error::success(); } @@ -1640,14 +1642,16 @@ template static Error initRelocations(RelocationSection *Relocs, - SymbolTableSection *SymbolTable, T RelRange) { + SymbolTableSection *SymbolTable, T RelRange, + bool IsMips64EL) { + Relocs->SetMips64EL(IsMips64EL); for (const auto &Rel : RelRange) { Relocation ToAdd; ToAdd.Offset = Rel.r_offset; getAddend(ToAdd.Addend, Rel); - ToAdd.Type = Rel.getType(false); + ToAdd.Type = Rel.getType(IsMips64EL); - if (uint32_t Sym = Rel.getSymbol(false)) { + if (uint32_t Sym = Rel.getSymbol(IsMips64EL)) { if (!SymbolTable) return createStringError( errc::invalid_argument, @@ -1879,7 +1883,8 @@ if (!Rels) return Rels.takeError(); - if (Error Err = initRelocations(RelSec, Obj.SymbolTable, *Rels)) + if (Error Err = initRelocations(RelSec, Obj.SymbolTable, *Rels, + ElfFile.isMips64EL())) return Err; } else { Expected::Elf_Rela_Range> Relas = @@ -1887,7 +1892,8 @@ if (!Relas) return Relas.takeError(); - if (Error Err = initRelocations(RelSec, Obj.SymbolTable, *Relas)) + if (Error Err = initRelocations(RelSec, Obj.SymbolTable, *Relas, + ElfFile.isMips64EL())) return Err; } } else if (auto GroupSec = dyn_cast(&Sec)) {