relocation truncated to fit

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Jaklub
Interested
Posts: 41
Joined: Mon Aug 24, 2009 1:36 pm

relocation truncated to fit

Post by Jaklub »

Hello. This time my problem is more complicated than the ones before.
When I try to compile the project, an error occurs. I use Stef's Genesis Mini DevKit 0.4.
Here is what it is.

Code: Select all

sega.o: In function 'VBL':
(.text+0x346): relocation truncated to fit: R_68K_PC16 against symbol '_vblankcallback' defined in .text section in D:/apps/GenDev/lib/base.o
make: *** [rom.out] Error 1
I have no idea where this came from and Google did not provide clear answers (for me).
Here's what I've tried to do:
- compile using "make -kf makefile.gen", did not work
- split code from 1 void to 2 voids, did not work either
Only deleting few rows of code helps.
How can I fix this problem? What causes it? Thanks in advance.
Last edited by Jaklub on Sat Mar 20, 2010 9:54 pm, edited 1 time in total.
Shiru
Very interested
Posts: 786
Joined: Sat Apr 07, 2007 3:11 am
Location: Russia, Moscow
Contact:

Post by Shiru »

I've got something similar twice, in two separate projects, not sure if it is exactly the same. In my case -o2 instead of -o3 fixed the problem.

Both times the problem happened suddenly, after adding just one new function (~3 lines of code). The projects were large enough, few thousands of lines.
Jaklub
Interested
Posts: 41
Joined: Mon Aug 24, 2009 1:36 pm

Post by Jaklub »

Thanks, but I think I didn't apply it right.
Changing O1 in FLAGS to O0, O2 or O3 results in additional "relocation truncated to fit" error. Adding -o2 to FLAGS has no result. make -o2 -f makefile.gen also does nothing.
What's the correct way to do it? :oops:

EDIT: Seems like -Os works, but please answer the new question. I'm afraid in future the same error may occur.
Shiru
Very interested
Posts: 786
Joined: Sat Apr 07, 2007 3:11 am
Location: Russia, Moscow
Contact:

Post by Shiru »

In my case I've had -O3 in makefile.gen, FLAGS. I've replaced it with -O2, and that worked. Lower values means less optimization, you could lose too much speed.

-Os optimizes by speed similar to -O2, but also for size. I'm not sure it will work fine, though, because the docs says something about disabling alignment for some things, and SMD (hardware, not emulators) could not like this.

Let's see what others say. I don't know too much about GCC, so I want to figure out the source of the problem, and right solution.
Chilly Willy
Very interested
Posts: 2993
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy »

Looks like somewhere in the code, you're getting PC relative or address register relative code generated. Both addressing modes only allow for +/- 32KB range. This is usually a result of trying to use the small data segment. It would help to see the makefile you're using. It might also be a "feature" of the version of GCC you're using to automatically use the small data segment. You can usually turn that off by adding -G0 to your gcc flags.
Shiru
Very interested
Posts: 786
Joined: Sat Apr 07, 2007 3:11 am
Location: Russia, Moscow
Contact:

Post by Shiru »

Chilly Willy wrote:You can usually turn that off by adding -G0 to your gcc flags.
GCC says 'unrecognized option'.
Jaklub
Interested
Posts: 41
Joined: Mon Aug 24, 2009 1:36 pm

Post by Jaklub »

The makefile I'm using:

Code: Select all

CC= D:/apps/GenDev/bin/gcc
OBJC= D:/apps/GenDev/bin/objcopy
ASMZ80= D:/apps/GenDev/bin/asmz80
BINTOC= D:/apps/GenDev/bin/bintoc

SRC_C= $(wildcard *.c)
SRC_S= $(wildcard *.s)
SRC_SZ80= $(wildcard *.s80)

OBJ= $(SRC_SZ80:.s80=.o)
OBJ+= $(SRC_C:.c=.o)
OBJ+= $(SRC_S:.s=.o)

LINKOBJ= sega.o \
        D:/apps/GenDev/lib/base.o \
        D:/apps/GenDev/lib/tools.o \
        D:/apps/GenDev/lib/vdp.o \
        D:/apps/GenDev/lib/font.o \
        D:/apps/GenDev/lib/vdp_bg.o \
        D:/apps/GenDev/lib/vdp_dma.o \
        D:/apps/GenDev/lib/vdp_pal.o \
        D:/apps/GenDev/lib/vdp_spr.o \
        D:/apps/GenDev/lib/vdp_tile.o \
        D:/apps/GenDev/lib/bitmap.o \
        D:/apps/GenDev/lib/bitmapx.o \
        D:/apps/GenDev/lib/z80_ctrl.o \
        D:/apps/GenDev/lib/tab_sin.o \
        D:/apps/GenDev/lib/tab_log2.o \
        D:/apps/GenDev/lib/tab_pow2.o \
        D:/apps/GenDev/lib/maths.o \
        D:/apps/GenDev/lib/maths3D.o \
        D:/apps/GenDev/lib/ym2612.o \
        D:/apps/GenDev/lib/psg.o \
        D:/apps/GenDev/lib/audio.o \
        D:/apps/GenDev/lib/joy.o \
        D:/apps/GenDev/lib/timer.o \
        D:/apps/GenDev/lib/logo_lib.o \
        D:/apps/GenDev/lib/z80_drv1.o \
        D:/apps/GenDev/lib/z80_drv2.o \
        D:/apps/GenDev/lib/z80_mvst.o \
        $(OBJ)

