<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>Hi Tim,</div><div>I'm still struggling on the instruction:</div><div><br></div><div>call void bitcast (void (%struct.png_struct_def.68*, i8*, i8* (%struct.png_struct_def.68*, i64)*, void (%struct.png_struct_def.68*, i8*)*)* @png_set_mem_fn to void (%struct.png_struct_def*, i8*, i8* (%struct.png_struct_def*, i64)*, void (%struct.png_struct_def*, i8*)*)*)(%struct.png_struct_def* %create_struct, i8* %mem_ptr, i8* (%struct.png_struct_def*, i64)* %malloc_fn, void (%struct.png_struct_def*, i8*)* %free_fn) #15<br></div><div><br></div><div>I'm pretty sure that this is a CallInst but when I try to call getCalledFunction() I receive a null pointer and that really surprise me. <br></div><div><br></div><div>I would like to understand how to get the function that is called and its parameters. Can you tell me how please?<br></div><div><br></div><div>Am i right saying that:</div><div><br></div><div>(void (%struct.png_struct_def.68*, i8*, i8* (%struct.png_struct_def.68*, i64)*, void (%struct.png_struct_def.68*, i8*)*)* -> "old parameters type"</div><div>(%struct.png_struct_def*, i8*, i8* (%struct.png_struct_def*, i64)*, void (%struct.png_struct_def*, i8*)*)*) ->  "new parameters type"</div><div>(%struct.png_struct_def* %create_struct, i8* %mem_ptr, i8* 
(%struct.png_struct_def*, i64)* %malloc_fn, void 
(%struct.png_struct_def*, i8*)* %free_fn) "the parameters passed to the png_set_mem_fn"</div><div><br></div><div>As a clarification the function is declared like this:</div><div><br></div><div>void PNGAPI<br>png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr<br>  malloc_fn, png_free_ptr free_fn)</div><div><br></div><div><br></div><div>Thanks again<br></div><div><br></div></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Il giorno dom 10 mar 2019 alle ore 08:59 Tim Northover <<a href="mailto:t.p.northover@gmail.com">t.p.northover@gmail.com</a>> ha scritto:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Alberto,<br>
<br>
> I would like to understand where bitcast is defined because it is not defined within libpng.<br>
<br>
It's because the function (@png_set) has been defined to take one kind<br>
of argument, but is being called with another. In this case the<br>
difference seems to be whether it takes pointers to<br>
%struct.png_struct_def or %struct.png_struct_def.68.<br>
<br>
This kind of situation isn't terribly common, but can happen for<br>
example in LTO where two modules are linked together, and one of them<br>
only has an opaque handle for the type to hide the implementation<br>
(e.g. from plain "struct png_struct_def;" in C). When that happens<br>
LLVM can't merge the types, so it adds a numeric tag to one of them,<br>
and then it has to insert bitcasts in the calls like this so that its<br>
own type system works.<br>
<br>
> I also noticed that the @ is not present, what does the missing @ mean? I guess it must be an LLVM function.<br>
<br>
The @ is only used directly before a global variable (including a<br>
declared/defined function). In this case it's buried, but it is there<br>
(@png_set). In other cases, like when you call a function pointer, it<br>
will be missing entirely.<br>
<br>
Cheers.<br>
<br>
Tim.<br>
</blockquote></div>