[comp.unix.xenix] segment size exceeds 64K

jl42+@andrew.cmu.edu (Jay Mathew Libove) (09/01/88)

I built umoria2 on a SCO Xenix System V/286 v2.2.1 system and during the
load phase got the error:

/bin/ld: Segment size exceeds 64K
Input File: treasure2.o(treasure2.c) pos: 8e Record type: 98
*** Error code -107

Stop.


So, what exactly is the problem? Did the compiler generate one segment
of code that was more than 64K in length? I thought it was supposed to
take care of that for me.

How do I correct for this? I compiled all the modules with just the
basics, -Ml2e -O -LARGE.

Thanks for any help and suggestions!
Jay Libove (libove@andrew.cmu.edu or libove@cs.cmu.edu)
5731 Centre Avenue, Apt 3
Pittsburgh, PA 15206
(412) 362-8983

tif@cpe.UUCP (09/01/88)

Written  6:34 pm  Aug 31, 1988 by andrew.cmu.edu!jl42+ in cpe:comp.unix.xenix
>/bin/ld: Segment size exceeds 64K

I believe the usual corrective action is to add -Gt32 to the cc line.

			Paul Chamberlain
			Computer Product Engineering, Tandy Corp.
			{convex,killer}!ninja!cpe!tif

john@jetson.UPMA.MD.US (John Owens) (09/02/88)

In article <4X78oOd68k-0I=K0RL@andrew.cmu.edu>, jl42+@andrew.cmu.edu (Jay Mathew Libove) writes:
> /bin/ld: Segment size exceeds 64K
> So, what exactly is the problem? Did the compiler generate one segment
> of code that was more than 64K in length? I thought it was supposed to
> take care of that for me.

I wish the error message at least said which segment.  The compiler
cannot keep segments under 64K by itself, because some of the segments
it generates for each module are joined in the final module.  Since
you're using large model (-Ml), the code segments for each module are
separate, but all the data goes into _DATA, which is limited to 64K.

> How do I correct for this? I compiled all the modules with just the
> basics, -Ml2e -O -LARGE.

The first thing to try is to add the option -Mt###, where ### is the
threshold for moving an individual data item to another segment.  If
you can, set this such that all normal-sized varibles, single
structures, and small arrays stay in _DATA, but arrays of significant
size are moved to their own segment.  I'd recommend starting with
-Mt512, and not going lower than -Mt64.

The second thing to try is to cause specific modules to have all their
data in another segment.  Use the option -NDmodule_DATA, where module
is the base of the filename (for main.c, use -NDmain_DATA or
-NDMAIN_DATA, whichever you like).  Ideally, pick modules that have
lots of large data that's always or almost always accessed only by
routines in that module.  If you use this option, don't do the -Mt
thing above.  (You can do it, but since both of these degrade
performance, you don't want to do more than is necessary.)

Of course, the easiest solution is to get a 386 machine.... :-)

-- 
John Owens		john@jetson.UPMA.MD.US		uunet!jetson!john
+1 301 249 6000		john%jetson.uucp@uunet.uu.net

richard@neabbs.UUCP (RICHARD RONTELTAP) (09/02/88)

In large model, no data item (read: array) may be larger than 64K.
Do you have one of those? Then You'll just have to program around it,
and break in into peaces.

If you don't want to do this, you can try huge model. (-Mh)
 
Richard
(...!mcvax!neabbs!richard)
 
PS of course you know that these problems disappear on XENIX/386..

jayen@munginya.cs.mu.oz (Jayen Vaghani) (09/02/88)

The problem is that even though you specified the large model when compiling
you did not specify the large model when linking. Unless the linker
specifically told which model to use, it will default to the small model.
So, where as

	cc -o test -Ml2 test.c one.c two.c

will compile and link using large models everywhere,

	cc -c -Ml2 test.c one.c two.c
	cc -o test test.o one.o two.o

will compile with large model but attempt to link with small model.
Simply, put the -Ml flag in the link command line to fix.

Jayen.

greg@gryphon.CTS.COM (Greg Laskin) (09/02/88)

In article <133@jetson.UPMA.MD.US> john@jetson.UPMA.MD.US (John Owens) writes:
>In article <4X78oOd68k-0I=K0RL@andrew.cmu.edu>, jl42+@andrew.cmu.edu (Jay Mathew Libove) writes:
>> /bin/ld: Segment size exceeds 64K
>> So, what exactly is the problem? Did the compiler generate one segment
>> of code that was more than 64K in length? I thought it was supposed to
>> take care of that for me.
>
>you're using large model (-Ml), the code segments for each module are
>separate, but all the data goes into _DATA, which is limited to 64K.

_DATA gets the stack, INITIALIZED data, and constants.  Constants include
string constants.  Uninitialized data goes in a different segment.  The linker
arranges for segments other than _DATA to be less than 64K so this
message almost always applies to _DATA.  The problem with umoria is too
many string constants to fit in _DATA.

>
>> How do I correct for this? I compiled all the modules with just the
>> basics, -Ml2e -O -LARGE.
>
>The first thing to try is to add the option -Mt###, where ### is the
>threshold for moving an individual data item to another segment.  If
>you can, set this such that all normal-sized varibles, single
>structures, and small arrays stay in _DATA, but arrays of significant
>size are moved to their own segment.  I'd recommend starting with
>-Mt512, and not going lower than -Mt64.

What you are trading off by using -Mt# is code size and access time.
_DATA is always is kept in the DS segment register (and SS) so data
references by default refer to _DATA.  When you move data to any other
segment, the compiler has to load ES with the correct segment and
refer to the data item with an ES: prefix.  It takes a few more bytes
per reference and a few more cycles to access data through ES.

>
>The second thing to try is to cause specific modules to have all their
>data in another segment.  Use the option -NDmodule_DATA, where module
>is the base of the filename (for main.c, use -NDmain_DATA or
>-NDMAIN_DATA, whichever you like).  Ideally, pick modules that have
>lots of large data that's always or almost always accessed only by
>routines in that module.  If you use this option, don't do the -Mt
>thing above.  (You can do it, but since both of these degrade
>performance, you don't want to do more than is necessary.)
>
You need to be very careful using this option because it causes
the compiler to set DS to MAIN_DATA upon entry to the module and
restore DS before leaving the module.  A problem occurs if you
call certain (read most) library routines from a module with a
renamed data segment.  The library does not set DS on entry, so
when you are executing library code, DS is referencing an unexpected
segment.  Library routines expect to access static data and
the CONST segment through DS so they frequently blow up under
these circumstances.  Renaming a data segment works ok if the
module contains ONLY global data declarations.


-- 
Greg Laskin  greg@gryphon.CTS.COM    <any backbone site>!gryphon!greg