I am currently working on famous System Programming problem, "Bomb lab" phase2. When I disassembled phase_2 with gdb, code looks like this...
Phase_2
0x00005555555555cb <+0>: endbr64
0x00005555555555cf <+4>: push %rbp
0x00005555555555d0 <+5>: push %rbx
0x00005555555555d1 <+6>: sub $0x28,%rsp
0x00005555555555d5 <+10>: mov %fs:0x28,%rax
0x00005555555555de <+19>: mov %rax,0x18(%rsp)
0x00005555555555e3 <+24>: xor %eax,%eax
0x00005555555555e5 <+26>: mov %rsp,%rsi
0x00005555555555e8 <+29>: callq 0x555555555bd5 <read_six_numbers>
0x00005555555555ed <+34>: cmpl $0x0,(%rsp)
0x00005555555555f1 <+38>: js 0x5555555555fd <phase_2+50>
0x00005555555555f3 <+40>: mov %rsp,%rbp
0x00005555555555f6 <+43>: mov $0x1,%ebx
0x00005555555555fb <+48>: jmp 0x555555555615 <phase_2+74>
0x00005555555555fd <+50>: callq 0x555555555ba9 <explode_bomb>
0x0000555555555602 <+55>: jmp 0x5555555555f3 <phase_2+40>
0x0000555555555604 <+57>: callq 0x555555555ba9 <explode_bomb>
0x0000555555555609 <+62>: add $0x1,%ebx
0x000055555555560c <+65>: add $0x4,%rbp
0x0000555555555610 <+69>: cmp $0x6,%ebx
0x0000555555555613 <+72>: je 0x555555555621 <phase_2+86>
0x0000555555555615 <+74>: mov %ebx,%eax
0x0000555555555617 <+76>: add 0x0(%rbp),%eax
0x000055555555561a <+79>: cmp %eax,0x4(%rbp)
0x000055555555561d <+82>: je 0x555555555609 <phase_2+62>
0x000055555555561f <+84>: jmp 0x555555555604 <phase_2+57>
0x0000555555555621 <+86>: mov 0x18(%rsp),%rax
0x0000555555555626 <+91>: xor %fs:0x28,%rax
0x000055555555562f <+100>: jne 0x555555555638 <phase_2+109>
0x0000555555555631 <+102>: add $0x28,%rsp
0x0000555555555635 <+106>: pop %rbx
0x0000555555555636 <+107>: pop %rbp
0x0000555555555637 <+108>: retq
0x0000555555555638 <+109>: callq 0x555555555220 <__stack_chk_fail#plt>
I guess that in line <+62>, %ebx means index, and increments the value until the value is 6 (by line <+69>). But I don't really understand lines such as
0x000055555555560c <+65>: add $0x4,%rbp
or
0x0000555555555615 <+74>: mov %ebx,%eax
0x0000555555555617 <+76>: add 0x0(%rbp),%eax
0x000055555555561a <+79>: cmp %eax,0x4(%rbp)
I guess it is probably related to features of sequence that I have to find, but I don't understand why values such as 0x4(%rbp)is compared with %eax etc... Can someone explain?
clang allows the following loop syntax:
for (...) #autorelease { ... }
while (...) #autorelease { ... }
do #autorelease { ... } while (...);
I haven't found any documentation on that syntax so far (Apple doesn't use this syntax in their guides, at least no in the guides introducing the #autorelease construct), but is it reasonable to assume that the three statement above are equivalent to the three statements below:
for (...) { #autorelease { ... } }
while (...) { #autorelease { ... } }
do { #autorelease { ... } } while (...);
Since that is what I would expect them to be (going by standard C syntax rules), yet I'm not entirely sure if that's really the case. It could also be some "special syntax", where the autorelease pool is not renewed for every loop iteration.
The reason that the first syntax example works is clear when you consider that any conditional statement can omit the { ... } block, resulting in only the following statement being executed.
For example:
if (something == YES)
NSLog(#"Something is yes");
is equivalent to
if (something == YES)
{
NSLog(#"Something is yes");
}
The #autoreleasepool { ... } block is simply the next statement following the conditional.
Personally I use the second syntax as it's less error-prone when making changes, and I find it easier to read. Imagine that when you add a statement between the conditional and the #autoreleasepool { ... } block, the result is considerably different from the original. See this naive example...
int i = 1;
while (i <= 10)
#autoreleasepool
{
NSLog(#"Iteration %d", i);
++i;
}
Will output "Iteration 1" through "Iteration 10". However:
int i = 1;
int total = 0;
while (i <= 10)
total += i;
#autoreleasepool
{
NSLog(#"Iteration %d", i);
++i;
}
Will actually cause an infinite loop because the ++i statement is never reached as it is syntactically equivalent to:
int i = 1;
int total = 0;
while (i <= 10)
{
total += i;
}
#autoreleasepool
{
NSLog(#"Iteration %d", i);
++i;
}
Both syntax are same
-(void)aFunc
{
int i=0;
for(;i<5;)
#autoreleasepool {
++i;
}
}
-(void)bFunc
{
int i=0;
for(;i<5;)
{
#autoreleasepool {
++i;
}
}
}
Assembly code
"-[AppDelegate aFunc]": ## #"\01-[AppDelegate aFunc]"
.cfi_startproc
Lfunc_begin0:
.loc 1 12 0 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:12:0
## BB#0:
pushq %rbp
Ltmp2:
.cfi_def_cfa_offset 16
Ltmp3:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp4:
.cfi_def_cfa_register %rbp
subq $32, %rsp
movq %rdi, -8(%rbp)
movq %rsi, -16(%rbp)
.loc 1 14 12 prologue_end ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:14:12
Ltmp5:
movl $0, -20(%rbp)
LBB0_1: ## =>This Inner Loop Header: Depth=1
.loc 1 15 5 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:15:5
Ltmp6:
cmpl $5, -20(%rbp)
jge LBB0_3
## BB#2: ## in Loop: Header=BB0_1 Depth=1
.loc 1 16 26 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:16:26
Ltmp7:
callq _objc_autoreleasePoolPush
.loc 1 17 13 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:17:13
movl -20(%rbp), %ecx
addl $1, %ecx
movl %ecx, -20(%rbp)
.loc 1 18 9 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:18:9
movq %rax, %rdi
callq _objc_autoreleasePoolPop
jmp LBB0_1
Ltmp8:
LBB0_3:
.loc 1 19 1 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:19:1
addq $32, %rsp
popq %rbp
ret
Ltmp9:
Lfunc_end0:
.file 2 "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObject.h"
.file 3 "/Users/Parag/Desktop/Test/Test/AppDelegate.h"
.cfi_endproc
.align 4, 0x90
"-[AppDelegate bFunc]": ## #"\01-[AppDelegate bFunc]"
.cfi_startproc
Lfunc_begin1:
.loc 1 20 0 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:20:0
## BB#0:
pushq %rbp
Ltmp12:
.cfi_def_cfa_offset 16
Ltmp13:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp14:
.cfi_def_cfa_register %rbp
subq $32, %rsp
movq %rdi, -8(%rbp)
movq %rsi, -16(%rbp)
.loc 1 22 12 prologue_end ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:22:12
Ltmp15:
movl $0, -20(%rbp)
LBB1_1: ## =>This Inner Loop Header: Depth=1
.loc 1 23 5 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:23:5
Ltmp16:
cmpl $5, -20(%rbp)
jge LBB1_3
## BB#2: ## in Loop: Header=BB1_1 Depth=1
.loc 1 25 26 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:25:26
Ltmp17:
callq _objc_autoreleasePoolPush
.loc 1 26 14 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:26:14
movl -20(%rbp), %ecx
addl $1, %ecx
movl %ecx, -20(%rbp)
.loc 1 27 9 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:27:9
movq %rax, %rdi
callq _objc_autoreleasePoolPop
Ltmp18:
.loc 1 28 5 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:28:5
jmp LBB1_1
Ltmp19:
LBB1_3:
.loc 1 29 1 ## /Users/Parag/Desktop/Test/Test/AppDelegate.m:29:1
addq $32, %rsp
popq %rbp
ret
Ltmp20:
Lfunc_end1:
I have tried the following code:
#interface Foo : NSObject
#end
#implementation Foo
- (void) dealloc
{
NSLog(#"Deallocating %#.", self);
[super dealloc];
}
#end
for (;;) #autoreleasepool {
[[[Foo alloc] init] autorelease];
sleep(1);
}
The console starts to fill with the deallocated Foo instances, so the syntax appears to work as expected.
This is just the normal C syntax for blocks and statements. When if, else, for, while, etc. do not have braces, they take the following statement, which could be a compound statement.
For example, you can do:
for (...) if (...) { ... }
if (...) while (...) { ... }
and so on... #autoreleasepool blocks are no different.
i have a problem when compile objective-c source code on windows platform.
of course compile objective-c source code on windows platform , we usually using gnustep environment(gcc objecitve-c compiler . gnustep libojc dynamic library . gnustep foundation framework ... and so on).
but i want a clean environment try compiler objective-c , and use a different libobjc library.
since mac os x 10.6 . apple move macosx system to x86 platform(no ppc support any more) , AND REWRITE system application by cocoa tech.include iTunes.
and iTunes have windows version.
by searching system folders after install iTunes.i found any support dll file in:
C:\Program Files (x86)\Common Files\Apple\Apple Application Support
by the way , my system is windows 7 x86_64.
i found it has:
ApplePushService.dll
AppleVersions.dll
APSDaemon_main.dll
ASL.dll
AVFoundationCF.dll
CFNetwork.dll
CoreAudioToolbox.dll
CoreFoundation.dll
CoreGraphics.dll
CoreMedia.dll
CoreText.dll
CoreVideo.dll
Foundation.dll
icudt46.dll
icuin40.dll
icuuc40.dll
JavaScriptCore.dll
libcache.dll
libdispatch.dll
libicuin.dll
libicuuc.dll
libtidy.dll
libxml2.dll
libxslt.dll
MediaToolbox.dll
objc.dll
pthreadVC2.dll
QTMovieWin.dll
QuartzCore.dll
SQLite3.dll
VideoToolbox.dll
WebKit.dll
WebKitQuartzCoreAdditions.dll
YSCrashDump.dll
YSUtilities.dll
zlib1.dll
look like , apple implement these low level framework to windows platform.
CFNetwork.framework -> CFNetwork.dll
CoreGraphics.framework -> CoreGraphics.dll
Foundation.framework -> Foundation.dll
libobjc.a.dylib -> objc.dll
WebKit.framework -> WebKit.dll
so , i think using apple's libobjc release version is better(iTunes is running well).the others library file is useful too.
i want build a learnning environment for objective-c beginner people(my class mates and i).
so i copy objc.dll and rename it to libobjc.dll
using mingw tool "pexports" export libobjc.dll 's def to libobjc.def then using visual studio command tool "lib.exe" convert .def file to libobjc.lib.
then i download
mingw64's x86(32 bit) compilers dng precompiled package.
mingw64's clang+llvm(32 bit) compilers dng precompiled package.
mingw64's msys environment precompiled package.
install these 3 package to system.
then copy libobjc.dll,libobjc.lib to /lib (on windows platform , .a and .lib using same bin format).
then i wrote a sample objective-c source code.code is here:
file:test.m
#import <stdio.h>
#interface Foo {
int count;
}
+ (void)fooWithBar;
#end
#implementation Foo
+ (void)fooWithBar {
printf("abc");
}
#end
int main(){
[Foo fooWithBar];
return 0;
}
simply compile it:
clang test.m
error happen, then using -v options show detail:
clang version 3.1 (branches/release_31)
Target: i686-w64-mingw32
Thread model: posix
"c:/mingw64w32/bin/clang.exe" -cc1 -triple i686-w64-mingw32 -S -disable-free -main-file-name test.m -mrelocation-model static -mdisable-fp-elim -mconstructor-aliases -target-cpu pentium4 -target-linker-version 2.20.51.0.2 -momit-leaf-frame-pointer -v -resource-dir "c:/mingw64w32/bin\\..\\lib\\clang\\3.1" -fmodule-cache-path "C:/Users/Joe/AppData/Local/Temp\\clang-module-cache" -fno-dwarf-directory-asm -fdebug-compilation-dir C:/MINGW64-X86-MSYS-20111123/home/Joe -ferror-limit 19 -fmessage-length 0 -mstackrealign -fno-use-cxa-atexit -fgnu-runtime -fobjc-runtime-has-arc -fobjc-runtime-has-weak -fobjc-fragile-abi -fobjc-exceptions -fdiagnostics-show-option -o C:/Users/Joe/AppData/Local/Temp/test-709512.s -x objective-c test.m
clang -cc1 version 3.1 based upon LLVM 3.1 default target i686-w64-mingw32
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "c:/mingw64w32/bin/../lib/clang/3.1/../../../x86_64-w64-mingw32/include"
ignoring nonexistent directory "/mingw/include"
ignoring nonexistent directory "c:/mingw/include"
ignoring nonexistent directory "/usr/include"
#include "..." search starts here:
#include <...> search starts here:
c:/mingw64w32/bin/../lib/clang/3.1/include
c:/mingw64w32/bin/../lib/clang/3.1/../../../i686-w64-mingw32/include
c:/mingw64w32/bin/../lib/clang/3.1/../../../include
End of search list.
"c:/mingw64w32/bin/i686-w64-mingw32-gcc.exe" -v -c -o C:/Users/Joe/AppData/Local/Temp/test-709513.o -x assembler C:/Users/Joe/AppData/Local/Temp/test-709512.s
Using built-in specs.
COLLECT_GCC=c:/mingw64w32/bin/i686-w64-mingw32-gcc.exe
Target: i686-w64-mingw32
Configured with: /home/drangon/work/mingw-w64-dgn_32/source/gcc/configure --host=i686-w64-mingw32 --target=i686-w64-mingw32 --disable-nls --enable-languages=c,c++,objc,obj-c++ --with-gmp=/home/drangon/work/mingw-w64-dgn_32/build/for_target --enable-twoprocess --disable-libstdcxx-pch --disable-win32-registry --prefix=/home/drangon/work/mingw-w64-dgn_32/target --with-sysroot=/home/drangon/work/mingw-w64-dgn_32/target
Thread model: win32
gcc version 4.7.2 20120823 (prerelease) (GCC)
COLLECT_GCC_OPTIONS='-v' '-c' '-o' 'C:/Users/Joe/AppData/Local/Temp/test-709513.o' '-mtune=generic' '-march=pentiumpro'
c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/bin/as.exe -v -o C:/Users/Joe/AppData/Local/Temp/test-709513.o C:/Users/Joe/AppData/Local/Temp/test-709512.s
GNU assembler version 2.23.51 (i686-w64-mingw32) using BFD version (GNU Binutils) 2.23.51.20120823
COMPILER_PATH=c:/mingw64w32/bin/../libexec/gcc/i686-w64-mingw32/4.7.2/;c:/mingw64w32/bin/../libexec/gcc/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/bin/
LIBRARY_PATH=c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/;c:/mingw64w32/bin/../lib/gcc/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/lib/../lib/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../lib/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/lib/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../
COLLECT_GCC_OPTIONS='-v' '-c' '-o' 'C:/Users/Joe/AppData/Local/Temp/test-709513.o' '-mtune=generic' '-march=pentiumpro'
"c:/mingw64w32/bin/i686-w64-mingw32-gcc.exe" -v -o a.out C:/Users/Joe/AppData/Local/Temp/test-709513.o
Using built-in specs.
COLLECT_GCC=c:/mingw64w32/bin/i686-w64-mingw32-gcc.exe
COLLECT_LTO_WRAPPER=c:/mingw64w32/bin/../libexec/gcc/i686-w64-mingw32/4.7.2/lto-wrapper.exe
Target: i686-w64-mingw32
Configured with: /home/drangon/work/mingw-w64-dgn_32/source/gcc/configure --host=i686-w64-mingw32 --target=i686-w64-mingw32 --disable-nls --enable-languages=c,c++,objc,obj-c++ --with-gmp=/home/drangon/work/mingw-w64-dgn_32/build/for_target --enable-twoprocess --disable-libstdcxx-pch --disable-win32-registry --prefix=/home/drangon/work/mingw-w64-dgn_32/target --with-sysroot=/home/drangon/work/mingw-w64-dgn_32/target
Thread model: win32
gcc version 4.7.2 20120823 (prerelease) (GCC)
COMPILER_PATH=c:/mingw64w32/bin/../libexec/gcc/i686-w64-mingw32/4.7.2/;c:/mingw64w32/bin/../libexec/gcc/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/bin/
LIBRARY_PATH=c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/;c:/mingw64w32/bin/../lib/gcc/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/lib/../lib/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../lib/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/lib/;c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../
COLLECT_GCC_OPTIONS='-v' '-o' 'a.out' '-mtune=generic' '-march=pentiumpro'
c:/mingw64w32/bin/../libexec/gcc/i686-w64-mingw32/4.7.2/collect2.exe --sysroot=/home/drangon/work/mingw-w64-dgn_32/target -m i386pe -Bdynamic -o a.out c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/lib/../lib/crt2.o c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/crtbegin.o -Lc:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2 -Lc:/mingw64w32/bin/../lib/gcc -Lc:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/lib/../lib -Lc:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../lib -Lc:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/lib -Lc:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../.. C:/Users/Joe/AppData/Local/Temp/test-709513.o -lmingw32 -lgcc_eh -lgcc -lmoldname -lmingwex -lmsvcrt -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_eh -lgcc -lmoldname -lmingwex -lmsvcrt c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/crtend.o
C:/Users/Joe/AppData/Local/Temp/test-709513.o:fake:(.text+0x4d): undefined reference to `objc_lookup_class'
C:/Users/Joe/AppData/Local/Temp/test-709513.o:fake:(.text+0x62): undefined reference to `objc_msg_lookup'
C:/Users/Joe/AppData/Local/Temp/test-709513.o:fake:(.text+0x9e): undefined reference to `__objc_exec_class'
c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/bin/ld.exe: C:/Users/Joe/AppData/Local/Temp/test-709513.o: bad reloc address 0x14 in section `.data'
c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
clang: error: linker (via gcc) command failed with exit code 1 (use -v to see invocation)
by google searching , i found objc_lookup_class is a method defined in gnustep's libobjc library.and in apple's libojbc.dll 's .def file:"libojbc.def" , i found another method named "objc_lookUpClass".
google searching again.so,
apple's libojbc are different with gnustep's libobjc.
apple's libojbc using NextStep library interface.gnustep made a different one.
man gcc
gcc have two options about this.
-fgnu-runtime . that's gcc's default options,using gnu style runtime.
-fnext-runtime , this using nextstep(now it's apple) style running.
so i pass nextstep style option to clang(or gcc?).
clang -fnext-runtime
compile .o to .s with no error.seem like ld.exe finds all method it need from apple's libobjc library file.but another error happen,with -v options,here are detail:
clang version 3.1 (branches/release_31)
Target: i686-w64-mingw32
Thread model: posix
"c:/mingw64w32/bin/clang.exe" -cc1 -triple i686-w64-mingw32 -S -disable-free -main-file-name test.m -mrelocation-model static -mdisable-fp-elim -mconstructor-aliases -target-cpu pentium4 -target-linker-version 2.20.51.0.2 -momit-leaf-frame-pointer -v -resource-dir "c:/mingw64w32/bin\\..\\lib\\clang\\3.1" -fmodule-cache-path "C:/Users/Joe/AppData/Local/Temp\\clang-module-cache" -fno-dwarf-directory-asm -fdebug-compilation-dir C:/MINGW64-X86-MSYS-20111123/home/Joe -ferror-limit 19 -fmessage-length 0 -mstackrealign -fno-use-cxa-atexit -fobjc-fragile-abi -fobjc-exceptions -fdiagnostics-show-option -o C:/Users/Joe/AppData/Local/Temp/test-467378.s -x objective-c test.m
clang -cc1 version 3.1 based upon LLVM 3.1 default target i686-w64-mingw32
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "c:/mingw64w32/bin/../lib/clang/3.1/../../../x86_64-w64-mingw32/include"
ignoring nonexistent directory "/mingw/include"
ignoring nonexistent directory "c:/mingw/include"
ignoring nonexistent directory "/usr/include"
#include "..." search starts here:
#include <...> search starts here:
c:/mingw64w32/bin/../lib/clang/3.1/include
c:/mingw64w32/bin/../lib/clang/3.1/../../../i686-w64-mingw32/include
c:/mingw64w32/bin/../lib/clang/3.1/../../../include
End of search list.
"c:/mingw64w32/bin/i686-w64-mingw32-gcc.exe" -fnext-runtime -v -c -o C:/Users/Joe/AppData/Local/Temp/test-467379.o -x assembler C:/Users/Joe/AppData/Local/Temp/test-467378.s
Using built-in specs.
COLLECT_GCC=c:/mingw64w32/bin/i686-w64-mingw32-gcc.exe
Target: i686-w64-mingw32
Configured with: /home/drangon/work/mingw-w64-dgn_32/source/gcc/configure --host=i686-w64-mingw32 --target=i686-w64-mingw32 --disable-nls --enable-languages=c,c++,objc,obj-c++ --with-gmp=/home/drangon/work/mingw-w64-dgn_32/build/for_target --enable-twoprocess --disable-libstdcxx-pch --disable-win32-registry --prefix=/home/drangon/work/mingw-w64-dgn_32/target --with-sysroot=/home/drangon/work/mingw-w64-dgn_32/target
Thread model: win32
gcc version 4.7.2 20120823 (prerelease) (GCC)
COLLECT_GCC_OPTIONS='-fnext-runtime' '-v' '-c' '-o' 'C:/Users/Joe/AppData/Local/Temp/test-467379.o' '-mtune=generic' '-march=pentiumpro'
c:/mingw64w32/bin/../lib/gcc/i686-w64-mingw32/4.7.2/../../../../i686-w64-mingw32/bin/as.exe -v -o C:/Users/Joe/AppData/Local/Temp/test-467379.o C:/Users/Joe/AppData/Local/Temp/test-467378.s
GNU assembler version 2.23.51 (i686-w64-mingw32) using BFD version (GNU Binutils) 2.23.51.20120823
C:/Users/Joe/AppData/Local/Temp/test-467378.s: Assembler messages:
C:/Users/Joe/AppData/Local/Temp/test-467378.s:4: Error: unknown pseudo-op: `.lazy_reference'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:57: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:57: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:67: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:67: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:76: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:76: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:92: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:92: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:99: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:99: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:107: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:107: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:123: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:123: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:128: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:128: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:133: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:133: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:137: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:137: Error: junk at end of line, first unrecognized character is `,'
C:/Users/Joe/AppData/Local/Temp/test-467378.s:146: Error: bad or irreducible absolute expression
C:/Users/Joe/AppData/Local/Temp/test-467378.s:146: Error: junk at end of line, first unrecognized character is `,'
clang: error: assembler (via gcc) command failed with exit code 1 (use -v to see invocation)
i don't know Assembler language.but seem like Assembler app couldn't understand this .s file.
so i using -S option to keep .s files.one is clang with -fgnu-runtime . other is clang with -fnext-runtime.
//test.s ,clang with -fgnu-runtime option
.def __c_Foo__fooWithBar;
.scl 3;
.type 32;
.endef
.text
.align 16, 0x90
__c_Foo__fooWithBar:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl 12(%ebp), %eax
movl 8(%ebp), %ecx
leal L_.str, %edx
movl %ecx, -4(%ebp)
movl %eax, -8(%ebp)
movl %edx, (%esp)
calll _printf
movl %eax, -12(%ebp)
addl $16, %esp
popl %ebp
ret
.def _main;
.scl 2;
.type 32;
.endef
.globl _main
.align 16, 0x90
_main:
pushl %ebp
movl %esp, %ebp
pushl %esi
subl $20, %esp
calll ___main
leal L_.class_name, %eax
movl $0, -8(%ebp)
movl %eax, (%esp)
calll _objc_lookup_class
leal _.objc_selector_list, %ecx
movl %eax, (%esp)
movl %ecx, 4(%esp)
movl %eax, -12(%ebp)
calll _objc_msg_lookup
movl $0, %ecx
leal _.objc_selector_list, %edx
movl -12(%ebp), %esi
movl %esi, (%esp)
movl %edx, 4(%esp)
movl %ecx, -16(%ebp)
calll *%eax
movl -16(%ebp), %eax
addl $20, %esp
popl %esi
popl %ebp
ret
.def _.objc_load_function;
.scl 3;
.type 32;
.endef
.align 16, 0x90
_.objc_load_function:
.cfi_startproc
pushl %ebp
Ltmp2:
.cfi_def_cfa_offset 8
Ltmp3:
.cfi_offset %ebp, -8
movl %esp, %ebp
Ltmp4:
.cfi_def_cfa_register %ebp
pushl %eax
leal ___unnamed_1, %eax
movl %eax, (%esp)
calll ___objc_exec_class
addl $4, %esp
popl %ebp
ret
.cfi_endproc
.data
L_.str:
.asciz "abc"
.globl ___objc_class_name_Foo
.align 4
___objc_class_name_Foo:
.long 0
L___unnamed_2:
.asciz "count"
L___unnamed_3:
.asciz "i"
.globl ___objc_ivar_offset_value_Foo.count
.align 4
___objc_ivar_offset_value_Foo.count:
.long 0
.align 4
_.ivar.offsets:
.long ___objc_ivar_offset_value_Foo.count
.lcomm _.objc_property_list,8,8
L___unnamed_4:
.asciz "v8#0:4"
L___unnamed_5:
.asciz "fooWithBar"
.align 16
_.objc_method_list:
.long 0
.long 1
.long L___unnamed_5
.long L___unnamed_4
.long __c_Foo__fooWithBar
.align 8
_.objc_ivar_list:
.long 1
.long L___unnamed_2
.long L___unnamed_3
.long 0
.globl ___objc_ivar_offset_Foo.count
.align 4
___objc_ivar_offset_Foo.count:
.long _.objc_ivar_list+12
L_.class_name:
.asciz "Foo"
.globl __OBJC_METACLASS_Foo
.align 16
__OBJC_METACLASS_Foo:
.long 0
.long 0
.long L_.class_name
.long 0
.long 18
.long 72
.long 0
.long _.objc_method_list
.long 0
.long 0
.long 0
.long 0
.long 0
.long 1
.long 0
.long 0
.long 0
.long 0
.lcomm _.objc_protocol_list,8,8
.globl __OBJC_CLASS_Foo
.align 16
__OBJC_CLASS_Foo:
.long __OBJC_METACLASS_Foo
.long 0
.long L_.class_name
.long 0
.long 17
.long 4
.long _.objc_ivar_list
.long 0
.long 0
.long 0
.long 0
.long _.objc_protocol_list
.long 0
.long 1
.long _.ivar.offsets
.long _.objc_property_list
.long 1
.long 1
.section .rdata$__objc_class_ref_Foo,"r"
.linkonce discard
.globl ___objc_class_ref_Foo
.align 4
___objc_class_ref_Foo:
.long ___objc_class_name_Foo
.data
L___unnamed_6:
.asciz "AnotherHack"
L___unnamed_7:
.asciz "__ObjC_Protocol_Holder_Ugly_Hack"
.lcomm _.objc_protocol_list1,8,8
.align 16
___unnamed_8:
.long L___unnamed_6
.long L___unnamed_7
.long 0
.long 0
.long _.objc_protocol_list1
.section .rdata$.objc_sel_namefooWithBar,"r"
.linkonce discard
.globl _.objc_sel_namefooWithBar
_.objc_sel_namefooWithBar:
.asciz "fooWithBar"
.data
.align 8
_.objc_selector_list:
.long _.objc_sel_namefooWithBar
.long L___unnamed_4
.zero 8
.align 16
___unnamed_9:
.long 1
.long _.objc_selector_list
.short 1
.short 1
.long __OBJC_CLASS_Foo
.long ___unnamed_8
.long 0
.long 0
L_.objc_source_file_name:
.asciz "./test.m"
.align 8
___unnamed_1:
.long 8
.long 16
.long L_.objc_source_file_name
.long ___unnamed_9
.section .ctors,"w"
.align 4
.long _.objc_load_function
//test.s ,clang with -fnext-runtime option
.objc_class_name_Foo=0
.globl .objc_class_name_Foo
.lazy_reference .objc_class_name_Foo
.def _2B__5B_Foo_20_fooWithBar_5D_;
.scl 3;
.type 32;
.endef
.text
.align 16, 0x90
_2B__5B_Foo_20_fooWithBar_5D_:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl 12(%ebp), %eax
movl 8(%ebp), %ecx
leal L_.str, %edx
movl %ecx, -4(%ebp)
movl %eax, -8(%ebp)
movl %edx, (%esp)
calll _printf
movl %eax, -12(%ebp)
addl $16, %esp
popl %ebp
ret
.def _main;
.scl 2;
.type 32;
.endef
.globl _main
.align 16, 0x90
_main:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
calll ___main
movl $0, %eax
movl $0, -4(%ebp)
movl L_OBJC_CLASS_REFERENCES_, %ecx
movl L_OBJC_SELECTOR_REFERENCES_, %edx
movl %ecx, (%esp)
movl %edx, 4(%esp)
movl %eax, -8(%ebp)
calll _objc_msgSend
movl -8(%ebp), %eax
addl $16, %esp
popl %ebp
ret
.data
L_.str:
.asciz "abc"
.section __TEXT,__cstring,cstring_literals,"w"
L_OBJC_METH_VAR_NAME_:
.asciz "fooWithBar"
L_OBJC_METH_VAR_TYPE_:
.asciz "v8#0:4"
L_OBJC_CLASS_NAME_:
.asciz "Foo"
.section __OBJC,__cls_meth,regular,no_dead_strip,"w"
.align 4
L_OBJC_CLASS_METHODS_Foo:
.long 0
.long 1
.long L_OBJC_METH_VAR_NAME_
.long L_OBJC_METH_VAR_TYPE_
.long _2B__5B_Foo_20_fooWithBar_5D_
.section __OBJC,__meta_class,regular,no_dead_strip,"w"
.align 4
L_OBJC_METACLASS_Foo:
.long L_OBJC_CLASS_NAME_
.long 0
.long L_OBJC_CLASS_NAME_
.long 0
.long 2
.long 48
.long 0
.long L_OBJC_CLASS_METHODS_Foo
.long 0
.long 0
.long 0
.long 0
.section __TEXT,__cstring,cstring_literals,"w"
L_OBJC_METH_VAR_NAME_1:
.asciz "count"
L_OBJC_METH_VAR_TYPE_2:
.asciz "i"
.section __OBJC,__instance_vars,regular,no_dead_strip,"w"
.align 4
L_OBJC_INSTANCE_VARIABLES_Foo:
.long 1
.long L_OBJC_METH_VAR_NAME_1
.long L_OBJC_METH_VAR_TYPE_2
.long 0
.section __OBJC,__class,regular,no_dead_strip,"w"
.align 4
L_OBJC_CLASS_Foo:
.long L_OBJC_METACLASS_Foo
.long 0
.long L_OBJC_CLASS_NAME_
.long 0
.long 1
.long 4
.long L_OBJC_INSTANCE_VARIABLES_Foo
.long 0
.long 0
.long 0
.long 0
.long 0
.section __OBJC,__cls_refs,literal_pointers,no_dead_strip,"w"
.align 4
L_OBJC_CLASS_REFERENCES_:
.long L_OBJC_CLASS_NAME_
.section __OBJC,__message_refs,literal_pointers,no_dead_strip,"w"
.align 4
L_OBJC_SELECTOR_REFERENCES_:
.long L_OBJC_METH_VAR_NAME_
.section __TEXT,__cstring,cstring_literals,"w"
L_OBJC_CLASS_NAME_3:
.zero 1
.section __OBJC,__symbols,regular,no_dead_strip,"w"
.align 4
L_OBJC_SYMBOLS:
.long 0
.long 0
.short 1
.short 0
.long L_OBJC_CLASS_Foo
.section __OBJC,__module_info,regular,no_dead_strip,"w"
.align 4
L_OBJC_MODULES:
.long 7
.long 16
.long L_OBJC_CLASS_NAME_3
.long L_OBJC_SYMBOLS
i believe the key issues is from the .s file create way.
anyone can help me fix this problem?
althrough using these .dll file could not create application for business.
but by using these .dll , we could build a greate cocoa learnning environment on window platform. all framework's windows version is more stable and useful than gnustep.
thanks.
Well, first of all this is in violation of the iTunes EULA, so whether commercial or not you're not supposed to do it.
Second problem is that -fnext-runtime in clang/gcc only functions on Darwin, it is missing assorted bits and pieces for Windows and other operating systems. I'd (educated) guess and assume -fgnu-runtime is useless for linking against Apple's own frameworks.
As you can see -fnext-runtime is emitting Darwin specific assembler command, e.g. .lazy_reference, on Windows, not a great start.
This has been the situation with -fnext-runtime in gcc and now clang for quite a long time, no one maintains -fnext-runtime in the mainlines for non-Darwin systems.
My rough understanding is that Apple actually does not use clang directly on Windows, they rewrite the Objective-C into C and use Visual Studio to compile for Windows.
You can either start doing some serious hacking on clang, or don't bother.
I tried to do exactly the same as you have recently, and I found similar results. The core (technical, not legal) issue is that -fnext-runtime isn't supported on Windows and probably won't ever be supported. I will get to -fgnu-runtime in a moment.
No matter how basic an Objective-C program you write on Windows you will always end up with unresolved references. Looking inside the .dll files you will find that they simply do not contain some of the core methods required to link an Objective-C program compiled with Clang on Windows. (If memory serves I was able to compile a program that had only 2 unresolved references as a minimum).
So on the basis that -fnext-runtime is not supported, you can try -fgnu-runtime with GCC. Of course, you lose compatibility with all Apple's libraries, but you do get working Objective-C programs on Windows. GCC recently upgraded their Objective-C runtime to work almost identically to Apple's Objective-C runtime so compatibility is now much less of an issue.
Again, you don't get Apple's libraries, you'd have to write them yourself (any takers?) but the runtime works in the same way. It takes a bit of working to make your own NSObject (looking at Apple's implementation helps though) and Constant String #"..." object but once you have them, you can build up your own Windows-compatible Objective-C framework. From experience I can tell you that it is definitely possible.
Should I avoid using the 'insertvalue' instruction combined with load and store when I emit LLVM code?
I always get bad optimized native code when I use it. Look at the following example:
; ModuleID = 'mod'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-pc-linux-gnu"
%A = type { i64, i64, i64, i64, i64, i64, i64, i64 }
#aa = external global %A*
define void #func() {
entry:
%a1 = load %A** #aa
%a2 = load %A* %a1
%a3 = insertvalue %A %a2, i64 3, 3
store %A %a3, %A* %a1
ret void
}
When I run "llc -o - -O3 mod.ll", I get this horrible code:
func: # #func
.Ltmp0:
.cfi_startproc
# BB#0: # %entry
movq aa(%rip), %rax
movq (%rax), %r8
movq 8(%rax), %r9
movq 16(%rax), %r10
movq 32(%rax), %rdi
movq 40(%rax), %rcx
movq 48(%rax), %rdx
movq 56(%rax), %rsi
movq %rsi, 56(%rax)
movq %rdx, 48(%rax)
movq %rcx, 40(%rax)
movq %rdi, 32(%rax)
movq %r10, 16(%rax)
movq %r9, 8(%rax)
movq %r8, (%rax)
movq $3, 24(%rax)
ret
But what I would like to see is this:
func: # #func
.Ltmp0:
.cfi_startproc
# BB#0: # %entry
movq aa(%rip), %rax
movq $3, 24(%rax)
ret
Of course I can use getelementptr or something, but sometimes it is easier to generate insertvalue and extractvalue instructions, and I want these to be optimized...
I think it would be quite easy for the codegen to see that things like these are bad:
movq 56(%rax), %rsi
movq %rsi, 56(%rax)
First, note that llc does not do any IR-level optimizations. So, you should run opt to run the set of IR-level optimizers.
However, opt does not help in this. I'd expect that standard IR-level optimizers canonicalize the stuff into gep somehow.
Please file a LLVM PR, this looks like a missed optimization!