Note that there are some explanatory texts on larger screens.

plurals
  1. POWhat is `objc_msgSend_fixup`, exactly?
    primarykey
    data
    text
    <p>I'm messing around with the Objective-C runtime, trying to compile objective-c code without linking it against <code>libobjc</code>, and I'm having some segmentation fault problems with a program, so I generated an assembly file from it. I think it's not necessary to show the whole assembly file. At some point of my <code>main</code> function, I've got the following line (which, by the way, is the line after which I get the seg fault):</p> <pre><code>callq *l_objc_msgSend_fixup_alloc </code></pre> <p>and here is the definition for <code>l_objc_msgSend_fixup_alloc</code>:</p> <pre><code>.hidden l_objc_msgSend_fixup_alloc # @"\01l_objc_msgSend_fixup_alloc" .type l_objc_msgSend_fixup_alloc,@object .section "__DATA, __objc_msgrefs, coalesced","aw",@progbits .weak l_objc_msgSend_fixup_alloc .align 16 l_objc_msgSend_fixup_alloc: .quad objc_msgSend_fixup .quad L_OBJC_METH_VAR_NAME_ .size l_objc_msgSend_fixup_alloc, 16 </code></pre> <p>I've reimplemented <code>objc_msgSend_fixup</code> as a function (<code>id objc_msgSend_fixup(id self, SEL op, ...)</code>) which returns <code>nil</code> (just to see what happens), but this function isn't even being called (the program crashes before calling it).</p> <p>So, my question is, what is <code>callq *l_objc_msgSend_fixup_alloc</code> supposed to do and what is <code>objc_msgSend_fixup</code> (after <code>l_objc_msgSend_fixup_alloc:</code>) supposed to be (a function or an object)?</p> <p><strong>Edit</strong></p> <p>To better explain, I'm not linking my source file against the objc library. What I'm trying to do is implement some parts of the libray, just to see how it works. Here is an approach of what I've done:</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;objc/runtime.h&gt; @interface MyClass { } +(id) alloc; @end @implementation MyClass +(id) alloc { // alloc the object return nil; } @end id objc_msgSend_fixup(id self, SEL op, ...) { printf("Calling objc_msgSend_fixup()...\n"); // looks for the method implementation for SEL in self's method list return nil; // Since this is just a test, this function doesn't need to do that } int main(int argc, char *argv[]) { MyClass *m; m = [MyClass alloc]; // At this point, according to the assembly code generated // objc_msgSend_fixup should be called. So, the program should, at least, print // "Calling objc_msgSend_fixup()..." on the screen, but it crashes before // objc_msgSend_fixup() is called... return 0; } </code></pre> <p>If the runtime needs to access the object's vtable or the method list of the obect's class to find the correct method to call, what is the function which actually does this? I think it is <code>objc_msgSend_fixup</code>, in this case. So, when <code>objc_msgSend_fixup</code> is called, it receives an object as one of its parameters, and, if this object hasn't been initialized, the function fails.</p> <p>So, I've implemented my own version of <code>objc_msgSend_fixup</code>. According to the assembly source above, it should be called. It doesn't matter if the function is actually looking for the implementation of the selector passed as parameter. I just want <code>objc_msgSend_lookup</code> to be called. But, it's not being called, that is, the function that looks for the object's data is not even being called, instead of being called and cause a fault (because it returns a <code>nil</code> (which, by the way, doesn't matter)). The program seg fails before <code>objc_msgSend_lookup</code> is called...</p> <p><strong>Edit 2</strong></p> <p>A more complete assembly snippet:</p> <pre><code>.globl main .align 16, 0x90 .type main,@function main: # @main .Ltmp20: .cfi_startproc # BB#0: pushq %rbp .Ltmp21: .cfi_def_cfa_offset 16 .Ltmp22: .cfi_offset %rbp, -16 movq %rsp, %rbp .Ltmp23: .cfi_def_cfa_register %rbp subq $32, %rsp movl $0, %eax leaq l_objc_msgSend_fixup_alloc, %rcx movl $0, -4(%rbp) movl %edi, -8(%rbp) movq %rsi, -16(%rbp) movq L_OBJC_CLASSLIST_REFERENCES_$_, %rsi movq %rsi, %rdi movq %rcx, %rsi movl %eax, -28(%rbp) # 4-byte Spill callq *l_objc_msgSend_fixup_alloc movq %rax, -24(%rbp) movl -28(%rbp), %eax # 4-byte Reload addq $32, %rsp popq %rbp ret </code></pre> <p>For <code>l_objc_msgSend_fixup_alloc</code>, we have:</p> <pre><code>.hidden l_objc_msgSend_fixup_alloc # @"\01l_objc_msgSend_fixup_alloc" .type l_objc_msgSend_fixup_alloc,@object .section "__DATA, __objc_msgrefs, coalesced","aw",@progbits .weak l_objc_msgSend_fixup_alloc .align 16 l_objc_msgSend_fixup_alloc: .quad objc_msgSend_fixup .quad L_OBJC_METH_VAR_NAME_ .size l_objc_msgSend_fixup_alloc, 16 </code></pre> <p>For <code>L_OBJC_CLASSLIST_REFERENCES_$_</code>:</p> <pre><code>.type L_OBJC_CLASSLIST_REFERENCES_$_,@object # @"\01L_OBJC_CLASSLIST_REFERENCES_$_" .section "__DATA, __objc_classrefs, regular, no_dead_strip","aw",@progbits .align 8 L_OBJC_CLASSLIST_REFERENCES_$_: .quad OBJC_CLASS_$_MyClass .size L_OBJC_CLASSLIST_REFERENCES_$_, 8 </code></pre> <p><code>OBJC_CLASS_$_MyClass</code> is a pointer to the <code>MyClass</code> struct definition, which has been also generated by the compiler and it's also present in the assembly code.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload