Index: llvm/include/llvm/ObjectYAML/ELFYAML.h =================================================================== --- llvm/include/llvm/ObjectYAML/ELFYAML.h +++ llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -138,6 +138,7 @@ Group, RawContent, Relocation, + RelocationOffsets, NoBits, Note, Hash, @@ -440,6 +441,17 @@ } }; +struct RelocationOffsetsSection : Section { + Optional> Entries; + Optional Content; + + RelocationOffsetsSection() : Section(ChunkKind::RelocationOffsets) {} + + static bool classof(const Chunk *S) { + return S->Kind == ChunkKind::RelocationOffsets; + } +}; + struct SymtabShndxSection : Section { std::vector Entries; Index: llvm/lib/ObjectYAML/ELFEmitter.cpp =================================================================== --- llvm/lib/ObjectYAML/ELFEmitter.cpp +++ llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -110,6 +110,7 @@ typedef typename ELFT::Rela Elf_Rela; typedef typename ELFT::Relr Elf_Relr; typedef typename ELFT::Dyn Elf_Dyn; + using uintX_t = typename ELFT::uint; enum class SymtabType { Static, Dynamic }; @@ -165,6 +166,9 @@ void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::RelocationSection &Section, ContiguousBlobAccumulator &CBA); + void writeSectionContent(Elf_Shdr &SHeader, + const ELFYAML::RelocationOffsetsSection &Section, + ContiguousBlobAccumulator &CBA); void writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::Group &Group, ContiguousBlobAccumulator &CBA); void writeSectionContent(Elf_Shdr &SHeader, @@ -454,6 +458,8 @@ writeSectionContent(SHeader, *S, CBA); } else if (auto S = dyn_cast(Sec)) { writeSectionContent(SHeader, *S, CBA); + } else if (auto S = dyn_cast(Sec)) { + writeSectionContent(SHeader, *S, CBA); } else if (auto S = dyn_cast(Sec)) { writeSectionContent(SHeader, *S, CBA); } else if (auto S = dyn_cast(Sec)) { @@ -770,10 +776,6 @@ if (Section.EntSize) SHeader.sh_entsize = *Section.EntSize; - else if (Section.Type == llvm::ELF::SHT_RELR) - SHeader.sh_entsize = sizeof(Elf_Relr); - else - SHeader.sh_entsize = 0; if (Section.Info) SHeader.sh_info = *Section.Info; @@ -827,6 +829,30 @@ } } +template +void ELFState::writeSectionContent( + Elf_Shdr &SHeader, const ELFYAML::RelocationOffsetsSection &Section, + ContiguousBlobAccumulator &CBA) { + raw_ostream &OS = + CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); + SHeader.sh_entsize = + Section.EntSize ? (uint64_t)(*Section.EntSize) : sizeof(Elf_Relr); + + if (Section.Content) { + SHeader.sh_size = writeContent(OS, Section.Content, None); + return; + } + + for (const llvm::yaml::Hex64 &Hex : *Section.Entries) { + if (!ELFT::Is64Bits && Hex > UINT32_MAX) + reportError(Section.Name + ": the value is too large for 32-bits: 0x" + + Twine::utohexstr(Hex)); + support::endian::write(OS, Hex, ELFT::TargetEndianness); + } + + SHeader.sh_size = sizeof(uintX_t) * Section.Entries->size(); +} + template void ELFState::writeSectionContent( Elf_Shdr &SHeader, const ELFYAML::SymtabShndxSection &Shndx, @@ -889,7 +915,6 @@ void ELFState::writeSectionContent( Elf_Shdr &SHeader, const ELFYAML::StackSizesSection &Section, ContiguousBlobAccumulator &CBA) { - using uintX_t = typename ELFT::uint; raw_ostream &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign); @@ -1115,8 +1140,6 @@ void ELFState::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::DynamicSection &Section, ContiguousBlobAccumulator &CBA) { - typedef typename ELFT::uint uintX_t; - assert(Section.Type == llvm::ELF::SHT_DYNAMIC && "Section type is not SHT_DYNAMIC"); Index: llvm/lib/ObjectYAML/ELFYAML.cpp =================================================================== --- llvm/lib/ObjectYAML/ELFYAML.cpp +++ llvm/lib/ObjectYAML/ELFYAML.cpp @@ -1101,6 +1101,12 @@ IO.mapOptional("Relocations", Section.Relocations); } +static void sectionMapping(IO &IO, ELFYAML::RelocationOffsetsSection &Section) { + commonSectionMapping(IO, Section); + IO.mapOptional("Entries", Section.Entries); + IO.mapOptional("Content", Section.Content); +} + static void groupSectionMapping(IO &IO, ELFYAML::Group &Group) { commonSectionMapping(IO, Group); IO.mapOptional("Info", Group.Signature); @@ -1200,6 +1206,11 @@ Section.reset(new ELFYAML::RelocationSection()); sectionMapping(IO, *cast(Section.get())); break; + case ELF::SHT_RELR: + if (!IO.outputting()) + Section.reset(new ELFYAML::RelocationOffsetsSection()); + sectionMapping(IO, *cast(Section.get())); + break; case ELF::SHT_GROUP: if (!IO.outputting()) Section.reset(new ELFYAML::Group()); @@ -1441,6 +1452,12 @@ return {}; } + if (const auto *ROS = dyn_cast(C.get())) { + if (ROS->Entries && ROS->Content) + return "\"Entries\" and \"Content\" can't be used together"; + return {}; + } + return {}; } Index: llvm/test/tools/llvm-readobj/ELF/file-header-abi-version.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/file-header-abi-version.test +++ /dev/null @@ -1,47 +0,0 @@ -## This is a test to test how ABI version (EI_ABIVERSION) of an ELF file header is dumped. - -## EI_ABIVERSION is set to zero. -# RUN: yaml2obj %s --docnum=1 -o %t.abiver.zero -# RUN: llvm-readobj --file-headers %t.abiver.zero | FileCheck %s --match-full-lines --check-prefix=ABIVER-ZERO-LLVM -# RUN: llvm-readelf --file-headers %t.abiver.zero | FileCheck %s --match-full-lines --check-prefix=ABIVER-ZERO-GNU -## EI_ABIVERSION is set to an arbitrary number. -# RUN: yaml2obj %s --docnum=2 -o %t.abiver.any -# RUN: llvm-readobj --file-headers %t.abiver.any | FileCheck %s --match-full-lines --check-prefix=ABIVER-ANY-LLVM -# RUN: llvm-readelf --file-headers %t.abiver.any | FileCheck %s --match-full-lines --check-prefix=ABIVER-ANY-GNU -## EI_ABIVERSION is set to the maximum possible value. -# RUN: yaml2obj %s --docnum=3 -o %t.abiver.max -# RUN: llvm-readobj --file-headers %t.abiver.max | FileCheck %s --match-full-lines --check-prefix=ABIVER-MAX-LLVM -# RUN: llvm-readelf --file-headers %t.abiver.max | FileCheck %s --match-full-lines --check-prefix=ABIVER-MAX-GNU - -# ABIVER-ZERO-LLVM: ABIVersion: 0 -# ABIVER-ZERO-GNU: ABI Version: 0x0 - -# ABIVER-ANY-LLVM: ABIVersion: 52 -# ABIVER-ANY-GNU: ABI Version: 0x34 - -# ABIVER-MAX-LLVM: ABIVersion: 255 -# ABIVER-MAX-GNU: ABI Version: 0xFF - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - ABIVersion: 0x0 - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - ABIVersion: 0x34 - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - ABIVersion: 0xFF Index: llvm/test/tools/llvm-readobj/ELF/file-header-os-abi.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/file-header-os-abi.test +++ /dev/null @@ -1,305 +0,0 @@ -## This is a test to test how OS/ABI identification (EI_OSABI) of an ELF file header is dumped. - -## EI_OSABI is set to ELFOSABI_NONE. -# RUN: yaml2obj %s --docnum=1 -o %t.osabi.none -# RUN: llvm-readobj --file-headers %t.osabi.none | FileCheck %s --match-full-lines --check-prefix=OSABI-NONE-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.none | FileCheck %s --match-full-lines --check-prefix=OSABI-NONE-GNU - -# OSABI-NONE-LLVM: OS/ABI: SystemV (0x0) -# OSABI-NONE-GNU: OS/ABI: UNIX - System V - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_NONE - -## EI_OSABI is set to ELFOSABI_HPUX. -# RUN: yaml2obj %s --docnum=2 -o %t.osabi.hpux -# RUN: llvm-readobj --file-headers %t.osabi.hpux | FileCheck %s --match-full-lines --check-prefix=OSABI-HPUX-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.hpux | FileCheck %s --match-full-lines --check-prefix=OSABI-HPUX-GNU - -# OSABI-HPUX-LLVM: OS/ABI: HPUX (0x1) -# OSABI-HPUX-GNU: OS/ABI: UNIX - HP-UX - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_HPUX - -## EI_OSABI is set to ELFOSABI_NETBSD. -# RUN: yaml2obj %s --docnum=3 -o %t.osabi.netbsd -# RUN: llvm-readobj --file-headers %t.osabi.netbsd | FileCheck %s --match-full-lines --check-prefix=OSABI-NETBSD-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.netbsd | FileCheck %s --match-full-lines --check-prefix=OSABI-NETBSD-GNU - -# OSABI-NETBSD-LLVM: OS/ABI: NetBSD (0x2) -# OSABI-NETBSD-GNU: OS/ABI: UNIX - NetBSD - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_NETBSD - -## EI_OSABI is set to ELFOSABI_LINUX. -# RUN: yaml2obj %s --docnum=4 -o %t.osabi.linux -# RUN: llvm-readobj --file-headers %t.osabi.linux | FileCheck %s --match-full-lines --check-prefix=OSABI-LINUX-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.linux | FileCheck %s --match-full-lines --check-prefix=OSABI-LINUX-GNU - -# OSABI-LINUX-LLVM: OS/ABI: GNU/Linux (0x3) -# OSABI-LINUX-GNU: OS/ABI: UNIX - GNU - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_LINUX - -## EI_OSABI is set to ELFOSABI_HURD. -# RUN: yaml2obj %s --docnum=5 -o %t.osabi.hurd -# RUN: llvm-readobj --file-headers %t.osabi.hurd | FileCheck %s --match-full-lines --check-prefix=OSABI-HURD-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.hurd | FileCheck %s --match-full-lines --check-prefix=OSABI-HURD-GNU - -# OSABI-HURD-LLVM: OS/ABI: GNU/Hurd (0x4) -# OSABI-HURD-GNU: OS/ABI: GNU/Hurd - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_HURD - -## EI_OSABI is set to ELFOSABI_SOLARIS. -# RUN: yaml2obj %s --docnum=6 -o %t.osabi.solaris -# RUN: llvm-readobj --file-headers %t.osabi.solaris | FileCheck %s --match-full-lines --check-prefix=OSABI-SOLARIS-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.solaris | FileCheck %s --match-full-lines --check-prefix=OSABI-SOLARIS-GNU - -# OSABI-SOLARIS-LLVM: OS/ABI: Solaris (0x6) -# OSABI-SOLARIS-GNU: OS/ABI: UNIX - Solaris - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_SOLARIS - -## EI_OSABI is set to ELFOSABI_AIX. -# RUN: yaml2obj %s --docnum=7 -o %t.osabi.aix -# RUN: llvm-readobj --file-headers %t.osabi.aix | FileCheck %s --match-full-lines --check-prefix=OSABI-AIX-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.aix | FileCheck %s --match-full-lines --check-prefix=OSABI-AIX-GNU - -# OSABI-AIX-LLVM: OS/ABI: AIX (0x7) -# OSABI-AIX-GNU: OS/ABI: UNIX - AIX - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_AIX - -## EI_OSABI is set to ELFOSABI_IRIX. -# RUN: yaml2obj %s --docnum=8 -o %t.osabi.irix -# RUN: llvm-readobj --file-headers %t.osabi.irix | FileCheck %s --match-full-lines --check-prefix=OSABI-IRIX-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.irix | FileCheck %s --match-full-lines --check-prefix=OSABI-IRIX-GNU - -# OSABI-IRIX-LLVM: OS/ABI: IRIX (0x8) -# OSABI-IRIX-GNU: OS/ABI: UNIX - IRIX - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_IRIX - -## EI_OSABI is set to ELFOSABI_FREEBSD. -# RUN: yaml2obj %s --docnum=9 -o %t.osabi.freebsd -# RUN: llvm-readobj --file-headers %t.osabi.freebsd | FileCheck %s --match-full-lines --check-prefix=OSABI-FREEBSD-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.freebsd | FileCheck %s --match-full-lines --check-prefix=OSABI-FREEBSD-GNU - -# OSABI-FREEBSD-LLVM: OS/ABI: FreeBSD (0x9) -# OSABI-FREEBSD-GNU: OS/ABI: UNIX - FreeBSD - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_FREEBSD - -## EI_OSABI is set to ELFOSABI_TRU64. -# RUN: yaml2obj %s --docnum=10 -o %t.osabi.tru64 -# RUN: llvm-readobj --file-headers %t.osabi.tru64 | FileCheck %s --match-full-lines --check-prefix=OSABI-TRU64-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.tru64 | FileCheck %s --match-full-lines --check-prefix=OSABI-TRU64-GNU - -# OSABI-TRU64-LLVM: OS/ABI: TRU64 (0xA) -# OSABI-TRU64-GNU: OS/ABI: UNIX - TRU64 - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_TRU64 - -## EI_OSABI is set to ELFOSABI_MODESTO. -# RUN: yaml2obj %s --docnum=11 -o %t.osabi.modesto -# RUN: llvm-readobj --file-headers %t.osabi.modesto | FileCheck %s --match-full-lines --check-prefix=OSABI-MODESTO-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.modesto | FileCheck %s --match-full-lines --check-prefix=OSABI-MODESTO-GNU - -# OSABI-MODESTO-LLVM: OS/ABI: Modesto (0xB) -# OSABI-MODESTO-GNU: OS/ABI: Novell - Modesto - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_MODESTO - -## EI_OSABI is set to ELFOSABI_OPENBSD. -# RUN: yaml2obj %s --docnum=12 -o %t.osabi.openbsd -# RUN: llvm-readobj --file-headers %t.osabi.openbsd | FileCheck %s --match-full-lines --check-prefix=OSABI-OPENBSD-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.openbsd | FileCheck %s --match-full-lines --check-prefix=OSABI-OPENBSD-GNU - -# OSABI-OPENBSD-LLVM: OS/ABI: OpenBSD (0xC) -# OSABI-OPENBSD-GNU: OS/ABI: UNIX - OpenBSD - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_OPENBSD - -## EI_OSABI is set to ELFOSABI_OPENVMS. -# RUN: yaml2obj %s --docnum=13 -o %t.osabi.openvms -# RUN: llvm-readobj --file-headers %t.osabi.openvms | FileCheck %s --match-full-lines --check-prefix=OSABI-OPENVMS-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.openvms | FileCheck %s --match-full-lines --check-prefix=OSABI-OPENVMS-GNU - -# OSABI-OPENVMS-LLVM: OS/ABI: OpenVMS (0xD) -# OSABI-OPENVMS-GNU: OS/ABI: VMS - OpenVMS - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_OPENVMS - -## EI_OSABI is set to ELFOSABI_NSK. -# RUN: yaml2obj %s --docnum=14 -o %t.osabi.nsk -# RUN: llvm-readobj --file-headers %t.osabi.nsk | FileCheck %s --match-full-lines --check-prefix=OSABI-NSK-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.nsk | FileCheck %s --match-full-lines --check-prefix=OSABI-NSK-GNU - -# OSABI-NSK-LLVM: OS/ABI: NSK (0xE) -# OSABI-NSK-GNU: OS/ABI: HP - Non-Stop Kernel - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_NSK - -## EI_OSABI is set to ELFOSABI_AROS. -# RUN: yaml2obj %s --docnum=15 -o %t.osabi.aros -# RUN: llvm-readobj --file-headers %t.osabi.aros | FileCheck %s --match-full-lines --check-prefix=OSABI-AROS-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.aros | FileCheck %s --match-full-lines --check-prefix=OSABI-AROS-GNU - -# OSABI-AROS-LLVM: OS/ABI: AROS (0xF) -# OSABI-AROS-GNU: OS/ABI: AROS - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_AROS - -## EI_OSABI is set to ELFOSABI_FENIXOS. -# RUN: yaml2obj %s --docnum=16 -o %t.osabi.fenixos -# RUN: llvm-readobj --file-headers %t.osabi.fenixos | FileCheck %s --match-full-lines --check-prefix=OSABI-FENIXOS-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.fenixos | FileCheck %s --match-full-lines --check-prefix=OSABI-FENIXOS-GNU - -# OSABI-FENIXOS-LLVM: OS/ABI: FenixOS (0x10) -# OSABI-FENIXOS-GNU: OS/ABI: FenixOS - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_FENIXOS - -## EI_OSABI is set to ELFOSABI_CLOUDABI. -# RUN: yaml2obj %s --docnum=17 -o %t.osabi.cloudabi -# RUN: llvm-readobj --file-headers %t.osabi.cloudabi | FileCheck %s --match-full-lines --check-prefix=OSABI-CLOUDABI-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.cloudabi | FileCheck %s --match-full-lines --check-prefix=OSABI-CLOUDABI-GNU - -# OSABI-CLOUDABI-LLVM: OS/ABI: CloudABI (0x11) -# OSABI-CLOUDABI-GNU: OS/ABI: CloudABI - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_CLOUDABI - -## EI_OSABI is set to ELFOSABI_STANDALONE. -# RUN: yaml2obj %s --docnum=18 -o %t.osabi.standalone -# RUN: llvm-readobj --file-headers %t.osabi.standalone | FileCheck %s --match-full-lines --check-prefix=OSABI-STANDALONE-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.standalone | FileCheck %s --match-full-lines --check-prefix=OSABI-STANDALONE-GNU - -# OSABI-STANDALONE-LLVM: OS/ABI: Standalone (0xFF) -# OSABI-STANDALONE-GNU: OS/ABI: Standalone App - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: ELFOSABI_STANDALONE - -## EI_OSABI is set to an arbitrary value which is not supported by llvm-readobj/llvm-readelf. -# RUN: yaml2obj %s --docnum=19 -o %t.osabi.unknown -# RUN: llvm-readobj --file-headers %t.osabi.unknown | FileCheck %s --match-full-lines --check-prefix=OSABI-UNKNOWN-LLVM -# RUN: llvm-readelf --file-headers %t.osabi.unknown | FileCheck %s --match-full-lines --check-prefix=OSABI-UNKNOWN-GNU - -# OSABI-UNKNOWN-LLVM: OS/ABI: 0xFE -# OSABI-UNKNOWN-GNU: OS/ABI: fe - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL - Machine: EM_X86_64 - OSABI: 0xFE Index: llvm/test/tools/obj2yaml/relr-section.yaml =================================================================== --- /dev/null +++ llvm/test/tools/obj2yaml/relr-section.yaml @@ -0,0 +1,103 @@ +## This is a test to test how we dump SHT_RELR sections. + +## Test how we dump SHT_RELR sections for 32 and 64-bits targets. +## Test we use the "Entries" property when it is possible do +## dump values correctly. + +# RUN: yaml2obj --docnum=1 %s -o %t.64le +# RUN: obj2yaml %t.64le | FileCheck %s --check-prefix=ELF64LE +# RUN: yaml2obj --docnum=2 %s -o %t.32le +# RUN: obj2yaml %t.32le | FileCheck %s --check-prefix=ELF32LE +# RUN: yaml2obj --docnum=3 %s -o %t.64be +# RUN: obj2yaml %t.64be | FileCheck %s --check-prefix=ELF64BE +# RUN: yaml2obj --docnum=4 %s -o %t.32be +# RUN: obj2yaml %t.32be | FileCheck %s --check-prefix=ELF32BE + +# ELF64LE: Sections: +# ELF64LE-NEXT: - Name: .relr.dyn +# ELF64LE-NEXT: Type: SHT_RELR +# ELF64LE-NEXT: EntSize: 0x0000000000000008 +# ELF64LE-NEXT: Entries: [ 0x8877665544332211 ] + +# ELF32LE: Sections: +# ELF32LE-NEXT: - Name: .relr.dyn +# ELF32LE-NEXT: Type: SHT_RELR +# ELF32LE-NEXT: EntSize: 0x0000000000000004 +# ELF32LE-NEXT: Entries: [ 0x0000000044332211, 0x0000000088776655 ] + +# ELF64BE: Sections: +# ELF64BE-NEXT: - Name: .relr.dyn +# ELF64BE-NEXT: Type: SHT_RELR +# ELF64BE-NEXT: EntSize: 0x0000000000000008 +# ELF64BE-NEXT: Entries: [ 0x1122334455667788 ] + +# ELF32BE: Sections: +# ELF32BE-NEXT: - Name: .relr.dyn +# ELF32BE-NEXT: Type: SHT_RELR +# ELF32BE-NEXT: EntSize: 0x0000000000000004 +# ELF32BE-NEXT: Entries: [ 0x0000000011223344, 0x0000000055667788 ] + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .relr.dyn + Type: SHT_RELR + Content: "1122334455667788" + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_386 +Sections: + - Name: .relr.dyn + Type: SHT_RELR + Content: "1122334455667788" + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2MSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .relr.dyn + Type: SHT_RELR + Content: "1122334455667788" + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2MSB + Type: ET_DYN + Machine: EM_386 +Sections: + - Name: .relr.dyn + Type: SHT_RELR + Content: "1122334455667788" + +## Test we use the "Content" property when a SHT_RELR section is truncated. + +# RUN: yaml2obj --docnum=5 %s -o %t.content +# RUN: obj2yaml %t.content | FileCheck %s --check-prefix=CONTENT + +# CONTENT: - Name: .relr.dyn +# CONTENT-NEXT: Type: SHT_RELR +# CONTENT-NEXT: EntSize: 0x0000000000000008 +# CONTENT-NEXT: Content: '11223344556677' + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2MSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .relr.dyn + Type: SHT_RELR + Content: "11223344556677" Index: llvm/test/tools/yaml2obj/ELF/relr-section.yaml =================================================================== --- /dev/null +++ llvm/test/tools/yaml2obj/ELF/relr-section.yaml @@ -0,0 +1,195 @@ +## This is a test to test how we create SHT_RELR sections. + +## Test how we create SHT_RELR sections for 64-bits LE targets. +## Test that sh_entsize is 8. +# RUN: yaml2obj --docnum=1 %s -o %t.le64 +# RUN: llvm-readobj --sections --section-data %t.le64 | FileCheck %s --check-prefix=LE64 + +# LE64: Name: .relr.dyn +# LE64-NEXT: Type: SHT_RELR +# LE64-NEXT: Flags [ +# LE64-NEXT: SHF_ALLOC +# LE64-NEXT: ] +# LE64-NEXT: Address: 0x0 +# LE64-NEXT: Offset: 0x40 +# LE64-NEXT: Size: 32 +# LE64-NEXT: Link: 0 +# LE64-NEXT: Info: 0 +# LE64-NEXT: AddressAlignment: 0 +# LE64-NEXT: EntrySize: 8 +# LE64-NEXT: SectionData ( +# LE64-NEXT: 0000: DDCCBBAA 00000000 2211FFEE 00000000 +# LE64-NEXT: 0010: 66554433 00000010 AA998877 00000010 +# LE64-NEXT: ) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .relr.dyn + Type: SHT_RELR + Flags: [ SHF_ALLOC ] +## An arbitrary 32-bits values. + Entries: [ 0x00000000AABBCCDD, 0x00000000EEFF1122, +## An arbitrary 64-bits values. + 0x1000000033445566, 0x10000000778899AA ] + +## Test how we create SHT_RELR sections for 64-bits BE targets. +# RUN: yaml2obj --docnum=2 %s -o %t.be64 +# RUN: llvm-readobj --sections --section-data %t.be64 | FileCheck %s --check-prefix=BE64 + +# BE64: Name: .relr.dyn +# BE64: SectionData ( +# BE64-NEXT: 0000: 00000000 AABBCCDD 00000000 EEFF1122 +# BE64-NEXT: 0010: 10000000 33445566 10000000 778899AA +# BE64-NEXT: ) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2MSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .relr.dyn + Type: SHT_RELR + Flags: [ SHF_ALLOC ] +## An arbitrary 32-bits values. + Entries: [ 0x00000000AABBCCDD, 0x00000000EEFF1122, +## An arbitrary 64-bits values. + 0x1000000033445566, 0x10000000778899AA ] + +## Test how we create SHT_RELR sections for 32-bit LE targets. +## Test that sh_entsize is 4. +# RUN: yaml2obj --docnum=3 %s -o %t.le32 +# RUN: llvm-readobj --sections --section-data %t.le32 | FileCheck %s --check-prefix=LE32 + +# LE32: Name: .relr.dyn +# LE32-NEXT: Type: SHT_RELR +# LE32-NEXT: Flags [ +# LE32-NEXT: SHF_ALLOC +# LE32-NEXT: ] +# LE32-NEXT: Address: 0x0 +# LE32-NEXT: Offset: 0x34 +# LE32-NEXT: Size: 16 +# LE32-NEXT: Link: 0 +# LE32-NEXT: Info: 0 +# LE32-NEXT: AddressAlignment: 0 +# LE32-NEXT: EntrySize: 4 +# LE32-NEXT: SectionData ( +# LE32-NEXT: 0000: DDCCBBAA BBAAFFEE BBAAFFEE BCAAFFEE +# LE32-NEXT: ) + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_386 +Sections: + - Name: .relr.dyn + Type: SHT_RELR + Flags: [ SHF_ALLOC ] + Entries: [ 0xAABBCCDD, 0xEEFFAABB, + 0xEEFFAABB, 0xEEFFAABC ] + +## Test how we create SHT_RELR sections for 32-bit LE targets. +# RUN: yaml2obj --docnum=4 %s -o %t.be32 +# RUN: llvm-readobj --sections --section-data %t.be32 | FileCheck %s --check-prefix=BE32 + +# BE32: Name: .relr.dyn +# BE32: SectionData ( +# BE32-NEXT: 0000: AABBCCDD EEFFAABB EEFFAABB EEFFAABC | +# BE32-NEXT: ) + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2MSB + Type: ET_DYN + Machine: EM_386 +Sections: + - Name: .relr.dyn + Type: SHT_RELR + Flags: [ SHF_ALLOC ] + Entries: [ 0xAABBCCDD, 0xEEFFAABB, + 0xEEFFAABB, 0xEEFFAABC ] + +## Test we can use "Content" to describe SHT_RELR section. +# RUN: yaml2obj --docnum=5 %s -o %t.content +# RUN: llvm-readobj --sections --section-data %t.content | FileCheck %s --check-prefix=CONTENT + +# CONTENT: Name: .relr.dyn +# CONTENT: SectionData ( +# CONTENT-NEXT: 0000: 112233 | +# CONTENT-NEXT: ) + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_386 +Sections: + - Name: .relr.dyn + Type: SHT_RELR + Flags: [ SHF_ALLOC ] + Content: "112233" + +## Check we are able to set an arbitrary sh_entsize. +# RUN: yaml2obj --docnum=6 %s -o %t.entsize +# RUN: llvm-readelf --sections %t.entsize | FileCheck %s --check-prefix=ENTSIZE + +# ENTSIZE: [Nr] Name Type Address Off Size ES +# ENTSIZE: [ 1] .relr.dyn RELR 00000000 000034 000001 34 + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_386 +Sections: + - Name: .relr.dyn + Type: SHT_RELR + Flags: [ SHF_ALLOC ] + EntSize: 0x34 + Content: "12" + +## Test we can't use 64-bit offsets/bitmaps when creating a 32-bit object. +# RUN: not yaml2obj --docnum=7 %s 2>&1 | FileCheck %s --check-prefix=TOO-LARGE + +# TOO-LARGE: error: .relr.dyn: the value is too large for 32-bits: 0xaabbccddeeff0011 + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_386 +Sections: + - Name: .relr.dyn + Type: SHT_RELR + Flags: [ SHF_ALLOC ] + Entries: [ 0xAABBCCDDEEFF0011 ] + +## Test we can't specify "Entries" and "Content" properties at the same time. +# RUN: not yaml2obj --docnum=8 %s 2>&1 | FileCheck %s --check-prefix=BOTH + +# BOTH: error: "Entries" and "Content" can't be used together + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_386 +Sections: + - Name: .relr.dyn + Type: SHT_RELR + Flags: [ SHF_ALLOC ] + Entries: [ 0x0 ] + Content: "00" Index: llvm/tools/obj2yaml/elf2yaml.cpp =================================================================== --- llvm/tools/obj2yaml/elf2yaml.cpp +++ llvm/tools/obj2yaml/elf2yaml.cpp @@ -27,6 +27,7 @@ typedef typename ELFT::Word Elf_Word; typedef typename ELFT::Rel Elf_Rel; typedef typename ELFT::Rela Elf_Rela; + using Elf_Relr = typename ELFT::Relr; using Elf_Nhdr = typename ELFT::Nhdr; using Elf_Note = typename ELFT::Note; @@ -66,6 +67,8 @@ dumpDependentLibrariesSection(const Elf_Shdr *Shdr); Expected dumpDynamicSection(const Elf_Shdr *Shdr); Expected dumpRelocSection(const Elf_Shdr *Shdr); + Expected + dumpRelocOffsetsSection(const Elf_Shdr *Shdr); Expected dumpContentSection(const Elf_Shdr *Shdr); Expected @@ -251,6 +254,14 @@ Y->Chunks.emplace_back(*SecOrErr); break; } + case ELF::SHT_RELR: { + Expected SecOrErr = + dumpRelocOffsetsSection(&Sec); + if (!SecOrErr) + return SecOrErr.takeError(); + Y->Chunks.emplace_back(*SecOrErr); + break; + } case ELF::SHT_GROUP: { Expected GroupOrErr = dumpGroup(&Sec); if (!GroupOrErr) @@ -723,6 +734,29 @@ return S.release(); } +template +Expected +ELFDumper::dumpRelocOffsetsSection(const Elf_Shdr *Shdr) { + auto S = std::make_unique(); + if (auto E = dumpCommonSection(Shdr, *S)) + return std::move(E); + + if (Expected> Relrs = Obj.relrs(Shdr)) { + S->Entries.emplace(); + for (Elf_Relr Rel : *Relrs) + S->Entries->emplace_back(Rel); + return S.release(); + } else { + consumeError(Relrs.takeError()); + } + + Expected> ContentOrErr = Obj.getSectionContents(Shdr); + if (!ContentOrErr) + return ContentOrErr.takeError(); + S->Content = *ContentOrErr; + return S.release(); +} + template Expected ELFDumper::dumpContentSection(const Elf_Shdr *Shdr) {