Subject: linker problem: relocation truncated to fit

From: Petter Reinholdtsen <[email-masked]>
Date: Sun, 16 Sep 2001 14:17:54 +0200

Hello

I'm using debian/mips (sid) on an SGI Indy with 256 MB RAM.  It is as
far as I know up to date with the latest packages.

When I try to compile and link a huge C++ program using Qt and various
other libraries, I get strange error message like this during linking:

  libopera.a(registerdialog.o): In function
    `RegisterDialog::RegisterDialog(QWidget *, char const *, bool)':
  linux/ui/registerdialog.cpp(.text+0xd08): relocation truncated to
    fit: R_MIPS_GOT16 RegisterDialog virtual table
  libopera.a(registerdialog.o): In function
    `RegisterDialog::slotOk(void)':
  linux/ui/registerdialog.cpp(.text+0xdd8): relocation truncated to
    fit: R_MIPS_CALL16 RegisterWidget::verifySettings(void)
  libopera.a(registerdialog.o): In function `onceinalifetime(void)':
  regkey/regver.h(.text+0x10d8): relocation truncated to fit:
    R_MIPS_CALL16 regkey_init(void)

Is this a known problem, and is there anything I can do to fix it?

% dpkg -l | egrep 'gcc|binutils|g\+\+'
ii  binutils       2.11.90.0.31-1 The GNU assembler, linker and binary utiliti
ii  g++            2.95.4-6       The GNU C++ compiler.
ii  g++-2.95       2.95.4-0.01090 The GNU C++ compiler.
ii  gcc            2.95.4-6       The GNU C compiler.
ii  gcc-2.95       2.95.4-0.01090 The GNU C compiler.

---

From: "H . J . Lu" <[email-masked]>
Date: Sun, 16 Sep 2001 09:16:54 -0700

>     R_MIPS_CALL16 regkey_init(void)

This may be a MIPS linker bug/limitation. But I don't use Qt on mips
and have no plan to do so. If you can provide a complete testcase,
in this case, every single file used for the final linking, I will
take a look.

H.J.

---

From: Wilbern Cobb <[email-masked]>
Date: Sun, 16 Sep 2001 13:29:38 -0300 (ADT)

> This may be a MIPS linker bug/limitation. But I don't use Qt on mips

This is a `feature' of the MIPS toolchain. Global and static items <= n
bytes are placed into the small data or small bss sections instead of
the normal data or bss sections as an optimization. Excess items would
cause these linker errors.

Pass the compiler the -Gn flag (default is 8 bytes), ie. -G4 should work
for most purposes.

-vedge

---

From: Petter Reinholdtsen <[email-masked]>
Date: Mon, 17 Sep 2001 00:07:19 +0200

[Wilbern Cobb]
> Pass the compiler the -Gn flag (default is 8 bytes), ie. -G4 should work

I tried -G4, -G2 and -G1 without any luck.  Even with -G1 there are still
more than 9300 relocation messages.  (Do I need to compile all the object
files again, by the way?  I've only tried to relink -- it takes 12 hours
to compile :-( ))

Unfortunately, my problem is with is a prorietary software product
(Opera web browser), so I can not send you any source or object files.
:-(

---

From: Ryan Murray <[email-masked]>
Date: Sun, 16 Sep 2001 15:38:57 -0700

> I tried -G4, -G2 and -G1 without any luck.  Even with -G1 there are still

I don't think -G is the problem here.  The problem is that the GOT
needs to be bigger than a 16 bit value.  The only way to do this is to
recompile everything that is going to be linked in statically
(libc_noshared.a and libgcc.a included) with -Wa,-xgot This problem
currently affects openh323 and mozilla, among other things.

-- 
Ryan Murray, Debian Developer ([email-masked], [email-masked])
The opinions expressed here are my own.

---

From: "H . J . Lu" <[email-masked]>
Date: Sun, 16 Sep 2001 15:50:03 -0700

> currently affects openh323 and mozilla, among other things.

I don't think mips is the only platform which has this problem. Do
Alpha, PowerPC and Sparc have similar problems like that? What are
the solutions for them?

BTW, it sounds like the -fpic vs. -fPIC issue. 

H.J.

---

From: Wilbern Cobb <[email-masked]>
Date: Sun, 16 Sep 2001 19:50:08 -0300 (ADT)

> (Opera web browser), so I can not send you any source or object files.

You most definately need to recompile all object files, sorry =).

-vedge

---

From: Ralf Baechle <[email-masked]>
Date: Mon, 17 Sep 2001 03:50:40 +0200

> Pass the compiler the -Gn flag (default is 8 bytes), ie. -G4 should work

