Skip to content

Call site info: Volatile registers shouldn't be used in DW_AT_call_target expressions #70948

@OCHyams

Description

@OCHyams

clang version 18.0.0 (bc41b0a)
Target: x86_64-unknown-linux-gnu

In the reproducer below, there's an indirect call through b's vtable to virtual function v. The vtable address is loaded into RAX, and as v is the second vtable entry we get the code call qword ptr [rax + 8].

The DW_AT_call_target attribute on the call site info, below, is not only wrong (see #70949) but also we should not be using a volatile register in DW_AT_call_target expressions.

DW_AT_call_target       (DW_OP_reg0 RAX)

From the DWARF 5 spec

The call site may have a DW_AT_call_target attribute which is a DWARF expression. For indirect calls or jumps where it is unknown at compile time which subprogram will be called the expression computes the address of the subprogram that will be called.

The DWARF expression should not use register or memory locations that might be clobbered by the call.

DW_AT_call_target_clobbered should be used instead.

$ cat test.cpp

struct Base {
  virtual int zz() { return x; }
  [[clang::noinline]]
  virtual int v() { return zz(); }
  int x;
};
struct Child: public Base {
  [[clang::noinline]]
  virtual int v() { return x * 2; }
  int x;
};

[[clang::noinline]]
[[clang::disable_tail_calls]]
int foo(Base* b) {
  return b->v();
}

$ clang test.cpp -O2 -g -c -o test.o
$ llvm-dwarfdump test.o --name foo --show-children

0x00000027: DW_TAG_subprogram
              DW_AT_name ("foo")
              ...


0x00000037:   DW_TAG_formal_parameter
                ...

0x00000040:   DW_TAG_call_site
                DW_AT_call_target    (DW_OP_reg0 RAX)
                DW_AT_call_return_pc (0x0000000000000007)

0x00000044:     DW_TAG_call_site_parameter
                  ...

0x0000004b:     NULL

0x0000004c:   NULL

$ llvm-objdump --disassemble-symbols=_Z3fooP4Base test.o --x86-asm-syntax=intel

0000000000000000 <_Z3fooP4Base>:
       0: 50                           push rax
       1: 48 8b 07                     mov  rax, qword ptr [rdi]
       4: ff 50 08                     call qword ptr [rax + 0x8]
       7: 59                           pop  rcx
       8: c3                           ret

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions