This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: gas/ld x86 16-bit 64kb limit and ominous "unreal mode"
- From: Etienne Lorrain <etienne_lorrain at yahoo dot fr>
- To: Josef Angermeier <sijoange at cip dot informatik dot uni-erlangen dot de>
- Cc: binutils at sources dot redhat dot com
- Date: Mon, 4 Jul 2005 11:52:33 +0200 (CEST)
- Subject: Re: gas/ld x86 16-bit 64kb limit and ominous "unreal mode"
Hello Josef,
--- Josef Angermeier <sijoange@cip.informatik.uni-erlangen.de> wrote:
> Hello Etienne
>
> > GAS does not care of the address of functions, it just emit a "near
> > long" or "far short" call with a relocation in the object file
> > with a 32bits relocation field.
>
> Ok, principially thats right. In my case, i used the "-Os", optimizing
> size option and then gas produced also lots of 16-bit relocs. Didn't
> know about that connection before... ok, let's go ahead!
Even with -Os, which is a GCC option so has no influence on GAS, the
only 16 bits relocs in Gujin are in the assembler inserts: asm("...").
At some point, I wanted to remove all the 16 bits relocs to
be able to do a link even if the executable was non-useable
(>65536 offsets) to know the size of sections .code, .xcode ...
> > A really clean solution for calll (i.e. call far) would probably be to
> > add another kind of relocation adjusting the linear address to a
> > segment:offset pair (to use only for far call and indirect far call),
> > and put all the code in the same section (of max 640 Kbytes), but I did
> > not need that for Gujin.
>
> Yes, i think i'll try that, because the bios-code shall be extendable to
> 500kb, best 1MB. Because the code shall be compilable without somehow
> patched ld/gas i will try to do ld all the address relocation stuff, and
> write a post-linker-tool, which patches the call to far calls and the
> 32-bit addresses to segment:off ones. Hopefully the code/data references
> can all be replaced accordingly.
You can't reliably find the beginning of assembly instructions in a
binary executable, to search for call's and ret's. You have to patch
ld to do what I describled, i.e. force a relocation (in the object file)
which fit in 20 bits to be inserted (after a far call, direct or indirect)
in the executable on the segment:offset form by ld. I do not know how
to do the conversion (i.e. only 16 segments 0x0000, 0x1000, 0x2000... or
having only offset below 0x000F, or a mix of that), I just know that
a function cannot cross a segment boundary, i.e. be bigger than 64 Kbytes.
You will also need a GCC or GAS patch to end functions by "retl/retl n".
This system cannot be applied to data because the 80x86 does not have
a "load far address into register" assembler instruction, you have to
load first the segment, then use this segment in the "load to register"
assembly instruction. Please use segment %fs for that, i.e. the convention
that %ds = %es = %ss at all times, %gs preserved by function call, %fs
temporary and not preserved by function call.
> > This solution may smell bad if you have two relocation at the
> > same place (addition not possible), but most of the time you will
> > only add on segment and substract on offset. I do not know, that
> > could probably work.
> Mmm, are you talking about the all-in-one-section-solution or not ? -
> where is there a problem ?
Yes, all in one code section. the call far is not relative to current
position so you can ignore the initial value of the relocation you will
read in the object file, but you will have multiple relocation
produced by GCC at the same place if you have pointer calculus like:
int fct1(void) {return 1;}
int fct2(void) {return 2;}
static const unsigned fct1_length = (unsigned)fct2 - (unsigned)fct1;
> Thanks Etienne, have been a great help for me
Cheers,
please note that this is complex stuff you are looking at, not a two
weeks project...
___________________________________________________________________________
Appel audio GRATUIT partout dans le monde avec le nouveau Yahoo! Messenger
Téléchargez cette version sur http://fr.messenger.yahoo.com