Default is -G0 because GP optimization isn't supported with SVR4 PIC code.

SVR4 code uses the $gp register as a pointer to the middle of a 64kbyte
sized data segment called GOT, global offset table.  A GOT overflow results
in obscure error messages as you observe them.

The only easy way to get around this is -Wa,-xgot and making sure that all
the static objects like libgcc which can't be rebuilt easily with -Wa,-xgot
get linked in first.  More effort is splitting files with this problem into
multiple shared libraries each below the critical size but this usually
results in better code.

The best solution which currently isn't supported by binutils is a multi-got
code model.

  Ralf

---

From: Ralf Baechle <[email-masked]>
Date: Mon, 17 Sep 2001 03:55:09 +0200

> BTW, it sounds like the -fpic vs. -fPIC issue. 

It is.  Yet I wouldn't like to assign a different meaning to -fpic and
-fPIC as most makefiles make little difference between these two options,
so that would imply quite some overhead.

  Ralf

---

From: Richard Henderson <[email-masked]>
Date: Mon, 17 Sep 2001 15:40:01 -0700

> so that would imply quite some overhead.

There is already such a difference.  Sparc uses 13-bit GOT offsets
with -fpic and 32-bit offsets with -fPIC.  I'm considering changes
to Alpha to use a 16/32 split for pic/PIC.

r~

---

From: Richard Henderson <[email-masked]>
Date: Mon, 17 Sep 2001 15:47:54 -0700

> Alpha, PowerPC and Sparc have similar problems like that? What are

Alpha has a complicated scheme by which every input object file may
be assigned to a different GOT, each of which is limited to 64k.  The
other reason this works is that variables assigned to .sdata/.sbss 
are _not_ treated differently wrt code generation.  Instead, this is
optimized via linker relaxation.

IA-64 will overflow its small data area at 22 bits.

PowerPC and Sparc do not use .sdata/.sbss.

r~

---

From: Jakub Jelinek <[email-masked]>
Date: Tue, 18 Sep 2001 00:56:01 +0200

> PowerPC and Sparc do not use .sdata/.sbss.

Minor correction: PowerPC uses .sdata/.sbss, Sparc does not.

	Jakub

---

From: "H . J . Lu" <[email-masked]>
Date: Mon, 17 Sep 2001 15:53:25 -0700

> to Alpha to use a 16/32 split for pic/PIC.

Can you mix object files compiled with -fPIC/-fpic on Sparc/Alpha?

H.J.

---

From: Richard Henderson <[email-masked]>
Date: Mon, 17 Sep 2001 15:56:16 -0700

> Can you mix object files compiled with -fPIC/-fpic on Sparc/Alpha?

Yes, but of course the total GOT/small data area is constrained
by the size allowed by -fpic.

r~

---

From: Jakub Jelinek <[email-masked]>
Date: Tue, 18 Sep 2001 01:01:07 +0200

> Can you mix object files compiled with -fPIC/-fpic on Sparc/Alpha?

At least on the Sparc, you can mix them as you want, if you don't
overflow the signed 13bit relocs in -fpic objects. The linker will tell
you...

	Jakub

---

From: "H . J . Lu" <[email-masked]>
Date: Mon, 17 Sep 2001 16:06:28 -0700

> by the size allowed by -fpic.

It doesn't help much if you do need -fPIC on some Qt code. Since I
don't use Qt on mips, I will let others work on it.

H.J.

---

From: Ralf Baechle <[email-masked]>
Date: Mon, 17 Sep 2001 03:55:09 +0200

Ralf

---

From: Geoff Keating <[email-masked]>
Date: Thu, 20 Sep 2001 15:52:30 -0700

> Date: Mon, 17 Sep 2001 15:47:54 -0700
> From: Richard Henderson <[email-masked]>
> Cc: Ryan Murray <[email-masked]>, [email-masked],
>         [email-masked], [email-masked]

> PowerPC and Sparc do not use .sdata/.sbss.

Actually, powerpc could use .sdata/.sbss for shared libraries, but it
never got implemented, and it would have the disadvantage that such
code can't be linked into non-shared objects.

It would be a significant speed/space win for certain objects, most
notably libm.

-- 
- Geoffrey Keating <[email-masked]>

---

From: Erik Corry <[email-masked]>
Date: Wed, 26 Sep 2001 12:08:31 +0200

> > currently affects openh323 and mozilla, among other things.

I think the current favoured solution on IRIX is multigot, where
if I understand correctly you switch GOT on some function calls 
in order to have multiple GOTs in one .o (or .so).

-- 
Erik Corry [email-masked]