memset - undefined reference

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

memset - undefined reference

Post by tsdnz »

Hi guys, my OS is going well, very enjoyable.
When I compile and link using -Ofast I get undefined reference to `memset'
The code in question is, which is my own:

Code: Select all

il void SetMem(void* pMem, byte To, dword Size)
{
	byte* p = (byte*)pMem;
	byte* pEnd = (byte*)pMem + Size - sizeof(qword);

	qword Toqword = CharsToqword(To, To, To, To, To, To, To, To);

	while (p < pEnd)
	{
		*(qword*)p = Toqword;
		p += sizeof(qword);
	}

	pEnd += sizeof(qword);
	while (p < pEnd)
	{
		*(byte*)p = To;
		p += sizeof(byte);
	}
}
Not sure how to use memset or to remove this automatic feature.

My command lines are:

Code: Select all

$ x86_64-elf-g++ -c kernel.c -o kernel.o -ffreestanding -Ofast -Wall -Wextra -nostdlib -nostartfiles -nodefaultlibs -m64 -std=c++11 -mno-3dnow
$ x86_64-elf-g++ -T linker.ld -o kernel.lkr -ffreestanding -Ofast -Wall -Wextra -nostdlib -nostartfiles -nodefaultlibs kernel.o -lgcc -fno-use-linker-plugin
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: memset - undefined reference

Post by Combuster »

The C compiler sees that part of what you are doing is actually a memset and replaces it. You could better have written the function as a standards-compliant memset so the compiler doesn't need to fix your badly named code. Similarly, GCC will substitute other things with either inline versions or library calls where appropriate - it's meant to improve the emitted code, not something you should want to fight.


Also, your compiler flags are broken. See the wiki tutorial on 64-bit kernels before other things start to blow up as well.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Re: memset - undefined reference

Post by tsdnz »

Checked it out, add -mno-red-zone, did not realise this.

With this in it works.

Below are my command lines

Code: Select all

$ x86_64-elf-g++ -c kernel.c -o kernel.o -ffreestanding -mcmodel=large -mno-red-zone -Ofast -Wall -Wextra -nostdlib -nostartfiles -nodefaultlibs -m64 -std=c++11 -mno-3dnow
$ x86_64-elf-g++ -T linker.ld -o kernel.lkr -Ofast -nostdlib kernel.o -lgcc -fno-use-linker-plugin
Thanks,
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Re: memset - undefined reference

Post by tsdnz »

Hi, just looked into memset here
http://stuff.mit.edu/afs/sipb/contrib/l ... emset_64.S

If someone can help point me in the right direction so I can use memset it would be appreciated.

I have tracked it down to this??
-nodefaultlibs
Do not use the standard system libraries when linking. Only the libraries you specify are passed to the linker, and options specifying linkage of the system libraries, such as -static-libgcc or -shared-libgcc, are ignored. The standard startup files are used normally, unless -nostartfiles is used.
The compiler may generate calls to memcmp, memset, memcpy and memmove. These entries are usually resolved by entries in libc. These entry points should be supplied through some other mechanism when this option is specified.
How do I specify these entry points?
Thanks,
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: memset - undefined reference

Post by sortie »

Hi,

The GNU C Compiler in freestanding mode requires the existence of the symbols memset, memcpy, memmove and memcmp. You *must* supply these functions yourself as described in the C standard. You cannot and should not (if you could) prevent the compiler from assuming these functions exist as the compiler uses them for important optimizations. Fortunately these functions are really easy to write. Note that if you are writing C++ you must export them with C linkage, for instance:

Code: Select all

extern "C" void* memcpy(void* dst, const void* src, size_t size)
{
    for ( size_t i = 0; i < size; i++ )
        ((uint8_t*) dst)[i] = ((const uint8_t*) src)[i];
    return dst;
}

Code: Select all

$ x86_64-elf-g++ -c kernel.c -o kernel.o -ffreestanding -mcmodel=large -mno-red-zone -Ofast -Wall -Wextra -nostdlib -nostartfiles -nodefaultlibs -m64 -std=c++11 -mno-3dnow
$ x86_64-elf-g++ -T linker.ld -o kernel.lkr -Ofast -nostdlib kernel.o -lgcc -fno-use-linker-plugin
Please note that passing -nostdlib is the same as pasing both -nostartfiles and -nodefaultlibs. For that reason, you should simply only pass -nostdlib and delete all references to -nostartfiles and -nodefaultlibs where they are passed. Additionally, these options make no sense when compiling, only when linking, so you should delete them from all gcc invocations containing -c. You also don't have to pass -m64 at any times when using the x86_64-* toolchain because -m64 is the default. Likewise, optimization options doesn't really make sense when you link the kernel and have no effect (or am I wrong there?). I'm not sure why you pass -fno-use-linker-plugin - it seems to work around a problem that shouldn't exist. I recommend that you don't pass an option unless you have researched whether you need to pass it in the first place - there is a *lot* of misinformation out there.
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Re: memset - undefined reference

Post by tsdnz »

Cheers mate, I had tried many things.

This is what is was missing extern "C" void*
User avatar
dozniak
Member
Member
Posts: 723
Joined: Thu Jul 12, 2012 7:29 am
Location: Tallinn, Estonia

Re: memset - undefined reference

Post by dozniak »

Code: Select all

il void
il void?
Learn to read.
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Re: memset - undefined reference

Post by tsdnz »

il void?
I am using VS 2012 as my IDE.
When testing code I want it to compile fast, so VS changed an include file to
#define il // DEBUG

OR when in RELEASE
#define il inline // RELEASE

As it turned out I dont use it as the gcc compiler option -O1 is fast when compiling.
So everything is inlined (#define il inline)
This was just left in.

I used a lot of this when I designed the asm version.
I had VS injecting values in for me, checking procs, creating proc lists etc.
Not at this point in the c++ version yet.
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Re: memset - undefined reference

Post by tsdnz »

Hi, I added this code.

But the code calls the same code, infinite loop

Here is the c++ extern

Code: Select all

extern "C" void* memset(void * s,int c,size_t count)
{
	for ( size_t i = 0; i < count; i++ )
        ((byte*) s)[i] = (byte)c;
    return s;
}
Here is the objdump

Code: Select all

00000000010010b0 <memset>:
 10010b0:	48 85 d2             	test   rdx,rdx
 10010b3:	74 1b                	je     10010d0 <memset+0x20>
 10010b5:	48 83 ec 08          	sub    rsp,0x8
 10010b9:	40 0f b6 f6          	movzx  esi,sil
 10010bd:	48 b8 b0 10 00 01 00 	movabs rax,0x10010b0
 10010c4:	00 00 00 
 10010c7:	ff d0                	call   rax
 10010c9:	48 83 c4 08          	add    rsp,0x8
 10010cd:	c3                   	ret    
 10010ce:	66 90                	xchg   ax,ax
 10010d0:	48 89 f8             	mov    rax,rdi
 10010d3:	c3                   	ret    
 10010d4:	66 66 66 2e 0f 1f 84 	data32 data32 nop WORD PTR cs:[rax+rax*1+0x0]
 10010db:	00 00 00 00 00 
Any ideas?

I am going to change it to use asm rep on 16 boundary, so no issues for me, but seams strange??

Also, can I inline this?
tsdnz
Member
Member
Posts: 333
Joined: Sun Jun 16, 2013 4:09 am

Re: memset - undefined reference

Post by tsdnz »

Found this, looks like a known bug.

http://www.marshut.com/qnktz/infinite-r ... ction.html

To answer my own question, yes if you use rep stos it will inline
User avatar
XanClic
Member
Member
Posts: 138
Joined: Wed Feb 13, 2008 9:38 am

Re: memset - undefined reference

Post by XanClic »

It's not really a bug. See also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56888
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: memset - undefined reference

Post by sortie »

Yes, it's a bug. There are some fools in that gcc bug report. The compiler should never emit calls to the memcpy from a function called memcpy. The argument "It's undefined behavior because memcpy is in the standard library" is silly because exactly this problem is hitting the libc developers.
User avatar
piranha
Member
Member
Posts: 1391
Joined: Thu Dec 21, 2006 7:42 pm
Location: Unknown. Momentum is pretty certain, however.
Contact:

Re: memset - undefined reference

Post by piranha »

As a "hack-y" temporary fix, adding "-fno-tree-loop-distribute-patterns" is mentioned in that bug report, and does indeed "fix" the problem of the compiler generating calls to memset inside memset.

-JL
SeaOS: Adding VT-x, networking, and ARM support
dbittman on IRC, @danielbittman on twitter
https://dbittman.github.io
Post Reply