This is a list of frequently asked questions (FAQ) about porting
programs to the MIPS ABI. A current copy of this FAQ is available by
contacting SGI Developer Support
devprogram@sgi.com
or
marketing@mipsabi.org
(please put ABI FAQ
in the Subject line to insure
expeditious routing).
This is an evolutionary document, which will be most useful if feedback on its' contents is received. Suggestions, improvements, new questions (preferably *with* answers), and better answers are always welcome.
This document is a set of notes on porting to the MIPS ABI. This information is not the standard. The standard is defined by the Conformance Guide (What is the Black Book?). (The Conformance Guide is also informally referred to as the Black Book). In case of a dispute, refer to the official standards documents. This document is intended to be a quick place to look things up, and does not in any way eliminate the need to read and understand the standard.
Much of the programming information has to do with porting from a BSD-flavor environment to an SVR4-flavor environment. Many popular systems, including IRIX 4 and SunOS, have some BSD flavor to them, but also have non-BSD aspects, so included examples may or may not be directly applicable. Other issues are POSIX support (for signals and other things), porting to ANSI C, and using IEEE math. There are much more complete works available regarding such code transitions. Again, this is only a collection of pointers, not an absolute reference.
abicc
.
abicc
, then use abild
on the collection of
objects to make the DSO. check_abi_compliance
. Manual pages are available on the
IRIX Reference Platform for these utilities.
The MIPS ABI is an Application Binary Interface for MIPS processors running UNIX SVR4. It documents a standard binary interface for application programs on systems based on members of the MIPS processor family that implement the interfaces of UNIX System V Release 4.0 or above.
The MIPS ABI is actually comprised of a number of documents (What makes up the spec?).
The MIPS ABI Group has worked to complete the standard in order to allow software vendors to port their applications to the ABI and be confident that it will operate correctly on all the platforms that support the ABI.
The following vendors are shipping operating systems which support the MIPS ABI:
The MIPS ABI is based on a Reference Platform (RP model. Under this model, a single platform is designated as a "tie-breaker". The software developer should build and test the application on the RP; the other ABI-conforming vendors guarantee that ABI compliant binaries that run correctly on the RP will run correctly on their platforms.
To be strictly accurate, there are two different forms of ABI compliance. All the ABI-conforming systems are ABI Execution Platforms the Reference Platform is the "tie-breaker" for how a program should work. There are also ABI Generation Platforms which are used to build ABI programs; the Reference Platform is again the "tie-breaker". The ABI generation environment need not necessarily be hosted on top of an ABI execution environment. As of the current version of this document, only the Reference Platform is an approved Generation Platform, although there are plans to certify additional Generation Platforms in the near future.
Given the current situation, it is thus a requirement that a software developer have a Reference Platform on hand, or visit or remotely access a porting center, in order to perform and test an ABI port.
A cornerstone of this strategy is the availability of test technology to certify ABI compliance of a binary. At the moment, facilities for such testing are available, but limited in scope (How to check if it's ABI compliant). Improved application checking technology is under development and is expected to be available in the second half of 1995.
Each edition of the Conformance Guide has a matching Reference Platform which implements that level of technology. For version 1.1 of the Conformance Guide, the Reference Platform is Silicon Graphics IRIX 5.3 with the "IRIS Development Option" ("IDO") 3.19 and patches 183, 410, 448, 541, 595, 596, and 604. The IDO is essentially the compilers and libraries. Any Silicon Graphics system which can run this software can be a Reference Platform.
Prior to the release of IRIX 5.3,
IRIX 5.2 with IDO 3.18 or IRIX 5.1 with IDO 3.17 plus a special ABI
Construction Kit (available from the SGI Developer's Technical Program)
was used as the Reference Platform for the 1.1 Conformance Guide). The
Reference Platform conforming to the 1.0 Conformance Guide edition was
MIPS Computer Systems' RISC/os 5.01 with ANSI C 3.11.
The Reference Platform for the (future) 1.2 Conformance Guide will be a future version of IRIX.
The ABI maintains backwards, but not forwards compatibility, so programs developed on the earlier RP will execute on the later ones, but will not be able to take advantage of new features.
In general, the latest RP is the best one to develop on, as it is likely to have the strongest level of support available.
The Black Book is the MIPS Processor ABI Conformance
Guide
. It is the defining document for the ABI. The current
version of the Black Book may be found in
Version 1.1.2
The ABI is defined by a series of documents. The basic defining document is SVID 3. The Generic ABI defines those elements which must be available on all ABI compliant platforms. The MIPS Processor Supplement defines how the Generic ABI is implemented on the MIPS processor family. The Conformance Guide defines additional interfaces agreed upon by the MIPS ABI group members, and provides guidance in implementation.
These are the references for the documents which define the standard:
Which Reference Platform Version Should I Use?. Approval of version 1.2 (referred to occasionally in this text) is forthcoming, but formal release will be delayed until a matching Reference Platform is available. The functionality approved for 1.2 is described in the 1.1.2 Future Directions section.
Additional documents are referred to within the above standards:
The IEEE has approved (12/93)
POSIX 1295, which describes the interfaces of Motif. The specification
is closely derived from the preceding reference, but as an approved
standard, may replace the above in a future Conformance Guide.
The Conformance Guide is available from participating vendors It is also available in PostScript form to registered developers in the SGI Developer Program, on the Developer Toolbox CD-ROM, release 4.0 and beyond.
The SGI Developer Toolbox also includes a note in PostScript format on porting to the ABI, and some sample programs illustrating porting techniques.
Prior to the 1.2 Conformance Guide, there is no reliable programmatic interface for determining which version of the ABI a particular system conforms to. Contact the system vendor for further information.
Specific features can usually be tested for, but compliance levels cannot be inferred from this, as the particular feature may have been introduced on a given platform before full compliance for the version of the spec in which the feature first appeared.
With the 1.2 Conformance Guide, the ABI version will be obtainable by
examining the file /etc/mipsabiversion
. If this file is
not present, the only assumption that should be made is
pre-1.2
.
The Open Computing environment for MIPS Platforms ("OCMP") group is a Japanese version of a MIPS ABI. Several MIPS ABI group members are also active in OCMP. The OCMP-ABI is aligned with the 1.0 version of the Conformance Guide, with a number of extensions for internationalization and localization, CD-ROM access, X11R5 and OSF/Motif 1.2, to name a few. The MIPS ABI and OCMP groups work together to keep the specifications aligned, and in fact X11R5 and OSF/Motif 1.2 became part of the MIPS ABI specification with the 1.1 Conformance Guide. The OCMP web page may be found at http://www1.sony.co.jp
A port to the OCMP specification will allow an application to run in Japanese double-byte character mode on any OCMP compliant platform, and will still be MIPS ABI compliant.
OCMP members include:
There is no simple answer to this question, and is best left to the internal coding conventions of each software developer.
Here are some possible guidelines:
For high-level standard definitions, there are some commonly used
symbols which may be useful in porting. Such defines are used to
select major functionality sets based on the heritage of the target
operating system. For example, SVR4
, SYSV
,
BSD43
and OSF1
are often used. The
appropriate symbol for the MIPS ABI would be SVR4
. This
symbol is not automatically defined on the Reference Platform, and
should be defined in the Makefile
.
For standards such as ANSI C
, POSIX
, and
X/Open
, the appropriate symbols are __STDC__
,
_POSIX_SOURCE
, _XOPEN_SOURCE
. Appropriate
defines and values for these are supplied by the compiler on the
Reference Platform. The IRIX Reference Platform also introduces the
private symbol _ABI_SOURCE
, which is automatically defined
when the abicc
script is used for compilation. This
symbol is used to select functionality from system header files.
Fine-grained feature tests can be used for specific features of
interest. To illustrate the techniques, the missing index
string routine can either be selected at an operating system
functionality level:
#ifdef SVR4 #define index(s, c) strchr((s), (c)) #endif
Or at a feature level:
#ifdef HAVE_STRCHR #define index(s, c) strchr((s), (c)) #endif
It may be useful to use the operating system-level define to select the feature-level define, as follows:
#ifdef SVR4 #define HAVE_STRCHR #endif ... #ifdef HAVE_STRCHR #define index(s, c) strchr((s), (c)) #endif
On the IRIX Reference Platform, the includes files for ABI programming
are simply in /usr/include
, with the exception of the
OSF/Motif include files, which are in /usr/include/abi
.
The proper sections of the standard include files are selected when
_ABI_SOURCE
is defined. The abi specific include files
are selected when -abi
is given to the compiler. Both are
selected automatically when abicc
is used (the preferred
compilation method).
On the Reference Platform for the 1.0 Conformance Guide (RISC/os 5.01),
the include files are those from the SVR4 environment,
/svr4/usr/include
. These are selected automatically when
/svr4/bin/cc
is used for compilation.
socket
Code?
rpc
? xdr
?
Many of the network functions and definitions that were present in the
BSD libc are now in libsocket.so
. Programs which use
socket-based networking services will need to be linked with
-lnsl
-lsocket
. The socket library is
actually emulation code built on top of services provided by the
network services library (libnsl) so it is not generally possible to
specify just -lsocket
.
Programs which use the X11 and Motif interfaces will need to link with these libraries.
The ABI requires that programs
which use dynamic shared objects specify them on the link line so that
they appear in the dependency list. Do not count on ABI libraries
having built-in dependencies. These dependencies may differ on
different platforms, so a program may work on one because the
dependency is supplied "invisibly", then fail on others. Use
elfdump -Dl
on the IRIX Reference Platform to check the
library list (ldd
may be appropriate on some other
platforms).
The socket emulation code does
not always provide exactly equivalent functionality to native sockets.
Routines such as
gethostbyname
may have different
behavior; in particular, gethostbyname
differs in that
under socket emulation, it only returns information from the
/etc/hosts
file, it does not access NIS or the
nameserver. Some platforms may provide a native socket interface, or
may have modified the generic socket emulation library to provide
additional functionality; the point is that applications can not count
on more functionality than is provided by the generic socket eumlation
library.
The rpc
and xdr
routines are in
libnsl
, and the old rpcsvc
library is no
longer present.
dlopen
attachments
Objects loaded by a call to dlopen
can, in general, not
access objects loaded by a different call to dlopen
. A
provision for making symbols in a dlopen
attached object
global will be introduced with the 1.2 Conformance Guide, where the
RTLD_GLOBAL
flag can be or'd with the mode
argument to dlopen
. Until the RTLD_GLOBAL
functionality is implemented, dlsym
should be used to
indirectly reference the symbols. For example, if routine
sub2
in module mod2
wants to call routine
sub1
in mod1
, one (simple-minded) way to make
that work would be as follows:
dltest.c: void *dlhandle1, *dlhandle2; int (*sub1_ptr)(int); ... /* open objects */ dlhandle1 = dlopen ("mod1.o", RTLD_NOW); dlhandle2 = dlopen ("mod2.o", RTLD_NOW); /* find address of function */ if (*sub1_ptr == NULL) sub1_ptr = (int (*)())dlsym (dlhandle1, "sub1"); (void) sub2 (); mod1.c: /* define routine sub1() */ int sub1 (int arg); int sub1 (int arg) { printf ("This is a test of sub1 (arg %d)\n", arg); return 1; } mod2.c: /* call routine in different dlopen() attachment */ #include <stdio.h> #define CALL_ARG 10 extern int (*sub1_ptr)(int); void sub2() { int rv = 0; if (*sub1_ptr != NULL) rv = (*sub1_ptr)(CALL_ARG); else printf ("routine not mapped\n"); }
When RTLD_GLOBAL
is available, care should be taken not to
overuse it. There are benefits to not having to worry about namespace
conflicts, if symbols in DSOs in general are kept private, a DSO can be
developed with fewer constraints, for example, when multiple groups are
developing DSOs for a large product set and don't want to have to
coordinate a "global namespace".
Another note about the above. The symbols contained in the original
a.out
and the objects loaded at program startup with the
a.out are not available to dlsym
, since they are directly
available. If dlsym
needs to access all the symbols in
the aggregate symbol table, the ones from the a.out
and
objects loaded with the a.out
at startup can be made
available by making a call to dlopen
with the PATHNAME
argument set to 0
.
regex
?
The regexp
functions (see regexpr(3G)) are not defined in
libc, as they are on some UNIX implementations. Under the MIPS ABI,
you must link with libgen.a
(-lgen
) in order
to get these definitions.
The
libgen.a
library
is not specified by the ABI, but applications are free to link it in in
their build. For questions about on-site linkage, see the section on
Shipping Objects and Libraries
libgen.a
will be included in version 1.2 of the
Conformance Guide.
nlist
?
The nlist
routine is in a library not specified by the
ABI, and should be avoided. On IRIX and some other platforms it is
found in libmld
, on the rest it is found in
libelf
.
/proc
Instead of
ptrace
.
Programs should use the /proc
interface in preference to
the ptrace
routines to examine running programs. The
ptrace
routines are not standardized.
A library for user-level mutual exclusion is provided in
libmutex.so
. Each vendor has implemented the
functionality in the most optimal manner for the hardware, so providing
the entry points as a DSO allows programs to access these routines in a
portable manner. Programs should #include
<abi_mutex.h>
and add -lmutex
to the load
line to use this functionality. See the Conformance Guide for a
definition of the interfaces.
bcopy, bzero,
bcmp
The bcopy
, bzero
, and bcmp
routines are available in the BSD Compatibility Library, however, the
memory
routines should be used instead. Note that bcopy
can be replaced either by memcpy
or memmove
.
memmove
preserves the feature that overlapping copies
work, and should be used if this is important.
#ifdef SVR4 #include <memory.h> #endif #ifdef SVR4 #ifndef bcmp #define bcmp(s1, s2, n) memcmp ((s1), (s2), (n)) #endif #ifndef bzero #define bzero(s, n) memset ((s), 0, (n)) #endif #ifndef bcopy #define bcopy(s, d, n) memmove ((d), (s), (n)) #endif #endif /* SVR4 */
index,
rindex
The index
and rindex
routines are available
in the BSD Compatibility Library, however, the strchr
and
strrchr
routines should be used instead. Note that
<string.h>
should be included instead of
<strings.h>
even if the latter file exists on the
system as it does, for example, on the current Reference Platform.
#ifdef SVR4 #include <string.h> #else #include <strings.h> #endif /* SVR4 */ #ifdef SVR4 #ifndef index #define index(s, c) strchr((s), (c)) #endif #ifndef rindex #define rindex(s, c) strrchr((s), (c)) #endif #endif /* SVR4 */
strcasecmp
?
The strcasecmp
and strncasecmp
routines, for
doing case-insensitive string compares, is not part of the ABI.
However, public-domain versions are available, or, since they are
self-contained routines, the objects can be extracted from a static
archive and included on the link line for the application.
getwd
The getwd
routine is available in the BSD Compatibility
Library, however, the standard routine getcwd
is
preferred. getcwd
provides more functionality, so
conversion is fairly straightforward. The following is one approach:
#ifdef SVR4 #include >sys/param.h> /* for MAXPATHLEN */ #define HAVE_GETCWD #endif ... char *string; char *cp; #ifdef HAVE_GETCWD cp = getcwd (string, MAXPATHLEN + 2); #else /* HAVE_GETCWD */ cp = getwd (string); #endif /* HAVE_GETCWD */
getdtablesize
The getdtablesize
routine is available in the BSD
Compatibility Library, however, the use of the POSIX interface
sysconf
is preferred.
#ifdef SVR4 #include <sys/unistd.h> #endif /* SVR4 */ ... long tsize; #ifdef _SC_OPEN_MAX tsize = sysconf (_SC_OPEN_MAX); #else /* Assume BSD */ tsize = getdtablesize(); #endif
setjmp
And
longjmp
The setjmp
and longjmp
routines are
provided. However, the 4.3BSD setjmp
and
longjmp
routines save and restore the signal mask, while
the SVR4/MIPS ABI ones do not. If the 4.3BSD behavior is needed, the
POSIX interfaces sigsetjmp
and siglongjmp
should be used. sigsetjmp
and siglongjmp
take a second argument, savemask
, which, if non-zero,
saves and restores the signal mask and scheduling parameters.
#ifdef SVR4 #define HAVE_SIGSETJMP #endif #ifdef HAVE_SIGSETJMP sigjmp_buf env; int savemask; #else jmp_buf env; endif ... #ifdef HAVE_SIGSETJMP savemask = 1; sigsetjmp(env, savemask); #else setjmp(env); #endif /* HAVE_SIGSETJMP */
gethostname
The gethostname
routine can be replaced by the use of the
sysinfo
routine.
#ifdef SVR4 #include <sys/systeminfo.h> #endif /* SVR4 */ ... char buf[MAXHOSTNAME]; #ifdef SVR4 if (sysinfo(SI_HOSTNAME, buf, sizeof(buf)) < 0) { perror("SI_HOSTNAME"); exit(BAD); } #else /* Assume BSD */ if (gethostname(buf, sizeof(buf)) < 0) { perror("gethostname"); exit(BAD); } #endif /* SVR4 */
gethostid
The MIPS ABI provides a function of the sysinfo
routine
for obtaining the host id. This should be used in preference to the
gethostid
call in the BSD compatibility library. Notice
that sysinfo
returns an ASCII representation of the value
instead of a numeric one; this example uses strtoul
to
convert it to integer. See the
Conformance Guide for details of
sysinfo
.
#ifdef _ABI_SOURCE #include <limits.h> /* for SYS_NMLN define */ #include <sys/systeminfo.h> #endif ... int hostid #ifdef _ABI_SOURCE char hostbuf[SYS_NMLN] char *hp; #endif #ifdef _ABI_SOURCE sysinfo (_MIPS_SI_HOSTID, hostbuf, SYS_NMLN - 1); hostid = strtoul (hostbuf, (char **)NULL, 0); #else hostid = gethostid (); #endif
The POSIX sysconf
routine should be used to obtain the
page size.
#include <sys/unistd.h> ... int pagesize #ifdef _ABI_SOURCE pagesize = sysconf (_SC_PAGESIZE); #else pagesize = getpagesize(); #endif
(answer under construction). The SVR4 pty routines
grantpt
, ptsname
and unlockpt
should be used.
termios
routines
The stty
/gtty
routines are not supported.
The termio
routines do exist, but should be replaced by
the POSIX termios
routines. The termios
routines provide simple routines to perform common operations, rather
than having to directly use the ioctl(2)
interface. For
example, cfsetospeed
to change the output baud rate,
tcflush
to flush output, and tcsetattr
to set
arbitrary values in the termios
structure. See
termios(2)
for details.
Note also that the termio
structure is not specified by
the ABI, and termios
should be used instead. As a
consequence, the ioctl
calls which access the
termio
routines, TCGETA
, TCSETA
,
TCSETAW
and TCSEAF
are not supported by the
ABI; the call TCGETS
, TCSETS
,
TCSETSW
and TCSESF
access the
termios
structure and are the appropriate alternatives if
the code can't be converted to use the POSIX termios
routines.
ltchars
defined?
A common porting problem from BSD-flavor UNIX is what to do with the
ltchars
structure. The termios
can provide
an alternative.
/* * If _ABI_SOURCE is defined, use the`termios
' * structure and provided routines instead of the * `ltchars
' struct */ #ifdef _ABI_SOURCE #define SVR4 #endif #include <stdio.h> #include <sys/types.h> #ifdef SVR4 #include <sys/termios.h> #else #include <sys/ioctl.h> #endif #ifdef SVR4 struct termios old_tty, new_tty; #else #ifdef TIOCSLTC struct ltchars old_chars, new_chars; #endif #endif ... #ifdef SVR4 /* * save off ltchars settings, * and change some - SVR4 flavor */ tcgetattr (fileno (stdin), &old_tty); new_tty = old_tty; if (old_tty.c_cc[VLNEXT] == CTRL('v')) new_tty.c_cc[VLNEXT] = -1; if (old_tty.c_cc[VRPRNT] == CTRL('r')) new_tty.c_cc[VRPRNT] = -1; tcsetattr (fileno (stdin), TCSAFLUSH, &new_tty); #else /* !SVR4 */ #ifdef TIOCSLTC /* * save off ltchars settings, * and change some */ (void)ioctl(fileno(stdin), TIOCGLTC, (char *)&old_chars); new_chars = old_chars; if (old_chars.t_lnextc == ctl('v')) new_chars.t_lnextc = -1; if (old_chars.t_rprntc == ctl('r')) new_chars.t_rprntc = -1; (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&new_chars); #endif #endif ... /* * on program exit, restore old ltchars settings */ void on_quit() { #ifdef SVR4 tcsetattr (fileno (stdin), TCSAFLUSH, &old_tty); #else /* !SVR4 */ #ifdef TIOCSLTC (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&old_chars); #endif #endif }
IEEE math is selected since __STDC__
is defined. As a
result math functions return IEEE bounds conditions. For example, many
routines return HUGE_VAL
instead of HUGE
in
IEEE math mode.
/* * illustrate the use of IEEE math * test that strtod called with an overflow-causing positive string * returns +HUGE (+HUGE_VAL for IEEE) and sets errno to ERANGE */ #include <stdlib.h> #include <math.h> #include <errno.h> void prt_error (char *); ... char *str2 = "+9e+999"; errno = 0; #ifdef _ABI_SOURCE if (strtod (str2, (char **)NULL) != HUGE_VAL) prt_error ("FAILED, did not return HUGE_VAL."); #else if (strtod (str2, (char **)NULL) != HUGE) prt_error ("FAILED, did not return HUGE."); #endif if (errno != ERANGE) prt_error ("FAILED, errno not set to ERANGE."); ... /* stub for example */ void prt_error (char *arg) { /*ARGSUSED*/ }
The POSIX signal interfaces (sigaction
,
sigpending
, sigprocmask
,
sigsuspend
and sigsetjmp
) should be used in
ABI conforming applications, although the simplified interface will
work fine. The IRIX manpages have excellent detail on this issue; see,
for example, sigaction(2)
and follow the *SEE ALSO*
pointers.
The POSIX wait interfaces (wait
and waitpid
)
should be used in ABI conforming applications. The IRIX manpages have
excellent detail on this issue; see, for example, wait(2)
,
which includes code samples.
HZ
is
undefined
System clock rate information should not be obtained by looking at the
define HZ
, which is generally undefined, and in any case,
would not be portable to different machines. Instead,
sysconf
should be used to obtain the information. One
possible way to code this would be:
#ifdef SVR4 #include <unistd.h> #endif ... #ifdef SVR4 #define HZ sysconf(_SC_CLK_TCK) #endif
If the clock rate is to be accessed very often, it is better to read in into a global variable at startup and change code to access the variable, thus saving a system call for each access.
gettimeofday
takes only one
argument
As defined by the ABI, the gettimeofday
routine takes only
a single argument, as timezone information is obtained from the
environment variable TZ
instead.
#include <sys/time.h> ... struct timeval tv; #ifndef SVR4 struct timezone tz; #endif ... #ifdef SVR4 gettimeofday(&tv); #else gettimeofday(&tv, &tz); #endif
In secure installations the /etc/passwd
file may not
contain the user's actual password. Applications should not assume
that the password in /etc/passwd
is the user's actual
password and should not use it for user authentication, nor should they
assume the presence of a shadow password file
/etc/shadow
.
NULL
pointers
Not all ABI systems behave the same when NULL
pointers are
dereferenced. On some platforms, the program will fail with a
segmentation violation, on others a read access will succeed because a
read-only page has been mapped at address zero. The psABI suggests
that mapping a page of memory at address 0
using
mmap
be left up to the individual process, but does not
specifically mandate that the system leave address 0
unmapped. Application programmers may need to be aware of this
possible difference in behavior.
/etc/mtab
or
/etc/mnttab
?
The /etc/mnttab
file used by some versions of the
mount
command and others, is not by itself an ABI
requirement, and application programs should not depend on its'
existence or format. On IRIX, this file is called
/etc/mtab
, for example.
/etc/fstab
or
/etc/vfstab
?
The /etc/vfstab
file used by some versions of the
mount
command and others, is not by itself an ABI
requirement, and application programs should not depend on its'
existence or format. On IRIX, this file is called
/etc/fstab
, for example.
Not all development environments on ABI systems behave the same with
respect to multiply defined global symbols. On some platforms, the
loader will emit a warning, on others a fatal error. This has
implications for applications which will be on-site linked; in the
presence of multiple defined global symbols, linking may fail on some
platforms. Application source code should be modified such that each
external data symbol is defined in exactly one place, done by omitting
the extern
keyword. All other references should use the
extern
keyword.
stat
/fstat
/lstat
The MIPS ABI uses an expanded format for device types, known as
Extended Fundamental Types (EFT). Routines which obtain device
information, such as stat
(and lstat
and
fstat
) internally have a different interface to these
routines, so those entry points are not in the standard C library. In
order to correctly use the stat
family of routines, the
<sys/stat.h>
*must* be included.
mknod
The MIPS ABI uses an expanded format for device types, known as
Extended Fundamental Types (EFT). Routines which obtain device
information, such as mknod
, internally have a different
interface to these routines, so those entry points are not in the
standard C library. In order to correctly use the mknod
routine, the <sys/stat.h>
must be included.
On the IRIX Reference Platform, a wrapper shell script is supplied to
provide command-line options compatible with those for the Software
Generation System (SGS) described in the SVID 3. This script is
supported on all Conformance Guide 1.1 compliant platforms, providing a
mechanism for delivering software systems which are used by the
end-user to construct tailored applications. It is also the preferred
method for constructing ABI applications on the RP. This script is
called abicc
.
Using abicc
allows the specific compiler calling
conventions to be hidden. The specific invocation for three different
revisions of the Reference Platform are noted in the rest of this
section. Each is different, and there is no guarantee that the methods
will not continue to change. Thus, the compilation method for IRIX 5.3
is simply to set an equate in the Makefile
:
CC = abicc
-abi
flag to cc
is sufficient to generate an ABI binary.
On IRIX 5.1 with the IRIS Development Option 3.17, the following
command line flags to the compiler are needed:
-abi -Wl,-abi -D_ABI_SOURCE -L -L/usr/lib/abi -I/usr/include/abi
Note that the sequence -L -L/usr/lib/abi
is very important,
searching the standard IRIX library paths *must* be turned off.
On RISC/os 5.01 with ANSI C 3.11, the following command line switches
are used with /svr4/bin/cc
:
-SYSTYPE_SVR4 -KPIC -std0 -G0
Actually, all of those flags are not strictly necessary if the SVR4
cc driver is used, but it may be safest to include them.
ld
directly?
On the IRIX Reference Platform, a wrapper shell script is supplied to
provide command-line options compatible with those for the Software
Generation System (SGS) described in the SVID 3. This script is
supported on all Conformance Guide 1.1 compliant platforms, providing a
mechanism for delivering software systems which are used by the
end-user to construct tailored applications. It is also the preferred
method for constructing ABI applications on the RP. This script is
called abild
.
Using abild
allows the specific compiler calling
conventions to be hidden. The specific invocation for three different
revisions of the Reference Platform are noted in the rest of this
section. Each is different, and there is no guarantee that the methods
will not continue to change. Thus, the suggested compilation method is
simply to set an equate in the Makefile
:
LD = abild
-abi
flag to ld
is sufficient to generate an
ABI binary.
On IRIX 5.1 with the IRIS Development Option 3.17, the following
command line flags to the compiler are needed:
-abi -L -L/usr/lib/abi
Note that the sequence -L -L/usr/lib/abi
is very important,
searching the standard IRIX library paths *must* be turned off.
On RISC/os 5.01 with ANSI C 3.11, the following command line switches
are used with /svr4/bin/ld
:
-SYSTYPE_SVR4 -KPIC -std0 -G0
Actually, all of those flags are not strictly necessary if the SVR4
ld driver is used, but it may be safest to include them.
If ld
is to be used directly, it is useful to study the output of
cc -abi -v
to get the flags and run-time startup files correct.
Assembler code that is to be compiled in with an ABI application must
be Position-Independent Code (PIC). There are a number of
considerations here; for example the register usage conventions of the
ABI must be observed. If the file is assembled directly by
as
, the -KPIC
option must be supplied in
order to activate the PIC directives. It is suggested that assembly
language be assembled by the use of the abicc
script
rather than calling as
directly. The code itself must
contain a directive to produce PIC code:
.option pic2Note that the assembly language format is not standardized by the ABI, so much care must be taken with assembly language which is to be used for "on-site linking"; in fact, it may not be possible. Standardizing the assembly language interface is under consideration by the MIPS ABI Group as a future direction.
If the program links correctly using the proper compiler switches,
there is a tool which can be used to check the dangling references in
an executable and make sure there are none outside the ABI. This tool
is called check_abi_compliance
. It reports references
that are outside the ABI, and also missing references that are required
by the ABI.
The tool check_for_syscalls
can be used to check that an
executable makes no system calls directly. All system calls are to be
made by ABI-specified DSOs.
On the IRIX Reference Platform, elfdump
can be used to
examine information about an ELF file. A combination of
dump
and ldd
may provide similar
functionality on other platforms.
More sophisticated application checkers are under development and will be available in the future.
It is quite reasonable to deliver custom DSOs as part of an
application. ABI programs must use always Position Independent Code
for calls to DSOs, and the DSO library must follow PIC conventions at
the call point. The IRIX RP compilers generate PIC by default; on the
RP for the 1.0 Conformance Guide (RISC/os), the -KPIC
and
-G0
options were necessary.
On IRIX 5.3 and 5.2, abild
should be used to make the
DSO. It takes the -G
flag to do this. On IRIX 5.1, the
-shared
flag is needed. Note that abicc
is
not able to make a DSO directly, the objects need to be built first,
then abild
called to link the DSO.
If DSOs are attached via dlopen
, some care must be taken
with the visibility of symbols.
To check a DSO to make sure it is ABI compliant, run
check_abi_interface
on it. It may be worthwhile to
construct a list of entry points in the DSO and install it in
/usr/lib/abi/data
. In this way, the interfaces provided
by the DSO can be checked to make sure that they don't accidentally
pull in non-ABI interfaces from other libraries (for example,
references to gethostname
, which is not part of the ABI).
If an application includes a construction kit which is used by the end-user to make a binary, there are a few issues to consider.
First, the compilation environments on the different systems come from
different sources, so getting the right arguments and flags on each
system can be pretty tricky, and in particular, may require testing on
each platform to get them right, which is at odds with the Reference
Platform concept. To alleviate this problem, all the system suppliers
have agreed to provide "standard" compiler wrappers abicc
and abild
that interpret arguments and flags from the SVR4
SGS.
Another potential problem is that libraries and include files outside the ABI are not guaranteed to be identical on all systems. Problems from this can only be avoided by careful planning when executing the port, and a thorough understanding of what is supported by the ABI. When linking an executable on the Reference Platform it is permissible to link in code from static archives that are not explicitly specified by the ABI, as long as those routines do not themselves use non-abi facilities. This has the potential for problems for on-site linkage, since it may cause differences in behavior if those static archives are implemented differently on the target than on the Reference Platform. Programs which are fully linked on the RP, on the other hand, will be consistent since they'll always have the RP version. Thus, caution is advised when requiring non-ABI libraries for an on-site linking situation.
Note that when ABI compliant libraries and object files are linked on a target system, the ABI specification does not require that the resulting executable be ABI compliant. However, the resulting binary must run on the target system if all the pieces of the original application were ABI compliant and the application would have run if linked on the Reference Platform.
As specific examples, the Math library, libm.a
, is
guaranteed to be compatible on all the ABI platforms, and can safely be
used for on-site linkage.
The curses library (libcurses
) in IRIX 5.2 is known to
depend on private interfaces in libc.so.1
and on
incompatible structure layouts and should be avoided for all uses.
The BSD compatibility library (libucb
) may be incompatible
across versions and should be avoided for on-site linkage.
The Motif library is a supported ABI library, and the ABI platform vendors have pledged to "make it work", but application vendors should take care to not depend too heavily on specific features of any specific OSF minor release. The release notes for the application should document the version of Motif it was built against for reference purposes.
The X11 library libXt
is required by Motif and is
supported for on-site linking, as is libgen
. Other X11
libraries (libXaw
, libXmu
and
libXext
are no explcitly supported but may work. No
specific X server extensions are supported by the ABI.
An ABI application may be packaged for delivery either using the SVR4
packaging tools (pkgmk
, pkgtrans
, etc.), or
use their own packaging and installation tools. In the latter case,
tools must be restricted to those defined in chapter 8 of the gABI and
the Conformance Guide.
Nodes for standard devices are provided in /dev/abi
. See
Chapter 2 of the Conformance Guide for the device names.
According the the gABI, an application collectively called PKG
should install static package objects in /opt/PKG
, package
objects that change in normal operations (such as log files) in
/var/opt/PKG
, and machine-specific configuration files in
/etc/opt/PKG
. Only package objects that must reside in
specific locations within the system file tree in order to function
properly (e.g., special files in /dev
) should be installed
in those locations.
The Conformance Guide extends these requirements slightly for
efficiency reasons (to keep search paths short); for example executable
objects installed in /opt/PKG/bin
may symbolically link
files to /opt/bin
. See the
Conformance Guide for details.
ABI platforms are required to provide the directories
/opt/bin
, /opt/man
, and
/opt/include
.
When constructing installation scripts or pkgmap
files, be
aware that the /opt
subtree may well be symbolically
linked to someplace else - any existing links should be preserved.
On the IRIX reference platform, the dbx
debugger can be
used for full symbolic debugging. The way in which debugging
information is encoded in the binary is not fully standardized,
however, so binaries built on IRIX are only guaranteed to be debuggable
at the assembly-language level on the other ABI platforms.
On the IRIX Reference Platform, check what DSOs an executable needs by doing
elfdump -Dl PROGRAM
On the Reference Platform for the 1.0 Conformance Guide (RISC/os),
use odump
instead of elfdump
.
Version 1.0 of the Conformance Guide specified X11R4. Version 1.1 of
the Conformance Guide specifies X11R5. libX11.so
is
supplied as a DSO. The correct version matching X11R5 is
libX11.so.2
. The correct version matching X11R4 is
libX11.so.1
.
The X Toolkit, libXt, is supplied as a static archive. Existing test technology is not available to insure that each vendor's implementation of libXt as a DSO is functionally equivalent, thus linking is to be done with the libXt static archive on the Reference Platform.
The X Consortium standard represented by libX11
is fully
supported. The X Toolkit (libXt
) is also supported.
Other "standard" X11 libraries, such as libXaw
,
libXmu
, and libXext
, may be present on the
Reference Platform as static archives, but are not officially
supported. Portions of the X11R5 sample implementation which represent
X Consortium "works in progress" may work but are not guaranteed to be
supported. PEX is not covered by the ABI.
Version 1.0 of the Conformance Guide calls for support for Motif 1.1. Version 1.1 of the Conformance Guide updates this to Motif 1.2. The question of staying compatible across official patches to these major releases, and still addressing critical bugs, has proven to be a thorny issue. At this time, Conformance Guide 1.1 compliant platforms are expected to run Motif 1.2.3 plus some known fixes. 1.0 compliant platforms run Motif 1.1.3.
The entire Motif 1.2 library (libXm
) is supported. Other
Motif libraries may be present on the Reference Platform as static
archives, but are not guaranteed to be supported. The Resource Manager
(libMrm
and User Interface compiler (uil
and
libuil
) are not supplied on the Reference Platform.
A number of the ABI platforms are multiprocessor, and *will* run ABI
applications. Some information about the configuration of the machine
(number of processors, for example) is available through the
sysinfo
facility, but multi-threading and synchronization
primitives for an MP environment are not covered by the ABI, and thus
cannot be utilized by compliant programs. This is a subject for
ongoing work by the MIPS ABI group.
Normal (non-trusted) apps will run without changes. If an application knows that the system is secure and acts on it, it will not be considered ABI compliant. However, this does not mean that the same application running at different levels of security is necessarily non-ABI compliant.
The MIPS ABI group is considering specifying OpenGL as an optional component of the ABI in a future version of the Conformance Guide. Where present, implementations will be binary compatible. OpenGL provides a portable, device independent 3D graphics implementation.
Additional X11 libraries will be considered for standardization. The ABI will continue to track X11 releases from the X Consortium as appropriate; a statement on X11R6 will be forthcoming.
Asynchronous I/O will be introduced as a required interface with version 1.2 of the Conformance Guide. The interface follows the async I/O sections from POSIX 1003.1b.
The Global Offset Table (GOT) is limited to 16,384 external references. In some circumstances, this has proven to be too small. The MIPS ABI Group has agreed to a specification for an expanded GOT for the 1.2 Conformance Guide. An ABI conforming application can not use expanded GOT facilities, even if available on the Reference Platform, and still be compliant with the 1.1 version of the Conformance Guide.
Alternative solutions are to modify the application to use fewer global
symbols, or if the application uses its' own static archives, to turn
some of those into DSOs, since each DSO has its' own GOT. The
elfdump
program on the Reference Platform can provide
insight into the current size of GOTs.
Machines supporting the MIPS ABI range in size from laptop computers to large datacenter machines, come in multiprocessor configurations, offer fault tolerance, real-time capabilities, etc. The MIPS processor family includes members from the R2000 up through forthcoming high-end processors with a wide performance range. In order to support this range, the current ABI is pegged to a common denominator, the MIPS I instruction set architecture. The MIPS ABI group is considering extensions to take advantage of newer processor architectures as a future direction. For most applications, use of the MIPS I instruction set does not provide a significant performance penalty.
The MIPS ABI group recognizes that there are significant bodies of applications code which are not written in C, but which still could benefit from binary compatibility. The group's intention is to continue work to define standard binary compatible interfaces for FORTRAN, C++, and other languages as demand warrants. Some efforts along these line are in progress in future versions of gABI. At the present time, only the C interfaces defined by the ABI are supported on all platforms.
This section describes workarounds for areas of known incompatibility of the IRIX 5.2 Reference Platform with the MIPS ABI. This information is not available for earlier Reference Platforms (RISC/os or IRIX 5.1).
The current Reference Platform (IRIX 5.3) Problems and issues may be found at the end of this document.
While IRIX 5.2 with IDO 3.18 serves as the Reference Platform, it is not, by default, installed as an ABI environment.
The eoe1.sw.svr4net
package must be installed to get the
ABI libsocket
and libnsl
libraries. If this
package is not installed from the miniroot, the system must be rebooted
to force the kernel to be rebuilt before the changes will take effect.
The dev.sw.abi
and compiler_dev.sw.abi
packages must be installed to get the ABI Development environment.
The eoe2.sw.oampkg
package must be installed in order to
access the ABI packaging utilities.
/dev/abi
According to the Conformance Guide, devices for supported installation
media are found in /dev/abi
. If one of the supported media
devices (floppy, QIC-120 cartridge, 6250 bpi 9-track tape, or ISO 9660
CD-ROM) is present on the system, the corresponding node should be
found in /dev/abi
. These nodes are not made on IRIX 5.2.
This has been corrected in the IRIX 5.3 Reference Platform.
One possible workaround is to special-case installation for IRIX, to check known device names for these media. More likely, it is best to prompt for the installation device, rather than checking for particular defaults, thus avoiding the question of whether an expected default node has been made or not.
/opt
not made
The Conformance Guide specifies that the special install directories
/opt/bin
, /opt/man
, and
/opt/include
are provided for symlinking files from
/opt/PKG/*
, in order that each package installed doesn't
have to have its' bin
directory added to the
$PATH
, or man
directory added to
$MANPATH
. /opt/include
and
/opt/man
are not made on IRIX 5.2. This has been
corrected in the IRIX 5.3 Reference Platform.
The workaround is for an install procedure to check for these directories, and make them if they are not present.
-abi
flag is not documented
for cc
or ld
The -abi
flag for cc
and ld
is
used to make ABI binaries on the IRIX Reference Platform. This flag is
not documented in the cc
and ld
manpages.
Developers are urged to use the abicc
and
abild
wrappers to build ABI binaries. These wrappers hide
the details of how cc
or ld
should be
called. If the exact invocation is needed, cc -abi -v
will show how the compiler passes are called; this output should be
saved for reference, and will show the combination of preprocessor
defines, ANSI compliance modes, etc. that make up ABI mode.
-F
TYPE
According to the ABI, the mount
command should take the
-F
TYPE flag and argument. On IRIX 5.2, mount
-t
TYPE must be used instead.
Note that in the case of mounting an CD-ROM device, the IRIX
mediad
program may automatically mount the CD-ROM on the
mountpoint /CDROM
, as long as the CD-ROM is in a format
mediad
recognizes, and mediad
is running.
This behavior is not necessarily expected on other ABI-conforming
platforms.
cdfs
type
The mount
command does not accept the cdfs
type. On IRIX 5.2, this type is called iso9660
. In IRIX
5.3, cdfs
is also accepted.
The monitor
library routine, and the synonym
_monitor
, are not found in the ABI C library on IRIX 5.2.
On IRIX, the routine has been moved to libprof.a
, which is
not present in the ABI Development Environment. The cc
compiler will also look for this library if the profiling flag
(-p
) is supplied, and fail to find it, resulting in an
error message.
Profiling should probably not be used in an ABI application. The IRIX
static archive libprof.a
cannot be used, as it pulls in a
number of non-ABI symbols.
This has been corrected in IRIX 5.3.
libucb.a
is not provided
The Conformance Guide specifies that libucb.a
is available
as a transition aid for popular BSD UNIX interfaces. This library is
not available on IRIX. However, virtually all of the functionality is
available within libc. A possible workaround is to perform this
command before compiling:
cd /usr/lib/abi ln -s libc.so libucb.aThis is not guaranteed to work correctly in all cases, but might serve as a transitional aid (
libucb.a
is only supposed to be a
transitional aid anyway). Be sure to run
check_abi_compliance
on the resulting binary to insure no
non-ABI interfaces were pulled in.
libucb.a
is
scheduled to be phased out in future versions of the MIPS ABI.
_lib_version
not set
_lib_version
is not set in binaries generated on the
Reference Platform running IRIX 5.2. ABI programs require ANSI C
semantics, so _lib_version
should be set non-zero. This
will be corrected in the next release.
The run-time ABI socket library (libsocket
)) in IRIX 5.2
has some bugs. The workaround is to arrange things so that the native
IRIX libc
is used to provide the socket interfaces. To
perform this workaround, first check that the IRIX package
eoe1.sw.svr4net
is installed. If not installed, go back
and install it, since this is required for the ABI execution
environment.
cd /usr/lib ls -l libsocket.so mv libsocket.so libsocket.so.orig ln -s libc.so.1 libsocket.soThe
ls -l
step is to check that the workaround has not
already been enabled; if libsocket.so
is already a
symbolic link to libc.so.1
, there is no need to continue
as the workaround has been enabled.
Do *not* make any changes in the compile-time ABI environment,
/usr/lib/abi
.
In the next release, this problem will be corrected in a way such that
the interfaces found in libsocket
will actually be
resolved against the native IRIX libc
.
Three of the static archives supplied in the ABI build environment on
the IRIX 5.2 Reference Platform are not fully ABI-clean. The three
libraries are libXt.a
, libXmu.a
, and
libmld.a
. Workarounds are generally possible if the
non-ABI symbols are pulled in to a program (this will not always
happen).
If check_abi_compliance
reports compliance problems with
the symbol gethostname
, it could have come from any of the
three libraries. The workaround is to
provide a stub gethostname
routine.
The other problems reported are with
bzero
and
getpagesize
In each case providing the stub in the program itself will force the symbol to be resolved to the local routine, not to the non-ABI-compliance routine in a system DSO.
uname
call workaround
The uname
routine is a source-level interface. The
internal calling sequence has not been properly standardized with the
1.1 Conformance Guide (an oversight in the standard itself). If the
file <sys/utsname.h>
is included on the IRIX 5.2
Reference Platform, the call to uname
will not be binary
compatible. The workaround is to include a stub routine which will
cause the proper internal call for binary compatibility.
static int uname (struct utsname *_buf) { int ret; ret = nuname(_buf); return ret; }
This has been corrected in IRIX 5.3.
The preferred method of accessing the terminal interface is to use the
general terminal interface routines specified by POSIX. These routines
are tcgetattr
, tcsetattr
,
tcsendbreak
, tcdrain
, tcflush
,
tcflow
, cfgetospeed
,
cfsetospeed
, cfgetispeed
,
cfsetispeed
, tcgetpgrp
,
tcsetpgrp
, tcgetsid
.
The termio
structure is not specified by the ABI, the
termios
structure should be used instead. As a
consequence, the ioctl
calls which access the
termio
routines, TCGETA
, TCSETA
,
TCSETAW
and TCSETAF
are not supported by the
ABI; the calls TCGETS
, TCSETS
,
TCSETSW
and TCSETSF
access the
termios
structure and are the appropriate alternatives if
the code can't be converted to use the POSIX terminal interface
routines.
The curses library (libcurses
, which is the same as the
libterminfo
or libtermcap
library) and header
file use the termio
structure. As a result, programs
linked with the curses library are generally not binary-compatible. As
a workaround, a modified version of libcurses.a
and
curses.h
are available from the MIPS ABI Developer Support
Program. These modifications have been incorporated into IRIX 5.3.
Please note that alternative terminal and cursor management packages
are not immune from these considerations; if a third-party developed
package is being used with an application it should be checked. The
par
command (on IRIX) and truss
command
(other platforms) can be used to observe whether invalid
ioctl(TCGETA)
family calls are being made. Note that one
such call will legitimately be made by a program via the
isatty
call, and since the structure is never manipulated
by that call, it is safe.
If an effort to link-edit ABI-compliant objects on a machine other than
the Reference Platform results in error messages indicating undefined
symbols, and the symbols are known not to really be undefined, it is
probably due to a problem in the IRIX compilation system. The IRIX
compilation system maintains two separate tables of symbol information,
one is the ELF symbol table required by the MIPS ABI, the other is the
mdebug
section, which is used by certain of the other
tools in the IRIX compilation system. In this bug, routines which are
declared static
in a particular code module are
erroneously entered into the ELF symbol table as undefined symbols.
Those ABI platforms which use compilation systems of a similar heritage
to the one used in IRIX will be able to handle this case, but certain
others will not.
One workaround is to use the -znodefs
linker option, which
allows a binary to be linked even if there are undefineds. Since these
are not really undefined symbols, there will be no unmatched reference
to them, so this is safe. Unfortunately, the abicc
script
only passes some linker-specific options down to the linker, and one of
the ones it doesn't pass is -znodefs
. If the nodefs
workaround is to be used with abicc
, something will need
to be added to the options
line in the configuration file
for the particular abicc
. On IRIX the configuration file
is /usr/lib/abi/sgicc.cfg
; the name and location will
differ on other ABI platforms (check the ABILIB variable near the top
of abicc
). See abicc Doesn't Pass
Some Linker Flags , for one approach to making this modification.
A negative consideration here is that this modification has to be made
not only to the machine a developer is working on, but also to customer
sites for those customers who will be doing on-site linking of the
application.
Another workaround requires obtaining a different linker and using it
as a post-processor to remove these erroneous references from the ELF
symbol table. This other linker is available from the MIPS ABI
Developer Support Program. It is called ld32
. The example
illustrates how an object would be created using this scheme:
abicc -c $OPTIONS sample.c ld32 -abi -r -g sample.o -o sample.x mv sample.x sample.o
In certain circumstances it is desirable to combine objects into a
relocatable aggregate object file which will be shipped as part of a
product. While a similar effect often can be achieved by using an
archive library, there are cases where a relocatable object is
appropriate. The IRIX 5.2 compilation system will not produce a fully
ABI-compliant object when ld -r
is used.
The workaround requires obtaining a different linker and using it as a
post-processor to recreate the required ordering of symbol table
entries. This linker should only be used after the regular linker has
been used to combine the objects, as it will not, by itself, produce
the mdebug
information that the regular IRIX linker, and
other linkers of the same heritage, require. This other linker is
available from the MIPS ABI Developer Support Program. It is called
ld32
. The example illustrates how an object would be
created using this scheme:
abicc -c $OPTIONS sample1.c abicc -c $OPTIONS sample2.c abicc -c $OPTIONS sample3.c abild -r -o sample.o sample1.o sample2.o sample3.o ld32 -abi -r -g sample.o -o sample.x mv sample.x sample.oNote that
ld32
must still be considered an unsupported
workaround at this point, although it has received considerable
testing.
See also the section on Undefined Symbols During On-Site Linking
sigaltstack
Incompatibility
There is a difference between various ABI platforms in how the
sigaltstack
routine is implemented. On IRIX and some
other platforms, the stack pointer ss_sp
in the
sigstk
structure must be manually adjusted to point to the
top of the new stack after the stack has been allocated, since stacks
in the MIPS architecture grow down. On other platforms, the adjustment
is made internally so that when the handler is active on the alternate
stack, the stack pointer is in the right place.
Changing the behavior to be consistent across platforms would have introduced too much risk of incompatibility with existing application code, so while a more permanent solution is explored, a workaround is offered.
To guarantee working on all the ABI platforms, a stack twice the size actually estimated to be required can be allocated. The stack pointer is then moved up by the original estimated size. This results in a stack pointer at the top of the space for automatically-adjusting systems, and in the middle, but still with as much space as the original estimate, on the non-adjusting systems.
A refinement on the above approach would be to use the *allocate
double* method in a test case run at initialization time, force the
signal handler for the test case to be invoked, and have it examine
where the stack pointer is placed relative to the ss_sp
field to
determine whether this is an automatically-adjusting or a non-adjusting
system. The information would be stored in a global variable for use
by the remainder of the program.
Example code illustrating the allocate double scheme follows:
#include <signal.h> ... /* * allocate alternate stack * MIPS ABI version: allocates extra space, adjusts * stack pointer compatibly for all platforms */ int setup_altstack (stack_t *sigstk, stack_t *osigstk, int altstacksize, .... ) { int altstackadj = altstacksize; /* set up alternate stack */ if ((sigstk->ss_sp = (char *) malloc (altstacksize*2)) == NULL) { perror("malloc"); return -1; } sigstk->ss_size = altstacksize; /* adjust ss_sp to point to middle of stack */ sigstk->ss_sp += altstacksize - sizeof (int); sigstk->ss_flags = 0; if (sigaltstack(sigstk, osigstk) < 0) { perror("sigaltstack"); return -1; } }
makecontext
Incompatibility
The makecontext
routine has the same problem as
sigaltstack
in that on some platforms, the stack pointer
described by the ucontext
structure uc_stack
element is automatically adjusted when the registered signal handler is
invoked, while on other platforms it is left unchanged as it is
expected to have been adjusted by the programmer to point to the
correct address.
see
sigaltstack
Incompatibility
for further details.
The lex library, libl
, is not supplied in an ABI version.
Programs cannot be linked with the -ll
option. Similarly,
the yacc library liby
, is not supplied so programs cannot
be linked with -ly
. These libraries can be obtained from
MIPS ABI Developer Support if needed.
strtod
Errors
C library routines which make use of the internal routine
_tenscale
suffer from an implementation problem on IRIX
which may give bad results. The affected routines are
strtod
, atof
, ecvt
and
fcvt
, and possibly also the floating point portions of the
printf
family. This has been corrected in IRIX 5.3 Reference
Platform.
The FD_ZERO
macro in system header file
<sys/select.h>
contains a reference to the
bzero
routine, which is not part of the MIPS ABI. This
can be worked around by defining bzero
in the program in
terms of the memset
routine:
#define bzero(s, n) memset((s), 0, (n))
An alternative is to modify the include file to redefine the
FD_ZERO
macro, although changing a system include file
usually is undesirable. To make the modification, the define should be
changed to look like this:
#ifdef _ABI_SOURCE #define FD_ZERO(p) memset((char *)(p), 0, sizeof(*(p))) #else #define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) #endif
This has been corrected in the IRIX 5.3 Reference Platform.
The standard library routine _cleanup
performs
flush-on-exit processing for standard I/O. This routine is intended to
be called automatically when a program exits normally (it is not called
if _exit
is called or the program terminates abnormally).
On many of the MIPS ABI systems, the call is arranged for by having the
run-time startup prologue, crt1.o
, register a call to
_cleanup
with the atexit
routine. On IRIX,
the call is arranged by having the C library exit
routine
make the call. When a program is made using the Reference Platform
scheme, it will be bound with the IRIX crt1.o, which does not contain
the atexit
registration, and when that program is run on a
different ABI platform, which does not contain the call to
_cleanup
from exit
, the effect is that
_cleanup
is not called.
How the call is _cleanup
is to be arranged is not
specified by the MIPS ABI. The member companies have agreed to change
their methods to be compatible with code built on the Reference
Platform. However, in the interim, a workaround is needed. The
simplest workaround is to simply insert the equivalent to what the
native crt1.o
would have done very early in the program -
somewhere at the top of the main
routine seems best:
atexit(_cleanup);The MIPS ABI Developer Support program or the individual platform vendors can supply information about which operating system revisions need the workaround, or, optionally, the application may choose to simply use the workaround regardless of target.
SIGTRAP
An integer divide-by-zero will raise a SIGTRAP
signal on
IRIX 5.2. The ABI requires the behavior specified in the SVID, which
is to raise a SIGFPE
signal and set the siginfo indication
(SI_CODE) to FPE_INTDIV
. There is no current workaround.
This has been correct in the IRIX 5.3 Reference Platform.
tanh
Errors
The tanh
routine in the Math library (libm
)
will overflow on large numbers (numbers which are more than half the
MAX_DOUBLE
value) on IRIX 5.2. There is no current
workaround. This has been correct in the IRIX 5.3 Reference Platform.
abicc
Doesn't
Pass Some Linker Flags
The abicc
shell script does not pass through some linker
flags that it ought to. Neither -Wl,xxx
construct nor the
specific flag will be passed unless it is among those documented in the
MIPS ABI Conformance Guide 1.1 documented for the abicc
command. For example, the -znodefs
option is needed on
some platforms because of other bugs, but it cannot be supplied from
the abicc
command line. There are two possible
workarounds.
One approach is to modify the setup script for abicc
.
A possible way to do this would be to change the options
line in the setup script (/usr/lib/abi/sgicc.cfg
on IRIX)
to pass a variable, the required flags can then be passed via an
environment variable. For example, if the line looked like this:
options="-abi"it could be changed to
options="-abi $ABICC_EXTRA"and then a flag could be passed by doing (for csh users):
setenv ABICC_EXTRA -znodefs
Another possible approach is to use abild
to do linking.
`abild' will accept all the options documented for it, so there is no
problem with whether abicc
will pass them on correctly.
However, linking with abild
is trickier than linking with
abicc
since the right startup files and default libraries
must be supplied. Linking with abild
has the same
relationship to abicc
as linking with ld
has
to cc
; if you would normally link with ld
it
makes sense to use abild
, otherwise it probably doesn't.
To get a start on linking with abild
, use
abicc
once to link the program, specifying the
-v
flag, save the output, and use it to begin building up
a correct link line for abild
.
This has been corrected in IRIX 5.3 and the above approach is not recommended.
Some platforms are more restrictive that others in their default
linking behavior. One such problem area is with the placement of
"string" data. With ANSI C, such data is usually made to be
const
, meaning it will be read-only. However, older code
may still depend on being able to modify locations in a string, for
example, in the case where a *template* string is used to generate a
temporary name. While this is bad coding practice by current
standards, there is a recognition that legacy code may depend on this
behavior. On IRIX, the default behavior is to put string and other
constant data into a special rodata
section, but to place
that section within the data section, where it remains writable. Other
platforms will make it read-only.
This becomes an issue where a program is linked and tested on the Reference Platform, where an code which modifies a string in this manner would still work; then is relinked on one of the more restrictive platforms which will put the string into read-only memory and potentially fail the program. It is only an issue where strings are actually written to. This is only for cases where the string would appear constant, like this example:
char string[] = "templateXXXX";and something knows to start writing a pattern beginning at
string[8]
.
One workaround is to inform the IRIX linker to put the strings into
read-only memory, such that errors of this type will be noticed during
the testing phase. This option cannot be supplied using
abicc
at the moment; the -rdata_shared
flag
needs to be given to the linker. One possible approach is to use the
technique for modifying the configuration script for abicc
as noted in abicc
Doesn't Pass Some
Linker Flags, then define ABICC_EXTRA like this (for csh users):
setenv ABICC_EXTRA "-Wl,-rdata_shared".This is correct only for IRIX and other platforms whose native linker accept the
-rdata_shared
flag.
An abicc
flag to acces the -rdata_shared
behavior will be available in the next release.
Legend BB Black Book CCUR Concurrent CDS Control Data NEC NEC PYRAMID Pyramid SGI IRIX 5.3 Reference Platform SNI Siemens Nixdorf SONY Sony TANDEM Tandem def means that there is a definition for the call def! indicates that there is no definition for the define or call BB CCUR CDS NEC PYRAMID SGI SNI SONY TANDEM netinet/in.h htonl def def def def def def def def def! htons def def def def def def def def def! ntohl def def def def def def def def def! ntohs def def def def def def def def def! netinet/in.h IP_ADD_MEMBERSHIP 5 def! 5 5 def! 23 def! 5 5 IP_DROP_MEMBERSHIP 6 def! 6 6 def! 24 def! 6 6 IP_HDRINCL 7 def! 7 7 def! 2 def! 7 def! IP_MULTICAST_IF 2 def! 2 2 def! 20 def! 2 3 IP_MULTICAST_LOOP 4 def! 4 4 def! 22 def! 4 4 IP_MULTICAST_TTL 3 def! 3 3 def! 21 def! 3 2 IP_RECVDSTADDR 12 def! 12 12 def! 7 def! 12 def! IP_RECVOPTS 10 def! 10 10 def! 5 def! 10 def! IP_RECVRETOPTS 11 def! 11 11 def! 6 def! 11 def! IP_RETOPTS 13 def! 13 13 def! 8 def! 13 def! IP_TOS 8 2 8 8 def! 3 2 8 7 IP_TTL 9 def! 9 def! def! 4 3 9 2 net/if.h IFF_MULTICAST 0x800 def! def! 0x800 def! 0x800 def! 0x800 0x4000 net/route.h RTF_REINSTATE 0x8 0x8 0x8 0x8 0x8 0x8 0x8 def! 0x8 sys/socket.h AF_NBS 7 7 7 7 7 def! 7 7 7 AF_OSINET 21 21 21 21 2 21 2 21 21 AF_X25 20 20 def! 20 20 20 20 20 20 PF_NBS 7 7 7 7 7 def! 7 7 7 PF_X25 20 20 def! 20 20 20 20 20 20
syslog(3)
behaves inconsistently on some platforms.
On the current Reference Platform, /dev/log is used as the device
through which the syslog call outputs to the console. It is known that
on some platforms different devices are used. The following table
shows the platforms and the device nodes that are used for syslog
output.
The following table represents the devices that are used when an application uses syslog natively:
NEC /dev/conslog Sony /dev/log Control Data /dev/log Concurrent /dev/conslog Dansk Data /dev/conslog SNI /dev/conslog Pyramid /dev/conslog SGI /dev/log Tandem /dev/eventwriteThe current workaround is to ensure that there is a /dev/log present for and that it matches the major and minor numbers for the designated file in /dev.
Back to the MIPS ABI Home Page
Copyright © 1995, MIPS ABI Group, Incorporated.