이 아니고이 아닌 Mach-O 개체 파일을 생성하는 가장 쉬운 방법은 플래그가 설정되어있어서 링커 (-dead_strip
)는 나중에 텍스트 섹션을 조각으로 잘라내어 조각을 추측하려고하지 않습니다. 익숙한?dead_stripped 할 수없는 객체 파일을 만드는 방법은 무엇입니까?
먼저 llvm/gcc (4.2.1)에 명령 줄 옵션을 사용하여 .subsections_via_symbols
을 방출하지 않도록하거나 명령 줄 도구를 사용하여 기존 개체 파일에서 플래그를 제거합니다 .
(Mach-O 사양을 기반으로하는 도구를 직접 작성하는 것은 옵션이지만 가능한 경우 하드 드라이브를 다시 만들지는 않을 것입니다.)
플랫폼 : iOS, XCode 4.5로 OSX에서 크로스 컴파일.
배경 : 우리는 다른 회사 앱에 구축 정적 라이브러리를 제공하고 있습니다. 라이브러리에 문제가 발생하면 스택 추적 및 다른 중요한 정보 (우리가 운이 좋다면)를 분석하여 추후에 분석 할 수있는 충돌 보고서를 생성합니다. 일반적으로 배포 된 앱에는 디버그 정보가 제거되어 스택 추적을 해석하는 것이 문제입니다. 우리가 직접 응용 프로그램을 만들고 있다면 스트립하기 전에 DWARF 디버그 데이터를 저장하고이를 사용하여 충돌 보고서의 주소를 디코딩합니다. 그러나 우리는 앱 제작자가 연결 단계에서 얻은 데이터를 제공하는 것에 의존 할 수 없습니다.
대신에 충돌 보고서에 선택한 함수의 런타임 주소가 포함되도록하는 것입니다. 이로부터 우리는 링커 맵의 주소와 충돌 보고서의 주소 사이의 오프셋을 추론 할 수 있습니다. 우리는 전체 라이브러리를 점진적으로 하나의 .o 파일에 연결하기 전에 .a 파일에 넣습니다. 앱이 결국 링크 될 때 사용되지 않는 기능을 제거하지 않아도되는 일은별로 없을 것입니다. 불행히도 작은 라이브러리에 때때로 사용되지 않는 코드 (주요 기능의 대체 API 진입 점, Google 오류 코드 해석을위한 작은 도우미 기능 등)가 있으며 개발자가 -dead_strip
과 연결하는 경우, 최종 애플리케이션의 상대 오프셋이 점증 적 링크 작업의 링커 맵과 다르다는 충돌 보고서의 주소 재구성을 방해합니다.
모든 앱 개발자에게 빌드 프로세스에서 불필요한 코드 제거 기능을 사용 중지하도록 요청할 수는 없으므로 .o를 '죽지 않는 코드'로 표시하고 최종 앱을 사용할 수 있다면 더 나은 방법이라고 생각됩니다. 그것을 존경하는 것.