diff --git a/llvm/lib/XRay/InstrumentationMap.cpp b/llvm/lib/XRay/InstrumentationMap.cpp --- a/llvm/lib/XRay/InstrumentationMap.cpp +++ b/llvm/lib/XRay/InstrumentationMap.cpp @@ -61,9 +61,10 @@ if ((!ObjFile.getBinary()->isELF() && !ObjFile.getBinary()->isMachO()) || !(ObjFile.getBinary()->getArch() == Triple::x86_64 || ObjFile.getBinary()->getArch() == Triple::ppc64le || + ObjFile.getBinary()->getArch() == Triple::arm || ObjFile.getBinary()->getArch() == Triple::aarch64)) return make_error( - "File format not supported (only does ELF and Mach-O little endian 64-bit).", + Twine("File format not supported. Supports: AArch64/ARM/ppc64le/x86-64."), std::make_error_code(std::errc::not_supported)); StringRef Contents = ""; @@ -123,12 +124,14 @@ // Copy the instrumentation map data into the Sleds data structure. auto C = Contents.bytes_begin(); - static constexpr size_t ELF64SledEntrySize = 32; - if ((C - Contents.bytes_end()) % ELF64SledEntrySize != 0) + bool Is32Bit = ObjFile.getBinary()->makeTriple().isArch32Bit(); + size_t ELFSledEntrySize = Is32Bit ? 16 : 32; + + if ((C - Contents.bytes_end()) % ELFSledEntrySize != 0) return make_error( Twine("Instrumentation map entries not evenly divisible by size of " - "an XRay sled entry in ELF64."), + "an XRay sled entry."), std::make_error_code(std::errc::executable_format_error)); auto RelocateOrElse = [&](uint64_t Offset, uint64_t Address) { @@ -143,17 +146,23 @@ int32_t FuncId = 1; uint64_t CurFn = 0; - for (; C != Contents.bytes_end(); C += ELF64SledEntrySize) { + for (; C != Contents.bytes_end(); C += ELFSledEntrySize) { DataExtractor Extractor( - StringRef(reinterpret_cast(C), ELF64SledEntrySize), true, + StringRef(reinterpret_cast(C), ELFSledEntrySize), true, 8); Sleds.push_back({}); auto &Entry = Sleds.back(); uint64_t OffsetPtr = 0; uint64_t AddrOff = OffsetPtr; - Entry.Address = RelocateOrElse(AddrOff, Extractor.getU64(&OffsetPtr)); + if (Is32Bit) + Entry.Address = RelocateOrElse(AddrOff, Extractor.getU32(&OffsetPtr)); + else + Entry.Address = RelocateOrElse(AddrOff, Extractor.getU64(&OffsetPtr)); uint64_t FuncOff = OffsetPtr; - Entry.Function = RelocateOrElse(FuncOff, Extractor.getU64(&OffsetPtr)); + if (Is32Bit) + Entry.Function = RelocateOrElse(FuncOff, Extractor.getU32(&OffsetPtr)); + else + Entry.Function = RelocateOrElse(FuncOff, Extractor.getU64(&OffsetPtr)); auto Kind = Extractor.getU8(&OffsetPtr); static constexpr SledEntry::FunctionKinds Kinds[] = { SledEntry::FunctionKinds::ENTRY, SledEntry::FunctionKinds::EXIT, diff --git a/llvm/test/tools/llvm-xray/ARM/elf32-pic.yaml b/llvm/test/tools/llvm-xray/ARM/elf32-pic.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-xray/ARM/elf32-pic.yaml @@ -0,0 +1,350 @@ +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_ARM + Flags: [ EF_ARM_SOFT_FLOAT, EF_ARM_EABI_VER5 ] + Entry: 0x000000000000042C +ProgramHeaders: + - Type: PT_PHDR + Flags: [ PF_R ] + VAddr: 0x0000000000000034 + Align: 0x0000000000000004 + - Type: PT_LOAD + Flags: [ PF_X, PF_R ] + Sections: + - Section: .note.android.ident + - Section: .note.gnu.build-id + - Section: .dynsym + - Section: .gnu.version + - Section: .gnu.version_r + - Section: .gnu.hash + - Section: .hash + - Section: .dynstr + - Section: .rel.dyn + - Section: .ARM.exidx + - Section: .rel.plt + - Section: .text + - Section: .plt + Align: 0x0000000000001000 + - Type: PT_LOAD + Flags: [ PF_W, PF_R ] + Sections: + - Section: .fini_array + - Section: .dynamic + - Section: .got.plt + VAddr: 0x0000000000001000 + Align: 0x0000000000001000 + - Type: PT_LOAD + Flags: [ PF_W, PF_R ] + Sections: + - Section: .data + - Section: xray_instr_map + - Section: xray_fn_idx + VAddr: 0x0000000000002000 + Align: 0x0000000000001000 + - Type: PT_DYNAMIC + Flags: [ PF_W, PF_R ] + Sections: + - Section: .dynamic + VAddr: 0x0000000000001004 + Align: 0x0000000000000004 + - Type: PT_GNU_RELRO + Flags: [ PF_R ] + Sections: + - Section: .fini_array + - Section: .dynamic + - Section: .got.plt + VAddr: 0x0000000000001000 + - Type: PT_GNU_STACK + Flags: [ PF_W, PF_R ] + Align: 0x0000000000000000 + - Type: PT_NOTE + Flags: [ PF_R ] + Sections: + - Section: .note.android.ident + - Section: .note.gnu.build-id + VAddr: 0x0000000000000154 + Align: 0x0000000000000004 + - Type: 0x70000001 + Flags: [ PF_R ] + Sections: + - Section: .ARM.exidx + VAddr: 0x000000000000040C + Align: 0x0000000000000004 +Sections: + - Name: .note.android.ident + Type: SHT_NOTE + Flags: [ SHF_ALLOC ] + Address: 0x0000000000000154 + AddressAlign: 0x0000000000000004 + Notes: + - Name: Android + Desc: '100000007231376300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034393838373334000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000' + Type: 0x00000001 + - Name: .note.gnu.build-id + Type: SHT_NOTE + Flags: [ SHF_ALLOC ] + Address: 0x00000000000001EC + AddressAlign: 0x0000000000000004 + Notes: + - Name: GNU + Desc: 1C681E460A3C4831BB5EB0D6D38BDE1214C7C9C5 + Type: 0x00000003 + - Name: .dynsym + Type: SHT_DYNSYM + Flags: [ SHF_ALLOC ] + Address: 0x0000000000000210 + Link: .dynstr + AddressAlign: 0x0000000000000004 + EntSize: 0x0000000000000010 + - Name: .gnu.version + Type: SHT_GNU_versym + Flags: [ SHF_ALLOC ] + Address: 0x0000000000000290 + Link: .dynsym + AddressAlign: 0x0000000000000002 + EntSize: 0x0000000000000002 + Entries: [ 54484, 2, 1, 1, 1, 1, 1, 1 ] + - Name: .gnu.version_r + Type: SHT_GNU_verneed + Flags: [ SHF_ALLOC ] + Address: 0x00000000000002A0 + Link: .dynstr + AddressAlign: 0x0000000000000004 + Info: 0x0000000000000001 + Dependencies: + - Version: 1 + File: libc.so + Entries: + - Name: LIBC + Hash: 331107 + Flags: 0 + Other: 2 + - Name: .gnu.hash + Type: SHT_GNU_HASH + Flags: [ SHF_ALLOC ] + Address: 0x00000000000002C0 + Link: .dynsym + AddressAlign: 0x0000000000000004 + EntSize: 0x0000000000000004 + Header: + SymNdx: 0x00000002 + Shift2: 0x0000001A + BloomFilter: [ 0x0000000000000000, 0x000000009C000000, 0x000000000D000098, + 0x0000000004000800 ] + HashBuckets: [ 0x00000002 ] + HashValues: [ 0x6A5EBC3C, 0x6A6128EA, 0x6A631F44, 0xECD54542, + 0x1C5871D8, 0x7C92E3BB ] + - Name: .hash + Type: SHT_HASH + Flags: [ SHF_ALLOC ] + Address: 0x00000000000002FC + Link: .dynsym + AddressAlign: 0x0000000000000004 + EntSize: 0x0000000000000004 + Bucket: [ 0, 5, 0, 0, 7, 1, 4, 0 ] + Chain: [ 0, 0, 0, 2, 3, 0, 0, 6 ] + - Name: .dynstr + Type: SHT_STRTAB + Flags: [ SHF_ALLOC ] + Address: 0x0000000000000344 + AddressAlign: 0x0000000000000001 + - Name: .rel.dyn + Type: SHT_REL + Flags: [ SHF_ALLOC ] + Address: 0x000000000000039C + Link: .dynsym + AddressAlign: 0x0000000000000004 + Relocations: + - Offset: 0x0000000000001000 + Type: R_ARM_RELATIVE + - Offset: 0x0000000000002000 + Type: R_ARM_RELATIVE + - Offset: 0x0000000000002004 + Type: R_ARM_RELATIVE + - Offset: 0x0000000000002008 + Type: R_ARM_RELATIVE + - Offset: 0x0000000000002014 + Type: R_ARM_RELATIVE + - Offset: 0x0000000000002018 + Type: R_ARM_RELATIVE + - Offset: 0x0000000000002024 + Type: R_ARM_RELATIVE + - Offset: 0x0000000000002028 + Type: R_ARM_RELATIVE + - Offset: 0x0000000000002038 + Type: R_ARM_RELATIVE + - Offset: 0x000000000000203C + Type: R_ARM_RELATIVE + - Offset: 0x0000000000002040 + Type: R_ARM_RELATIVE + - Offset: 0x0000000000002044 + Type: R_ARM_RELATIVE + - Offset: 0x0000000000002048 + Type: R_ARM_RELATIVE + - Offset: 0x000000000000204C + Type: R_ARM_RELATIVE + - Name: .ARM.exidx + Type: SHT_ARM_EXIDX + Flags: [ SHF_ALLOC, SHF_LINK_ORDER ] + Address: 0x000000000000040C + Link: .text + AddressAlign: 0x0000000000000004 + Content: 200000000100000028000000B0B0B0808000000001000000 + - Name: .rel.plt + Type: SHT_REL + Flags: [ SHF_ALLOC, SHF_INFO_LINK ] + Address: 0x0000000000000424 + Link: .dynsym + AddressAlign: 0x0000000000000004 + Info: .plt + Relocations: + - Offset: 0x00000000000010D0 + Symbol: __cxa_finalize + Type: R_ARM_JUMP_SLOT + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x000000000000042C + AddressAlign: 0x0000000000000004 + Content: 04009FE500008FE0210000EAC81B0000050000EA00F020E300F020E300F020E300F020E300F020E300F020E31EFF2FE1050000EA00F020E300F020E300F020E300F020E300F020E300F020E31EFF2FE1050000EA00F020E300F020E300F020E300F020E300F020E300F020E31EFF2FE1 + - Name: .plt + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x00000000000004A0 + AddressAlign: 0x0000000000000010 + Content: 04E02DE500E68FE200EA8EE220FCBEE5D4D4D4D4D4D4D4D4D4D4D4D4D4D4D4D400C68FE200CA8CE208FCBCE5D4D4D4D4 + - Name: .fini_array + Type: SHT_FINI_ARRAY + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000001000 + AddressAlign: 0x0000000000000004 + EntSize: 0x0000000000000004 + Content: 2C040000 + - Name: .dynamic + Type: SHT_DYNAMIC + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000001004 + Link: .dynstr + AddressAlign: 0x0000000000000004 + Entries: + - Tag: DT_NEEDED + Value: 0x0000000000000040 + - Tag: DT_SONAME + Value: 0x000000000000004D + - Tag: DT_FLAGS + Value: 0x000000000000000A + - Tag: DT_FLAGS_1 + Value: 0x0000000000000001 + - Tag: DT_REL + Value: 0x000000000000039C + - Tag: DT_RELSZ + Value: 0x0000000000000070 + - Tag: DT_RELENT + Value: 0x0000000000000008 + - Tag: DT_RELCOUNT + Value: 0x000000000000000E + - Tag: DT_JMPREL + Value: 0x0000000000000424 + - Tag: DT_PLTRELSZ + Value: 0x0000000000000008 + - Tag: DT_PLTGOT + Value: 0x00000000000010C4 + - Tag: DT_PLTREL + Value: 0x0000000000000011 + - Tag: DT_SYMTAB + Value: 0x0000000000000210 + - Tag: DT_SYMENT + Value: 0x0000000000000010 + - Tag: DT_STRTAB + Value: 0x0000000000000344 + - Tag: DT_STRSZ + Value: 0x0000000000000058 + - Tag: DT_GNU_HASH + Value: 0x00000000000002C0 + - Tag: DT_HASH + Value: 0x00000000000002FC + - Tag: DT_FINI_ARRAY + Value: 0x0000000000001000 + - Tag: DT_FINI_ARRAYSZ + Value: 0x0000000000000004 + - Tag: DT_VERSYM + Value: 0x0000000000000290 + - Tag: DT_VERNEED + Value: 0x00000000000002A0 + - Tag: DT_VERNEEDNUM + Value: 0x0000000000000001 + - Tag: DT_NULL + Value: 0x0000000000000000 + - Name: .got.plt + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x00000000000010C4 + AddressAlign: 0x0000000000000004 + Content: 000000000000000000000000A0040000 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + Address: 0x0000000000002000 + AddressAlign: 0x0000000000000004 + Content: '00200000' + - Name: xray_instr_map + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC, SHF_LINK_ORDER ] + Address: 0x0000000000002004 + Link: .text + AddressAlign: 0x0000000000000001 + Content: 3C0400003C04000000010000000000005C0400005C04000000010000000000007C0400007C0400000001000000000000 + - Name: xray_fn_idx + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC, SHF_LINK_ORDER ] + Address: 0x0000000000002038 + Link: .text + AddressAlign: 0x0000000000000008 + Content: '042000001420000014200000242000002420000034200000' + - Name: .comment + Type: SHT_PROGBITS + Flags: [ SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + EntSize: 0x0000000000000001 + Content: 4C696E6B65723A204C4C4420392E302E3120287373683A2F2F6769742D726F2E7669702E66616365626F6F6B2E636F6D2F646174612F6769747265706F732F6F736D6574612F65787465726E616C2F6C6C64206532646338343566353235623739326533383263336466313865636265343835316161633735393929004743433A2028474E552920342E392E78203230313530313233202870726572656C6561736529000046616365626F6F6B20636C616E672076657273696F6E20392E302E3120286C6C766D3A20303864363533376137663130383936643532313436323061663637623939396338303030653061632C206366653A20346533653138356366333539383731343163636362623866346564383335383732646333643461662C20636F6D70696C65722D72743A20333330326531326630383064633738623863323435306165386665363534626666343638386166622C206C6C643A206532646338343566353235623739326533383263336466313865636265343835316161633735393920346533653138356366333539383731343163636362623866346564383335383732646333643461662920287373683A2F2F6769742D726F2E7669702E66616365626F6F6B2E636F6D2F646174612F6769747265706F732F6F736D6574612F65787465726E616C2F6C6C766D20303864363533376137663130383936643532313436323061663637623939396338303030653061632920286261736564206F6E204C4C564D20392E302E312900 + - Name: .ARM.attributes + Type: SHT_ARM_ATTRIBUTES + AddressAlign: 0x0000000000000001 + Content: 412A000000616561626900012000000005355445000604080109010A02120414011501170318011A021E02 +DynamicSymbols: + - Name: __cxa_finalize + Type: STT_FUNC + Binding: STB_GLOBAL + - Name: _Z3barv + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x000000000000043C + Size: 0x0000000000000020 + - Name: _Z3foov + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x000000000000047C + Size: 0x0000000000000020 + - Name: _Z3jarv + Type: STT_FUNC + Section: .text + Binding: STB_GLOBAL + Value: 0x000000000000045C + Size: 0x0000000000000020 + - Name: _edata + Section: xray_fn_idx + Binding: STB_GLOBAL + Value: 0x0000000000002050 + - Name: __bss_start + Index: SHN_ABS + Binding: STB_GLOBAL + - Name: _end + Section: xray_fn_idx + Binding: STB_GLOBAL + Value: 0x0000000000002050 +... diff --git a/llvm/test/tools/llvm-xray/ARM/extract-instrmap-arm.test b/llvm/test/tools/llvm-xray/ARM/extract-instrmap-arm.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-xray/ARM/extract-instrmap-arm.test @@ -0,0 +1,18 @@ +## This test makes sure we can extract the instrumentation map from an +## XRay-instrumented PIE file. + +RUN: yaml2obj %S/elf32-pic.yaml -o %t.so +RUN: llvm-xray extract %t.so -s > %t.test +RUN: llvm-xray extract %t.so -s --no-demangle >> %t.test +RUN: cat %t.test | FileCheck %s + +CHECK: --- +CHECK-NEXT: - { id: 1, address: 0x000000000000043C, function: 0x000000000000043C, kind: function-enter, always-instrument: true, function-name: 'bar()' } +CHECK-NEXT: - { id: 2, address: 0x000000000000045C, function: 0x000000000000045C, kind: function-enter, always-instrument: true, function-name: 'jar()' } +CHECK-NEXT: - { id: 3, address: 0x000000000000047C, function: 0x000000000000047C, kind: function-enter, always-instrument: true, function-name: 'foo()' } +CHECK: ... +CHECK: --- +CHECK-NEXT: - { id: 1, address: 0x000000000000043C, function: 0x000000000000043C, kind: function-enter, always-instrument: true, function-name: _Z3barv } +CHECK-NEXT: - { id: 2, address: 0x000000000000045C, function: 0x000000000000045C, kind: function-enter, always-instrument: true, function-name: _Z3jarv } +CHECK-NEXT: - { id: 3, address: 0x000000000000047C, function: 0x000000000000047C, kind: function-enter, always-instrument: true, function-name: _Z3foov } +CHECK: ... diff --git a/llvm/test/tools/llvm-xray/X86/bad-instrmap-sizes.txt b/llvm/test/tools/llvm-xray/X86/bad-instrmap-sizes.txt --- a/llvm/test/tools/llvm-xray/X86/bad-instrmap-sizes.txt +++ b/llvm/test/tools/llvm-xray/X86/bad-instrmap-sizes.txt @@ -1,3 +1,3 @@ ; RUN: not llvm-xray extract %S/Inputs/elf64-badentrysizes.bin 2>&1 | FileCheck %s ; CHECK: llvm-xray: Cannot extract instrumentation map from '{{.*}}elf64-badentrysizes.bin'. -; CHECK-NEXT: Instrumentation map entries not evenly divisible by size of an XRay sled entry in ELF64. +; CHECK-NEXT: Instrumentation map entries not evenly divisible by size of an XRay sled entry. diff --git a/llvm/test/tools/llvm-xray/X86/unsupported-elf32.txt b/llvm/test/tools/llvm-xray/X86/unsupported-elf32.txt --- a/llvm/test/tools/llvm-xray/X86/unsupported-elf32.txt +++ b/llvm/test/tools/llvm-xray/X86/unsupported-elf32.txt @@ -1,3 +1,3 @@ ; RUN: not llvm-xray extract %S/Inputs/elf32-noxray.bin 2>&1 | FileCheck %s ; CHECK: llvm-xray: Cannot extract instrumentation map from '{{.*}}elf32-noxray.bin'. -; CHECK-NEXT: File format not supported (only does ELF and Mach-O little endian 64-bit). +; CHECK-NEXT: File format not supported. Supports: AArch64/ARM/ppc64le/x86-64.