Page 1 of 1

Very strange link error

Posted: Wed Sep 02, 2009 8:05 am
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!

Re: Very strange link error

Posted: Wed Sep 02, 2009 8:33 am
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.

Re: Very strange link error

Posted: Thu Sep 03, 2009 12:58 am
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:

Re: Very strange link error

Posted: Thu Sep 03, 2009 3:42 am
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?

Re: Very strange link error

Posted: Thu Sep 03, 2009 4:07 am
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?

Re: Very strange link error

Posted: Thu Sep 03, 2009 10:31 am
by Combuster
You do have a cross-compiler right? Have you been changing path to include the wrong compiler somewhere?

Re: Very strange link error

Posted: Thu Sep 03, 2009 1:48 pm
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...

Re: Very strange link error

Posted: Thu Sep 03, 2009 3:23 pm
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.

Re: Very strange link error

Posted: Thu Sep 03, 2009 3:39 pm
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.

Re: Very strange link error

Posted: Thu Sep 03, 2009 3:48 pm
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.

Re: Very strange link error

Posted: Sun Sep 13, 2009 12:26 pm
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: ).