Fix missed demangles (#6350)

This PR fixes missed demangle cases pointed out in #6348, namely of the
form `mov eax, OFFSET FLAT:_Z...` and `jmp qword ptr [rip + _Z...]`.

Closes #6348.

---------

Co-authored-by: Patrick Quist <partouf@gmail.com>
This commit is contained in:
Jeremy Rifkin
2024-04-13 13:54:49 -05:00
committed by GitHub
parent 5b52f931c9
commit 15271c9090
3 changed files with 58 additions and 15 deletions

View File

@@ -52,9 +52,10 @@ export class BaseDemangler extends AsmRegex {
readonly callPtrDef4 = /callq?.*qword\sptr\s\[[a-z]*\s\+\s([$._a-z][\w$.@]*)\+?\d?]/i;
// symbols in a mov or lea command starting with an underscore
readonly movUnderscoreDef = /mov.*\s(_[\w$.@]*)/i;
readonly leaUnderscoreDef = /lea.*\s(_[\w$.@]*)/i;
readonly movUnderscoreDef = /mov.*[\s:](_[\w$.@]*)/i;
readonly leaUnderscoreDef = /lea.*[\s:](_[\w$.@]*)/i;
readonly quadUnderscoreDef = /\.quad\s*(_[\w$.@]*)/i;
readonly ptrOffset = /\bptr\s*\[.+\b(_[\w$.@]*)\s*\]/i;
// E.g., ".entry _Z6squarePii("
// E.g., ".func (.param .b32 func_retval0) bar("
@@ -117,6 +118,9 @@ export class BaseDemangler extends AsmRegex {
protected collectLabels() {
const symbolMatchers = [
// this.ptrOffset needs to be checked before the jmp test since the jumpDef regex doesn't match the mangled
// symbol in `qword ptr [rip + _Z...]` and instead matches the `qword`
this.ptrOffset,
this.jumpDef,
this.callPtrDef4,
this.callPtrDef3,
@@ -129,8 +133,7 @@ export class BaseDemangler extends AsmRegex {
this.ptxFuncDef,
this.ptxVarDef,
];
for (let j = 0; j < this.result.asm.length; ++j) {
const line = this.result.asm[j].text;
for (const {text: line} of this.result.asm) {
if (!line) continue;
const labelMatch = line.match(this.labelDef);

View File

@@ -736,7 +736,7 @@ std::regex_error::regex_error(std::regex_constants::error_type, char const*) [ba
mov rsi, rdx
mov rdi, rax
call std::runtime_error::runtime_error(char const*) [base object constructor]
mov edx, OFFSET FLAT:_ZTVSt11regex_error+16
mov edx, OFFSET FLAT:vtable for std::regex_error+16
mov rax, QWORD PTR [rbp-8]
mov QWORD PTR [rax], rdx
mov rax, QWORD PTR [rbp-8]
@@ -761,8 +761,8 @@ std::__throw_regex_error(std::regex_constants::error_type, char const*):
mov esi, eax
mov rdi, rbx
call std::regex_error::regex_error(std::regex_constants::error_type, char const*) [complete object constructor]
mov edx, OFFSET FLAT:_ZNSt11regex_errorD1Ev
mov esi, OFFSET FLAT:_ZTISt11regex_error
mov edx, OFFSET FLAT:std::regex_error::~regex_error() [complete object destructor]
mov esi, OFFSET FLAT:typeinfo for std::regex_error
mov rdi, rbx
call __cxa_throw
mov r12, rax
@@ -1235,9 +1235,9 @@ main:
call bool std::regex_match<char, std::__cxx11::regex_traits<char> >(char const*, std::__cxx11::basic_regex<char, std::__cxx11::regex_traits<char> > const&, std::regex_constants::match_flag_type)
movzx eax, al
mov esi, eax
mov edi, OFFSET FLAT:_ZSt4cout
mov edi, OFFSET FLAT:std::cout
call std::basic_ostream<char, std::char_traits<char> >::operator<<(bool)
mov esi, OFFSET FLAT:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
mov esi, OFFSET FLAT:std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)
mov rdi, rax
call std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))
mov BYTE PTR [rbp-51], 1
@@ -1251,7 +1251,7 @@ main:
mov rdi, rcx
call int std::accumulate<bool*, int, std::bit_and<bool> >(bool*, bool*, int, std::bit_and<bool>)
mov esi, eax
mov edi, OFFSET FLAT:_ZSt4cout
mov edi, OFFSET FLAT:std::cout
call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
lea rax, [rbp-48]
mov rdi, rax
@@ -3728,7 +3728,7 @@ std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::~_Sp_counted_base() [base obj
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov edx, OFFSET FLAT:_ZTVSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE+16
mov edx, OFFSET FLAT:vtable for std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>+16
mov rax, QWORD PTR [rbp-8]
mov QWORD PTR [rax], rdx
nop
@@ -6586,7 +6586,7 @@ std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_Sp_counted_base() [base obje
push rbp
mov rbp, rsp
mov QWORD PTR [rbp-8], rdi
mov edx, OFFSET FLAT:_ZTVSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE+16
mov edx, OFFSET FLAT:vtable for std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>+16
mov rax, QWORD PTR [rbp-8]
mov QWORD PTR [rax], rdx
mov rax, QWORD PTR [rbp-8]
@@ -6674,7 +6674,7 @@ std::ctype<char> const& std::use_facet<std::ctype<char> const>(std::locale const
mov rbp, rsp
sub rsp, 32
mov QWORD PTR [rbp-24], rdi
mov edi, OFFSET FLAT:_ZNSt5ctypeIcE2idE
mov edi, OFFSET FLAT:std::ctype<char>::id
call std::locale::id::_M_id() const
mov QWORD PTR [rbp-8], rax
mov rax, QWORD PTR [rbp-24]
@@ -6702,8 +6702,8 @@ std::ctype<char> const& std::use_facet<std::ctype<char> const>(std::locale const
add rax, rdx
mov rax, QWORD PTR [rax]
mov ecx, 0
mov edx, OFFSET FLAT:_ZTISt5ctypeIcE
mov esi, OFFSET FLAT:_ZTINSt6locale5facetE
mov edx, OFFSET FLAT:typeinfo for std::ctype<char>
mov esi, OFFSET FLAT:typeinfo for std::locale::facet
mov rdi, rax
call __dynamic_cast
test rax, rax

View File

@@ -116,6 +116,46 @@ describe('Basic demangling', () => {
]);
});
it('Mov with OFFSET FLAT', () => {
// regression test for https://github.com/compiler-explorer/compiler-explorer/issues/6348
const result = {asm: [{text: 'mov eax, OFFSET FLAT:_ZN1a1gEi'}]};
const demangler = new DummyCppDemangler(cppfiltpath, new DummyCompiler(), ['-n']);
return Promise.all([
demangler
.process(result)
.then(output => {
expect(output.asm[0].text).toEqual('mov eax, OFFSET FLAT:a::g(int)');
})
.catch(catchCppfiltNonexistence),
]);
});
it('rip-relative jump', () => {
// regression test for https://github.com/compiler-explorer/compiler-explorer/issues/6348
const result = {
asm: [
{
text: 'jmp qword ptr [rip + _ZN4core3fmt3num3imp54_$LT$impl$u20$core..fmt..Display$u20$for$u20$usize$GT$3fmt17h7bbbd896a38dcccaE@GOTPCREL]',
},
],
};
const demangler = new DummyCppDemangler(cppfiltpath, new DummyCompiler(), ['-n']);
return Promise.all([
demangler
.process(result)
.then(output => {
expect(output.asm[0].text).toEqual(
'jmp qword ptr [rip + core::fmt::num::imp::<impl core::fmt::Display for usize>::fmt::h7bbbd896a38dccca@GOTPCREL]',
);
})
.catch(catchCppfiltNonexistence),
]);
});
it('Two destructors', () => {
const result = {
asm: [