ID Number: Q72702
6.00 6.00a 6.00ax | 6.00 6.00a
MS-DOS | OS/2
buglist6.00 buglist6.00a buglist6.00ax fixlist7.00
Summary:
SYMPTOMS
If the /NT (name code segments) switch is used to compile a small
(/AS) or compact (/AC) model program with the Microsoft C Compiler
version 6.0, 6.0a, or 6.0ax, it may not be possible to link the
resulting object module. Instead, the linker may return the
following error message:
error L2003: intersegment self-relative fix-up at 'number' in
segment 'segment'
RESOLUTION
To work around the problem, use the alloc_text pragma to place the
functions in the module in a particular segment.
STATUS
Microsoft has confirmed this to be a problem in C versions 6.0,
6.0a, and 6.0ax. This problem was corrected in C/C++ version 7.0.
More Information:
When /NT is used with the small or compact memory model, the compiler
incorrectly assumes that the named code segment is the default code
segment. As a result, the compiler creates near calls to helper
functions that may be required in the code.
These helper functions all start with "__aN..." (__aNchkstk, __aNlmul,
__aNfmuls, and so forth). When LINK tries to build the .EXE file, it
determines that the symbols are not in the default code segment for
that module (so they cannot be called with a near call), and the above
error message is generated.
For instance, if the sample code below is compiled and linked as
indicated, the following error messages will be generated by the
linker:
test2.obj(test2.c) : error L2003: intersegment self-relative fix-up at
3C in segment MYSEG target external '__aNfstsp'
test2.obj(test2.c) : error L2003: intersegment self-relative fix-up at
35 in segment MYSEG target external '__aNfsts'
test2.obj(test2.c) : error L2003: intersegment self-relative fix-up at
2F in segment MYSEG target external '__aNfmuls'
test2.obj(test2.c) : error L2003: intersegment self-relative fix-up at
29 in segment MYSEG target external '__aNflds'
test2.obj(test2.c) : error L2003: intersegment self-relative fix-up at
23 in segment MYSEG target external '__aNchkstk'
test2.obj(test2.c) : error L2003: intersegment self-relative fix-up at
16 in segment MYSEG target external '__aNlmul'
test2.obj(test2.c) : error L2003: intersegment self-relative fix-up at
7 in segment MYSEG target external '__aNchkstk'
This problem does not exist if the module is compiled with the quick
compile option (/qc) or if the alloc_text pragma is used to identify
the segments in which to place the functions. The use of alloc_text is
illustrated in a comment in the second .C module below.
Sample Code
-----------
Compile the two modules, TEST1.C and TEST2.C, (below) as specified and
then link as follows:
LINK /NOI TEST1+TEST2,,,/NOD:SLIBCA SLIBCAP, TEST.DEF;
TEST1.C
-------
/* Compile options needed: /c /FPa /AS (or /AC)
*/
int _cdecl printf(const char *, ...);
int main(void);
long _far func1(long, long);
float _far func2(float, float);
int main(void)
{
long c;
float d;
c = func1(100l, 200l);
if (c != 100l * 200l)
{
printf("Failed\n");
return(1);
}
d = func2(100.0f, 200.0f);
if (d!= (float)100.0f * 200.0f)
{
printf("Failed\n");
return(1);
}
printf("Passed\n");
return(0);
}
TEST2.C
-------
/* Compile options needed: /NTmyseg /c /FPa /AS (or /AC)
*/
long far func1(long, long);
float far func2(float d, float e);
/* Uncomment the following line to work around the problem. */
// #pragma alloc_text(myseg, func1, func2)
long far func1(long a, long b)
{
long c;
c = a*b;
return c;
}
float far func2(float d, float e)
{
float f;
f = d * e;
return(f);
}
TEST.DEF
--------
; Module definition file required for linking.
NAME TEST
SEGMENTS
MYSEG class 'CODE' LOADONCALL
Additional reference words: 6.00 6.00a 6.00ax