Well-behaved application restrictions
 |
| |
| This document contains: |
Overview
 |
| |
| Well-behaved applications do not make assumptions about: |
- run-time architecture
- platform architecture
- object file format
since any of the above can cause binary incompatibilities. Many of these
assumptions are made by:
- how data is read from or written to memory
- using ambiguously defined data types or data types that have changed
size
Each of the sections in this document describe a restriction and contain
instructions to help you determine whether you need to make source
changes.
Data model
information
 |
| |
| The data model indicates the sizes of various data types. HP-UX's
32-bit data model is ILP32. In ILP32, C integers,
longs and pointers are 32 bits long. |
For IPF (Itanium Processor Family), the enterprise Unix standard 64-bit
data model is LP64. In LP64, C longs and pointers are
now 64 bits long while C integers remain 32 bits long.
NT uses different data models.
Following is a summary table for data type sizes:
| data type |
ILP32 size
(bits) |
LP64 size
(bits) |
| char |
8 |
8 |
| short |
16 |
16 |
| int |
32 |
32 |
| long
Different |
32 |
64 |
| long long |
64 |
64 |
| pointer
Different |
32 |
64 |
| float |
32 |
32 |
| double |
64 |
64 |
| long double |
128 |
128 |
| enum |
32 |
32 |
In ILP32, the following assumptions are true:
- C longs and ints are the same size (both 32
bits)
- C pointers and ints are the same size (both 32 bits)
When using LP64, the above assumptions are no longer true.
Instead:
- C longs and ints are now different sizes (64 and
32 bits respectively)
- C pointers and ints are now different sizes (64 and 32 bits
respectively)
Note: Check your source code for:
- pointer assignments or pointer arithmetic
- assignments across types (e.g. casting a type to another
type)
- arithmetic across types (e.g. int -
long)
- bit shifts and bit masks
- bit fields
- enumerated types (e.g. enums)
- system data types (e.g. off_t)
To detect whether the following problems exist:
- data truncation (e.g. int = long may lose
part of the long's value). This can happen during:
- initialization
- assignment
- parameter passing
- function returns
- casts
- data type promotion (e.g. long = int;)
- data alignment and data sharing (e.g. an integer data array
created with ILP32-built application but read with
LP64-built application
|
Examples of potential problems with pointers are:
| description |
potential problem |
| assign 32-bit hex constant to
int or pointer |
invalid address (possible
dereference errors) |
| cast a pointer to an
int |
data truncation |
| cast an int to a
pointer |
dereference errors |
| functions returning pointers
(when declared improperly) |
return truncated values |
| comparing an int to
a pointer |
unexpected results |
| pointer arithmetic |
unexpected results |
| incrementing pointer to
long or pointer to int |
ILP32 and
LP64 increment by different amounts |
| casting long * to
int * |
types are different sizes |
Data type
promotion
 |
| |
| ANSI C converts operands to compatible types before performing
comparison and arithmetic operations. Therefore, some data type
promotions cause signed numbers to be treated as unsigned numbers. |
| Note: Check your source files for signed numbers that might be
promoted and then evaluated as unsigned numbers in comparisons or
arithmetic operations. |
Data alignment and
data sharing
 |
| |
| Data alignment is the manner in which data structures are aligned in
memory. Pointers and longs have different alignment in
ILP32 and LP64 which causes structures to be
aligned differently. |
Structures are aligned on the same boundary as their most strictly aligned
member.
| HP-UX
ILP32 and LP64 data alignment |
| data type |
ILP32 size
(bytes) |
ILP32 alignment |
LP64 size
(bytes) |
LP64 alignment |
| char |
1 |
1-byte |
1 |
1-byte |
| short |
2 |
2-byte |
2 |
2-byte |
| int |
4 |
4-byte |
4 |
4-byte |
| long
Different |
4 |
4-byte |
8 |
8-byte |
| long long |
8 |
8-byte |
8 |
8-byte |
| pointer
Different |
4 |
4-byte |
8 |
8-byte |
| float |
4 |
4-byte |
4 |
4-byte |
| double |
8 |
8-byte |
8 |
8-byte |
| long double |
16 |
8-byte |
16 |
8-byte |
| struct |
depends |
depends |
depends |
depends |
| enum |
4 |
4-byte |
4 |
4-byte |
| Note: Check your source files for longs and pointers in
structure that might change size between ILP32 and
LP64, thus causing corrupted memory reads and writes across
field or structure boundaries. |
Constants
Hexadecimal constants may change type when compiled for ILP32
and LP64 (e.g. 32-bit hex constants may no longer set pointers or
masks to the correct value). Here are four examples:
| constant |
ANSI C ILP32 |
ANSI C LP64 |
| 0x7fffffff |
int |
int |
| 0x7fffffffL |
long |
long |
| 0x80000000 |
unsigned int |
unsigned int |
| 0x80000000L
Different |
unsigned long |
long |
| Note: Check your source files for hexadecimal constants that
gain a signed bit. |
Bit shifts and bit masks
Source code for bit shift and bit mask operations often assumes that the
operand variable has the same type as the result variable. For the
example:
a = b operator c
The variables b and c are assumed to have the same
type as the variable a.
Note: Check your source files for any of the following cases. They can
cause unexpected results:
- if b and/or c are constants, the
ILP32 and LP64 sizes of them may be different
(see: Constants)
- if b and c are different types, ANSI C for
the LP64 data model may convert an operand to a compatible
type before comparing or doing arithmetic.
- if the result variable a has a smaller word size than
the operands b and c, a value greater than 32
bits will be truncated during the assignment.
|
Architecture-specific changes
PA 1.x to PA 2.0 changes
There are architecture-specific changes between 32-bits and 64-bits and PA
1.x and PA 2.0. Many of the changes in object file and debug formats enable
better performance and compatibility. Minimizing your software's architecture
specific dependencies improves your software's compatibility. The changes are
in the following three areas:
assembly language
- 64-bit PA 2.0 has different calling conventions
- PA 2.0 has new instructions for improved performance
procedure calling conventions
- stack unwinding has changed
- passing data in and out of the kernel has changed
object file format
| architecture & version |
word size |
object file format |
| PA 1.0, 1.1 |
32-bit |
SOM |
| PA 2.0 |
32-bit |
SOM |
| PA 2.0 |
64-bit |
ELF |
PA to IPF changes
The object file format for HP-UX 11i Version 1.6 is ELF, as it is for
64-bit HP-UX 11.x on PA systems. SOM object file format is not used on
IPF systems.
Since IPF is a new architecture, the assembly language has changed. See Itanium architecture-related documents for further reference.
See also
|