« More Fun with Quartz Composer | Main | Work »

objc_msgSend, the strange code revealed

I can't take much credit for this. The reason d'etre for the new objc_msgSend code was discovered by Dietmar Planitzer.

Because of the NDA requirement, I can't spell the solution out, but people with access to Tiger will be able to find this hidden feature. Also it's more fun this way. Here goes:

First look at Foundation, you should have a bash shell for the copy/pasting of this stuff:

otool -L /System/Library/Frameworks/Foundation.framework/Foundation | 
tail -3 | 
head -1 | 
awk '{ print $1 }' 
just notice that it's there. You don't need to do anything with it.
Now we extract a new compiler option from the libc library, which helpfully provides it:
NEWFLAG=`strings /usr/lib/libobjc.dylib | 
grep fobjc | 
awk '{ print $6 }' | 
cut -d , -f 1`
echo "NEWFLAG=$NEWFLAG"
Now make yourself a small test file:
cat > x.m << EOF
#import <Foundation/Foundation.h>

main()
{
   NSObject   *p;

   printf( "retain: %lx (%lX %s)\n",      
         (long) [NSObject instanceMethodForSelector:@selector( retain)],      
         (long) @selector( retain),
         (long) @selector( retain));
   printf( "autorelease: %lx (%lX %s)\n", 
        (long) [NSObject instanceMethodForSelector:@selector( autorelease)], 
        (long) @selector( autorelease),
        (char *) @selector( autorelease));
   printf( "release: %lx (%lX %s)\n",     
        (long) [NSObject instanceMethodForSelector:@selector( release)],     
        (long)  @selector( release),
        (char *) @selector( release));
}
EOF
compile and run it.
gcc -o x1 x.m -framework Foundation ; ./x1
There shouldn't be anything unexpected about the output. Now lets use the new compiler option
gcc $NEWFLAG -g -o x2 x.m -framework Foundation ; ./x2
Foundation should print out a dead give away in the start, but also look at the other values that are output.

Finally to round it off, examine with gdb the instructions of interest:

cat > gdb.batch << EOF
set prompt 
fb objc_msgSend
run
x/3i \$pc+4
quit
EOF

( cat gdb.batch | gdb -q x2 | tail -3) 2> /dev/null
Ok you need to know a little PPC assembler, but it shouldn't be too difficult to understand what an XOR together with a compare do.
Hint: $r4 is usually the selector address, and r11 is a scratch register.

Comments (2)

The Tiger:

Note that the mentioned option only works with gcc 3.3 (which might be the default compiler on Tiger ;-).
If you switched to gcc 3.5 to have the latest and greatest, you need to compile using gcc-3.3 instead of just gcc.

nbrmkkssltctmqimzyfsyweuxmqxvvdemxpabtg link http://rmxdyz.ubwqva.com

About

This page contains a single entry from the blog posted on July 26, 2004 2:43 AM.

The previous post in this blog was More Fun with Quartz Composer.

The next post in this blog is Work.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.34