My OS currently has got a protected-mode and a longmode version. I use shared-libraries for libc (and other libraries). Since I use "-z nocopyreloc" for ld, I get "unresolvable R_X86_64_32S relocation" warnings (only about relocations to data in the shared-library) but only in my longmode version. But everything worked fine untill now. Today I had to discover painfully that under some circumstances this leads to real trouble. The following Code resulted from debugging binutil's cxxfilt (I know that this is worse code and non-standard conformant, but it did the job ):
Code: Select all
// NOTE: _sch_istable is an array of some type and it is in libiberty.so
printf("@ 0x%x\n", &_sch_istable[0]);
printf("@ 0x%x\n", &_sch_istable[c]);
That looks pretty weird (c is a character read from stdin)@ 0x70045160
@ 0x90
Then I looked into the build log and found ld complaining about exactly that symbol with a "unresolvable R_X86_64_32S relocation"... So my question is basically how could I fix that
I implemented shared-libraries like this: The code of a shared-library is shared between all process's and the data is copy-on-write. When I load a library I save all the symbols in a global list. If another shared-library or a process needs one of the symbols it looks into that table and the relocation is done with the information from this global table.
The normal ld behaviour would be to copy all data from the shared-libraries into the userspace app. But some libraries (e.g. libc++) need symbols from other libraries (e.g. a FILE structure for stdout). And since I don't want to patch libc++'s code for every process differently, I use -z nocopyreloc. That basically tells ld not to copy the shared-libraries data into the userspace (this would normally be done via a special relocation type), but to use the address from the shared-library. This works fine for x86, but it results in ld warnings on x86-64.
My current compile/link flags for applications (for x86-64) look like this:
C_FLAGS= -std=gnu99 -nostdlib -fno-builtin -Wall -fno-omit-frame-pointer -m64
LD_FLAGS= -z nocopyreloc
Adding -mcmodel=medium did not change anything. iirc I also tried to compile the libraries with fPIC (instead of fpic) and this also did not change a thing.
In case anyone wants to get his/her hands dirty you could do a subversion checkout and try to build lightOS yourself (But that implies building a cross-compiler...).
I hope I posted all the information needed. If there is anything missing, just ask for it