[PATCH] D136938: [LLDB] Fix code breakpoints on tagged addresses

Jason Molenda via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 19 07:35:04 PST 2022


jasonmolenda added a comment.

I have a little example of a function pointer using ptrath in an arm64e (ARMv8.3) program, to show what I was talking about,

  * thread #1, queue = 'com.apple.main-thread', stop reason = instruction step into
      frame #0: 0x0000000100003fa0 a.out`main + 40 at a.c:6
     1   	int foo () { return 5; }
     2   	
     3   	int main()
     4   	{
     5   	  int (*func)() = foo;
  -> 6   	  return func();
     7   	}
  Target 0: (a.out) stopped.
  
  (lldb) p func
  (int (*)(...)) $0 = 0xb868000100003f70 (actual=0x0000000100003f70 a.out`foo at a.c:1)
  
  (lldb) reg read x8
        x8 = 0xb868000100003f70 (0x0000000100003f70) a.out`foo at a.c:1
  
  (lldb) ima loo -a func
        Address: a.out[0x0000000100003f70] (a.out.__TEXT.__text + 0)
        Summary: a.out`foo at a.c:1
  
  (lldb) br s -a func
  Breakpoint 2: where = a.out`foo at a.c:1, address = 0x0000000100003f70
  
  (lldb) mem read -c 1 -s 4 -f x func
  0x100003f70: 0x528000a0
  
  (lldb) x/1i func
      0x100003f70: 0x528000a0   mov    w0, #0x5
  (lldb) 

(nb out of the box installs of macOS will not run arm64e binaries like this, the ABI is not finalized -- it's meant to prevent people from sharing builds that may stop working some day when the ABI changes)

This process isn't using TBI, but the high bits end up being used for signing so it's the same effect.  I located this in OptionArgParser::ToAddress() because we'll need this same behavior in

  if (expr_result == eExpressionCompleted) {
    if (valobj_sp)
      valobj_sp = valobj_sp->GetQualifiedRepresentationIfAvailable(
          valobj_sp->GetDynamicValueType(), true);
    // Get the address to watch.
    if (valobj_sp)
      addr = valobj_sp->GetValueAsUnsigned(fail_value, &success);
    if (success) {
      if (error_ptr)
        error_ptr->Clear();
      if (abi_sp)
        addr = abi_sp->FixCodeAddress (addr);
      return addr;
    } else {

What do you think about locating this change in ToAddress instead of Target::GetBreakableLoadAddress?  It looks like the one caller to GetBreakableLoadAddress is Target::CreateBreakpoint(addr_t addr) - which is probably called by an SBTarget method if we want to think of the most general purpose use case.  I think stripping non-addressable bits in OptionArgParser::ToAddress is the right thing to do - but I don't have an opinion about whether it should be done in Target::GetBreakableLoadAddress or not.

One thing to note is that I also have an SBValue method that needs to be upstreamed, SBValue::GetValueAsAddress().  So if someone has an SBValue of a function pointer and they want to take the value of that func ptr and call SBTarget::CreateBreakpoint on it, I would say "well yes, you need to use GetValueAsAddress before you pass that to CreateBreakpoint".


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D136938/new/

https://reviews.llvm.org/D136938



More information about the llvm-commits mailing list