사전 빌드된 ABI 사용 검사기

Android 공유 라이브러리는 수시로 진화합니다. 사전 빌드된 바이너리를 최신 상태로 유지하려면 상당한 노력이 필요합니다. Android 9 이하에서는 삭제된 라이브러리나 ABI에 종속된 사전 빌드된 바이너리가 런타임 시에만 연결에 실패합니다. 개발자는 로그를 추적하여 오래 전에 사전 빌드된 바이너리를 찾아야 합니다. Android 10에는 기호 기반의 ABI 사용 검사기가 도입되었습니다. 검사기는 오래 전에 사전 빌드된 바이너리를 빌드 시간에 감지할 수 있습니다. 따라서 공유 라이브러리 개발자가 어떤 사전 빌드된 바이너리가 자체 변경사항에 의해 손상되었는지, 어떤 사전 빌드된 바이너리를 다시 빌드해야 하는지 알 수 있습니다.

기호 기반의 ABI 사용 검사기

기호 기반의 ABI 사용 검사기는 호스트의 Android 동적 링커를 에뮬레이션합니다. 검사기는 사전 빌드된 바이너리를 사전 빌드된 바이너리의 종속 항목과 연결하고 정의되지 않은 모든 기호가 결정되었는지 확인합니다.

첫째, 검사기는 사전 빌드된 바이너리의 타겟 아키텍처를 확인합니다. 사전 빌드된 바이너리가 ARM, AArch64, x86 또는 x86-64 아키텍처를 타겟팅하지 않으면 검사기는 사전 빌드된 바이너리를 건너뜁니다.

둘째, 사전 빌드된 바이너리의 종속 항목은 LOCAL_SHARED_LIBRARIES 또는 shared_libs에 나열되어야 합니다. 빌드 시스템은 모듈 이름을 공유 라이브러리의 일치하는 변형(즉, core vs. vendor)으로 결정합니다.

셋째, 검사기는 DT_NEEDED 항목을 LOCAL_SHARED_LIBRARIES 또는 shared_libs와 비교합니다. 특히, 검사기는 각 공유 라이브러리에서 DT_SONAME 항목을 추출하고 이러한 DT_SONAME을 사전 빌드된 바이너리에 기록된 DT_NEEDED 항목과 비교합니다. 불일치가 있는 경우 오류 메시지가 표시됩니다.

넷째, 검사기는 사전 빌드된 바이너리의 정의되지 않은 기호를 결정합니다. 이러한 정의되지 않은 기호는 종속 항목 중 하나에 정의되어야 하며 기호 결합은 GLOBAL 또는 WEAK여야 합니다. 정의되지 않은 기호를 결정할 수 없는 경우 오류 메시지가 표시됩니다.

모듈 속성 사전 빌드

사전 빌드된 바이너리의 종속 항목은 다음 중 하나에 지정되어야 합니다.

  • Android.bp: shared_libs: ["libc", "libdl", "libm"],
  • Android.mk: LOCAL_SHARED_LIBRARIES := libc libdl libm

사전 빌드된 라이브러리에서 결정할 수 없는 정의되지 않은 기호를 보유하도록 설계된 경우 다음 중 하나를 지정합니다.

  • Android.bp: allow_undefined_symbols: true,
  • Android.mk: LOCAL_ALLOW_UNDEFINED_SYMBOLS := true

사전 빌드된 바이너리가 ELF 파일 검사를 건너뛰도록 하려면 다음 중 하나를 지정합니다.

  • Android.bp: check_elf_files: false,
  • Android.mk: LOCAL_CHECK_ELF_FILES := false

검사기 실행

검사기는 Android 빌드 프로세스 중에 사전 빌드된 모든 ELF 모듈을 확인합니다.

처리 시간을 단축하기 위해 검사기를 단독으로 실행하려면 다음을 실행합니다.

m check-elf-files

ABI 오류 수정자

자동 수정자를 사용하면 ABI 확인 오류를 해결할 수 있습니다. Android.bp/Android.mk를 입력으로 사용하여 수정자를 간단하게 실행하면 수정자는 stdout에 제안된 수정사항을 출력합니다. (선택사항) --in-place 옵션을 사용하여 수정자를 실행하면 제안된 수정사항으로 Android.bp/Android.mk가 바로 업데이트됩니다.

Android.bp의 경우

m fix_android_bp_prebuilt
# Print the fixed Android.bp to stdout.
fix_android_bp_prebuilt <path-to-Android.bp>
# Update the Android.bp in place.
fix_android_bp_prebuilt --in-place <path-to-Android.bp>

Android.mk의 경우

m fix_android_mk_prebuilt
# Print the fixed Android.mk to stdout.
fix_android_mk_prebuilt <path-to-Android.mk>
# Update the Android.mk in place.
fix_android_mk_prebuilt --in-place <path-to-Android.mk>