Skip to contentSkip to conversation

linker problem: relocation truncated to fit

DISCUSSION Petter Reinholdtsen 9 participants 18 messages Sep 16, 2001 – Sep 26, 2001 MIPS

lore
Share & tools
lore
#0 lore raw

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.
#1 lore raw
Quoted 9 lines · Petter Reinholdtsen

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:

Quoted 12 lines

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)

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.

#2 lore raw
Quoted 12 lines · H . J . Lu
Quoted 11 lines

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)

Quoted 1 line

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

#3 lore raw

[Wilbern Cobb]

Quoted 7 lines

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.

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. :-(

#4 lore raw
Quoted 10 lines · Petter Reinholdtsen

[Wilbern Cobb]

Quoted 7 lines

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.

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.

Signature · 2 lines
Ryan Murray, Debian Developer ([email protected], [email protected])
The opinions expressed here are my own.
#5 lore raw
Quoted 10 lines · Ryan Murray
Quoted 9 lines · Petter Reinholdtsen

[Wilbern Cobb]

Quoted 7 lines

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.

Quoted 8 lines
Quoted 1 line

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.

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.

#6 lore raw
Quoted 5 lines · H . J . Lu

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.

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

#7 lore raw
Quoted 3 lines · Ralf Baechle

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.

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~

#8 lore raw
Quoted 8 lines · Richard Henderson
Quoted 3 lines · Ralf Baechle

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.

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.

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

H.J.

#9 lore raw
Quoted 1 line · H . J . Lu

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~

#10 lore raw
Quoted 5 lines · Richard Henderson
Quoted 1 line · H . J . Lu

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.

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.

#11 lore raw
In reply to H . J . Lu
Quoted 1 line · H . J . Lu

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

#12 lore raw
In reply to H . J . Lu
Quoted 3 lines · H . J . Lu

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?

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~

#13 lore raw
Quoted 1 line · Richard Henderson

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

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

Jakub

#14 lore raw
In reply to Richard Henderson
Quoted 16 lines

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

Quoted 3 lines · H . J . Lu

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?

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.

Quoted 3 lines

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

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.

Signature · 1 line
- Geoffrey Keating <[email protected]>
#15 lore raw
In reply to H . J . Lu
Quoted 6 lines · H . J . Lu
Quoted 6 lines

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.

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).

Signature · 1 line
Erik Corry [email protected]
#16 lore raw
In reply to Petter Reinholdtsen
Quoted 9 lines · Petter Reinholdtsen

[Wilbern Cobb]

Quoted 7 lines

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.

Quoted 8 lines

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. :-(

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

-vedge

#17 lore raw
In reply to Wilbern Cobb
Quoted 7 lines · Wilbern Cobb

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.

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