Page 1 of 2
LD Linking Problems... (2 of them...)
Posted: Tue Mar 30, 2004 1:14 pm
by astrocrep
Ok heres the thing... I am using djgpp under xp pro... and I am running a batch file to compile my os
Code: Select all
@echo off
echo Cleaning Up...
cd build
del *.o
del *.out
del *.bin
cd ..\source
del *.o
del *.out
del *.bin
cd ..
echo Entering Source...
cd source
echo Compiling Files...
set copt=-ffreestanding -nostdlib -fno-builtin -fno-rtti -fno-exceptions
nasm -f aout start.asm -o start.o
nasm -f aout misccode.asm -o misccode.o
nasm -f aout interrupts.asm -o interrupts.o
gxx -c %copt% *.cpp
move *.o ..\build
set copt=
echo Linking Objects
cd ..\build
ld -T kernel.ld -o kernel.bin *.o
echo Copying Kernel!
copy kernel.bin ..\..\Image
cd ..
Problem 1:
Originally instead of the wildcards I had each file named out... however the line that executes LD become longer than dos could support and as such linking became impossible. So I am now using wildcards... will this matter if the start procedure isn't at the head of the file? Or should I name the file with the start code 00start.o ?? This way it would technically be the first file?
Problem 2:
I am mixing C and Assembler code and having a nightmare... Inside C, calling an asm function is fine... however in asm calling an existing c function is nothing put troubles... gxx compiles fine and gives no errors... but linking goes crazy saying :
Code: Select all
interrupts.o(.text+0x12): undefined reference to `_int_00'
(1 error for each of my interrupt functions )
panic.o(.text+0xc):panic.cpp: undefined reference to `__Z5int00v'
(1 error for each of my interrupt functions )
It compiles fine no errors or anything
Heres a sample from interrupts.asm
Code: Select all
[extern _int_00]
[global _int00]
_int00:
pusha
push ds
push es
push fs
push gs
mov eax,0x10 ; Data segment
mov ds,eax
mov es,eax
cld
call _int_00 ; Divide by Zero #DE
pop gs
pop fs
pop es
pop ds
popa
iret
and heres some from panic.cpp
Code: Select all
void int_00(void)
{
printf("Divide By Zero Error");
}
and on the reverse side of the spectrum...
The CPP Code includess a header file which help refrence all of the assembler code:
I am soo lost by whats going on here... as you can probably tell... thanks for any help.
Rich P.
P.S. If anyone had any good examples or TUTs for making makefiles compatible with djgpp please let me know. Thanks again.
Re:LD Linking Problems... (2 of them...)
Posted: Tue Mar 30, 2004 1:18 pm
by astrocrep
Update on problem 2,
In my header file that declares the assembler based interrupt handlers I added
Code: Select all
extern "C" { all my functions... }
And it got rid of half my errors...
The ones that remain are genereated from the linker not being able to "find" the C++ Functions from ASM...
"undefined refrence"
Thanks for the help!
Rich P.
Re:LD Linking Problems... (2 of them...)
Posted: Tue Mar 30, 2004 1:25 pm
by Candy
astrocrep wrote:
Ok heres the thing... I am using djgpp under xp pro... and I am running a batch file to compile my os
what are "compile my os", "winxp" and "batch file" doing in the same post? Make has even been ported to windows-ish stuff, along with a decent shell, so you might want to consider that
Problem 1:
Originally instead of the wildcards I had each file named out... however the line that executes LD become longer than dos could support and as such linking became impossible. So I am now using wildcards... will this matter if the start procedure isn't at the head of the file? Or should I name the file with the start code 00start.o ?? This way it would technically be the first file?
You could do that, but you can also start using recursive linking. That also reduces the length of the compile line. Also, in a linker script you can list all the object files so you don't have to specify them on the command line anymore. As a final solution for a really big project you could start thinking about making it into multiple subdirectories and using something similar to recursive makefiles.
Problem 2:
I am mixing C and Assembler code and having a nightmare... Inside C, calling an asm function is fine... however in asm calling an existing c function is nothing put troubles... gxx compiles fine and gives no errors... but linking goes crazy saying :
Code: Select all
interrupts.o(.text+0x12): undefined reference to `_int_00'
(1 error for each of my interrupt functions )
panic.o(.text+0xc):panic.cpp: undefined reference to `__Z5int00v'
(1 error for each of my interrupt functions )
You are mixing C and assembler, and you are compiling with a C++ compiler. Because you indicate it's c++ code, the c++ name mangling is also done. Try using:
Code: Select all
extern "C" {
some C function definition or declaration
}
in your code to explicitly use C linkage, or rename it to .c and use that, or change your assembly code to conform to the naming of the c++-compiled code (your assembly function becomes '__Z5int00v' and your C function becomes '__Z6int_00v', the last one I'm not sure about.
Learn how your compiler transforms your code. It's a very useful thing to know when finding bugs.
P.S. If anyone had any good examples or TUTs for making makefiles compatible with djgpp please let me know. Thanks again.
[timbot] Use cygwin, not djgpp [/timbot] - cygwin uses default makefiles & include dirs.
Re:LD Linking Problems... (2 of them...)
Posted: Tue Mar 30, 2004 1:29 pm
by Pype.Clicker
you may like -fno-leading-underscore (info gcc for the exact syntax) which will make GCC use the 'real' name of a function/symbol instead of using _name.
The linker may indeed be sensitive to the order in which you pass .o files. May i suggest that you drop .o files in some directory distinct from the directory that has START.O and use something like
You may also love makefiles and linker scripts.
info make and
info ld will provide valuable tutorial about them
Re:LD Linking Problems... (2 of them...)
Posted: Tue Mar 30, 2004 2:01 pm
by astrocrep
I adjusted my batch file like pype.clicker said... thanks for the idea... and I am using the extern C to call my asm functions from C. But I am still unable to have my asm functions reach my c functions... I dunno what to do about this. Keep the ideas coming!
Thanks for the help guys,
Rich P.
Re:LD Linking Problems... (2 of them...)
Posted: Tue Mar 30, 2004 3:07 pm
by Candy
From reply #4:
But I am still unable to have my asm functions reach my c functions... I dunno what to do about this.
From reply #2:
change your assembly code to conform to the naming of the c++-compiled code (your assembly function becomes '__Z5int00v' and your C function becomes '__Z6int_00v', the last one I'm not sure about.
Or reformulated, you use c++ name mangling. You do not understand it. Stop using it badly or start using it properly, IE: stop using the compiler as a C++ compiler, or call your C functions from assembly as I said above (__Z6int_00v) (again, name not sure).
Re:LD Linking Problems... (2 of them...)
Posted: Tue Mar 30, 2004 3:20 pm
by astrocrep
Ive gotten past that problem...
Heres the flow of the code...
C++ Code loads up LDT with handlers... the wrappers are in asm and the asm calls C++ code...
The compiling and linking of the Installation of the handlers (ie the C++ code refrencing the ASM Code) is perfect no errors...
However the ASM Code the calls the C++ code fails upon linking... even if I remove my class refrences from it and compile it as a .c it still fails
asm code
Code: Select all
[extern _int_00]
[global _int00]
_int00:
pusha
push ds
push es
push fs
push gs
mov eax,0x10 ; Data segment
mov ds,eax
mov es,eax
cld
call _int_00 ; Divide by Zero #DE
pop gs
pop fs
pop es
pop ds
popa
iret
the linker cant find _int_00 actually its "void int_00(void)"
To clear up the confusion, int00 is the wrapper in asm, and int_00 is the c based handler...
Any other ideas ?
Thanks for the help,
Rich P.
Re:LD Linking Problems... (2 of them...)
Posted: Wed Mar 31, 2004 12:28 am
by Candy
You might want to search through the object file for all symbol names and find out what exactly its name becomes.
Re:LD Linking Problems... (2 of them...)
Posted: Wed Mar 31, 2004 2:07 am
by Pype.Clicker
Candy wrote:
You might want to search through the object file for all symbol names and find out what exactly its name becomes.
which you can do with "objdump -x YourFile.O | less"
yes, "less" exists for Djgpp (and probably for cygwin aswell
that's a wonderful tool for it can search regexps in the displayed document.
Re:LD Linking Problems... (2 of them...)
Posted: Wed Mar 31, 2004 3:25 am
by Solar
Candy wrote:
what are "compile my os", "winxp" and "batch file" doing in the same post? Make has even been ported to windows-ish stuff, along with a decent shell, so you might want to consider that.
I can understand him here... make is a very complex beast, with both syntax and documentation being less than enlightening. (I'm struggling to get a generic Makefile up and running myself ATM.)
Pype.Clicker wrote:
...which you can do with "objdump -x YourFile.O | less"
I have no idea if "grep" is available with DJGPP (and I second Candy and timbot, get Cygwin from
www.cygwin.com!), but if you have grep you can do:
objdump -d YourFile.O | grep "^[^ ]"
That yields much better-to-read output.
Re:LD Linking Problems... (2 of them...)
Posted: Wed Mar 31, 2004 11:55 am
by astrocrep
Ok I got cygwin... installed it w/ gcc and co. but using
yeilds
File format not recognized...
Interrupts.o is from interrupts.asm compiled with nasm into an aout file format... dunno if that makes a difference
However under djgpp objdump does work and this is what I get:
(Sorry its long... but I dunno exactly what I am looking for)
(Also remember int00 is the wrapper in asm, and int_00 is the c based handler...)
Code: Select all
interrupts.o: file format a.out-i386
interrupts.o
architecture: i386, flags 0x0000003f:
HAS_RELOC, EXEC_P, HAS_LINENO, HAS_DEBUG, HAS_SYMS, HAS_LOCALS
start address 0x00000000
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000258 00000000 00000000 00000020 2**3
CONTENTS, ALLOC, LOAD, RELOC, CODE
1 .data 00000000 00000258 00000258 00000278 2**3
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000258 00000258 00000000 2**3
ALLOC
SYMBOL TABLE:
00000000 *UND* 0000 00 01 _int_00
00000000 g .text 0000 00 05 _int00
00000000 *UND* 0000 00 01 _int_01
0000001e g .text 0000 00 05 _int01
00000000 *UND* 0000 00 01 _int_02
0000003c g .text 0000 00 05 _int02
00000000 *UND* 0000 00 01 _int_03
0000005a g .text 0000 00 05 _int03
00000000 *UND* 0000 00 01 _int_04
00000078 g .text 0000 00 05 _int04
00000000 *UND* 0000 00 01 _int_05
00000096 g .text 0000 00 05 _int05
00000000 *UND* 0000 00 01 _int_06
000000b4 g .text 0000 00 05 _int06
00000000 *UND* 0000 00 01 _int_07
000000d2 g .text 0000 00 05 _int07
00000000 *UND* 0000 00 01 _int_08
000000f0 g .text 0000 00 05 _int08
00000000 *UND* 0000 00 01 _int_09
0000010e g .text 0000 00 05 _int09
00000000 *UND* 0000 00 01 _int_10
0000012c g .text 0000 00 05 _int10
00000000 *UND* 0000 00 01 _int_11
0000014a g .text 0000 00 05 _int11
00000000 *UND* 0000 00 01 _int_12
00000168 g .text 0000 00 05 _int12
00000000 *UND* 0000 00 01 _int_13
00000186 g .text 0000 00 05 _int13
00000000 *UND* 0000 00 01 _int_14
000001a4 g .text 0000 00 05 _int14
00000000 *UND* 0000 00 01 _int_16
000001c2 g .text 0000 00 05 _int16
00000000 *UND* 0000 00 01 _int_17
000001e0 g .text 0000 00 05 _int17
00000000 *UND* 0000 00 01 _int_18
000001fe g .text 0000 00 05 _int18
00000000 *UND* 0000 00 01 _int_19
0000021c g .text 0000 00 05 _int19
00000000 *UND* 0000 00 01 _testint
0000023a g .text 0000 00 05 _int32
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000012 DISP32 _int_00
00000030 DISP32 _int_01
0000004e DISP32 _int_02
0000006c DISP32 _int_03
0000008a DISP32 _int_04
000000a8 DISP32 _int_05
000000c6 DISP32 _int_06
000000e4 DISP32 _int_07
00000102 DISP32 _int_08
00000120 DISP32 _int_09
0000013e DISP32 _int_10
0000015c DISP32 _int_11
0000017a DISP32 _int_12
00000198 DISP32 _int_13
000001b6 DISP32 _int_14
000001d4 DISP32 _int_16
000001f2 DISP32 _int_17
00000210 DISP32 _int_18
0000022e DISP32 _int_19
0000024c DISP32 _testint
Well actually, studing it for a while I did notice this
Code: Select all
00000000 *UND* 0000 00 01 _int_00
00000000 g .text 0000 00 05 _int00
UND means Undefined maybe ??
So means maybe Undefined int_00 (which is located in a cpp file)
the is being called in proc int00 (which is in the asm file)
But then it has a relocation table and I am not sure on how to handle that...
Thanks for the help all (sorry for being such a pain in the @$$)
Rich P.
Re:LD Linking Problems... (2 of them...)
Posted: Wed Mar 31, 2004 11:59 am
by Pype.Clicker
hmm ... i'm not sure it's a good idea to mix a.out (the nasm-generated .o file) with another format (i guesss .coff, for c++ generated files).
what does objdump give on gxx-generated files ?
Re:LD Linking Problems... (2 of them...)
Posted: Wed Mar 31, 2004 12:09 pm
by astrocrep
Very Very Wierd...
this is from version.cpp
Code: Select all
version.o: file format coff-go32
version.o
architecture: i386, flags 0x00000031:
HAS_RELOC, HAS_SYMS, HAS_LOCALS
start address 0x00000000
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000005c 00000000 00000000 000000b4 2**4
CONTENTS, ALLOC, LOAD, RELOC, CODE
1 .data 0000003c 00000000 00000000 00000110 2**4
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 00000000 2**2
ALLOC
3 .comment 00000014 00000000 00000000 0000014c 2**2
CONTENTS, DEBUGGING
SYMBOL TABLE:
[ 0](sec -2)(fl 0x00)(ty 0)(scl 103) (nx 1) 0x00000000 version.cpp
File
[ 2](sec 1)(fl 0x00)(ty 0)(scl 6) (nx 0) 0x00000032 LC0
[ 3](sec 1)(fl 0x00)(ty 0)(scl 6) (nx 0) 0x00000048 LC1
[ 4](sec 1)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000000 .text
[ 5](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __osfullName
[ 6](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000001a __osfullVer
[ 7](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000021 __osfullBuild
[ 8](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000034 __osfullBNum
[ 9](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000038 __osfullInternal
[ 10](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __Z6osNamev
[ 11](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000000a __Z9osVersionv
[ 12](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000014 __Z7osBuildv
[ 13](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000001e __Z10osBuildNumv
[ 14](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000028 __Z10osInternalv
[ 15](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x0000003e __Z10osCompDatev
[ 16](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000052 __Z10osCompTimev
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000004 dir32 __osfullName
0000000e dir32 __osfullVer+0xffffffe6
00000018 dir32 __osfullBuild+0xffffffdf
00000022 dir32 __osfullBNum+0xffffffcc
0000002c dir32 __osfullInternal+0xffffffc8
00000042 dir32 .text
00000056 dir32 .text
in my linker script is am using
I have 2 other asm files that I use w/ my kernel... one for startup... Which actualy calls a c++ procedure, and one for functions like write_cr0 read_cr0 write_cr3 write_cr3, those two both work file... if I switch the -f aout in my nasm commandline I get more errors on all c -> asm or asm -> c calls...
Thanks
Rich P.
Re:LD Linking Problems... (2 of them...)
Posted: Wed Mar 31, 2004 1:12 pm
by Pype.Clicker
and what does it work better when using nasm -f elf ?
Re:LD Linking Problems... (2 of them...)
Posted: Wed Mar 31, 2004 1:21 pm
by astrocrep
using -f elf gives the same amount of errors as with aout... but it it better than coff
Code: Select all
kernel\interrupts.o: In function `_int00':
kernel\interrupts.o(.text+0x12): undefined reference to `_int_00'
kernel\interrupts.o: In function `_int01':
kernel\interrupts.o(.text+0x30): undefined reference to `_int_01'
kernel\interrupts.o: In function `_int02':
kernel\interrupts.o(.text+0x4e): undefined reference to `_int_02'
kernel\interrupts.o: In function `_int03':
kernel\interrupts.o(.text+0x6c): undefined reference to `_int_03'
kernel\interrupts.o: In function `_int04':
kernel\interrupts.o(.text+0x8a): undefined reference to `_int_04'
kernel\interrupts.o: In function `_int05':
kernel\interrupts.o(.text+0xa8): undefined reference to `_int_05'
kernel\interrupts.o: In function `_int06':
kernel\interrupts.o(.text+0xc6): undefined reference to `_int_06'
kernel\interrupts.o: In function `_int07':
kernel\interrupts.o(.text+0xe4): undefined reference to `_int_07'
kernel\interrupts.o: In function `_int08':
kernel\interrupts.o(.text+0x102): undefined reference to `_int_08'
kernel\interrupts.o: In function `_int09':
kernel\interrupts.o(.text+0x120): undefined reference to `_int_09'
kernel\interrupts.o: In function `_int10':
kernel\interrupts.o(.text+0x13e): undefined reference to `_int_10'
kernel\interrupts.o: In function `_int11':
kernel\interrupts.o(.text+0x15c): undefined reference to `_int_11'
kernel\interrupts.o: In function `_int12':
kernel\interrupts.o(.text+0x17a): undefined reference to `_int_12'
kernel\interrupts.o: In function `_int13':
kernel\interrupts.o(.text+0x198): undefined reference to `_int_13'
kernel\interrupts.o: In function `_int14':
kernel\interrupts.o(.text+0x1b6): undefined reference to `_int_14'
kernel\interrupts.o: In function `_int16':
kernel\interrupts.o(.text+0x1d4): undefined reference to `_int_16'
kernel\interrupts.o: In function `_int17':
kernel\interrupts.o(.text+0x1f2): undefined reference to `_int_17'
kernel\interrupts.o: In function `_int18':
kernel\interrupts.o(.text+0x210): undefined reference to `_int_18'
kernel\interrupts.o: In function `_int19':
kernel\interrupts.o(.text+0x22e): undefined reference to `_int_19'
kernel\interrupts.o: In function `_int32':
kernel\interrupts.o(.text+0x24c): undefined reference to `_testint'
Thanks for the help,
Keep the ideas coming
Rich P.