INCS= -ID:/Apps/GenDev/include
FLAGS= $(OPTION) -m68000 -Wall -Os -fomit-frame-pointer $(INCS)
FLAGSZ80= -c -i -x1 -x2 -x3 -z -lnul

all: rom.bin


rom.bin: rom.out
	$(OBJC) --pad-to 131072 -O binary rom.out rom.bin

rom.out: $(OBJ)
	$(CC) -T D:/Apps/GenDev/bin/md.ld -nostdlib $(LINKOBJ) D:/apps/GenDev/bin/libgcc.a -o rom.out

%.o80: %.s80
	$(ASMZ80) $(FLAGSZ80) -o$@ $<

%.c: %.o80
	$(BINTOC) $<

%.o: %.c
	$(CC) $(FLAGS) -c $< -o $@

%.o: %.s
	$(CC) $(FLAGS) -c $< -o $@

The same thing as the one included in Stef's devkit with minor modifications.
Looks like somewhere in the code, you're getting PC relative or address register relative code generated. Both addressing modes only allow for +/- 32KB range. This is usually a result of trying to use the small data segment.
What does it mean? I have a quite big amount of warnings about some parts of code
Last edited by Jaklub on Sat Mar 20, 2010 6:51 pm, edited 1 time in total.
Shiru
Very interested
Posts: 786
Joined: Sat Apr 07, 2007 3:11 am
Location: Russia, Moscow
Contact:

Post by Shiru »

My makefile is based on the same, so all the options are the same (except for -O2). I don't have any warnings in all my projects.
Chilly Willy
Very interested
Posts: 2993
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy »

Make sure you use a zero, not a capital o. If that's how you have it, you have a REALLY old version of gcc there. I'd recommend updating just a smidgen. :lol:

For Windows, you could always use the MiNT compilers (m68k compilers for Atari ST). They keep their gcc compiler reasonably up to date. 4.4.3 is the current gcc on the MiNT web page.

http://vincent.riviere.free.fr/soft/m68k-atari-mint/

In linux, I suggest just building a cross-compiler from source. If someone needs some help, I can post a makefile that builds 4.4.2, which is what I currently use to compile my Genesis stuff.
Shiru
Very interested
Posts: 786
Joined: Sat Apr 07, 2007 3:11 am
Location: Russia, Moscow
Contact:

Post by Shiru »

Chilly Willy wrote:Make sure you use a zero, not a capital o. If that's how you have it, you have a REALLY old version of gcc there. I'd recommend updating just a smidgen. :lol:
Of course I've used zero, and also I've copy-pasted it from your text to be sure.

Well, seems that the solution is to change the compiler. That's sad. I'm using one from the Stef Devkit just because it was easy to setup and does not require to setup anything else - single archive, just unpack and edit dirs, and all works. I've had no success with all other M68K versions of GCC I've tried (few years ago).
Chilly Willy
Very interested
Posts: 2993
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy »

Well, there's a slightly older 4.x gcc binary for Windows I found here:

http://download.ronetix.info/toolchains/coldfire/

It's 4.1.1, using mingw.

It might be helpful to make a new Windows devkit based on a newer version of gcc.

Too bad the MiNT guy doesn't keep binaries on his page for Windows. Oldly enough, he does for linux and OSX.
Gigasoft
Very interested
Posts: 96
Joined: Fri Jan 01, 2010 2:24 am

Post by Gigasoft »

Changing GCC version or using different options can not fix this error, since it has nothing to do with GCC.

The error is in sega.s, which is part of the library. It can show up if your program exceeds a certain size.

The errors are on line 152 and 159, which read:
bsr _hblankcallback
bsr _vblankcallback

To fix it, change the bsr to jsr.

Another solution world be moving vblankcallback and hblankcallback towards to the beginning of the first source file (the one which appears first on the command line).
Shiru
Very interested
Posts: 786
Joined: Sat Apr 07, 2007 3:11 am
Location: Russia, Moscow
Contact:

Post by Shiru »

Gigasoft wrote:Changing GCC version or using different options can not fix this error, since it has nothing to do with GCC.
In my cases changing from O3 to O2 IS fix the error, very stable (O3 error, O2 no error) - you could see it with the Uwol code. I guess this moves the functions into bsr range.

Anyway, big thanks for the solution and explaination. I've just tried it, now Uwol compiles with O3. However, it also makes the file 84K large, instead of <64K, and it had no speed issues with O2, so in this case O3 not actually needed.
Jaklub
Interested
Posts: 41
Joined: Mon Aug 24, 2009 1:36 pm

Post by Jaklub »

Nice to know that GCC update is not necessary. Thanks, it works in my case too
Chilly Willy
Very interested
Posts: 2993
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy »

He didn't say he was using assembly in his program. Clearly, if one uses assembly, they need to be careful about branches and pc-relative addressing. You can get that same error from C if you use a small data segment, so given he mentioned nothing about assembly, I went with what causes the error in C.
Post Reply