Index: llvm/test/tools/llvm-readobj/ELF/gnu-phdrs.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/gnu-phdrs.test +++ llvm/test/tools/llvm-readobj/ELF/gnu-phdrs.test @@ -1,97 +1,356 @@ -#Source : -#__thread int a = 1; -#__thread int b; -# -#int main () { -# b = 2; -# throw (a + b) ; -# return 0; -#} -# compiled as clang++ source.cpp -# and clang++ -m32 source.cpp - -RUN: llvm-readelf -l %p/Inputs/phdrs-elf.exe-i386 \ -RUN: | FileCheck %s -check-prefix ELF32 -RUN: llvm-readelf -l %p/Inputs/phdrs-elf.exe-x86_64 \ -RUN: | FileCheck %s -check-prefixes ELF64-PHDRS,ELF64-MAPPING -RUN: llvm-readelf -program-headers %p/Inputs/phdrs-elf.exe-x86_64 \ -RUN: | FileCheck %s -check-prefixes ELF64-PHDRS,ELF64-MAPPING - -# Check that -section-mapping produces a mapping and not the program headers. -RUN: llvm-readelf -section-mapping %p/Inputs/phdrs-elf.exe-x86_64 \ -RUN: | FileCheck %s -check-prefix ELF64-MAPPING -implicit-check-not="Program Headers:" - -# Check that -section-mapping=false -program-headers produces just program headers. -RUN: llvm-readelf -section-mapping=false -program-headers %p/Inputs/phdrs-elf.exe-x86_64 \ -RUN: | FileCheck %s -check-prefix ELF64-PHDRS -implicit-check-not="Section to Segment mapping:" - -# Check that only one copy of the section/segment mapping table is produced. -RUN: llvm-readelf -section-mapping -program-headers %p/Inputs/phdrs-elf.exe-x86_64 \ -RUN: | FileCheck %s -check-prefix ELF64-ONEMAPPING - -ELF32: Elf file type is EXEC (Executable file) -ELF32-NEXT: Entry point 0x8048460 -ELF32-NEXT: There are 10 program headers, starting at offset 52 - -ELF32: Program Headers: -ELF32-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align -ELF32-NEXT: PHDR 0x000034 0x08048034 0x08048034 0x00140 0x00140 R E 0x4 -ELF32-NEXT: INTERP 0x000174 0x08048174 0x08048174 0x00013 0x00013 R 0x1 -ELF32-NEXT: [Requesting program interpreter: /lib/ld-linux.so.2] -ELF32-NEXT: LOAD 0x000000 0x08048000 0x08048000 0x006d0 0x006d0 R E 0x1000 -ELF32-NEXT: LOAD 0x000ef0 0x08049ef0 0x08049ef0 0x00128 0x00140 RW 0x1000 -ELF32-NEXT: DYNAMIC 0x000f08 0x08049f08 0x08049f08 0x000e8 0x000e8 RW 0x4 -ELF32-NEXT: NOTE 0x000188 0x08048188 0x08048188 0x00044 0x00044 R 0x4 -ELF32-NEXT: TLS 0x000ef0 0x08049ef0 0x08049ef0 0x00004 0x00008 R 0x4 -ELF32-NEXT: GNU_EH_FRAME 0x000640 0x08048640 0x08048640 0x0001c 0x0001c R 0x4 -ELF32-NEXT: GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4 -ELF32-NEXT: GNU_RELRO 0x000ef0 0x08049ef0 0x08049ef0 0x00110 0x00110 R 0x1 - -ELF32: Section to Segment mapping: -ELF32-NEXT: Segment Sections... -ELF32-NEXT: 00 -ELF32-NEXT: 01 .interp -ELF32-NEXT: 02 .interp .note.ABI-tag .note.gnu.build-id .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame -ELF32-NEXT: 03 .tdata .ctors .dtors .jcr .dynamic .got .got.plt .data .bss -ELF32-NEXT: 04 .dynamic -ELF32-NEXT: 05 .note.ABI-tag .note.gnu.build-id -ELF32-NEXT: 06 .tdata .tbss -ELF32-NEXT: 07 .eh_frame_hdr -ELF32-NEXT: 08 -ELF32-NEXT: 09 .tdata .ctors .dtors .jcr .dynamic .got -ELF32-NEXT: None .comment .shstrtab .symtab .strtab - -ELF64-PHDRS: Elf file type is EXEC (Executable file) -ELF64-PHDRS-NEXT: Entry point 0x400610 -ELF64-PHDRS-NEXT: There are 10 program headers, starting at offset 64 - -ELF64-PHDRS: Program Headers: -ELF64-PHDRS-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align -ELF64-PHDRS-NEXT: PHDR 0x000040 0x0000000000400040 0x0000000000400040 0x000230 0x000230 R E 0x8 -ELF64-PHDRS-NEXT: INTERP 0x000270 0x0000000000400270 0x0000000000400270 0x00001c 0x00001c R 0x1 -ELF64-PHDRS-NEXT: [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] -ELF64-PHDRS-NEXT: LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x000924 0x000924 R E 0x200000 -ELF64-PHDRS-NEXT: LOAD 0x000db4 0x0000000000600db4 0x0000000000600db4 0x000274 0x0002a4 RW 0x200000 -ELF64-PHDRS-NEXT: DYNAMIC 0x000dd0 0x0000000000600dd0 0x0000000000600dd0 0x000210 0x000210 RW 0x8 -ELF64-PHDRS-NEXT: NOTE 0x00028c 0x000000000040028c 0x000000000040028c 0x000044 0x000044 R 0x4 -ELF64-PHDRS-NEXT: TLS 0x000db4 0x0000000000600db4 0x0000000000600db4 0x000004 0x000008 R 0x4 -ELF64-PHDRS-NEXT: GNU_EH_FRAME 0x00083c 0x000000000040083c 0x000000000040083c 0x00002c 0x00002c R 0x4 -ELF64-PHDRS-NEXT: GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x8 -ELF64-PHDRS-NEXT: GNU_RELRO 0x000db4 0x0000000000600db4 0x0000000000600db4 0x00024c 0x00024c R 0x1 - -ELF64-MAPPING: Section to Segment mapping: -ELF64-MAPPING-NEXT: Segment Sections... -ELF64-MAPPING-NEXT: 00 -ELF64-MAPPING-NEXT: 01 .interp -ELF64-MAPPING-NEXT: 02 .interp .note.ABI-tag .note.gnu.build-id .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame -ELF64-MAPPING-NEXT: 03 .tdata .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss -ELF64-MAPPING-NEXT: 04 .dynamic -ELF64-MAPPING-NEXT: 05 .note.ABI-tag .note.gnu.build-id -ELF64-MAPPING-NEXT: 06 .tdata .tbss -ELF64-MAPPING-NEXT: 07 .eh_frame_hdr -ELF64-MAPPING-NEXT: 08 -ELF64-MAPPING-NEXT: 09 .tdata .init_array .fini_array .jcr .dynamic .got -ELF64-MAPPING-NEXT: None .comment .shstrtab .symtab .strtab - -ELF64-ONEMAPPING: Section to Segment mapping: -ELF64-ONEMAPPING-NOT: Section to Segment mapping: +## Check how llvm-readelf dumps program headers and prints sections to segments mapping. + +## Check that -l, --program-headers and --segments are the same option. +# RUN: yaml2obj --docnum=1 -DBITS=32 -DMACHINE=EM_386 %s -o %t32.elf +# RUN: llvm-readelf -l %t32.elf 2>&1 > %t.readelf-l.txt +# RUN: llvm-readelf --program-headers %t32.elf 2>&1 > %t.readelf-pheaders.txt +# RUN: cmp %t.readelf-l.txt %t.readelf-pheaders.txt +# RUN: llvm-readelf --segments %t32.elf 2>&1 > %t.readelf-segments.txt +# RUN: cmp %t.readelf-l.txt %t.readelf-segments.txt + +## Check we are able to print program headers of different types. +# RUN: llvm-readelf -l %t32.elf | \ +# RUN: FileCheck %s --check-prefixes=ELF32,MAPPING --strict-whitespace --match-full-lines + +# RUN: yaml2obj --docnum=1 -DBITS=64 -DMACHINE=EM_X86_64 %s -o %t64.elf +# RUN: llvm-readelf -l %t64.elf | \ +# RUN: FileCheck %s --check-prefixes=ELF64,MAPPING --strict-whitespace --match-full-lines + +# ELF32:There are 23 program headers, starting at offset 52 +# ELF32-EMPTY: +# ELF32-NEXT:Program Headers: +# ELF32-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align +# ELF32-NEXT: PHDR 0x000314 0x00001000 0x00001000 0x00003 0x00003 W 0x1 +# ELF32-NEXT: PHDR 0x000317 0x00002000 0x00002000 0x00007 0x00007 E 0x1 +# ELF32-NEXT: NULL 0x000317 0x00002000 0x00002000 0x00007 0x00007 E 0x1 +# ELF32-NEXT: DYNAMIC 0x000314 0x00001000 0x00001000 0x00003 0x00003 RWE 0x1 +# ELF32-NEXT: INTERP 0x00031e 0x00003000 0x00003000 0x00004 0x00004 RW 0x1 +# ELF32-NEXT: [Requesting program interpreter: ABC] +# ELF32-NEXT: NOTE 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-NEXT: SHLIB 0x000314 0x00001000 0x00001000 0x00001 0x00001 0x1 +# ELF32-NEXT: TLS 0x000322 0x00004000 0x00004000 0x00001 0x00001 0x1 +# ELF32-NEXT: : 0x60000000 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-NEXT: GNU_EH_FRAME 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-NEXT: SUNW_UNWIND 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-NEXT: GNU_STACK 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-NEXT: GNU_RELRO 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-NEXT: GNU_PROPERTY 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-NEXT: : 0x65a3dbe6 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-NEXT: : 0x65a3dbe7 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-NEXT: : 0x65a41be6 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-NEXT: : 0x6fffffff 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-NEXT: : 0x70000000 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-NEXT: : 0x70000001 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-NEXT: : 0x70000002 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-NEXT: : 0x70000003 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-NEXT: : 0x7fffffff 0x000314 0x00001000 0x00001000 0x00003 0x00003 0x1 +# ELF32-EMPTY: + +# ELF64:There are 23 program headers, starting at offset 64 +# ELF64-EMPTY: +# ELF64-NEXT:Program Headers: +# ELF64-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align +# ELF64-NEXT: PHDR 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 W 0x1 +# ELF64-NEXT: PHDR 0x00054b 0x0000000000002000 0x0000000000002000 0x000007 0x000007 E 0x1 +# ELF64-NEXT: NULL 0x00054b 0x0000000000002000 0x0000000000002000 0x000007 0x000007 E 0x1 +# ELF64-NEXT: DYNAMIC 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 RWE 0x1 +# ELF64-NEXT: INTERP 0x000552 0x0000000000003000 0x0000000000003000 0x000004 0x000004 RW 0x1 +# ELF64-NEXT: [Requesting program interpreter: ABC] +# ELF64-NEXT: NOTE 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-NEXT: SHLIB 0x000548 0x0000000000001000 0x0000000000001000 0x000001 0x000001 0x1 +# ELF64-NEXT: TLS 0x000556 0x0000000000004000 0x0000000000004000 0x000001 0x000001 0x1 +# ELF64-NEXT: : 0x60000000 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-NEXT: GNU_EH_FRAME 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-NEXT: SUNW_UNWIND 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-NEXT: GNU_STACK 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-NEXT: GNU_RELRO 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-NEXT: GNU_PROPERTY 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-NEXT: : 0x65a3dbe6 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-NEXT: : 0x65a3dbe7 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-NEXT: : 0x65a41be6 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-NEXT: : 0x6fffffff 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-NEXT: : 0x70000000 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-NEXT: : 0x70000001 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-NEXT: : 0x70000002 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-NEXT: : 0x70000003 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-NEXT: : 0x7fffffff 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ELF64-EMPTY: + +# MAPPING: Section to Segment mapping: +# MAPPING-NEXT: Segment Sections... +# MAPPING-NEXT: 00 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 01 .bar.begin .bar.end {{$}} +# MAPPING-NEXT: 02 .bar.begin .bar.end {{$}} +# MAPPING-NEXT: 03 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 04 .interp {{$}} +# MAPPING-NEXT: 05 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 06 .foo.begin {{$}} +# MAPPING-NEXT: 07 .tls {{$}} +# MAPPING-NEXT: 08 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 09 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 10 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 11 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 12 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 13 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 14 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 15 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 16 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 17 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 18 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 19 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 20 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 21 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 22 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: None .unused .strtab .shstrtab {{$}} + +--- !ELF +FileHeader: + Class: ELFCLASS[[BITS]] + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: [[MACHINE]] + Entry: 0x12345678 +Sections: + - Name: .foo.begin + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x1000 + Size: 0x1 + - Name: .foo.end + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Size: 0x2 + - Name: .bar.begin + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x2000 + Size: 0x3 + - Name: .bar.end + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Size: 0x4 + - Name: .interp + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x3000 + Content: "41424300" ## "ABC" + - Name: .tls + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_TLS ] + Address: 0x4000 + Size: 0x1 + - Name: .unused + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_TLS ] + Address: 0x5000 + Size: 0x1 +ProgramHeaders: +## Case 1: an arbitrary segment with sections. + - Type: PT_PHDR + Flags: [ PF_W ] + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 2: another segment with different sections. + - Type: PT_PHDR + Flags: [ PF_X ] + VAddr: 0x2000 + Sections: + - Section: .bar.begin + - Section: .bar.end +## Case 3: the PT_NULL segment. + - Type: PT_NULL + Flags: [ PF_X ] + VAddr: 0x2000 + Sections: + - Section: .bar.begin + - Section: .bar.end +## Case 4: the PT_DYNAMIC segment. + - Type: PT_DYNAMIC + Flags: [ PF_R, PF_W, PF_X ] + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 5: the PT_INTERP segment. + - Type: PT_INTERP + Flags: [ PF_R, PF_W ] + VAddr: 0x3000 + Sections: + - Section: .interp +## Case 6: the PT_NOTE segment. + - Type: PT_NOTE + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 7: the PT_SHLIB segment. + - Type: PT_SHLIB + VAddr: 0x1000 + Sections: + - Section: .foo.begin +## Case 8: the PT_TLS segment. + - Type: PT_TLS + VAddr: 0x4000 + Sections: + - Section: .tls +## Case 9: the PT_LOOS segment. + - Type: 0x60000000 ## PT_LOOS + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 10: the PT_GNU_EH_FRAME segment. + - Type: PT_GNU_EH_FRAME + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 11: the PT_SUNW_UNWIND segment. + - Type: 0x6464e550 ## PT_SUNW_UNWIND + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 12: the PT_GNU_STACK segment. + - Type: PT_GNU_STACK + Sections: + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 13: the PT_GNU_RELRO segment. + - Type: PT_GNU_RELRO + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 14: the PT_GNU_PROPERTY segment. + - Type: PT_GNU_PROPERTY + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 15: the PT_OPENBSD_RANDOMIZE segment. + - Type: 0x65a3dbe6 ## PT_OPENBSD_RANDOMIZE + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 16: the PT_OPENBSD_WXNEEDED segment. + - Type: 0x65a3dbe7 ## PT_OPENBSD_WXNEEDED + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 17: the PT_OPENBSD_BOOTDATA segment. + - Type: 0x65a41be6 ## PT_OPENBSD_BOOTDATA + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 18: the PT_HIOS segment. + - Type: 0x6fffffff ## PT_HIOS + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 19: the PT_LOPROC/PT_ARM_ARCHEXT/PT_MIPS_REGINFO segment. + - Type: 0x70000000 ## PT_LOPROC/PT_ARM_ARCHEXT/PT_MIPS_REGINFO + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 20: the PT_ARM_EXIDX/PT_MIPS_RTPROC segment. + - Type: 0x70000001 ## PT_ARM_EXIDX, PT_MIPS_RTPROC + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 20: the PT_MIPS_OPTIONS segment. + - Type: 0x70000002 ## PT_MIPS_OPTIONS + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 21: the PT_MIPS_ABIFLAGS segment. + - Type: 0x70000003 ## PT_MIPS_ABIFLAGS + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 22: the PT_HIPROC segment. + - Type: 0x7fffffff ## PT_HIPROC + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end + +## Check how we dump ARM specific program headers. +# RUN: yaml2obj --docnum=1 -DBITS=64 -DMACHINE=EM_ARM %s -o %tarm.elf +# RUN: llvm-readelf --program-headers %tarm.elf | FileCheck %s --check-prefix=ARM + +# ARM: : 0x70000000 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ARM-NEXT: EXIDX 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# ARM-NEXT: : 0x70000002 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 + +## Check how we dump MIPS specific program headers. +# RUN: yaml2obj --docnum=1 -DBITS=64 -DMACHINE=EM_MIPS %s -o %tmips.elf +# RUN: llvm-readelf --program-headers %tmips.elf | FileCheck %s --check-prefix=MIPS + +# MIPS: REGINFO 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# MIPS-NEXT: RTPROC 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# MIPS-NEXT: OPTIONS 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 +# MIPS-NEXT: ABIFLAGS 0x000548 0x0000000000001000 0x0000000000001000 0x000003 0x000003 0x1 + +## Check we report a warning when a program interpreter name is non-null-terminated or when +## PT_INTERP has an offset that goes past the end of the file. +# RUN: yaml2obj --docnum=2 %s -o %t.err + +## Show the size of the output produced. It is used in the YAML below. +# RUN: wc -c < %t.err | FileCheck %s --check-prefix=SIZE +# SIZE: 560 + +## Write the additional 'C', '\0, 'C' bytes to the end. +# RUN: echo -n -e "C\x00C" >> %t.err + +# RUN: llvm-readelf --program-headers %t.err 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t.err --check-prefix=ERROR-INTERP + +# ERROR-INTERP: Type Offset +# ERROR-INTERP-NEXT: INTERP 0x000[[#%x,OFFSET:0x000230]] +# ERROR-INTERP-NEXT: [Requesting program interpreter: C] +# ERROR-INTERP-NEXT: INTERP 0x000[[#OFFSET + 1]] +# ERROR-INTERP-NEXT: [Requesting program interpreter: ] +# ERROR-INTERP-NEXT: INTERP 0x000[[#OFFSET + 2]] +# ERROR-INTERP-NEXT: warning: '[[FILE]]': unable to read program interpreter name at offset 0x232: it is not null-terminated +# ERROR-INTERP-NEXT: INTERP 0x000[[#OFFSET + 3]] +# ERROR-INTERP-NEXT: warning: '[[FILE]]': unable to read program interpreter name at offset 0x233: it goes past the end of the file (0x233) +# ERROR-INTERP-NEXT: INTERP 0xaabbccddeeff1122 +# ERROR-INTERP-NEXT: warning: '[[FILE]]': unable to read program interpreter name at offset 0xaabbccddeeff1122: it goes past the end of the file (0x233) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +ProgramHeaders: +## Case 1: the offset points to the first additional byte. + - Type: PT_INTERP + Offset: 560 +## Case 1: the offset points to the second additional byte, +## which is a null byte. + - Type: PT_INTERP + Offset: 561 +## Case 3: the offset points to the third additional +## byte, which is the last byte in the file. + - Type: PT_INTERP + Offset: 562 +## Case 4: the offset goes 1 byte past the end of the file. + - Type: PT_INTERP + Offset: 563 +## Case 5: an arbitrary large offset that goes past the end of the file. + - Type: PT_INTERP + Offset: 0xAABBCCDDEEFF1122 Index: llvm/test/tools/llvm-readobj/ELF/gnu-section-mapping-no-shdrs.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/gnu-section-mapping-no-shdrs.test +++ /dev/null @@ -1,15 +0,0 @@ -RUN: llvm-objcopy --strip-sections %p/Inputs/phdrs-elf.exe-x86_64 %t.o -RUN: llvm-readelf --section-mapping %t.o | FileCheck %s -CHECK: Section to Segment mapping: -CHECK-NEXT: Segment Sections... -CHECK-NEXT: 00 {{$}} -CHECK-NEXT: 01 {{$}} -CHECK-NEXT: 02 {{$}} -CHECK-NEXT: 03 {{$}} -CHECK-NEXT: 04 {{$}} -CHECK-NEXT: 05 {{$}} -CHECK-NEXT: 06 {{$}} -CHECK-NEXT: 07 {{$}} -CHECK-NEXT: 08 {{$}} -CHECK-NEXT: 09 {{$}} -CHECK-NOT: {{.}} Index: llvm/test/tools/llvm-readobj/ELF/gnu-section-mapping.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-readobj/ELF/gnu-section-mapping.test @@ -0,0 +1,76 @@ +## Check how llvm-readelf prints sections to segments mapping. + +## Check that --section-mapping produces a sections to segments +## mapping and not anything else. +# RUN: yaml2obj %s -o %t64.elf +# RUN: llvm-readelf --section-mapping %t64.elf \ +# RUN: | FileCheck %s --check-prefix=MAPPING --strict-whitespace --match-full-lines --implicit-check-not={{.}} + +# MAPPING: Section to Segment mapping: +# MAPPING-NEXT: Segment Sections... +# MAPPING-NEXT: 00 .foo.begin .foo.end {{$}} +# MAPPING-NEXT: 01 .bar.begin .bar.end {{$}} +# MAPPING-NEXT: None .strtab .shstrtab {{$}} + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 + Entry: 0x12345678 +Sections: + - Name: .foo.begin + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x1000 + Size: 0x1 + - Name: .foo.end + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Size: 0x2 + - Name: .bar.begin + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x2000 + Size: 0x3 + - Name: .bar.end + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Size: 0x4 +ProgramHeaders: +## Case 1: an arbitrary segment with sections. + - Type: PT_PHDR + Flags: [ PF_W ] + VAddr: 0x1000 + Sections: + - Section: .foo.begin + - Section: .foo.end +## Case 2: another segment with different sections. + - Type: PT_PHDR + Flags: [ PF_X ] + VAddr: 0x2000 + Sections: + - Section: .bar.begin + - Section: .bar.end + +## Check that --section-mapping=false --program-headers produces just program headers. +# RUN: llvm-readelf --section-mapping=false --program-headers %t64.elf \ +# RUN: | FileCheck %s --check-prefix=SEC-MAPPING-FALSE --implicit-check-not="Section to Segment mapping:" + +# SEC-MAPPING-FALSE: Program Headers: + +## Check that only one copy of the section/segment mapping table is produced +## when both --section-mapping and --program-headers are used. +# RUN: llvm-readelf --section-mapping --program-headers %t64.elf \ +# RUN: | FileCheck %s --check-prefix=MAPPING --implicit-check-not="Section to Segment mapping:" + +## Check the output when an object has no section headers. +## RUN: llvm-objcopy --strip-sections %t64.elf %tno-shdrs.o +## RUN: llvm-readelf --section-mapping %tno-shdrs.o | FileCheck %s --check-prefix=NO-SECHDRS + +# NO-SECHDRS: Section to Segment mapping: +# NO-SECHDRS-NEXT: Segment Sections... +# NO-SECHDRS-NEXT: 00 {{$}} +# NO-SECHDRS-NEXT: 01 {{$}} +# NO-SECHDRS-NOT: {{.}} Index: llvm/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/ELFDumper.cpp +++ llvm/tools/llvm-readobj/ELFDumper.cpp @@ -4128,8 +4128,31 @@ for (auto Field : Fields) printField(Field); if (Phdr.p_type == ELF::PT_INTERP) { - OS << "\n [Requesting program interpreter: "; - OS << reinterpret_cast(Obj->base()) + Phdr.p_offset << "]"; + OS << "\n"; + auto ReportBadInterp = [&](const Twine &Msg) { + reportWarning( + createError("unable to read program interpreter name at offset 0x" + + Twine::utohexstr(Phdr.p_offset) + ": " + Msg), + this->FileName); + }; + + if (Phdr.p_offset >= Obj->getBufSize()) { + ReportBadInterp("it goes past the end of the file (0x" + + Twine::utohexstr(Obj->getBufSize()) + ")"); + continue; + } + + const char *Data = + reinterpret_cast(Obj->base()) + Phdr.p_offset; + size_t MaxSize = Obj->getBufSize() - Phdr.p_offset; + size_t Len = strnlen(Data, MaxSize); + if (Len == MaxSize) { + ReportBadInterp("it is not null-terminated"); + continue; + } + + OS << " [Requesting program interpreter: "; + OS << StringRef(Data, Len) << "]"; } OS << "\n"; }