Very strange link error

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
User avatar
hailstorm
Member
Member
Posts: 110
Joined: Wed Nov 02, 2005 12:00 am
Location: The Netherlands

Very strange link error

Post by hailstorm »

Hi Guys!

I think I need your help. Today I cleaned up the mess in my kernel source directory, creating more subdirectories in which my source files are now categorized. For now, I have a subdirectory for:
"the core" (core)
memory management (mm)
and last but not least, windows.
Therefore, I made a makefile for each subdirectory, so that each subdirectory will deliver one object file.
All object files are linked together in the final step. Before I post the makefiles, I give you the errormessage I get
in the final linking phase:

Code: Select all

ld -Tc:\os\script\hailos.ls -Map kernel.map -s -output-format=coff-i386 -o kerne
l.img start.o main.o core/core.o mm/mm.o windows/win.o tail.o
mm/mm.o:buddysys.c:(.data+0x0): multiple definition of `_environ'
core/core.o:binmath.asm:(.data+0x0): first defined here
windows/win.o:user_io.c:(.data+0x0): multiple definition of `_environ'
core/core.o:binmath.asm:(.data+0x0): first defined here
make.exe: *** [kernel.img] Error 1
My Makefiles are written as followed:

Main makefile:

Code: Select all

CC=gcc
AS=nasmw
CFLAGS=-Ic:\os\include -c -O2 -fomit-frame-pointer -Wall
AFLAGS=-f coff

LINKER_FILES = \
		start.o \
		main.o \
		core/core.o \
		mm/mm.o \
		windows/win.o \
		tail.o

kernel.img: $(LINKER_FILES)
	ld -Tc:\os\script\hailos.ls -Map kernel.map -s -output-format=coff-i386 -o kernel.img $(LINKER_FILES)


start.o: start.asm
	$(AS) $(AFLAGS) $^
	
main.o: main.c
	$(CC) -o $@ $(CFLAGS) $^

tail.o: tail.asm
	$(AS) $(AFLAGS) $^

core/core.o:
	cd core; make; cd ..
	
mm/mm.o:
	cd mm; make; cd ..

windows/win.o:
	cd windows; make; cd ..
	
clean:
	cd core; make clean
	cd ..\mm; make clean
	cd ..\windows; make clean
core makefile:

Code: Select all

CC=gcc
AS=nasmw
LD=ld
CFLAGS=-Ic:\os\include -c -O2 -fomit-frame-pointer -Wall
AFLAGS=-f coff

COMPILER_FILES = \
		binmath.o \
		console.o \
		crt.o \
		memlib.o \
		strlib.o \
		io.o \
		exceptions.o \
		context.o \
		x86.o \
		idt.o \
		gdt.o \
		cmos.o \
		kbd.o \
	    cpu_ints.o \
		hard_int.o \
		proc.o \
        pic.o \
		pit.o \
		irq.o \
		dma.o \
		sem.o \
		time.o \
		timer.o

core.o: $(COMPILER_FILES)
	$(LD) -r -output-format=coff-i386 -o core.o $(COMPILER_FILES)

%.o : %.c
	$(CC) $(CFLAGS) -c $< -o $@
	
%.o : %.asm
	$(AS) $(AFLAGS) -o $@ $<
	
clean:
	del *.o
mm makefile

Code: Select all

CC=gcc
AS=nasmw
LD=ld
CFLAGS=-Ic:\os\include -c -O2 -fomit-frame-pointer -Wall
AFLAGS=-f coff

COMPILER_FILES = \
		buddysys.o \
		paging.o \
		kcache.o 

mm.o: $(COMPILER_FILES)
	$(LD) -r -output-format=coff-i386 -o mm.o $(COMPILER_FILES)
		
%.o : %.c
	$(CC) $(CFLAGS) \
	-c -o $*.o $<
	
%.o : %.asm
	$(AS) $(AFLAGS) -o $*.o $<
	
clean:
	del *.o
windows makefile:

Code: Select all

CC=gcc
AS=nasmw
CFLAGS=-Ic:\os\include -c -O2 -fomit-frame-pointer -Wall
LD=ld
AFLAGS=-f coff

COMPILER_FILES = \
		user_io.o \
		window.o \
		win_ll.o 
		
win.o: $(COMPILER_FILES)
	$(LD) -r -output-format=coff-i386 -o win.o $(COMPILER_FILES)
		
%.o : %.c
	$(CC) $(CFLAGS) \
	-c -o $*.o $<
	
%.o : %.asm
	$(AS) $(AFLAGS) -o $*.o $<
	
clean:
	del *.o
I have a the feeling it has something to do with the linker-flags, although I can't put my finger on it. Any
help is appreciated.

Greetz!
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Very strange link error

Post by Solar »

The error message is pretty clear, and hasn't got anything to do with your Makefiles:

Code: Select all

