Hacking up an armv7s library
NOTE: Please take care with this. I obviously cannot test if this will actually work on a new iPhone 5 device! I provide no warranty if you submit having used this and it doesn’t actually work on the new device. Please think twice before submitting an app which you have used this method to create. You don’t have to submit an armv7s binary. Just set your “Architectures” build setting to armv7 only and submit the resulting binary.
UPDATE: It worked! I tested an app that I’d used this method to build an armv7s slice with. It ran fine on my iPhone 5 :-D.
Well the iPhone 5 has been announced and it just so happens that the architecture it uses is what they’re calling armv7s. This brings in yet another architecture to the mix alongside armv6 and armv7. And I bet you are wondering why you’re getting linker errors when building for armv7s when using external libraries. It’s because those external libraries do not have armv7s versions!
If you run file on the library then you’ll see that there is no armv7s version. For example:
|
1 2 3 4 5 |
$ file libUAirship-1.2.1.a libUAirship-1.2.1.a: Mach-O universal binary with 3 architectures libUAirship-1.2.1.a (for architecture armv7): current ar archive random library libUAirship-1.2.1.a (for architecture armv6): current ar archive random library libUAirship-1.2.1.a (for architecture i386): current ar archive random library |
So what can you do? You could wait for the library to be updated, or you could just follow these steps…
So what’s the deal?
Well, the problem is that when the linker does its merry business linking together all your object files, it is told what architecture to link for. Each of your libraries’ .a files will most likely be what are called “fat” meaning they have more than one architecture in them. But the linker won’t be able to find the armv7s version since it doesn’t exist in there.
But, we know that armv7s is a superset of armv7 (it’s just got a new version of the floating point unit so only adds new instructions). So what we can do is to copy the armv7 part of the library and add it again but tell it that it’s for armv7s. That sounds simple, but there’s more to it than that.
Inside each architecture’s portion of the fat library is something called an object file archive. This contains a collection of .o files that were combined together to form the library. Inside each .o is the code for each method. The linker uses these to build the final app binary, picking all the methods it needs to create the app. The problem is that these .o files also have a header to say what architecture they’re for.
Inside this header (called a Mach-O header) is a field for the CPU type and the CPU subtype. ARM is CPU type 12, armv7 is CPU subtype 9 and armv7s is CPU subtype 11. So, all we need to do is toggle all the 9s to 11s, right? Yup! But that’s easier said than done.
My solution is a script that strips out the armv7 portion of the fat library and then unpacks the archive into its constituent .o files. Then I wrote a little C program to do the 9 => 11 toggling which is run on each of the .o files. Then finally the new .o files are packaged up into a new portion which is re-added to the fat library.
Simple!
So, if you’re ready to get going then read on…
Do you need this to submit an app?
No.
Do not use this unless you really understand what you’re doing. You do not need to submit with an armv7s binary. Just set your Architectures build setting to armv7 only and submit the resulting binary.
A program you’ll need
The first thing you’ll need is the following program written in C:
armv7sconvert.c
|
/* * armv7sconvert <infile> <outfile> * Switches CPU subsystem type to armv7s * * By Matt Galloway - http://www.galloway.me.uk * * Based on g3spot.c from http://redbutton.sourceforge.net (c) Simon Kilvington, 2009 */ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <errno.h> #include <mach-o/loader.h> void fatal(char *msg, ...); void fatal(char *msg, ...) { va_listap; va_start(ap, msg); vfprintf(stderr, msg, ap); fprintf(stderr, "\n"); va_end(ap); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { if (argc != 3) { fatal("Syntax: %s <in_file> <out_file>", argv[0]); } char *inName = argv[1]; char *outName = argv[2]; FILE *inFile = fopen(inName, "r"); if (inFile == NULL) { fatal("Unable to read %s: %s", inName, strerror(errno)); } /* find out how big it is */ fseek(inFile, 0, SEEK_END); longsize = ftell(inFile); rewind(inFile); printf("%s: %lu bytes\n", inName, size); /* read it all into memory */ unsigned char *buf = malloc(size); if (buf == NULL) { fatal("Out of memory"); } if (fread(buf, 1, size, inFile) != size) { fatal("Error trying to read %s: %s", inName, strerror(errno)); } if (fclose(inFile)) { fatal("Error trying to close %s: %s", inName, strerror(errno)); } structmach_header *mach_hdr = (struct mach_header *) (buf); printf("Mach magic: 0x%08x\n", mach_hdr->magic); if (mach_hdr->magic != MH_MAGIC) { fatal("Wrong magic number (expecting 0x%08x)", MH_MAGIC); } printf("CPU type: %d\n", ntohl(mach_hdr->cputype)); printf("CPU sub-type: %d\n", ntohl(mach_hdr->cpusubtype)); printf("*** Changing to CPU sub-type 11\n"); mach_hdr->cpusubtype = 11; printf("Saving as %s\n", outName); FILE * |
Hacking up an armv7s library的更多相关文章
- Build FFmpeg for iOS
FFmpeg Build Instructions MAC 10.8 or better Copy ffmpeg-2.0.tar.bz2 (https://ffmpeg.org/releases/ff ...
- iOS - Library 库
1.动态库 & 静态库 什么是库: 库是程序代码的集合,是共享程序代码的一种方式.根据源代码的公开情况,库可以分为 2 种类型: 开源库: 公开源代码,能看到具体实现. 比如 SDWebIma ...
- iOS开发之Xcode 6更新默认不支持armv7s架构
最近一次的Xcode 6更新默认不再支持arm7s架构,究竟是要废除不用呢还是仅仅只是一个疏忽? 目前的Xcode 6配置里定义${ARCHS_STANDARD}为armv7, arm64,当然这个定 ...
- 转:Build Your First JavaScript Library
http://net.tutsplus.com/tutorials/javascript-ajax/build-your-first-javascript-library/ Step 1: Creat ...
- xcode5.1 armv7 armv7s arm64 类型, 区分, 概念等
官方: https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaTouch64BitGuide/In ...
- [转]Hacking the iOS Spotlight
原文:http://theiostream.tumblr.com/post/36905860826/hacking-the-ios-spotlight 原文:http://theiostream.tu ...
- iOS.Library.Architecture
在用file查看library的architechture时有以下输出: $ file WebPWebP: Mach-O universal binary with 3 architecturesWe ...
- Android Mokoid Open Source Project hacking
/***************************************************************************** * Android Mokoid Open ...
- Qt QML referenceexamples attached Demo hacking
/********************************************************************************************* * Qt ...
随机推荐
- 双行表头DatagridView的简单实现
DatagridView默认不支持多行表头的实现,一些第三方的控件,比如Spread就可以,因此要实现这个功能,只能自己想办法了.介绍两种思路:1,用重写DataGridView的Paint等方法,可 ...
- CentOS-6.4-minimal版中安装MongoDB-x86_64-3.0.2
完整版见https://jadyer.github.io/2015/06/03/centos-install-mongodb/ /** * CentOS-6.4-minimal版中安装MongoDB- ...
- 【转】 web 测试使用的chrome插件
1.二维码插件 https://chrome.google.com/webstore/detail/%E4%BA%8C%E7%BB%B4%E7%A0%81qr%E7%A0%81%E7%94%9F%E6 ...
- 【转】【Java/Android】Intent的简介以及属性的详解
一.Intent的介绍 Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作.动作涉及数据.附加数据进行描述 ...
- 第二百九十三,Memcached缓存
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度.Memcached ...
- CentOS学习之常用命令ls
命令格式与目录处理命令ls 命令格式: 命令[-选项][参数] 例如: ls -la /etc 说明: 1)个别命令使用不遵循此格式 2)当多个选项时,可以写在一起 3)简化选项与完整选项 -a ...
- 关于对afx_msg的解释-----来源百度百科
1AFX前缀 Afx前缀是微软MFC一个小组的名称简写,并没有别的意义. MFC的很多代码,包括全局函数名.宏.头文件名都使用了"Afx". Afx*.h是一组MFC的核心头文件, ...
- 【Java面试题】54 去掉一个Vector集合中重复的元素
在Java中去掉一个 Vector 集合中重复的元素 1)通过Vector.contains()方法判断是否包含该元素,如果没有包含就添加到新的集合当中,适用于数据较小的情况下. import jav ...
- Nginx的启动与停止,重启
1.先确定nginx所在的文件位置 如: 重启 1.验证nginx配置文件是否正确 方法一:进入nginx安装目录sbin下,输入命令./nginx -t 2.重启Nginx服务 方法一:进入ngin ...
- sudo 之后 unable to resolve host的问题解决办法
gedit /etc/hosts #127.0.0.1 localhost #127.0.0.1 Masterback或者其他 把后面的Masterback 或者其他改成新的主机名,应该是最近修改过主 ...