Comparing 32-bit and 64-bit Interfaces
As discussed in Chapter 2, When to Use 64-bit, most 32-bit applications run unchanged in the Solaris 64-bit operating environment. Some applications might only need to be recompiled as 64-bit applications; others need to be converted. This chapter is directed at developers who have determined that their application needs to be recompiled or converted to 64-bit, based on the items discussed in Chapter 2, When to Use 64-bit.
Application Programming Interfaces
The 32-bit application programming interfaces (APIs) supported in the 64-bit operating environment are the same as the APIs supported in the 32-bit operating environment. Thus, no changes are required for 32-bit applications between the 32-bit and 64-bit environments. However, recompiling as a 64-bit application can require cleanup. See the rules defined in Chapter 4, Converting Applications for guidelines on how to clean up code for 64-bit applications.
The 64-bit APIs are basically the UNIX® 98 family of APIs. Their specification is written in terms of derived types. The 64-bit versions are obtained by expanding some of the derived types to 64-bit quantities. Correctly written applications using these APIs are portable in source form between 32-bit and 64-bit environments.
Application Binary Interfaces
The SPARC V8 ABI is the existing processor-specific Application Binary Interface (ABI) on which the 32-bit SPARC version of the Solaris implementation is based. The SPARC V9 ABI extends the SPARC V8 ABI to support 64-bit operations and defines new capabilities for this extended architecture. See "What's New for Applications" for additional information.
Compatibility
The following sections discuss the different levels of compatibility between 32-bit and 64-bit applications.
Application Binaries
Existing 32-bit applications can run on either 32-bit or 64-bit operating environments. The only exceptions are those applications that use libkvm, /dev/mem, /dev/kmem, or /proc. See Chapter 2, When to Use 64-bit for more information.
Application Source Code
Source level compatibility has been maintained for 32-bit applications. For 64-bit applications, the principal changes that have been made are with respect to the derived types used in the application programming interface. Applications that use the derived types and interfaces correctly are source compatible for 32-bit, and make the transition to 64-bit more easily.
Device Drivers
Because 32-bit device drivers cannot be used with the 64-bit operating system, these drivers must be recompiled as 64-bit objects. Moreover, the 64-bit drivers need to support both 32-bit and 64-bit applications. All drivers supplied with the 64-bit operating environment support both 32-bit and 64-bit applications. However, the fundamental driver model and the interfaces supported by the DDI do not change. The principal work is to clean up the code to be correct in an LP64 environment. See the Writing Device Drivers manual for more information.
Which Solaris Operating Environment Are You Running?
The Solaris operating environment supports two first-class ABIs simultaneously. In other words, two separate, fully functional system call paths connect into the 64-bit kernel; two sets of libraries support applications. See Figure 2-1.
The 64-bit operating system can run on only 64-bit CPU hardware, while the 32-bit version can run on either 32-bit CPU hardware or 64-bit CPU hardware. Because the Solaris 32-bit and 64-bit operating environments look very similar, it might not be immediately apparent which version is running on a particular hardware platform.
The easiest way to determine which version is running on your system is to use the isainfo command. This new command prints information about the application environments supported on the system.
The following is an example of the isainfo command executed on an UltraSPARC system running the 64-bit operating system:
% isainfo -v 64-bit sparcv9 applications 32-bit sparc applications |
When the same command is run on older SPARC systems, or on UltraSPARC systems running the 32-bit operating system:
% isainfo -v 32-bit sparc applications |
When the same command is run on an IA system:
% isainfo -v 32-bit i386 applications |
One useful option of the isainfo(1) command is the -n option, which prints the native instruction set of the running platform:
% isainfo -n sparcv9 |
The -b option prints the number of bits in the address space of the corresponding native applications environment:
% echo "Welcome to "`isainfo -b`"-bit Solaris" Welcome to 64-bit Solaris |
Applications that must run on earlier versions of the Solaris operating environment can either base their version check on the output of uname(1) or check for the existence of /usr/bin/isainfo to determine whether 64-bit capabilities are available.
A related command, isalist(1), that is more suited for use in shell scripts, can be used to print the complete list of supported instruction sets on the platform. Some of the instruction set architectures listed by isalist are highly platform specific, while isainfo(1) describes only the attributes of the most portable application environments on the system. Both commands are built on the SI_ISALIST suboption of the sysinfo(2) system call. See isalist(5) for further details.
The following is an example of the isalist command executed on an UltraSPARC system running the 64-bit operating system:
% isalist sparcv9+vis sparcv9 sparcv8plus+vis sparcv8plus sparcv8 sparcv8-fsmuld sparcv7 sparc |
Note - In the above example, the isalist command displays sparcv9+vis and sparcv8+vis, which indicates that the system supports the UltraSPARC-1 extended instruction set. Because this extended instruction set is not supported on all SPARC V9 systems, it is recommended that portable applications should not rely on its presence and not code to the specifics of UltraSPARC.
The list of supported instruction sets are ordered by level of performance and functionality. For more detail on the use of this command, see the isalist(1) man page. Also see the optisa(1) man page.
Sample Program
The following sample program, foo.c, directly illustrates the effect of the LP64 versus ILP32 data models. The same program can be compiled as either a 32-bit program or a 64-bit program.
#include <stdio.h> int main(int argc, char *argv[]) { (void) printf("char is \t\t%lu bytes\n", sizeof (char)); (void) printf("short is \t%lu bytes\n", sizeof (short)); (void) printf("int is \t\t%lu bytes\n", sizeof (int)); (void) printf("long is \t\t%lu bytes\n", sizeof (long)); (void) printf("long long is \t\t%lu bytes\n", sizeof (long long)); (void) printf("pointer is \t%lu bytes\n", sizeof (void *)); return (0); } |
The result of 32-bit compilation is:
% cc -O -o foo32 foo.c % foo32 char is 1 bytes short is 2 bytes int is 4 bytes long is 4 bytes long long is 8 bytes pointer is 4 bytes |
The result of 64-bit compilation is:
% cc -xarch=v9 -O -o foo64 foo.c % foo64 char is 1 bytes short is 2 bytes int is 4 bytes long is 8 bytes long long is 8 bytes pointer is 8 bytes |
Note - The default compilation environment is designed to maximize portability, that is, to create 32-bit applications.