user: Please show me the C implementation that matches the assembly code listed below:

```asm
<format_process_info>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %rbx
  sub    $0x58,%rsp
  mov    %rdi,-0x58(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x18(%rbp)
  xor    %eax,%eax
  lea    -0x4c(%rbp),%rdx
  lea    -0x50(%rbp),%rcx
  mov    -0x58(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <get_uid_gid@plt>
  mov    %eax,-0x48(%rbp)
  cmpl   $0x0,-0x48(%rbp)
  je     L19
  mov    $0x0,%eax
  jmp    L57
L19:
  mov    -0x58(%rbp),%rax
  mov    %rax,%rdi
  call   <get_rss@plt>
  mov    %eax,-0x44(%rbp)
  cmpl   $0xffffffff,-0x44(%rbp)
  jne    L25
  mov    $0x0,%eax
  jmp    L57
L25:
  mov    -0x58(%rbp),%rax
  mov    %rax,%rdi
  call   <get_program_name@plt>
  mov    %rax,-0x40(%rbp)
  cmpq   $0x0,-0x40(%rbp)
  jne    L45
  mov    $0x0,%eax
  jmp    L57
L45:
  mov    -0x50(%rbp),%eax
  mov    %eax,%edi
  call   <get_user_name@plt>
  mov    %rax,-0x38(%rbp)
  mov    -0x4c(%rbp),%eax
  mov    %eax,%edi
  call   <get_group_name@plt>
  mov    %rax,-0x30(%rbp)
  mov    -0x40(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  mov    %eax,%ebx
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  add    %eax,%ebx
  mov    -0x30(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  add    %ebx,%eax
  sub    $0xffffff80,%eax
  cltq
  mov    %rax,-0x28(%rbp)
  mov    -0x28(%rbp),%rax
  mov    %rax,%rdi
  call   <xmalloc@plt>
  mov    %rax,-0x20(%rbp)
  mov    -0x58(%rbp),%rax
  mov    %eax,%r10d
  mov    -0x38(%rbp),%rdi
  mov    -0x40(%rbp),%rcx
  mov    -0x28(%rbp),%rsi
  mov    -0x20(%rbp),%rax
  mov    -0x44(%rbp),%edx
  push   %rdx
  push   -0x30(%rbp)
  mov    %rdi,%r9
  mov    %rcx,%r8
  mov    %r10d,%ecx
  lea    D9(%rip),%rdx
  mov    %rax,%rdi
  call   <snprintf@plt>
  add    $0x10,%rsp
  mov    -0x40(%rbp),%rax
  mov    %rax,%rdi
  call   <free@plt>
  mov    -0x38(%rbp),%rax
  mov    %rax,%rdi
  call   <free@plt>
  mov    -0x30(%rbp),%rax
  mov    %rax,%rdi
  call   <free@plt>
  mov    -0x20(%rbp),%rax
L57:
  mov    -0x18(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L9
  call   <__stack_chk_fail@plt>
L9:
  mov    -0x8(%rbp),%rbx
  leave
  ret
```

tool_calls: name: read_data
arguments: data_label: D9
type_guessed: string

tool: D9: <tr><td align="right">%d</td><td><tt>%s</tt></td><td>%s</td><td>%s</td><td align="right">%d</td></tr>


assistant: ```c
char *format_process_info(pid_t pid) {
  int rval;
  uid_t uid;
  gid_t gid;
  char *user_name;
  char *group_name;
  int rss;
  char *program_name;
  size_t result_length;
  char *result;
  rval = get_uid_gid(pid, &uid, &gid);
  if (rval != 0)
    return NULL;
  rss = get_rss(pid);
  if (rss == -1)
    return NULL;
  program_name = get_program_name(pid);
  if (program_name == NULL)
    return NULL;
  user_name = get_user_name(uid);
  group_name = get_group_name(gid);
  result_length = strlen(program_name) + strlen(user_name) + strlen(group_name) + 128;
  result = (char *)xmalloc(result_length);
  snprintf(result, result_length,
           "<tr><td align=\"right\">%d</td><td><tt>%s</tt></td><td>%s</td>"
           "<td>%s</td><td align=\"right\">%d</td></tr>\n",
           (int)pid, program_name, user_name, group_name, rss);
  free(program_name);
  free(user_name);
  free(group_name);
  return result;
}
```