mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2024-11-23 02:04:41 +08:00
llvmpipe: improvements to JIT assembly dump
Fix disassembly off-by-one instruction bug, add Aarch64 support, add addresses to symbol names, cleanup iostream usage. Reviewed-by: Konstantin Seurer <konstantin.seurer@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30626>
This commit is contained in:
parent
af8c680087
commit
6a3234ee3b
@ -104,7 +104,7 @@ def lookupMap(filename, matchSymbol):
|
||||
|
||||
def lookupAsm(filename, desiredFunction):
|
||||
stream = open(filename + '.asm', 'rt')
|
||||
while stream.readline() != desiredFunction + ':\n':
|
||||
while not stream.readline().startswith(desiredFunction + ' '):
|
||||
pass
|
||||
|
||||
asm = []
|
||||
|
@ -126,15 +126,22 @@ disassemble(const void* func, std::ostream &buffer)
|
||||
* so that between runs.
|
||||
*/
|
||||
|
||||
buffer << std::setw(6) << (unsigned long)pc << ":\t";
|
||||
buffer << std::setw(6) << std::hex << (unsigned long)pc
|
||||
<< std::setw(0) << std::dec << ":";
|
||||
|
||||
Size = LLVMDisasmInstruction(D, (uint8_t *)bytes + pc, extent - pc, 0, outline,
|
||||
sizeof outline);
|
||||
sizeof(outline));
|
||||
|
||||
if (!Size) {
|
||||
buffer << "invalid\n";
|
||||
pc += 1;
|
||||
#if DETECT_ARCH_AARCH64
|
||||
uint32_t invalid = bytes[pc + 0] << 0 | bytes[pc + 1] << 8 |
|
||||
bytes[pc + 2] << 16 | bytes[pc + 3] << 24;
|
||||
snprintf(outline, sizeof(outline), "\tinvalid %x", invalid);
|
||||
Size = 4;
|
||||
#else
|
||||
buffer << "\tinvalid\n";
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -145,10 +152,11 @@ disassemble(const void* func, std::ostream &buffer)
|
||||
unsigned i;
|
||||
for (i = 0; i < Size; ++i) {
|
||||
buffer << std::hex << std::setfill('0') << std::setw(2)
|
||||
<< static_cast<int> (bytes[pc + i]);
|
||||
<< static_cast<int> (bytes[pc + i])
|
||||
<< std::setw(0) << std::dec;
|
||||
}
|
||||
for (; i < 16; ++i) {
|
||||
buffer << std::dec << " ";
|
||||
buffer << " ";
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,20 +164,7 @@ disassemble(const void* func, std::ostream &buffer)
|
||||
* Print the instruction.
|
||||
*/
|
||||
|
||||
buffer << std::setw(Size) << outline << '\n';
|
||||
|
||||
/*
|
||||
* Stop disassembling on return statements, if there is no record of a
|
||||
* jump to a successive address.
|
||||
*
|
||||
* XXX: This currently assumes x86
|
||||
*/
|
||||
|
||||
#if DETECT_ARCH_X86 || DETECT_ARCH_X86_64
|
||||
if (Size == 1 && bytes[pc] == 0xc3) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
buffer << outline << '\n';
|
||||
|
||||
/*
|
||||
* Advance.
|
||||
@ -177,6 +172,21 @@ disassemble(const void* func, std::ostream &buffer)
|
||||
|
||||
pc += Size;
|
||||
|
||||
/*
|
||||
* Stop disassembling on return statements
|
||||
*/
|
||||
|
||||
#if DETECT_ARCH_X86 || DETECT_ARCH_X86_64
|
||||
if (Size == 1 && bytes[pc - 1] == 0xc3) {
|
||||
break;
|
||||
}
|
||||
#elif DETECT_ARCH_AARCH64
|
||||
if (Size == 4 && bytes[pc - 1] == 0xD6 && bytes[pc - 2] == 0x5F &&
|
||||
(bytes[pc - 3] & 0xFC) == 0 && (bytes[pc - 4] & 0x1F) == 0) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pc >= extent) {
|
||||
buffer << "disassembly larger than " << extent << " bytes, aborting\n";
|
||||
break;
|
||||
@ -191,8 +201,8 @@ disassemble(const void* func, std::ostream &buffer)
|
||||
* Print GDB command, useful to verify output.
|
||||
*/
|
||||
if (0) {
|
||||
buffer << "disassemble " << static_cast<const void*>(bytes) << ' '
|
||||
<< static_cast<const void*>(bytes + pc) << '\n';
|
||||
buffer << "disassemble " << std::hex << static_cast<const void*>(bytes) << ' '
|
||||
<< static_cast<const void*>(bytes + pc) << std::dec << '\n';
|
||||
}
|
||||
|
||||
return pc;
|
||||
@ -248,7 +258,8 @@ lp_profile(LLVMValueRef func, const void *code)
|
||||
if (perf_map_file) {
|
||||
const char *symbol = LLVMGetValueName(func);
|
||||
unsigned long addr = (uintptr_t)code;
|
||||
perf_asm_file << symbol << ":\n";
|
||||
perf_asm_file << symbol << " " << std::hex
|
||||
<< (uintptr_t)code << std::dec << ":\n";
|
||||
unsigned long size = disassemble(code, perf_asm_file);
|
||||
perf_asm_file.flush();
|
||||
fprintf(perf_map_file, "%lx %lx %s\n", addr, size, symbol);
|
||||
@ -259,5 +270,3 @@ lp_profile(LLVMValueRef func, const void *code)
|
||||
(void)code;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user