mm/mm.o:buddysys.c:(.data+0x0): multiple definition of `_environ'
core/core.o:binmath.asm:(.data+0x0): first defined here
In mm/mm.o, more precisely the source file buddysys.c, there is a definition of the symbol _environ. The same symbol is also defined in core/core.o, more precisely binmath.asm. The Linker cannot resolve the ambiguity and asks you to remove one of the two definitions.

Oh, and one seperate Makefile per subdirectory is a bad, but commonplace mistake.
Every good solution is obvious once you've found it.
User avatar
hailstorm
Member
Member
Posts: 110
Joined: Wed Nov 02, 2005 12:00 am
Location: The Netherlands

Re: Very strange link error

Post by hailstorm »

Whether using multiple makefiles is a bad practice, it's a good solution for me right now. But I surely will read the article about this issue you posted in your message.

Believe it or not, but the unresolved symbol "_environ" is nor used nor declared anywhere in my code. Searching the internet, I found that his symbol is used by the compiler to pass environment variables to the main program, if I read and understood it correctly. Therefore I think it has something to do with the linker or compiler flags I use (or don't use) in all of my makefiles in each subdirectory.

Another funny thing I discovered is that it's complaining about all three subcomponents of my kernel. The core, mm and windows objects seem to have this symbol declared. Second, the sourcefile that contains the declaration according to the linker is each time the first file declared in the makefiles.

I hope I made myself somewhat clearer about the problem, because I can't put my finger on it. :cry:
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Very strange link error

Post by pcmattman »

Code: Select all

CFLAGS=-Ic:\os\include -c -O2 -fomit-frame-pointer -Wall
I can't help but notice a lack of -ffreestanding -fno-builtins, -nostdlib, and friends?
User avatar
hailstorm
Member
Member
Posts: 110
Joined: Wed Nov 02, 2005 12:00 am
Location: The Netherlands

Re: Very strange link error

Post by hailstorm »

I have encountered these flags in the manual pages, but I didn't knew for sure if I needed them.
I will try out and let you know.

Thanks in advance!

Edit
Nope, didn't work. By the way, how is it possible that something that compiled and linked perfectly before, now suddenly (after moving some files to another directory, creating a number of makefiles...) stops working?
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: Very strange link error

Post by Combuster »

You do have a cross-compiler right? Have you been changing path to include the wrong compiler somewhere?
"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 ]
User avatar
hailstorm
Member
Member
Posts: 110
Joined: Wed Nov 02, 2005 12:00 am
Location: The Netherlands

Re: Very strange link error

Post by hailstorm »

Yes, I have a cross compiler. I am using gcc, but I didn't change the path environment variable.
I am digging through all manuals I can find on gcc and ld, but I still can't figure out what's causing the problem.
On the internet I found a few messages on other forums with more people that are bothered by this issue.
No solution is posted there also... :? It is really driving me mad...
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Very strange link error

Post by neon »

Hello,
Believe it or not, but the unresolved symbol "_environ" is nor used nor declared anywhere in my code.
If its never used, just define it yourself and move on. Always works for me (although I dont use GCC)...might work for a temporary solution:

Code: Select all

unsigned int environ;
As long as the symbol is defined in a source file [possibly need to extern it from a common header file] it should stop the linker from complaining.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
gravaera
Member
Member
Posts: 737
Joined: Tue Jun 02, 2009 4:35 pm
Location: Supporting the cause: Use \tabs to indent code. NOT \x20 spaces.

Re: Very strange link error

Post by gravaera »

As an append to what neon said: you should also do some research and find out what feature of the language requires the symbol, and if it is relevant to your kernel, give it an implementation. Try checking the ABI.
17:56 < sortie> Paging is called paging because you need to draw it on pages in your notebook to succeed at it.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Very strange link error

Post by pcmattman »

Code: Select all

CC=gcc
Combuster wrote:You do have a cross-compiler right?
Unless your Makefiles have changed since then, you're still using your host compiler, not a cross-compiler.
User avatar
hailstorm
Member
Member
Posts: 110
Joined: Wed Nov 02, 2005 12:00 am
Location: The Netherlands

Re: Very strange link error

Post by hailstorm »

I would like tell you all that I found a suitable, not the most wanted, solution to end my problem. When I was linking one of my sub components, I used the --verbose switch. Since the subcomponents aren't linked with the help of a linkerscript, the linker made up one of it's own. This automatic script, or whatever it was, contained the following keyword: PROVIDE(_environ = .)
Since it put it there at all three subcomponents, this sysmbol was defined three times, but not by me.

My solution is simple; I copied the linkerscript I use for the big link and made one linkerscript for all three subcomponents. Of course, I pulled out all the symbols that would lead to the same error as before, and linked again. It linked and worked perfectly (as perfect as my kernel ran before, which is, of course in the eye of the beholder :mrgreen: ).
Post Reply