How does __TEXT encode address in __DATA?

Session 406 of WWDC 2016 is great! It explains clearly how the iOS application is settled in memory before running, with ASLR and code-signing. The key point is the indirect pointers in __DATA avoid patching the __TEXT, which is required by ASLR but impossible because of code-signing.

There is this one point confusing me, __TEXT still needs to encode address pointing to __DATA segment, though __DATA page address is randomised now.

The answer is quite simple indeed: the offset between __TEXT and __DATA is not changing between runs, the offset is encoded in __TEXT.

In 64bit Mac OS X, it implements as:

movl 0xae(%rip), %edi

iOS ARMv7 generates:

 0000bf9c f240037c movw r3, #0x7c
 0000bfa0 f2c00300 movt r3, #0x0
 0000bfa4     447b add r3, pc  ;$pc(0xbfa8) + 0x7c -> global_var in __DATA

iOS ARMv8 (64) generates:

 0000000100007f2c adrp x8, 1 ; 0x100007000 + 4k*1
 0000000100007f30 add x8, x8, #64 ; +0x40 -> 0x100008040 
                                  ;-> global_var in __DATA

* adrp xd label  mask out lower 12bits of pc then add label<<12 to generate an address.

curl certificate issue

Mac OS X El Capitan, MacPorts, it goes well for so long. And one day, git complains:

 curl: (77) error setting certificate verify locations:
 CAfile: /opt/local/share/curl/curl-ca-bundle.crt
 CApath: none

Easy, update git config system to use ca-bundle.crt found by searching.

 [http]
 sslcainfo = /opt/local/share/apps/kssl/ca-bundle.crt

Problem sovled.

But, curl itself still complains:

curl --cacert /opt/local/share/apps/kssl/ca-bundle.crt ...

Problem solved again.

But, it is hard to bear the burden of adding such a long argument!

Why did curl ask for the damn file not existed?

curl-config --ca
/opt/local/share/curl/curl-ca-bundle.crt

OK, it seems that’s the value coded in the source. Fortunately, the command will check CURL_CA_BUNDLE environment variable.
Patch the ~/.profile (or .bashrc for bash, .zshrc for zsh…)

CURL_CA_BUNDLE=/opt/local/share/apps/kssl/ca-bundle.crt

The problem is really resolved.

Haunted by Apple Dev Account

I used this Apple ID without iDP enrollment to record a tutorial for a while, it stop working suddenly. Fortunately, I logged into the dev center soon and got award the developer account is hanged for unknown reason. After complaining with Apple guys, the account is restored.

But then, “The identity used to sign the executable is no longer valid.” started.

Well, I had never met this error before and I just reset this test device today for troubleshooting something. Maybe, there is some bug when restoring. But devices shows those provision files are all restored. Well, maybe the account restoring caused something weird? Let me try to reset signing id for iOS program, but no luck. And to delete apple id and re-add it didn’t make it, too.

So I opened Keychain Access app to take a look at certificates, well, the developer certificate of this id is marked as revoked. Good, got you!

But, this certificate refused to be deleted! Tried at least three times, it disappeared immediately after delete key pressed and appear back in 1 second! How mad!

When I got calm down, I guess there is something locked that certificate. So logout and re-login, woo la la, it disappeared. Problem solved.

calabash-ios failed with “No frameworks Group found. Aborting.”

I have quick looked many BDD tools and calabash looks right. It is a quite straightforward solution: integrate a http server into iOS project and bridge actions of cucumber step and iOS runtime using accessibility facility. Because predefined steps are quite complete, it is possible just write feature specs in  Gherkin without touching ruby code.

But it is always so struggling to ramp up a new open source technology.  The first try just failed, even with simplest environment, with a brand new simple view project.

Error message explains itself, I need create this Frameworks group in project to let script continue running. Or it just aborted, no target duplicated, no integration.

The interesting part is, it is an issue known for over 1 year: https://github.com/calabash/calabash-ios/issues/533

The struggling with CocoaPods seems got ending

CocoaPods is really cool tool to incorporate 3rd party open source library,  it is even cooler with the app built-in framework support added in recent (since 0.36) and  dedup-ing of targets along with simpler name in 0.38.

Naturally, I’m considering to use CocoaPods as a primary tool to organize the project, which means private repo and destruct the project into pods.

At beginning, I made my mind up like:

屏幕快照 2015-09-19 下午1.14.32

But soon I got a lot issue to struggle with, thus the working environment is involuted to:

