Subject: Linking

From: "Adam 'WeirdArms' Wiggins" <[email-masked]>
Date: Thu, 19 Aug 1999 02:41:48 +1000 (EST)

Why can the linker not deal with function calls more then a 26 bit
address offset from teh PC? Isn't this what long jump is for? Am I missing
something here? Any help appreciated.

	Cheers Adam

unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Philip Blundell <[email-masked]>
Date: Sat, 21 Aug 1999 22:06:36 +0100

>address offset from teh PC? 

The B instruction only has a 24-bit displacement field.  That stores a number
of words which gives you a 26-bit address offset.  To do jumps beyond that, 
the linker would have to bounce the call through a PLT entry.  It probably 
wouldn't be too hard to make this happen automatically for out of range 
jumps if you wanted (though this should be controlled by a switch).  As a 
matter of passing interest modutils already does something a bit like this 
so that kernel modules can be quite distant from the main code body.

Another possibility would be to extend the compiler and/or assembler to let 
you declare a particular function call as being "long" and have that generate 
code that rather than a straightforward branch contained code a bit like this:

	mov	lr, pc
	ldr	pc, =target

It would take quite a lot to convince me that the latter was worth including 
in GCC, though.  The linker thing seems conceptually cleaner - there will be 
a performance hit but I doubt it is measurable.

In theory a smart linker could actually perform the second trick too but GNU 
ld isn't currently up to it.

(Why do you want to do this in the first place, by the way?)

p.

---

From: "Adam 'WeirdArms' Wiggins" <[email-masked]>
Date: Sun, 22 Aug 1999 08:32:05 +1000 (EST)

> of words which gives you a 26-bit address offset.  To do jumps beyond that, 

	I relise that but isn't this a common thing in RISC chips and
linkers/compilers use long jump?

> ld isn't currently up to it.

	Ic.
> (Why do you want to do this in the first place, by the way?)
	I have initialiseation an initialisation section and a kernel text
section (both loadable segments) The initialisation section is mapped
one-one at 0xC0100000 (on the SA-1100) and the text section is mapped to
0xFFFF0000. I have debugging calls in the text section that I try to call
from the init sectin (putc, printf, dumpPT, etc) but the 26bit branching
gets in the way. I could use ASM macro's to make the calls but this seems
abit messy, is there a nice solution to this problem. Another solution is
to have the functions linked in both sections with different names but
again I think this is a bit messy.

	Cheers Adam

---

From: Philip Blundell <[email-masked]>
Date: Sat, 21 Aug 1999 23:59:24 +0100

>linkers/compilers use long jump?

What do you mean by "long jump"?

>again I think this is a bit messy.

Well, -fPIC is the obvious solution if you can handle the overhead.

p.

---

From: Nicolas Pitre <[email-masked]>
Date: Sat, 21 Aug 1999 19:26:33 -0400 (EDT)

> code that rather than a straightforward branch contained code a bit like this:

A C construct like this should also do the trick:

extern void func();
void (*target)() = func;

foo()
{
    target();
}

Nicolas Pitre, B. ing.
[email-masked]

---

From: "Adam 'WeirdArms' Wiggins" <[email-masked]>
Date: Sun, 22 Aug 1999 10:41:22 +1000 (EST)

> What do you mean by "long jump"?

	Isn't long jump a gcc function used to make cals to functions
further away then the branch inst allows? I might be confusing it
something else though.
> Well, -fPIC is the obvious solution if you can handle the overhead.

	Ah cheers, such a simple solution. Since its initialisation and
debugging code only that will be compiled like this its fine. 

	Many thanks, Adam

---

From: Philip Blundell <[email-masked]>
Date: Sun, 22 Aug 1999 14:20:02 +0100

>further away then the branch inst allows? 

Not as far as I know.  If you're thinking of __builtin_longjmp this is 
something rather different.

There isn't a great deal the compiler can do to help, because it doesn't know 
where each bit of code will end up in the final program image so it has no way 
of telling which branches will need a "far" jump instruction.  This is why 
it's really a job for the linker to fix things up.  Would probably make an 
interesting project for someone who wanted to get familiar with BFD.

p.