Sun Studio Support for the AMD64 Medium Memory Model

   
By Chris Quenelle, Sun Microsystems, December 6, 2005 (revised June 19, 2006)  

What is Medium Model in x64?

On a processor that supports 64-bit addresses, it would be nice to think that you could have as much code and data in your program as you could possibly want. Unfortunately, if your code used 64-bit addresses all the time, it would be much slower than a 32-bit program. To avoid that, the compiler and the linker try to use 64-bit address only where such addresses are required. For data on the heap (for example, pointers returned by malloc) 64-bit access is always used. The data size limitations described here apply only for data statically allocated by the compiler and linker.

A note on terminology: x64 is the marketing name used by Sun and Microsoft to advertise their hardware and software. However the older term, AMD64, is still widely used. The terms are interchangeable for all practical purposes.

The AMD64 ABI defines different memory models for programs running in 64-bit mode. The memory models define the maximum accessible size of data and text in a program. The list of memory models defined by the AMD64 ABI includes kernel, small, medium and large memory models. (There are also position independent versions of the small, medium and large models). The default model in Sun Studio 11 is the small model. This gives the best performance and capabilities for the majority of programs.

For a detailed specification, you can read the description in the AMD64 ABI document in version 0.96, Chapter 3 Low Level System Information, 3.5.1 Architectural Constraints).

In the large model, all text and data addresses are assumed to be 64-bits long, so code and data objects can always be placed in the full 64 bit address space. (The details of the large model are still being fine-tuned by the ABI working group) The medium model is a compromise between the small and large models. Code and small data objects are treated as in the small model, and large data objects are treated as in the large model. In all the models, heap address are always allowed to be 64-bits long. The “data objects” we're discussing here are objects allocated by the linker (“static” objects).

The compiler and linker implement the medium model by collecting smaller data objects together, and locating them within the reach of a 32-bit address. Larger data objects (larger than 64k bytes) are moved further away by placing them in special sections with names like .lbss, .ldata, etc. The compiler uses 32-bit instructions to reach data in the normal sections, and it uses 64-bit address to reach data in the new “large data” sections. This is compatible with the existing mechanisms in the small model, so it allows you to compile some source files with the small model and some with the medium model, and link them all together into one program.

Who will want to use Medium Model?

If you are building a 64-bit application or shared library and the combined data size of static and global variables exceeds 2 gigabytes, you might exceed the data size limitations of the small model. This can show up as a linker error.

Because of changes in the AMD64 ABI, some programs with data sizes that fit in a 32-bit program, will no longer fit when that program is compiled in 64-bit mode. Yes, this seems counter-intuitive, but it is required by the ABI. If your program get linker errors like the following when you try to compile in 64-bit mode, then you might want to try using medium model.

ld: fatal: relocation error: R_AMD64_32: file rmod.o: symbol fields_: value 0xfffffffffe72dae0 does not fit

ld: fatal: relocation error: R_AMD64_32: file rmod.o: symbol fields_: value 0xfffffffffe72dae0 does not fit

How do I use Medium Model?

When you are compiling an AMD64 program, just add -xmodel=medium to your command line. No special options at link-time are required.

Which Solaris patches are needed to run Medium Model?

Solaris 10 FCS or newer is needed to support running 64-bit program on an AMD64 compatible processor. The Solaris linker needs some additional features to make medium model work, so you need to have some patches installed to use this feature. The initial bugid to implement this feature in Solaris is 6236594. There were a few other related bugs, 6311865 and 6314743. All these are fixed in two patches. 120995-01 adds the new ELF fields to the header files, and 118345-11 implements the feature in the linker. To find out more, you can look up Solaris bugids in the OpenSolaris bug database, and patch ids at the SunSolve site.

 

I would recommend that you use the nifty new smpatch utility to automatically download and install the patches. When you name the patches explicitly, you might have to put them in the right order.

 

# smpatch update -i 118344-01 -i 118844-14

# smpatch update -i 120995-01 -i 118345-11

 

If “smpatch update” doesn't work for you, you can always download the patches from SunSolve and install them using the “smpatch add” command.

If you try to link a program with object files that use the medium model flag, and you don't have the necessary patches, you might see some errors like this from the linker:

ld: fatal: symbol `global_' is multiply-defined:

(file add.o type=OBJT; file copy_faces.o type=OBJT);

ld: fatal: symbol `partition_' is multiply-defined:

(file add.o type=OBJT; file copy_faces.o type=OBJT);

What Sun Studio patches do I need?

The following bugs in Sun Studio 11 FCS:

  • 6289012: Array indicies longer than 32-bits are truncated to 32-bits losing the most significant part of the index. This bug will be fixed in an upcoming patch.

  • (No bugid) Far access to long doubles does not work well in Sun Studio 11 FCS. This should also be fixed in the same patch.

were fixed by this compiler patch:

Are there any known bugs or caveats?

There is still an outstanding bug in the Sun Studio compilers that may affect a medium model program.

  • 6328434: Small array of known size is marked as far access when -xmodel=medium even though the ABI says it should be near access.

In Solaris 10, there are the following related bugs:

  • 6331519: The Solaris nm command does not print out LBCOMMON (it prints a number)

  • 6327926: ld does not set etext symbol correctly for AMD64 medium model

  • 6328420: Malloc sets errno to ENOMEM on AMD64 when -xmodel=medium

You can find out the status of Solaris bugs by checking bugs.opensolaris.org.


 
About the Author
Chris Quenelle is a tools developer at Sun Microsystems. He's worked on performance and debugging tools at Sun for more than 10 years. Before starting at Sun, he worked on runtime support libraries and development tools at Supercomputer Systems Incorporated and Pyramid Technologies.
 
Rate and Review
Tell us what you think of the content of this page.
Excellent   Good   Fair   Poor  
Comments:
Your email address (no reply is possible without an address):
Sun Privacy Policy

Note: We are not able to respond to all submitted comments.