CocoaPods repo setup with struggling env

Yep, I had to draw this to clear my mind.

One of those modules  come with CoreData model (.xcdatamodeld) and the model just didn’t appear after pod install. And lately I get it, the bundle folder itself is better to be added as a source file, but I still need to add it back to project, or it will not be compiled. And, I can’t.

After quite a lot struggling, I believe the answer can only dig out from its source code. CocoaPod is written in Ruby, which I haven’t learn yet, which means I have to learn Ruby firstly, which is why I didn’t read its code at first time.

Fortunately, Ruby is a simple language, it took about half day to learn the syntax. Thanks a lot to a good tutorial (http://ruby-doc.com/docs/ProgrammingRuby/) and a great quick reference (http://www.zenspider.com/Languages/Ruby/QuickRef.html). Here is my study notes:

Ruby Language

— Oh, no, I should have read (http://edwinmeyer.com/Release_Integrated_RHG_09_10_2008/) at first moment, it is way far efficient written for me.

Reading source code of CocoaPods is a little confusing, I cannot find the entry point until reading its CLAide sub project. Other parts are quite readable, soon I located the file_accessor using Dir glob to list files survived cleaning, which doesn’t understand specific folder is a bundle and will list its contents, those contents obviously are not recognized as source file. Considering I haven’t read all the source code and it is quite possible to have side effects to patch glob-ing part, I decided to insert the patch in adding source reference part.

So that a quick and a little dirty patch is created and PR is submitted. If you happen having same idea by now, try my fork (https://github.com/pinxue/CocoaPods).  After cloned, you may install it by:

gem build ./cocopods.gemspec
sudo gem install --local ./cocoapods-0.39.0.beta.4.gem

BTW, CocoaPods includes 1645 spec requirements (unit tests) and 1650 integration test requirements, really surprised me.

 

 

Update ordered ToMany relationship in CoreData

It is a well known bug, when a relationship is checked with ordered, some Dynamically-Generated accessor Methods (add*) will throw exception, some others (insert*) are just not generated.

I ran into this issue again. Yeah, I met it about 1 year ago. I’m one hundred percent sure it is a bug. And a patch is created by someone long ago https://github.com/CFKevinRef/KCOrderedAccessorFix

But, it seems Apple guys had decided not to fix it. The radar item are closed now!

Fortunately,  -mutableOrderedSetValueForKey: method mentioned by document always works. I guess it is the time for Apple to update their document (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdUsingMOs.html#//apple_ref/doc/uid/TP40001803-SW3) :

Typically, however, you do not want to set an entire relationship, instead you want to add or remove a single element at a time. To do this, you should usemutableSetValueForKey: or one of the automatically-generated relationship mutator methods (see Dynamically-Generated Accessor Methods): unless it is order!

Yet another trap of CocoaPods

Creating a pod in my private repo, it worked fine till I made some uncertain changes. Now running ‘pod install’ in Example will complain:

Resolving dependencies of `Podfile`
[!] Unable to satisfy the following requirements:

– `DataModel (from `../`)` required by `Podfile`
– `DataModel (from `../`)` required by `Podfile`
– `DataModel (= 0.1.0)` required by `Podfile.lock`

And eventually, I figured it out, it is caused by iOS platform version which I just modified to reflect truth of framework in bundle requires 8.0.

  s.platform     = :ios, ‘8.0’

It works like a charm when the version is 7.0 or 7.1 . How could it be so weird?! Well, it is not weird indeed, I just didn’t give the iOS version in Podspec file. It will work with right iOS platform version, like:

platform :ios, ‘8.0’

The error information didn’t mention platform version, it should have saved my day!

Xcode7 的两个小坑

Xcode7 还在 beta,时不时崩一下什么的倒也是预料之中的事,没料到的是之前用着好好的,今天升完 El Capitan 之后,模拟器居然不见了,设备倒是在 schema 栏右边里能看到,不过注明不能用。

看了看系统日志是 Simulator 服务不停的崩。查了查,有人已经分析过了:
http://stackoverflow.com/questions/31551480/xcode-7-beta-4-ios-simulators-missing-and-not-installable
简单点说,去把7.x / 8.x 的 simulator 映像文件都移走或者干脆删除,就好了。

另外,beta4 会报怨 CoreData 模型文件没有指定版本号,这新建的文件哪来的版本好,在 Editor 里给建了一个版本终于不 warning 了。