Hacking up an armv7s library

2023-10-22 00:18
文章标签 library hacking armv7s

本文主要是介绍Hacking up an armv7s library,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文链接:http://www.galloway.me.uk/2012/09/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 armv7swhen 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 .ois 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
 * 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_list ap;

  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);
  long size = 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));
  }

  struct mach_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 *outFile = fopen(outName, "w");
  if (outFile == NULL) {
      fatal("Unable to write %s: %s", outName, strerror(errno));
  }
  if (fwrite(buf, 1, size, outFile) != size) {
      fatal("Error trying to write %s: %s", outName, strerror(errno));
  }
  if (fclose(outFile)) {
      fatal("Error trying to close %s: %s", outName, strerror(errno));
  }

  return EXIT_SUCCESS;
}

Copy it, and save it as armv7sconvert.c. Then compile it with:

1
clang -o armv7sconvert armv7sconvert.c

Then add this to ~/bin and add ~/bin to your path by editing ~/.profile and adding:

~/.profile
1
PATH=${PATH}:${HOME}/bin

A script!

Now you’ll want the script which does the hard work of unpacking the library, running the armv7sconvert over the object files and repacking it. Copy and paste the following into a file calledarmv7sconvert.sh also in ~/bin:

armv7sconvert.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash

CONVERT="armv7sconvert"
ARCHIVE="$1"
LIPO="xcrun -sdk iphoneos lipo"
AR="xcrun -sdk iphoneos ar"
TEMP="`mktemp -d -t build`"

cp ${ARCHIVE} ${TEMP}
pushd ${TEMP}
${LIPO} -thin armv7 ${ARCHIVE} -output ${ARCHIVE}.armv7
${AR} -x ${ARCHIVE}.armv7
find . -name '*.o' -exec ${CONVERT} {} {}2 \;
rm *.o
${AR} -r ${ARCHIVE}.armv7s *.o2
rm *.o2
${LIPO} -create -arch armv7s ${ARCHIVE}.armv7s ${ARCHIVE} -output ${ARCHIVE}.new
popd

mv ${TEMP}/${ARCHIVE}.new ${ARCHIVE}

rm -rf ${TEMP}

What this does is a bit magical. I’ll explain later when I get chance. But now put this in your path somewhere and call it armv7sconvert.sh. Then run this command on it:

1
chmod +x armv7sconvert.sh

Convert those libraries!

Now go to where your library is located and do this:

1
armv7sconvert.sh libUAirship-1.2.1.a

That should now have the armv7s portion added to it. To confirm, do:

1
2
3
4
5
6
$ file libUAirship-1.2.1.a
libUAirship-1.2.1.a: Mach-O universal binary with 4 architectures
libUAirship-1.2.1.a (for architecture cputype (12) cpusubtype (11)):    current ar archive random library
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

You should then see armv7 and armv7s (or it might just say CPU type 12 and CPU sub-type 11 – just another name for armv7s).

And the verdict is…

I had an app that I’d done this little hack on for 4 libraries it used. I created just an armv7s binary and had it ready and waiting for my iPhone 5 to test on. I tested it and it worked like a dream. No problems what-so-ever. So, I would say that it’s a success!

这篇关于Hacking up an armv7s library的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/257859

相关文章

PIL Python Imaging Library (PIL)

介绍         把Python的基础知识学习后,尝试一下如何安装、加载、使用非标准库,选择了图像处理模块PIL。         Python Imaging Library (PIL)是PythonWare公司提供的免费的图像处理工具包,是python下的图像处理模块,支持多种格式,并提供强大的图形与图像处理功能。虽然在这个软件包上要实现类似MATLAB中的复杂的图像处理算法并不

Android studio jar包多层嵌套,Add library '__local_aars__:...@jar' to classpath问题

在添加jar包,早app下的build.gradle中的 implementation files('libs/jar包的名字.jar') 修改为 api files('libs/jar包的名字.jar') implementation 单层引用,只引用当前jar包层, api 多层引用,应用当前jar包层,已经jar包引用的jar包层

How can I provide a RGBA png file to OpenAI PHP library

题意:将RGBA PNG文件提供给OpenAI的PHP库 问题背景: I import Orhanerday\OpenAi library to my DALL-E Examples project but when I provide images, I got Invalid input image - format must be in ['RGBA'], got RGB. er

idea报错Cannot compile Groovy files: no Groovy library is defined for module 'xx'之方

0、病因描写 clone 原有的项目(新建的项目一般不会有) IntelliJ IDEA 关联了后缀为groovy的文件但是没有配置Groovy的library。 1、病因一之解决方法 病因:本项目不需要用的Groovy但是关联了groovy了文件 方子:那直接去掉后缀为groovy的关联即可 结果:良好,网上基本都是这种方子 如图:去掉红框部分并apply 2、病

CodeForces 490C Hacking Cypher

题意: 一串数字  从某个地方分开成两个数字  要求前面的数字被A整除  后面的被B整除  求分开的两个数字 思路: 假设我们将原串S这样分成两个数字XY  则X%A==0 Y%B==0 那么我们可以处理从头到i这个位置%A的值为多少  这样很容易判断第一个条件 对于第二个条件我们可以这样理解  S % B == ( X % B * 10^|Y| % B ) + Y % B 如果Y%B

记录Bintray网站发布Library

记录Bintray网站发布Library Bintray其实只是一个网站,他们负责维护JCenter这个库,也就是说JCenter库是托管在BIntray网站上的。但是Bintray不只是只有JCenter库。我们也可以在上面创建自己的账号,生成自己的maven仓库。 现在的android studio默认依赖的就是jcenter库,但是老版本的android studio依赖的是mavenC

Arduino library for proteus 下载 安装 测试

Arduino  library  include: https://drive.google.com/uc?export=download&id=1P4VtXaomJ4lwcGJOZwR_25oeon9Zzvwb 第一步: 也可从我的共享网盘当中下载: 第2步:解压文件:  第3步: copy  lib and idx  到对应的目录: 至于idx索引文件 好像自动生成

Support Library最新8个组件(Material Design设计风格:design support library)

在前不久的谷歌2015 I/O大会上,发布了Android新版本M,貌似从这个版本开始Android不在以数字命名版本了。 在这次的I/O大会上谷歌对Android并没有很大的改变,主要是修改完善之前Android L版本。不过在谷歌推出 Material Design设计风格之后,还是做了很多风格上的兼容,比如v7包的 RecyclerView,CardView,Palette等

struts.xml报这个错误:Can not find the tag library descriptor for /struts-tags`

错误:Can not find the tag library descriptor for “/struts-tags”` 解决办法: 1.有时候<%@taglib prefix=“s” uri="/struts-tags"%>没有任何错误,也依然会报错,解决办法是对文中修改重新报错(例如:删除空格,重新添加空格保存即可),即可。 2.struts.xml需要放在src下如果已经改变路径; 3

鸿蒙(API 12 Beta3版)【使用智能PhotoPicker】Media Library Kit媒体文件管理服务

智能PhotoPicker是基于PhotoPicker的高阶功能,可以从大量图片中根据配置的智能推荐参数,快速筛选出符合条件的图片,并在PhotoPicker中推荐给用户选择。 应用拉起PhotoPicker时,可以配置智能推荐参数。当设备中有满足应用传入的智能推荐参数的图片时,PhotoPicker界面除了展示全量的图片外,还会展示符合条件的推荐图片。 选择特定类型([Recommenda