Linking C & Asm not working, references not found.

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.
wacco

Linking C & Asm not working, references not found.

Post by wacco »

Hi there,

I've been trying to link my bootmanager files together, without much luck. Therefore I decided to build a little test thingy to see what goes wrong with the whole linking, and it's weird...
I've got three files, test.asm, main.c and Makefile. This is what they contain:

Code: Select all

Test.asm:
  [bits 32]
  GLOBAL _test
  _test: ret

main.c:
  void test();
  int main() {
    test();
    return 0;
  }

Makefile:
  test:
    nasm -fcoff -o test.o test.asm
    gcc -C -Wall main.c
    ld --oformat binary -e_main -omain.bin test.o main.o
After hitting make on the command line, everything goes without a fuss, except for ld. I get the following note:

Code: Select all

make:
  main.o(.text+0x1d) main.c: undefined reference to '_test'
  make.exe: *** [test] Error 1
My system is currently running windows 2000 Sp3 (My FreeBSD machine is right now in Amsterdam, I'm in Belfast... >:( ) with djgpp. Binutl-2.15, Gcc-3.42 and Make-3.791. The nasm version is unknown to me, I've placed it manually in the bin folder of djgpp and have been using that binary for a while now, so I can't even recall where I got it...
When I open the object files in notepad they look okay, with .text, .data etc. And _test can be read in it as well.

So... what am I doing wrong? I've got this feeling it's not my code but I sure hope it is... I'm not having internet at home right now (writing from work) so reinstalling stuff get's really tricky. Not to mention quick tests or requests for more info than I just gave. In that case, you'll have to wait till monday ;)

Thanks in advance, [: wacco :]
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Linking C & Asm not working, references not found.

Post by Solar »

Can't exactly reproduce here, I only have GAS / GCC on a Sparc ATM, but it should work. (With a bit of tampering with NASM vs. GAS syntax, it does work here.)

Use [/tt]objdump -d file[/tt] to check the symbols exported by each object file, and check NASM's and GCC's settings in regards to leading underscores.
Every good solution is obvious once you've found it.
B.E

Re:Linking C & Asm not working, references not found.

Post by B.E »

try adding an extern statement in main.c
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Linking C & Asm not working, references not found.

Post by Solar »

Nope. *shakeshishead* Funktion declarations at file level are automatically extern (or the compiler would already complain about not being able to find _test).
Every good solution is obvious once you've found it.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Linking C & Asm not working, references not found.

Post by Candy »

wacco wrote:

Code: Select all

Test.asm:
  [bits 32]
  GLOBAL _test
  _test: ret

main.c:
  void test();
  int main() {
    test();
    return 0;
  }

Makefile:
  test:
    nasm -fcoff -o test.o test.asm
    gcc -C -Wall main.c
    ld --oformat binary -e_main -omain.bin test.o main.o
After hitting make on the command line, everything goes without a fuss, except for ld. I get the following note:

Code: Select all

make:
  main.o(.text+0x1d) main.c: undefined reference to '_test'
  make.exe: *** [test] Error 1
Your system might not prefix underscores. It might mangle the names of the functions. It might prefer to jump through hoops and order a pizza instead.

Did you compile your own compiler?

As for a quick solution:
Use objdump -t on the main.o file and see what the name is. Use it on the test.o too to see what it was exported as (and whether it was exported).

Try to see if both are the same type of file.
My system is currently running windows 2000 Sp3 (My FreeBSD machine is right now in Amsterdam, I'm in Belfast... >:( )
SSH only failed me when the box was reset by somebody. Twice today actually, but aside from that it's stable.

If not, can you send me both binary .o files? email address in profile is correct.
wacco

Re:Linking C & Asm not working, references not found.

Post by wacco »

Your system might not prefix underscores. It might mangle the names of the functions. It might prefer to jump through hoops and order a pizza instead.

Did you compile your own compiler?
Not exactly sure what you mean with 'prefix underscores', but the linker looks for the object _test which is called from main (and -e_main works, -emain gives an error with a 'defaulting to') so gcc adds the underscores. It seems highely unlikely that nasm /removes/ them or something, and I've tried last evening to compile & link it with 'test' instead of '_test' in the assembly file. Without result. If nasm would add an underscore, it would have worked...
Oh, and I haven't compiled my own compiler. And I'm not having any way to get the gcc source files to my computer at the moment (no internet at home and work computers are seriously locked down).
If not, can you send me both binary .o files? email address in profile is correct.
I'll check if my djgpp install has objdump. If not I'll toss the files in a rar and burn it on a cd, and I'll try to find a computer here tomorrow which still has a cdrom player :)
Use [/tt]objdump -d file[/tt] to check the symbols exported by each object file, and check NASM's and GCC's settings in regards to leading underscores.
Not sure how to check nasm's & gcc's settings. Afaik there are no config files or anything (at least, I'm pretty sure there isn't one for nasm, maybe there is one for gcc but I wouldn't know where). Commandline options seemed correct though... I've been fiddling a bit with the nasm output flag, and besides the fact that it was pretty obvious, the only thing ld understood without errors was coff. Any other type and ld start borking on that fact. Of course we can conclude from this that ld /understands/ the test.o coff object file without a problem, but it doesn't seem to get the right _test info...

Weird Stuff. If anybody would like to see me do some tests, please tell me within 4 hours, cuz them I'm outta here ;)
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Linking C & Asm not working, references not found.

Post by Pype.Clicker »

shouldn't "gcc -C" be "gcc -c" instead ?
wacco

Re:Linking C & Asm not working, references not found.

Post by wacco »

-C Do not discard comments. All comments are passed through to the output file, except for comments in processed directives, which are deleted along with the directive.
&&
-c Compile or assemble the source files, but do not link. The linking stage simply is not done. The ultimate output is in the form of an object file for each source file.
Well, that sounds promising! Can't wait till I'm done working! :P
Chris Giese

Re:Linking C & Asm not working, references not found.

Post by Chris Giese »

try adding "SECTION .text" near the top of test.asm.

Looking at test.o file, it seems to make a difference. Without the SECTION directive:

nm -n test.o
U _test
00000000 a .absolut
00000000 t .text

With the directive:

nm -n test.o
00000000 a .absolut
00000000 t .text
00000000 T _test

Anyone here on the NASM mailing list? This seems like a bug. I thought the NASM docs said something about ".text" being the default segment/section? At least other assemblers (TASM) will say something like "code emission to undeclared segment"
wacco

Re:Linking C & Asm not working, references not found.

Post by wacco »

Chris Giese: I'll try it when I'm back home, and you'll hear from me on monday :)

About objdump, a run of make, and I figured out how to get the version of nasm:

Code: Select all

C:\DOCUME~1\wacco\MYDOCU~1\MYCODE~1\Perseus\codebase\try>objdump -t test.o

test.o:     file format coff-go32

SYMBOL TABLE:
[  0](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x00000000 test.asm
File
[  2](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .text
AUX scnlen 0x1 nreloc 0 nlnno 0
[  4](sec -1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000000 .absolut
[  5](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 _test

C:\DOCUME~1\wacco\MYDOCU~1\MYCODE~1\Perseus\codebase\try>objdump -t main.o

main.o:     file format coff-go32

SYMBOL TABLE:
[  0](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x00000000 main.c
File
[  2](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .text
AUX scnlen 0x28 nreloc 1 nlnno 0
[  4](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .data
AUX scnlen 0x0 nreloc 0 nlnno 0
[  6](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .bss
AUX scnlen 0x0 nreloc 0 nlnno 0
[  8](sec  4)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .comment
AUX scnlen 0x11 nreloc 0 nlnno 0
[ 10](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 _main
[ 11](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 _test

C:\DOCUME~1\wacco\MYDOCU~1\MYCODE~1\Perseus\codebase\try>make
nasm -fcoff -o test.o test.asm
gcc -c -Wall main.c
ld --oformat binary -e_main -omain.bin test.o main.o
main.o(.text+0x1d):main.c: undefined reference to `_test'
make.exe: *** [test] Error 1

C:\DOCUME~1\wacco\MYDOCU~1\MYCODE~1\Perseus\codebase\try>nasm -r
NASM version 0.98
Now I know how coff works in basics, but the info objdump gives here keeps me clueless... hope that some of you guys do know what it all means :)

For the people who wanted to see the object files, the zip is actually a rar (since rar isn't allowed as an attachement) so rename it... after that you'll see the c, h, Makefile, and objectfiles.

Thanks for the effort!
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Linking C & Asm not working, references not found.

Post by Pype.Clicker »

what troubles me is that your "_test" symbol is in section 0 in both files (which means, iirc, that it's an external symbol to be resolved, and not a local symbol.?..)
wacco

Re:Linking C & Asm not working, references not found.

Post by wacco »

Chris Giese wrote: try adding "SECTION .text" near the top of test.asm.
Wheeee that did the trick! Excellent! Just weird that I have to explicitly tell nasm so... but whatever, it works! :D

Thanks! Now back to coding, cuz finally we're getting somewhere ;D (with a bit of luck you'll see the first kernel-less OS ever (afaik) posted here before the end of the month, otherwise you'll have to wait half a year ;) )
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Linking C & Asm not working, references not found.

Post by Solar »

wacco wrote:
...the first kernel-less OS ever...
Not wanting to spoil your fun, but depending on your definition of "kernel-less" prepare for a nasty surprise. Exokernels are, while not exactly mainstream, not a novelty anymore either.
Every good solution is obvious once you've found it.
wacco

Re:Linking C & Asm not working, references not found.

Post by wacco »

Yeah, but I'm not talking about an exokernel, I'm talking about no kernel at all. An exokernel still has an interface which processes call, and the kernel than refers them to the userspace processes dealing with that request. In my case, the processes get entries in their ldt and can call those processes straight away, and there is no ring-0 'kernel' anymore. Even the whole set up of a new process is done in userspace and the only 'kernel' part is the actual 'this process is set up, let the isr which is dealing with the process multitasking know it's there'. But that's hardly worth the name 'kernel'.

At least, that's the idea.

We'll see how far I get it working before something pops up and I need more stuff running in ring0 ;) I might add two very small callbacks for ldt / gdt editting, but it's probably possible to do that at the 'register' stage, and my process manager (which runs in userspace) deals with the setup for that (by communicating with the userspace-memmanager (which basicly has all the memory malloc()'ed, and free()'s pages when some other process malloc()'s) and filesystem (which uses I/O permission bitmaps to run in userspace as well)). :)

But I'm telling to much here, let's see if I can implement it first, then we'll talk ;)
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Linking C & Asm not working, references not found.

Post by Solar »

wacco wrote: Yeah, but I'm not talking about an exokernel, I'm talking about no kernel at all. An exokernel still has an interface which processes call, and the kernel than refers them to the userspace processes dealing with that request.
Erm... wrong. Exokernels strive to do only the multiplexing of hardware ressources, while leaving abstraction to user-defined libraries (running in ring 0).
In my case, the processes get entries in their ldt and can call those processes straight away, and there is no ring-0 'kernel' anymore.
Somewhere there has to be code running in ring 0 to do the stuff that can only be done in ring 0.

But we're getting rapidly OT here. ;)
Every good solution is obvious once you've found it.
Post Reply