고급 개발자로 가는 길

Embedded/Arm 아키텍처

[Arm 아키텍처] AAPCS(Calling Convention)

다크엔지니어 2022. 2. 19. 14:31
반응형

AAPCS(Calling Convention) 을 알아야 하는 이유

프로그래밍의 근본 동작 원리 파악이 가능

  • 실제 Arm 코어는 c 코드가 아니라 어셈블리 명령어를 실행함
  • 대부분 c 코드는 함수로 구성 됨

 

안정적이고 최적화된 이쁜 코드 작성 할 수 있는 기반 지식

  • 함수에 전달되는 인자의 갯수
  • 프로세스의 스택을 최대한 사용하지 않는 코드 설계를 해야 함

 

디버깅 실력을 키우고 이는 문제 해결 능력으로 이어짐

  • 스택 오버플로우, 스택 Corruption
  • 콜 스택 복원

 

objdump 나 trace32 를 통해 어셈블리 영역을 볼 수 있다. 

또한, 함수 호출 시 인자의 갯수를 전달 할 수 있는 레지스터는 8개로 한정되어있다.

8개 초과 시 해당 프로세스의 스택영역에 할당하여 컨텍스트 스위칭을 진행하게 된다.

물론 프로세스의 리소스가 여유로운 경우가 많아 큰 문제는 없을 수 있지만,

개발자가 이를 모르고 과도하게 사용할 경우 결국 문제를 일으킬 수 있다.

이러한 경우 struct 를 이용하여 함수 호출을 하는 방법이 있다.

아래는 실제 커널 소스로 확인이 가능하다. 

 #ifdef __ARCH_WANT_SYS_CLONE
 #ifdef CONFIG_CLONE_BACKWARDS
 SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
                  int __user *, parent_tidptr,
                  unsigned long, tls,
                  int __user *, child_tidptr)
 #elif defined(CONFIG_CLONE_BACKWARDS2)
 SYSCALL_DEFINE5(clone, unsigned long, newsp, unsigned long, clone_flags,
                  int __user *, parent_tidptr,
                  int __user *, child_tidptr,
                  unsigned long, tls)
 #elif defined(CONFIG_CLONE_BACKWARDS3)
 SYSCALL_DEFINE6(clone, unsigned long, clone_flags, unsigned long, newsp,
                 int, stack_size,
                 int __user *, parent_tidptr,
                 int __user *, child_tidptr,
                 unsigned long, tls)
 #else
 SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
                  int __user *, parent_tidptr,
                  int __user *, child_tidptr,
                  unsigned long, tls)
 #endif
 {
         struct kernel_clone_args args = {
                 .flags          = (lower_32_bits(clone_flags) & ~CSIGNAL),
                 .pidfd          = parent_tidptr,
                 .child_tid      = child_tidptr,
                 .parent_tid     = parent_tidptr,
                 .exit_signal    = (lower_32_bits(clone_flags) & CSIGNAL),
                 .stack          = newsp,
                 .tls            = tls,
         };

         return kernel_clone(&args);
 }
 #endif

 

ftrace 나 trace32 등을 통해 콜스텍 확인이 가능하며 trace32 의 경우 여러 명령어를 통해

어셈블리와 덤프로 해당 주소 영역을 따라 갈 수 있다.

 

해당 내용 관련해서는 구글링을 통해 자세히 기술 하신분들이나 문서로 확인이 가능하다.

위 내용은 고급 프로그래머가 되기 위한 가장 기본적인 내용이라고 생각한다.

이러한 내용을 잘 모르는 경우가 많기는 하지만 이 글을 통해 더 알아 갈 수 있는 기회가 되었길 바란다.

반응형