Page 1 of 1

ld acting extremely weird with multiple input files

Posted: Sat Jun 25, 2011 6:33 am
by Tobba
Yesterday I decided to split a part of my project into multiple files, since the main file was becoming too big
I moved the IDE driver to its own file, and since both that and my main file used both used IO functions like outb I moved those to their own file too

Now, recompiling it, ld is acting extremely weird, it is skipping over functions in one of my input files (outb in io.o)

My build script:

Code: Select all

i586-elf-gcc -c sysldr.c ide.c io.c
i586-elf-ld -T link.ld -o sysldr.bin -Map sysldr.map sysldr.o ide.o io.o
If i move io.o to before sysldr.o, it skips the entire file, if i move it before ide.o, it skips about half of it

And, taking a look at my link map, i see this:

Code: Select all

 .text          0x0000a464       0xa7 io.o
                0x0000a480                inb
                0x0000a4a8                outl
                0x0000a4be                inl
                0x0000a4e6                insl
outb is missing! and yes, it is (obviously) defined in io.c
objdump also shows that outb is in io.o, so its all compiled properly

ld throws these errors:

Code: Select all

ide.c:(.text+0x1c2): undefined reference to `outb'
ide.c:(.text+0x1fc): undefined reference to `outb'
ide.c:(.text+0x233): undefined reference to `outb'
ide.c:(.text+0x26a): undefined reference to `outb'
Some code if it helps:
io.h

Code: Select all

void outb(unsigned short port, unsigned char val);
unsigned char inb(unsigned short port);
void outl(unsigned short port, unsigned long val);
unsigned long inl(unsigned short port);
void insl(unsigned short port, void *buffer, unsigned long len);
io.c

Code: Select all

void outb(unsigned short port, unsigned char val)
{
	asm volatile( "outb %0, %1" : : "a"(val), "Nd"(port) );
}

unsigned char inb(unsigned short port)
{
	unsigned char ret;
	asm volatile( "inb %1, %0" : "=a"(ret) : "Nd"(port) );
	return ret;
}

void outl(unsigned short port, unsigned long val)
{
	asm volatile( "outl %0, %1" : : "a"(val), "Nd"(port) );
}

unsigned long inl(unsigned short port)
{
	unsigned long ret;
	asm volatile( "inl %1, %0" : "=a"(ret) : "Nd"(port) );
	return ret;
}

void insl(unsigned short port, void *buffer, unsigned long len)
{
	asm volatile( "rep insl" : : "Nd"(port), "D"(buffer), "c"(len) ); 
}

Re: ld acting extremely weird with multiple input files

Posted: Sat Jun 25, 2011 8:11 am
by Tobba
specifying files multiple times make it complain about re-defining functions though

And using --start-group and --end-group did not help
(I used it like this, since everything requires io.o)

Code: Select all

# i586-elf-ld -T link.ld -o sysldr.bin -Map sysldr.map --start-group sysldr.o ide.o io.o --end-group
And even if it only takes required things, it does not explain why it suddenly thinks nothing uses outb

Re: ld acting extremely weird with multiple input files

Posted: Sun Jun 26, 2011 5:03 am
by Tobba
berkus wrote:
Tobba wrote:specifying files multiple times make it complain about re-defining functions though
And even if it only takes required things, it does not explain why it suddenly thinks nothing uses outb
Try using gcc driver instead of ld directly.
I cant get it to use my linker script, I have to use ld directly

Either way, i just moved outb to ide.c so I could move onto the rest of my project

Guessing my cross compiler is bad

Re: ld acting extremely weird with multiple input files

Posted: Sun Jun 26, 2011 5:27 am
by Tobba
It tried with -Wl,-T too, it just spewed this from the linker

Code: Select all

/usr/local/cross/lib/gcc/i586-elf/4.5.1/../../../../i586-elf/bin/ld: crt0.o: No
such file: No such file or directory
collect2: ld returned 1 exit status
Just going to re-build my cross compiler with a newer GCC/binutils version if I run into worse problems

Re: ld acting extremely weird with multiple input files

Posted: Sun Jun 26, 2011 5:42 am
by gerryg400
I think you need

Code: Select all

-nostartfiles
and possibly

Code: Select all

-nostdlib

Re: ld acting extremely weird with multiple input files

Posted: Sun Jun 26, 2011 5:51 am
by Tobba
gerryg400 wrote:I think you need

Code: Select all

-nostartfiles
and possibly

Code: Select all

-nostdlib
Oh yeah, when I used ld seperately I didnt need those
All it did was breaking insl too though :|

Re: ld acting extremely weird with multiple input files

Posted: Sun Jun 26, 2011 6:11 am
by gerryg400
Are you using cygwin ? And are you making a binary formatted output file ?

If so the problem may be a known bug in the toolchain. I don't remember what the bug is but try temporarily setting your output format to ELF.

Check this thread

Re: ld acting extremely weird with multiple input files

Posted: Sun Jun 26, 2011 6:47 am
by Tobba
gerryg400 wrote:Are you using cygwin ? And are you making a binary formatted output file ?

If so the problem may be a known bug in the toolchain. I don't remember what the bug is but try temporarily setting your output format to ELF.

Check this thread
Ah, I though so, I'm on cygwin

I'm using a (decently) old GCC version though, an upgrade might help

And I cant change it to ELF currently, I'm not using GRUB, I'm using my own loader
I could objdump the code out, but it'd be awfully annoying and probably buggy

Re: ld acting extremely weird with multiple input files

Posted: Sun Jun 26, 2011 6:52 am
by gerryg400
I've got a feeling the bug isn't fixed even in later binutils releases. Others have had this same problem and used objcopy to convert the ELF file to binary in the last step.

I've thought about reporting the bug but I don't have access to Cygwin or windows.

Re: ld acting extremely weird with multiple input files

Posted: Sun Jun 26, 2011 7:40 am
by Owen
Building an ELF (or PE, or...) and then opjcopy-ing out a flat binary is the better strategy anyway. You get a binary with symbol information in it that you can use to generate listings, and pass to debuggers and such.