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

```asm
<transform_symlink>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %rbx
  sub    $0x58,%rsp
  mov    %rdi,-0x48(%rbp)
  mov    %rsi,-0x50(%rbp)
  mov    %rdx,-0x58(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x18(%rbp)
  xor    %eax,%eax
  mov    -0x50(%rbp),%rax
  mov    %rax,-0x30(%rbp)
  cmpq   $0x0,-0x58(%rbp)
  je     L28
  mov    -0x58(%rbp),%rax
  movq   $0x0,(%rax)
  mov    -0x30(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  jne    L61
  mov    -0x48(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  jne    L61
  lea    -0x48(%rbp),%rdx
  lea    -0x30(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <strip_common@plt>
  mov    -0x48(%rbp),%rax
  mov    %rax,%rdi
  mov    $0x0,%eax
  call   <count_components@plt>
  mov    %eax,-0x34(%rbp)
  cmpl   $0x0,-0x34(%rbp)
  je     L137
  subl   $0x1,-0x34(%rbp)
  mov    -0x34(%rbp),%edx
  mov    %edx,%eax
  add    %eax,%eax
  add    %edx,%eax
  movslq %eax,%rbx
  mov    -0x30(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  add    %rbx,%rax
  add    $0x2,%rax
  mov    %rax,%rdi
  call   <malloc@plt>
  mov    %rax,-0x20(%rbp)
  cmpq   $0x0,-0x20(%rbp)
  jne    L136
  lea    D2(%rip),%rax
  mov    %rax,%rsi
  mov    $0x1,%edi
  mov    $0x0,%eax
  call   <av_log@plt>
  mov    $0x1,%edi
  call   <exit@plt>
L136:
  mov    -0x20(%rbp),%rax
  mov    %rax,-0x28(%rbp)
  movl   $0x0,-0x38(%rbp)
  jmp    L85
L99:
  mov    -0x28(%rbp),%rax
  movl   $0x2f2e2e,(%rax)
  addl   $0x1,-0x38(%rbp)
  addq   $0x3,-0x28(%rbp)
L85:
  mov    -0x38(%rbp),%eax
  cmp    -0x34(%rbp),%eax
  jl     L99
  mov    -0x30(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L103
  mov    -0x30(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <strcpy@plt>
  jmp    L128
L103:
  cmpl   $0x0,-0x34(%rbp)
  jne    L82
  mov    -0x28(%rbp),%rax
  movw   $0x2e,(%rax)
  jmp    L128
L82:
  mov    -0x28(%rbp),%rax
  movb   $0x0,(%rax)
L128:
  mov    -0x58(%rbp),%rax
  mov    -0x20(%rbp),%rdx
  mov    %rdx,(%rax)
  jmp    L142
L28:
  nop
  jmp    L142
L61:
  nop
  jmp    L142
L137:
  nop
L142:
  mov    -0x18(%rbp),%rax
  sub    %fs:0x28,%rax
  je     L75
  call   <__stack_chk_fail@plt>
L75:
  mov    -0x8(%rbp),%rbx
  leave
  ret
```

tool_calls: name: read_data
arguments: label: D2
type_guessed: string

tool: D2: transform_symlink: memory allocation failed

assistant: ```c
void transform_symlink(const char *path, const char *linkdest, char **linkp) {
  const char *l = linkdest;
  char *newlink;
  char *s;
  int dotdots;
  int i;
  if (linkp == ((void *)0))
    return;
  *linkp = ((void *)0);
  if (l[0] != '/' || path[0] != '/')
    return;
  strip_common(&l, &path);
  dotdots = count_components(path);
  if (!dotdots)
    return;
  dotdots--;
  newlink = malloc(dotdots * 3 + strlen(l) + 2);
  if (!newlink) {
    av_log(001, "transform_symlink: memory allocation failed");
    exit(1);
  }
  for (s = newlink, i = 0; i < dotdots; i++, s += 3)
    strcpy(s, "../");
  if (l[0])
    strcpy(s, l);
  else if (!dotdots)
    strcpy(s, ".");
  else
    s[0] = '\0';
  *linkp = newlink;
}
```