macOS의 gcc 바이너리 살펴보기

1 week ago 17

macOS의 gcc는 단순한 별칭이 아니라 실행 파일이며, 실제 컴파일은 clang으로 이어짐 첫 번째 바이너리는 libxcselect.dylib의 xcselect_invoke_xcrun() 을 호출하며, 이는 사실상 xcrun을 실행하는 것과 같음 xcrun은 개발자 도구 디렉터리의 도구를 실행하며, --find로 실제 호출 대상의 위치를 확인할 수 있음 해당 디렉터리의 gcc 역시 래퍼 바이너리로, 다시 /usr/bin/xcrun을 실행해 호출 이름에 따라 clang 또는 clang++을 선택함 이 간접 실행 구조가 SIP와 재시작 없는 개발 도구 업데이트, 디렉터리 위치 변경의 유연성 때문이라는 해석은 확인된 이유가 아닌 추측임 첫 번째 gcc 바이너리와 xcrun macOS에서 gcc라는 이름으로 실행하는 도구는 clang으로 이어지지만, 셸 별칭이 아닌 바이너리임 역어셈블 결과에는 호출된 도구 이름에 따른 변환 로직이 있음 cc와 llvm-gcc는 clang으로 바꿈 c++와 llvm-g++는 clang++로 바꾸고, 나머지는 원래 도구 이름을 사용함 핵심 호출은 xcselect_invoke_xcrun() 이며, libxcselect.dylib에 속한 함수임 xcrun 바이너리 자체도 사실상 이 함수를 호출함 조사한 Xcode 설치 개발 도구에서도 같은 바이너리 구조가 나타나며, xcode-select가 설치하는 개발 도구는 xcrun을 거쳐 실행됨 xcrun 매뉴얼에 따르면 개발자 도구 디렉터리에서 도구를 찾아 실행하며, --find 로 실제 실행 파일 위치를 확인할 수 있음 개발자 도구 디렉터리에도 있는 gcc 래퍼 실제 도구 디렉터리에는 c++, llvm-gcc, llvm-g++가 없으므로, 앞선 바이너리가 이 이름들을 하드코딩해 변환함 cc와 clang++는 clang의 별칭임 g++는 같은 디렉터리에 있는 별도의 gcc 바이너리의 별칭임 이 두 번째 gcc 바이너리도 컴파일러 자체가 아닌 래퍼로 작동함 실행 이름의 마지막 두 문자가 ++이면 clang++, 아니면 clang을 선택함 기존 명령행 인수를 이어 붙이고, execv()로 /usr/bin/xcrun을 실행함 이런 구조의 이유로 SIP와 업데이트 방식의 관계를 추측할 수 있지만, 확인된 설계 근거는 아님 /usr/bin은 macOS의 보호된 디렉터리이며, 이를 갱신하려면 재시작이 필요할 것이라는 가정과 Xcode 도구는 재시작 없이 업...

Read Entire Article




피플앤툴즈 네트워크
🛍 샵