Page 1 of 1

Undefined reference to `outb(unsigned short, unsigned char)'

Posted: Fri May 11, 2012 8:52 pm
by Lionel
Hey again!
I'm having some trouble with getting outb implemented.
This is outb:

Code: Select all

void outb( unsigned short port, unsigned char val )
{
	asm volatile("outb %0, %1" : : "a"(val), "Nd"(port) );
}
This outb lives in a C file called common.c, which is in the folder src.

Now, this project is primarily in C++, and the C++ code needs to reference outb.

Now you might be wondering "Why doesn't he just put the code in a C++ file?".
Good question! Putting the code in C++ gives the error

Code: Select all

Error: operand type mismatch for `out'
Which doesn't make sense.
Now back to our friend outb, Compiling the c file gives no errors, yet when linked to the kernel, it gives

Code: Select all

undefined reference to `outb(unsigned short, unsigned char)'
But the weird part is that it exists, and the header file has a prototype for it.
Also, the object file is being referenced by the linker.

Help Please?

PS:I searched on Google, and on google again with the site:osdev.org tag, none of them worked or applied.

Re: Undefined reference to `outb(unsigned short, unsigned ch

Posted: Fri May 11, 2012 9:01 pm
by NickJohnson
Did you declare outb as an extern C function instead of an extern C++ function in your header file? It sounds like C++ is attempting to find a mangled outb(unsigned short, unsigned char) symbol when it should be looking for just the outb symbol.

Re: Undefined reference to `outb(unsigned short, unsigned ch

Posted: Fri May 11, 2012 9:13 pm
by Lionel
Yes I am:
common.h:

Code: Select all

#ifndef COMMON_H
#define COMMON_H

// Some nice typedefs, to standardise sizes across platforms.
// These typedefs are written for 32-bit X86.
typedef unsigned int   u32int;
typedef          int   s32int;
typedef unsigned short u16int;
typedef          short s16int;
typedef unsigned char  u8int;
typedef          char  s8int;
#ifdef __cplusplus__
extern "C"
{
#endif
void outb( unsigned short port, unsigned char val );
#ifdef __cplusplus__
}
#endif
#endif // COMMON_H

Re: Undefined reference to `outb(unsigned short, unsigned ch

Posted: Fri May 11, 2012 9:24 pm
by NickJohnson
I think that you should be checking if "__cplusplus" is defined, not "__cplusplus__".

Re: Undefined reference to `outb(unsigned short, unsigned ch

Posted: Fri May 11, 2012 9:37 pm
by Lionel
*facepalm*

Thanks, it worked. I should have checked if it was the right variable.

Re: Undefined reference to `outb(unsigned short, unsigned ch

Posted: Sat May 12, 2012 1:09 am
by xenos
Just one more suggestion for portability reasons: Instead of defining your own fixed size data types such es u8int in your code, you could simply include <cstdint>, which is part of a freestanding C++ implementation (i.e., it does not depend on any libraries and can thus be used in your kernel) and declares fixed size types such as uint8_t. The advantage is that the size of these types is actually fixed, while the size if types such as short or int is implementation defined, so it may be different if you use a different compiler.

Re: Undefined reference to `outb(unsigned short, unsigned ch

Posted: Sat May 12, 2012 3:52 pm
by Lionel
berkus wrote:It certainly makes sense to just fix the damn gcc assembler error.

Here's the code i'm using, can you try compiling it as cpp file and tell if it works or not?

Code: Select all

20       /*!
21	     * Write a byte out to the specified port.
22	     */
23	    static inline void outb(uint16_t port, uint8_t value) ALWAYS_INLINE
24	    {
25	        //("a" puts value in eax, "dN" puts port in edx or uses 1-byte constant.)
26	        asm volatile ("outb %0, %1" :: "a" (value), "dN" (port));
27	    }
That does work, only if you remove the static keyword. (Static in c++ says that the function can only be used in that source file.)
Anyway, thanks!