Page 1 of 1

Compiling issues

Posted: Sun Jul 19, 2015 8:28 am
by hometue
Hi guys. I have been roaming in the forums quietly and just decided to restart my OS (despite not achieving much with it). So right now I am more or less using the Meaty Skeleton.

Anyways, I have been playing around with my OS. Maybe to a point of not being productive, and in my 'adventures' I bumped into an issue which I have somehow resolved, but I am still not sure why it happened and if my fix works (in the sense that the function I copied over works)

I have copied over this code from the inline assembly examples:

Code: Select all

static inline uint64_t rdtsc()
{
    uint64_t ret;
    asm volatile ( "rdtsc" : "=A"(ret) );
    return ret;
}
I placed it in kernel/arch/i386/io.c (I notice this is not really io related function, and will rename it later). Additionally, the file solely contains this function (and a few necessary includes), and I also added io.h along with the other headers, which contains a few includes and the function declaration. For some reason, it failed, with the make process failing due to rdtsc() not being declared, despite having included io.h in the kernel and io.c being compiled and linked. After checking the object file, I discovered it does not contain the function (Practically empty save a few functions for debugging purposes judging from the names, probably those that are added into all object files by GCC). I had to edit the function declaration to the following before the object file contained the function and the make process worked.

Code: Select all

uint64_t rdtsc()
My questions are these: Why didn't the object file contain the function initially, what is the effect of me removing static and inline (I am familiar with these two keywords, but I do not understand why do they have to be added to the function declaration) and lastly, is there a better way for me to add this function (I am thinking of just stuffing everything into io.h, but not very sure if it works or even a good way to do so)?

I do understand this might be quite simple, but I do not get it, and hope if you guys can provide me with some knowledge about this issue. Thanks.

Re: Compiling issues

Posted: Sun Jul 19, 2015 8:54 am
by Nable
Keyword 'static' means that this function cannot be accessed outside of the same module (object file). If it isn't used by any function in your "io" module, it would be optimized away (resulting into empty object file). "Inline" means that compiler may skip placing the full function body (only inlined pieces inside other functions that use this one).

Re: Compiling issues

Posted: Sun Jul 19, 2015 2:15 pm
by Candy
Nable wrote:Keyword 'static' means that this function cannot be accessed outside of the same module (object file). If it isn't used by any function in your "io" module, it would be optimized away (resulting into empty object file). "Inline" means that compiler may skip placing the full function body (only inlined pieces inside other functions that use this one).
Close but not quite entirely.

Static means that the name may not be exported for outside use, ie, it is required to be hidden in the object file. If you find a relocation pointing to it, it'll have no name.

Inline means that the compiler is recommended and allowed, but not forced (!), to fully inline the function wherever it pleases. It typically does export a full function with addressable name, as you can take the address of an inline function too (and it needs to have one to be able to do that), and you could have done that in a file in which it's only declared. As it is static though, the compiler in this case won't create this copy for others to use as they wouldn't be able to access it anyway (as it's hidden).

Net result is that this function is hidden to everybody outside your file, and it's inlined into any function that uses it - which is nothing. Hence, it's not visible.

Re: Compiling issues

Posted: Mon Jul 20, 2015 3:10 am
by hometue
Thanks for the replies, I now understand more about the keywords. However, I still have some lingering questions. What is the purpose of inline in this function? I mean, it is called inline assembly, but why must it be inline? Is it solely performance-related as I have read online?

Also, side note just in case anyone faces a similar issue and searches the forum, inline functions are to be placed in the header file along with the function declaration (in my case io.h), not in a separate C file as I have done. (Though I noticed this should be basic knowledge so...yeah...)

Re: Compiling issues

Posted: Mon Jul 20, 2015 4:14 am
by Combuster
"static inline" is basically a type-safe version of a macro you put in a header.

If you don't make it inline and just static, then the lack of a hint suggests compilation to create a full-blown function and you would get identical copies of that function in all object files that use it - without any of the performance improvements you get over just giving it a separate source file. Some compilers are a bit smarter and do the "inline" anyway in some situations.

If you don't make it static and just inline, you get duplicate symbols. I can't think of any situation where this is actually what you want.

Re: Compiling issues

Posted: Mon Jul 20, 2015 5:13 am
by Kevin
In practice, using "static" without "inline" in a header file will have the additional problem of gcc emitting a warning for unused static functions (because for static functions it can know that it's dead code). Declaring the function "static inline" avoids this warning.

Re: Compiling issues

Posted: Mon Jul 20, 2015 9:13 am
by hometue
Thanks for the replies. I understand the keywords much better (Especially inline, which I really had no idea why it was useful till now). Now I can finally implement some IO inline assembly functions on my rebooted OS project :D

Re: Compiling issues

Posted: Thu Jul 23, 2015 6:54 am
by Candy
On the object / binary level the compiler outputs the symbols with "weak" linkage, which means that it will merge any such occurrence if your compiler does output them. If you do not make it inline it will be with "strong" linkage, which means that any two identically-named ones will collide.