Discussion Forum

"improper fixup" linking error caused by load and store library routines?

Next Thread | Thread List | Previous Thread Start a Thread | Settings

DetailsMessage
Read-Only
Author
Slarti Bartfast
Posted
26-Apr-2002 20:30 GMT
Toolset
C51
New! "improper fixup" linking error caused by load and store library routines?
Hi,

It seems as if the load and store library routines used by the C51 compiler (see http://www.keil.com/support/docs/1964.htm for a description of these routines) are the cause of an 'improper fixup' error I'm getting while linking. I'm using the ROM(SMALL) directive in conjunction with a customized linker command line:

CODE(?CO?StateTest(0x4005), ?PR?*) OVERLAY(* ! ?PR?_UPDATE?StateTest, * ! ?CO StateTest)

to link the following small program:
=============================================
#pragma ROM(SMALL)

unsigned int update(unsigned int arg0, unsigned int arg1);

typedef struct ProcessFragmentState {
unsigned int x;
unsigned char a;
} PFragState;

unsigned int code StateSize = sizeof(PFragState);

PFragState xdata * statePtr;

unsigned int update(unsigned int arg0, unsigned int arg1) {
(statePtr -> x) = (statePtr -> x) + 1;
return arg0 + arg1;
}

=============================================

Shouldn't the linker be able to figure out where to place the load and store routines such that they satisfy the ROM(SMALL) requirements? Is there a way around this?

Thanks,
Slarti
Read-Only
Author
Slarti Bartfast
Posted
26-Apr-2002 20:34 GMT
Toolset
C51
New! oops... forgot to mention...
Here's the error I'm getting:

==========================================
*** ERROR L121: IMPROPER FIXUP MODULE:
D:\PROJECTS\PUSHPIN\CODE\VERSION3\TESTCODEV3\STATETEST\STATETEST.OBJ
(STATETEST)
>> SEGMENT: ?PR?_UPDATE?STATETEST
OFFSET: 000AH
==========================================

And here's the part of the listing file of interest:

===========================================

; FUNCTION _update (BEGIN)
; SOURCE LINE # 23
;---- Variable 'arg1' assigned to Register 'R4/R5' ----
;---- Variable 'arg0' assigned to Register 'R6/R7' ----
; SOURCE LINE # 24
0000 850082 R MOV DPL,statePtr+01H
0003 850083 R MOV DPH,statePtr
0006 E4 CLR A
0007 75F001 MOV B,#01H
000A 1100 E ACALL ?C?IILDX
; SOURCE LINE # 25
000C EF MOV A,R7
000D 2D ADD A,R5
000E FF MOV R7,A
000F EE MOV A,R6
0010 3C ADDC A,R4
0011 FE MOV R6,A
; SOURCE LINE # 26
0012 ?C0001:
0012 22 RET
; FUNCTION _update (END)

============================================

It's the ACALL to ?C?IILDX that seems to be causing the error.

Cheers,
Slarti
Read-Only
Author
Jon Ward
Posted
26-Apr-2002 23:12 GMT
Toolset
C51
New! RE: oops... forgot to mention...
What version of the C compiler are you using?

Jon
Read-Only
Author
Slarti Bartfast
Posted
26-Apr-2002 23:19 GMT
Toolset
C51
New! compiler and linker version numbers
I'm using:

C51 COMPILER V6.14
BL51 BANKED LINKER/LOCATER V4.14

-slarti-
Read-Only
Author
Slarti Bartfast
Posted
27-Apr-2002 05:12 GMT
Toolset
C51
New! problem solved...
The solution lies in changing the CODE linker directive from:

CODE(?CO?StateTest(0x4005), ?PR?*)

to:

CODE(?CO?StateTest(0x4005), ?PR?*, ?C?*)

so that the linker knows to put the library included by the compiler in the same 2Kbyte block as the rest of the code.

Thanks,
Slarti
Read-Only
Author
Jon Young
Posted
27-Apr-2002 12:27 GMT
Toolset
C51
New! RE: problem solved...
I am using 8052 All Variants device.

The following should work without worrying about wild carding all all the segments.
  CODE( 0x4005, ?CO?StateTest(0x4005) )

There is something wrong with the linker however, because the following should have also worked but fails.
  CODE( 0x4005, ?CO?StateTest )
Read-Only
Author
Jon Ward
Posted
29-Apr-2002 05:36 GMT
Toolset
C51
New! RE: problem solved...
There is something wrong with the linker however, because the following should have also worked but fails.

Nope. There is nothing wrong with the linker.

If you take a look at the original posting, the ROM(SMALL) directive tells the linker that you will have all of your program code reside within one 2K block. So, the linker uses AJMPs and ACALLs.

Since the CODE linker directive is used to change the starting address of the program, but only SOME segments are included, the linker locates all other segments starting at 0.

The appropriate thing to do would have been to specify that the CODE area resides from 0x4000-0x47FF rather than manually locating segments in that range.

Jon
Read-Only
Author
Jon Young
Posted
29-Apr-2002 19:29 GMT
Toolset
C51
New! RE: problem solved...
I believe that StateTest (and maybe others) are required to be located at fixed locations. Setting code to 0x4005-0x47FF on the linker tab and adding
 
CODE(?CO?StateTest(0x4005))
to the misc tab gives an duplicate keyword error.

Using CODE(0x4005-0x47FF, ?CO?StateTest ) fails.

Next Thread | Thread List | Previous Thread Start a Thread | Settings