2.00: C/C++


Contrary to many people's belief, the C environment on the RS/6000 is
not very special.  The C compiler has quite a number of options that can
be used to control how it works, which "dialect" of C it compiles, how
it interprets certain language constructs, etc.  InfoExplorer includes a
Users Guide and a Reference Manual.

The compiler can be invoked with either xlc for strict ANSI mode and cc
for RT compatible mode (i.e. IBM 6150 with AIX 2).  The default options
for each mode are set in the /etc/xlc.cfg file, and you can actually add
another stanza and create a link to the /bin/xlc executable.

The file /usr/lpp/xlc/bin/README.xlc has information about the C
compiler, and the file /usr/lpp/bos/bsdport (AIX 3 only) contains useful
information, in particular for users from a BSD background.

The file /etc/xlc.cfg also shows the symbol _IBMR2 that is predefined,
and therefore can be used for #ifdef'ing RS/6000 specific code.

------------------------------

2.01: I cannot make alloca work


A famous routine, in particular in GNU context, is the allocation
routine alloca().  Alloca allocates memory in such a way that it is
automatically free'd when the block is exited.  Most implementations
does this by adjusting the stack pointer.  Since not all C environments
can support it, its use is discouraged, but it is included in the xlc
compiler.  In order to make the compiler aware that you intend to use
alloca, you must put the line

#pragma alloca

before any other statements in the C source module(s) where alloca is
called.  If you don't do this, xlc will not recognize alloca as anything
special, and you will get errors during linking.

For AIX 3.2, it may be easier to use the -ma flag.

------------------------------

2.02: How do I compile my BSD programs?


The file /usr/lpp/bos/bsdport contains information on how to port
programs written for BSD to AIX 3.  This file may be very useful for
others as well.

A quick cc command for most "standard" BSD programs is:
  
  $ cc -D_BSD -D_BSD_INCLUDES  -o [loadfile] [sourcefile.c] -lbsd

If your software has system calls predefined with no prototype
parameters, also use the -D_NO_PROTO flag.

------------------------------

2.03: Isn't the linker different from what I am used to?


Yes.  It is not at all like what you are used to:

- The order of objects and libraries is normally _not_ important.  The
  linker reads _all_ objects including those from libraries into memory
  and does the actual linking in one go.  Even if you need to put a
  library of your own twice on the ld command line on other systems, it
  is not needed on the RS/6000 - doing so will even make your linking slower.

- One of the features of the linker is that it will replace an object in
  an executable with a new version of the same object:

  $ cc -o prog prog1.o prog2.o prog3.o		# make prog
  $ cc -c prog2.c				# recompile prog2.c
  $ cc -o prog.new prog2.o prog			# make prog.new from prog
						# by replacing prog2.o
  
- The standard C library /lib/libc.a is linked shared, which means that
  the actual code is not linked into your program, but is loaded only
  once and linked dynamically during loading of your program.

- The ld program actually calls the binder in /usr/lib/bind, and you can
  give ld special options to get details about the invocation of the
  binder.  These are found on the ld man page or in InfoExplorer.

- If your program normally links using a number of libraries (.a files),
  you can 'prelink' each of these into an object, which will make your
  final linking faster.  E.g. do:

  $ cc -c prog1.c prog2.c prog3.c
  $ ar cv libprog.a prog1.o prog2.o prog3.o
  $ ld -r -o libprog.o libprog.a
  $ cc -o someprog someprog.c libprog.o

This will solve all internal references between prog1.o, prog2.o and
prog3.o and save this in libprog.o Then using libprog.o to link your
program instead of libprog.a will increase linking speed, and even if
someprog.c only uses, say prog1.o and prog2.o, only those two modules
will be in your final program.  This is also due to the fact that the
binder can handle single objects inside one object module as noted above.

If you are using an -lprog option (for libprog.a) above, and still want
to be able to do so, you should name the prelinked object with a
standard library name, e.g. libprogP.a (P identifying a prelinked
object), that can be specified by -lprogP.  You cannot use the archiver
(ar) on such an object.

You should also have a look at section 3.01 of this article, in
particular if you have mixed Fortran/C programs.

Dave Dennerline (d.dennerline@bull.com) claims that his experiences
in prelinking on AIX does not save much time since most people have
separate libraries which do not have many dependencies between them,
thus not many symbols to resolve.

------------------------------

2.04: How do I statically link my program?


  cc -o prog -bnoso -bI:/lib/syscalls.exp obj1.o obj2.o obj3.o

will do that for a program consisting of the three objects obj1.o, etc.

[Editor's note: You should never link programs statically that are
supposed to leave your local environment, e.g. intended for
distribution. Statically linked programs may fail to work after
installing a new AIX version or even after installing a PTF.]

From: Marc Pawliger (marc@sti.com)

As of AIX 3.2.5, you can install a speedup for AIXwindows called
Shared Memory Transport.  To static link an X application after the
SMT PTF has been installed, you must link with
-bI:/usr/lpp/X11/bin/smt.exp and the executable will NOT run on a
machine where SMT is not installed.  See /usr/lpp/X11/README.SMT
Newsgroups: comp.unix.aix,comp.answers,news.answers
Path: news.univie.ac.at!aconews.univie.ac.at!newscore.univie.ac.at!fu-berlin.de!news-ber1.dfn.de!news-ham1.dfn.de!newsserver.rrzn.uni-hannover.de!baghira.han.de!jum
From: jum@anubis.han.de
Approved: news-answers-request@mit.edu
Followup-To: comp.unix.aix
Supersedes: <aix-faq-4-886305604@anubis.han.de>
Reply-To: jum@anubis.han.de (Jens-Uwe Mager)
Keywords: AIX RS/6000 questions answers
Sender: jum@baghira.han.de (Jens-Uwe Mager)
Expires: Sun, 5 Apr 1998 05:01:07 GMT
Organization: At Home
Message-ID: <aix-faq-4-888724807@anubis.han.de>
References: <aix-faq-1-888724807@anubis.han.de> 
Date: Sun, 1 Mar 1998 04:00:24 GMT
         and their answers.  AIX is IBM's version of Unix.
Lines: 1806
Xref: news.univie.ac.at comp.unix.aix:125562 comp.answers:29712 news.answers:39490

Posted-By: auto-faq 3.3 (Perl 4.035)
Archive-name: aix-faq/part4
Posting-Frequency: monthly


------------------------------

2.05: How do I make my own shared library?


To make your own shared object or library of shared objects, you should
know that a shared object cannot have undefined symbols.  Thus, if your
code uses any externals from /lib/libc.a, the latter MUST be linked with
your code to make a shared object.  Mike Heath (mike@pencom.com) said it
is possible to split code into more than one shared object when externals
in one object refer to another one.  You must be very good at
import/export files.  Perhaps he or someone can provide an example. 

Assume you have one file, sub1.c, containing a routine with no external
references, and another one, sub2.c, calling stuff in /lib/libc.a.  You
will also need two export files, sub1.exp, sub2.exp.  Read the example
below together with the examples on the ld man page. 

---- sub1.c ----
    int addint(int a, int b)
    {
      return a + b;
    }
---- sub2.c ----
    #include <stdio.h>

    void printint(int a)
    {
      printf("The integer is: %d\n", a);
    }
---- sub1.exp ----
    #!
    addint
---- sub2.exp ----
    #!
    printint
---- usesub.c ----
    main()
    {
      printint( addint(5,8) );
    }

The following commands will build your libshr.a, and compile/link the
program usesub to use it.  Note that you need the ld option -lc for
sub2shr.o since it calls printf from /lib/libc.a.  [Note that you can leave
out the "-T512 -H512" on AIX 4. -- Ed.]

  $ cc  -c sub1.c
  $ ld -o sub1shr.o sub1.o -bE:sub1.exp -bM:SRE -T512 -H512 
  $ cc  -c sub2.c
  $ ld -o sub2shr.o sub2.o -bE:sub2.exp -bM:SRE -T512 -H512  -lc
  $ ar r libshr.a sub1shr.o sub2shr.o
  $ cc -o usesub usesub.c -L: libshr.a
  $ usesub
  The integer is: 13
  $

------------------------------

2.06: Linking my program fails with strange errors. Why?


Very simple, the linker (actually called the binder), cannot get the
memory it needs, either because your ulimits are too low or because you
don't have sufficient paging space.  Since the linker is quite different
>from normal Unix linkers and actually does much more than these, it also
uses a lot of virtual memory.  It is not unusual to need 10000 pages (of
4k) or more to execute a fairly complex linking.

If you get 'BUMP error', either ulimits or paging is too low, if you get
'Binder killed by signal 9' your paging is too low.

First, check your memory and data ulimits; in korn shell 'ulimit -a' will
show all limits and 'ulimit -m 99999' and 'ulimit -d 99999' will
increase the maximum memory and data respectively to some high values. 
If this was not your problem, you don't have enough paging space.

If you will or can not increase your paging space, you could try this:

- Do you duplicate libraries on the ld command line? That is never
  necessary.

- Do more users link simultaneously? Try having only one linking going
  on at any time.

- Do a partwise linking, i.e. you link some objects/libraries with the
  -r option to allow the temporary output to have unresolved references,
  then link with the rest of your objects/libraries.  This can be split
  up as much as you want, and will make each step use less virtual memory.

  If you follow this scheme, only adding one object or archive at a
  time, you will actually emulate the behavior of other Unix linkers.

If you decide to add more paging space, you should consider adding a new
paging space on a second hard disk, as opposed to just increasing the
existing one.  Doing the latter could make you run out of free space on
your first harddisk. It is more involved to shrink a paging space
but easier to delete one.

------------------------------

2.07: Why does it take so long to compile "hello world" with xlc?


Some systems have experienced delays of more than 60 seconds in
compiling "#include <stdio.h> int main () {printf ("Hello world");}"
The problem is with the license manager contact IBM to make sure
you've got the latest PTF.

------------------------------

2.08: What's with malloc()?

 
malloc() uses a late allocation algorithm based on 4.3 BSD's malloc()
for speed.  This lets you allocate very large sparse memory spaces,
since the pages are not actually allocated until they are touched for
the first time.  Unfortunately, it doesn't die gracefully in the face of
loss of available memory.  See the "Paging Space Overview" under
InfoExplorer, and see the notes on the linker in this document for an
example of an ungraceful death.

If you want your program to get notified when running out of memory, you
should handle the SIGDANGER signal.  The default is to ignore it. 
SIGDANGER is sent to all processes when paging space gets low, and if
paging space gets even lower, processes with the highest paging space
usage are sent the SIGKILL signal.

malloc() is substantially different in 3.2, allocating memory more
tightly.  If you have problems running re-compiled programs on 3.2,
try running them with MALLOCTYPE=3.1.

Early Page Space Allocation (EPSA) added to AIX 3.2: see
/usr/lpp/bos/README.PSALLOC - IX38211 / U422496 Allows setting of
early allocation (vs. default late allocation) on a per-process basis.

------------------------------

2.09: Why does xlc complain about 'extern char *strcpy()'


The header <string.h> has a strcpy macro that expands strcpy(x,y) to
__strcpy(x,y), and the latter is then used by the compiler to generate
inline code for strcpy.  Because of the macro, your extern declaration
contains an invalid macro expansion.  The real cure is to remove your
extern declaration but adding -U__STR__ to your xlc will also do the
trick, although your program might run a bit more slowly as the compiler
cannot inline the string functions any more.

------------------------------

2.10: Why do I get 'Parameter list cannot contain fewer ....'


This is the same as above (2.9).

------------------------------

2.11: Why does xlc complain about

               '(sometype *)somepointer = something'

Software that is developed using gcc may have this construct. However,
standard C does not permit casts to be lvalues, so you will need to
change the cast and move it to the right side of the assignment. If you
compile with 'cc', removing the cast completely will give you a warning,
'xlc' will give you an error (provided somepointer and something are of
different types - but else, why would the cast be there in the first place?)

------------------------------

2.12: Some more common errors


Here are a few other common errors with xlc:

305 |     switch((((np)->navigation_type) ? (*((np)->navigation_type)) :
      ((void *)0)))
      .a...........  
a - 1506-226: (S) The second and third operands of the conditional
operator must be of the same type.

The reason for this is that xlc defines NULL as (void *)0, and it does
not allow two different types as the second and third operand of ?:. 
The second argument above is not a pointer and the code used NULL
incorrectly as a scalar. NULL is a nil pointer constant in ANSI C and
in some traditional compilers.

You should change NULL in the third argument above to an integer 0.


------------------------------

2.13: Can the compiler generate assembler code?


Starting with version 1.3 of xlc and xlf the -S option will generate a
.s assembly code file prior to optimization. The option -qlist will
generate a human readable one in a .lst file.

There is also a disassembler in /usr/lpp/xlc/bin/dis include with the
1.3 version of xlc (and in /usr/lpp/xlC/bin/dis with the 2.1 version
of xlC) that will disassemble existing object or executable files.

------------------------------

2.14: Curses


Curses based applications should be linked with -lcurses and _not_ with
-ltermlib. It has also been reported that some problems with curses are
avoided if your application is compiled with -DNLS.

Peter Jeffe <peter@ski.austin.ibm.com> also notes:

>the escape sequences for cursor and function keys are *sometimes*
>treated as several characters: eg. the getch() - call does not return
>KEY_UP but 'ESC [ C.'

You're correct in your analysis: this has to do with the timing of the
escape sequence as it arrives from the net. There is an environment
variable called ESCDELAY that can change the fudge factor used to decide
when an escape is just an escape. The default value is 500; boosting
this a bit should solve your problems.

Christopher Carlyle O'Callaghan <asdfjkl@wam.umd.edu> has more comments
concerning extended curses:

1) The sample program in User Interface Programming Concepts, page 7-13
   is WRONG. Here is the correct use of panes and panels.

#include <cur01.h>
#include <cur05.h>

main()
{
PANE *A, *B, *C, *D, *E, *F, *G, *H;
PANEL *P;

initscr();

A = ecbpns (24, 79, NULL, NULL, 0, 2500, Pdivszp, Pbordry, NULL, NULL);
D = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
E = ecbpns (24, 79, D,    NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
B = ecbpns (24, 79, A, D, Pdivtyh, 3000, Pdivszp, Pbordry, NULL, NULL);
F = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
G = ecbpns (24, 79, F,    NULL, 0, 5000, Pdivszp, Pbordry, NULL, NULL);
H = ecbpns (24, 79, G,    NULL, 0, 3000, Pdivszp, Pbordry, NULL, NULL);
C = ecbpns (24, 79, B, F, Pdivtyh, 0, Pdivszf, Pbordry, NULL, NULL);
P = ecbpls (24, 79, 0, 0, "MAIN PANEL", Pdivtyv, Pbordry, A);

ecdvpl (P);
ecdfpl (P, FALSE);
ecshpl (P); 
ecrfpl (P);
endwin();
}

2) DO NOT include <curses.h> and any other <cur0x.h> file together.
   You will get a bunch of redefined statements.

3) There is CURSES and EXTENDED CURSES. Use only one or the other. If the
   manual says that they're backwards compatible or some other indication 
   that you can use CURSES routines with EXTENDED, don't believe it. To 
   use CURSES you need to include <curses.h> and you can't (see above).

4) If you use -lcur and -lcurses in the same link command, you will get
   Memory fault (core dump) error. You CANNOT use both of them at the same
   time. -lcur is for extended curses, -lcurses is for regular curses.

5) When creating PANEs, when you supply a value (other than 0) for the
   'ds' parameter and use Pdivszf value for the 'du' parameter, the 'ds'
   will be ignored (the sample program on page 7-13 in User Interface
   Programming Concepts is wrong.) For reasons as yet undetermined,
   Pdivszc doesn't seem to work (or at least I can't figure out how to
   use it.)

6) If you're running into bugs and can't figure out what is happening,
   try the following:
   include -qextchk -g in your compile line
	-qextchk will check to make sure you're passing the right number of
  	 parameters to the functions
	-g enables debug

7) Do not use 80 as the number of columns if you want to use the whole
   screen. The lower right corner will get erased.  Use 79 instead.

8) If you create a panel, you must create at least 1 pane, otherwise you
   will get a Memory fault (core dump).

9) When creating a panel, if you don't have a border around it, any title
   you want will not show up.

10) to make the screen scroll down:
    wmove (win, 0, 0);
    winsertln (win)

11) delwin(win) doesn't work in EXTENDED WINDOWS

    To make it appear as if a window is deleted, you need to do the following:
    for every window that you want to appear on the screen
	touchwin(win)
	wrefresh(win)

    you must make sure that you do it in the exact same order as you put
    them on the screen (i.e., if you called newwin with A, then C, then B,
    then you must do the loop with A, then C, then B, otherwise you won't
    get the same screen back).  The best thing to do is to put them into
    an array and keep track of the last window index.

12) mvwin(win, line, col) implies that it is only used for viewports and
    subwindows. It can also be used for the actual windows themselves.

13) If you specify the attribute of a window using wcolorout(win), any
    subsequent calls to chgat(numchars, mode) or any of its relatives
    will not work. (or at least they get very picky.)

------------------------------

2.15: How do I speed up linking


Please refer to sections 2.03 and 2.06 above.

From: losecco@undpdk.hep.nd.edu (John LoSecco) and
      hook@chaco.aix.dfw.ibm.com (Gary R. Hook)

From oahu.cern.ch in /pub/aix3 you can get a wrapper for the existing
linker called tld which can reduce link times with large libraries by
factors of 3 to 4.

------------------------------

2.16: What is deadbeef?


When running the debugger (dbx), you may have wondered what the
'deadbeef' is you occasionally see in registers.  Do note, that
0xdeadbeef is a hexadecimal number that also happens to be some kind
of word (the RS/6000 was built in Texas!), and this hexadecimal number
is simply put into unused registers at some time, probably during
program startup.


------------------------------

2.17: How do I make an export list from a library archive?

From: d.dennerline@bull.com (Dave Dennerline)

[ This script has been moved to section 8.10 ]

------------------------------

2.19: Building imake, makedepend

From: crow@austin.ibm.com (David L. Crow)

[Editor's note: if you have AIX 4.x,  you need the X11.adt.imake LPP
and probably most if not all of the X11.adt.* LPPs.  Imake, xmkmf and
other utilities are delivered precompiled.]

    You need X11dev.src release 1.2.3.0 (ie the R5 release) [on AIX 3.2].


     Unless you have an R5 release of AIXwindows, there is no xmkmf.
  These are the steps that I use to make imake, makedepend and all
  of it's config files, and then install them in the working tree
  (ie not the Xamples) for daily use:
  
      cd /usr/lpp/X11/Xamples
      make Makefile
      make SUBDIRS="config util" Makefiles
      make SUBDIRS="config util" linklibs
      make SUBDIRS="config util" depend
      make SUBDIRS="config util" 
      make SUBDIRS="config util" install
      
  Then redo the steps everytime you apply an X11 update.

------------------------------

2.20: How can tell what shared libraries a binary is linked with?


Use "dump -H <execfilename>" and see if anything other than /unix is
listed in the loader section (at the bottom).  The first example is
/bin/sh (statically linked) and the second example is
/usr/local/bin/bash (shared).

INDEX  PATH                          BASE                MEMBER              
0      /usr/lib:/lib                                                         
1      /                             unix                                    

INDEX  PATH                          BASE                MEMBER              
0      ./lib/readline/:./lib/glob/:/usr/lib:/lib               
1                                    libc.a              shr.o               
2                                    libcurses.a         shr.o               

The freeware tool "ldd" lists all the shared libraries needed
by an executable, including those recursively included by other
shared libraries. See question 2.27 "Where can I find ldd for AIX?".

------------------------------

2.21: Can I get a PTF for my C/C++ compiler from the net?


<http://service.software.ibm.com/>  contains pointers to most PTFs, including
compilers.  You'll need the fixdist program (see 1.142) to retrieve them.

------------------------------

2.22: Why does "install"ing software I got from the net fail?


Note that the RS/6000 has two install programs, one with System V flavor
in the default PATH (/etc/install with links from /usr/bin and /usr/usg),
and one with BSD behavior in /usr/ucb/install.

------------------------------

2.23: What is Linker TOC overflow error 12?


There is a hard coded limit in the AIX 3.2.5 linker that is fixed in
AIX 4.1.  A kind soul donated the following information to help people
get the 3.2.5 fix

    The LPS (paperwork) 
      AIX TOC Data Binder/6000 #P91128
      Version 1.1
      Program Number 5799-QDY
      Reference No. GC23-2604-00, FC 5615
    Pre Reqs listed were AIX 3.2.5
      IBM C Set++ V2 (5765-186)

The above is not available any longer, see section 1.006.

You could also put some of the application code into shared libraries
or, in the case of gcc, use -mminimal-toc.

------------------------------

2.24: What is the limit on number of shared memory segments

               I can attach?

Each process has 16 segments.  One is used for private code, one for
stack, one for heap; those, if memory serves, are segments 0, 1, and
2.  (If you look in sys/shm.h, you'll see that SHMLOSEG is 3 -- the
lowest segment, in number and in the process' virtual address space,
available to shmat.)

SHMHISEG, the highest segment you can attach to (also defined in
sys/shm.h), is 12.  Segments 3 through 12 are available to shmat,
giving the 10 segments your program used successfully.  (NSHMSEGS in
sys/shm.h will give you this value, though it's of limited use, since
most platforms that I've seen don't define it.)

Segment 13 is used by shared code your program has attached to;
I think one of the others might be for kernel-mode data.

See also mmap.

------------------------------

2.25: I deleted libc.a by accident --- how do I recover?

From: Ed Ravin <eravin@panix.com>

You can recover from this without rebooting or reinstalling, if you
have another copy of libc.a available that is also named "libc.a".  If
you moved libc.a to a different directory, you're in luck -- do the
following:

export LIBPATH=/other/directory


And your future commands will work.  But if you renamed libc.a, this
won't do it.  If you have an NFS mounted directory somewhere, you can
put libc.a on the that host, and point LIBPATH to that directory as
shown above.

Failing that, turn off your machine, reboot off floppies or other
media, and get a root shell.  I don't think you should do "getrootfs"
as you usually do when accessing the root vg this way -- AIX may start
looking for libc.a on the disk, and you'll just run into the same
problem.  So do an importvg, varyonvg, and then mount /usr somewhere,
then manually move libc.a back or copy in a new one from floppy.

------------------------------

2.26: Where can I find dlopen, dlclose, and dlsym for AIX?


An implementation of these dynamic code loading functions was written by
Jens-Uwe Mager <jum@anubis.han.de> and can be found at
<ftp://anubis.han.de/pub/aix/dlfcn.shar>

From: Gary R. Hook <hook@austin.ibm.com>

Starting with AIX 4.2 a dlopen et. al. are included in the base OS in
the libdl.a library. Under AIX 4.1 this is available as SLHS (Shared
Library Hookable Symbols) as APAR IX IX71849 for the runtime package and
APAR IX IX72973 for the development tools.

------------------------------

2.27: Where can I find ldd for AIX?

From: Jens-Uwe Mager <jum@anubis.han.de>

Try <ftp://anubis.han.de/pub/aix/ldd.c>. Also the "aix.tools"
package from <http://www-frec.bull.com>

------------------------------

2.28: How do I make my program binary executable on the

                POWER, POWER2, and POWERPC architecures?

AIX will emulate those instructions not available in POWERPC processors, but
you can avoid this emulation and consequent performance degradtation by
using only the common to all.

If you are using IBM's xlc (cc) compiler, the default is to use the common
instruction set.  If you want to be explicit, use the -qarch=com option.

The option -mcpu=common makes GCC use the common instruction set.  Please
note that (unlike xlc) this is *not* the default with GCC on AIX.

------------------------------

2.29: How do I access more than 256 Megabytes of memory?


By default each program gets one segment register (see 2.24) for its
data segment. As each segment register covers 256 MB, any calls to
malloc more will fail. Also programs that declare large global or static
arrays may fail to load. To allocate more segment registers to your
program, use the linker option -bmaxdata to specify the number of bytes
you need in the data segment as follows:

cc -o myprog -bmaxdata:0x20000000 myprog.c

The example above would allocate an additional segment register to allow
for 512MB of data.

------------------------------

2.30: How do I use POSIX threads with gcc 2.7.x?

From: David Edelsohn <dje@watson.ibm.com>

The code generated by GCC is compatible with threads, but gcc-2.7 
was released so long ago that it did not provide an option to perform
the extra link steps necessary to support threads:

1) Compile all source files with "-D_THREAD_SAFE" macro defined.
2) Link with "-L/usr/lib/threads -lpthreads -lc_r /usr/lib/libc.a"
   to obtain the pthreads support 
   and add "-nostartfiles /usr/lib/crt0_r.o" to the beginning of the
   link command line (using gcc to link!) to initialize threads.

------------------------------

2.00: C/C++


Contrary to many people's belief, the C environment on the RS/6000 is
not very special.  The C compiler has quite a number of options that can
be used to control how it works, which "dialect" of C it compiles, how
it interprets certain language constructs, etc.  InfoExplorer includes a
Users Guide and a Reference Manual.

The compiler can be invoked with either xlc for strict ANSI mode and cc
for RT compatible mode (i.e. IBM 6150 with AIX 2).  The default options
for each mode are set in the /etc/xlc.cfg file, and you can actually add
another stanza and create a link to the /bin/xlc executable.

The file /usr/lpp/xlc/bin/README.xlc has information about the C
compiler, and the file /usr/lpp/bos/bsdport (AIX 3 only) contains useful
information, in particular for users from a BSD background.

The file /etc/xlc.cfg also shows the symbol _IBMR2 that is predefined,
and therefore can be used for #ifdef'ing RS/6000 specific code.

------------------------------

2.01: I cannot make alloca work


A famous routine, in particular in GNU context, is the allocation
routine alloca().  Alloca allocates memory in such a way that it is
automatically free'd when the block is exited.  Most implementations
does this by adjusting the stack pointer.  Since not all C environments
can support it, its use is discouraged, but it is included in the xlc
compiler.  In order to make the compiler aware that you intend to use
alloca, you must put the line

#pragma alloca

before any other statements in the C source module(s) where alloca is
called.  If you don't do this, xlc will not recognize alloca as anything
special, and you will get errors during linking.

For AIX 3.2, it may be easier to use the -ma flag.

------------------------------

2.02: How do I compile my BSD programs?


The file /usr/lpp/bos/bsdport contains information on how to port
programs written for BSD to AIX 3.  This file may be very useful for
others as well.

A quick cc command for most "standard" BSD programs is:
  
  $ cc -D_BSD -D_BSD_INCLUDES  -o [loadfile] [sourcefile.c] -lbsd

If your software has system calls predefined with no prototype
parameters, also use the -D_NO_PROTO flag.

------------------------------

2.03: Isn't the linker different from what I am used to?


Yes.  It is not at all like what you are used to:

- The order of objects and libraries is normally _not_ important.  The
  linker reads _all_ objects including those from libraries into memory
  and does the actual linking in one go.  Even if you need to put a
  library of your own twice on the ld command line on other systems, it
  is not needed on the RS/6000 - doing so will even make your linking slower.

- One of the features of the linker is that it will replace an object in
  an executable with a new version of the same object:

  $ cc -o prog prog1.o prog2.o prog3.o		# make prog
  $ cc -c prog2.c				# recompile prog2.c
  $ cc -o prog.new prog2.o prog			# make prog.new from prog
						# by replacing prog2.o
  
- The standard C library /lib/libc.a is linked shared, which means that
  the actual code is not linked into your program, but is loaded only
  once and linked dynamically during loading of your program.

- The ld program actually calls the binder in /usr/lib/bind, and you can
  give ld special options to get details about the invocation of the
  binder.  These are found on the ld man page or in InfoExplorer.

- If your program normally links using a number of libraries (.a files),
  you can 'prelink' each of these into an object, which will make your
  final linking faster.  E.g. do:

  $ cc -c prog1.c prog2.c prog3.c
  $ ar cv libprog.a prog1.o prog2.o prog3.o
  $ ld -r -o libprog.o libprog.a
  $ cc -o someprog someprog.c libprog.o

This will solve all internal references between prog1.o, prog2.o and
prog3.o and save this in libprog.o Then using libprog.o to link your
program instead of libprog.a will increase linking speed, and even if
someprog.c only uses, say prog1.o and prog2.o, only those two modules
will be in your final program.  This is also due to the fact that the
binder can handle single objects inside one object module as noted above.

If you are using an -lprog option (for libprog.a) above, and still want
to be able to do so, you should name the prelinked object with a
standard library name, e.g. libprogP.a (P identifying a prelinked
object), that can be specified by -lprogP.  You cannot use the archiver
(ar) on such an object.

You should also have a look at section 3.01 of this article, in
particular if you have mixed Fortran/C programs.

Dave Dennerline (d.dennerline@bull.com) claims that his experiences
in prelinking on AIX does not save much time since most people have
separate libraries which do not have many dependencies between them,
thus not many symbols to resolve.

------------------------------

2.04: How do I statically link my program?


  cc -o prog -bnoso -bI:/lib/syscalls.exp obj1.o obj2.o obj3.o

will do that for a program consisting of the three objects obj1.o, etc.

[Editor's note: You should never link programs statically that are
supposed to leave your local environment, e.g. intended for
distribution. Statically linked programs may fail to work after
installing a new AIX version or even after installing a PTF.]

From: Marc Pawliger (marc@sti.com)

As of AIX 3.2.5, you can install a speedup for AIXwindows called
Shared Memory Transport.  To static link an X application after the
SMT PTF has been installed, you must link with
-bI:/usr/lpp/X11/bin/smt.exp and the executable will NOT run on a
machine where SMT is not installed.  See /usr/lpp/X11/README.SMT
Newsgroups: comp.unix.aix,comp.answers,news.answers
Path: news.univie.ac.at!aconews.univie.ac.at!newscore.univie.ac.at!fu-berlin.de!news-ber1.dfn.de!news-ham1.dfn.de!newsserver.rrzn.uni-hannover.de!baghira.han.de!jum
From: jum@anubis.han.de
Approved: news-answers-request@mit.edu
Followup-To: comp.unix.aix
Supersedes: <aix-faq-4-886305604@anubis.han.de>
Reply-To: jum@anubis.han.de (Jens-Uwe Mager)
Keywords: AIX RS/6000 questions answers
Sender: jum@baghira.han.de (Jens-Uwe Mager)
Expires: Sun, 5 Apr 1998 05:01:07 GMT
Organization: At Home
Message-ID: <aix-faq-4-888724807@anubis.han.de>
References: <aix-faq-1-888724807@anubis.han.de> 
Date: Sun, 1 Mar 1998 04:00:24 GMT
         and their answers.  AIX is IBM's version of Unix.
Lines: 1806
Xref: news.univie.ac.at comp.unix.aix:125562 comp.answers:29712 news.answers:39490

Posted-By: auto-faq 3.3 (Perl 4.035)
Archive-name: aix-faq/part4
Posting-Frequency: monthly


------------------------------

2.05: How do I make my own shared library?


To make your own shared object or library of shared objects, you should
know that a shared object cannot have undefined symbols.  Thus, if your
code uses any externals from /lib/libc.a, the latter MUST be linked with
your code to make a shared object.  Mike Heath (mike@pencom.com) said it
is possible to split code into more than one shared object when externals
in one object refer to another one.  You must be very good at
import/export files.  Perhaps he or someone can provide an example. 

Assume you have one file, sub1.c, containing a routine with no external
references, and another one, sub2.c, calling stuff in /lib/libc.a.  You
will also need two export files, sub1.exp, sub2.exp.  Read the example
below together with the examples on the ld man page. 

---- sub1.c ----
    int addint(int a, int b)
    {
      return a + b;
    }
---- sub2.c ----
    #include <stdio.h>

    void printint(int a)
    {
      printf("The integer is: %d\n", a);
    }
---- sub1.exp ----
    #!
    addint
---- sub2.exp ----
    #!
    printint
---- usesub.c ----
    main()
    {
      printint( addint(5,8) );
    }

The following commands will build your libshr.a, and compile/link the
program usesub to use it.  Note that you need the ld option -lc for
sub2shr.o since it calls printf from /lib/libc.a.  [Note that you can leave
out the "-T512 -H512" on AIX 4. -- Ed.]

  $ cc  -c sub1.c
  $ ld -o sub1shr.o sub1.o -bE:sub1.exp -bM:SRE -T512 -H512 
  $ cc  -c sub2.c
  $ ld -o sub2shr.o sub2.o -bE:sub2.exp -bM:SRE -T512 -H512  -lc
  $ ar r libshr.a sub1shr.o sub2shr.o
  $ cc -o usesub usesub.c -L: libshr.a
  $ usesub
  The integer is: 13
  $

------------------------------

2.06: Linking my program fails with strange errors. Why?


Very simple, the linker (actually called the binder), cannot get the
memory it needs, either because your ulimits are too low or because you
don't have sufficient paging space.  Since the linker is quite different
>from normal Unix linkers and actually does much more than these, it also
uses a lot of virtual memory.  It is not unusual to need 10000 pages (of
4k) or more to execute a fairly complex linking.

If you get 'BUMP error', either ulimits or paging is too low, if you get
'Binder killed by signal 9' your paging is too low.

First, check your memory and data ulimits; in korn shell 'ulimit -a' will
show all limits and 'ulimit -m 99999' and 'ulimit -d 99999' will
increase the maximum memory and data respectively to some high values. 
If this was not your problem, you don't have enough paging space.

If you will or can not increase your paging space, you could try this:

- Do you duplicate libraries on the ld command line? That is never
  necessary.

- Do more users link simultaneously? Try having only one linking going
  on at any time.

- Do a partwise linking, i.e. you link some objects/libraries with the
  -r option to allow the temporary output to have unresolved references,
  then link with the rest of your objects/libraries.  This can be split
  up as much as you want, and will make each step use less virtual memory.

  If you follow this scheme, only adding one object or archive at a
  time, you will actually emulate the behavior of other Unix linkers.

If you decide to add more paging space, you should consider adding a new
paging space on a second hard disk, as opposed to just increasing the
existing one.  Doing the latter could make you run out of free space on
your first harddisk. It is more involved to shrink a paging space
but easier to delete one.

------------------------------

2.07: Why does it take so long to compile "hello world" with xlc?


Some systems have experienced delays of more than 60 seconds in
compiling "#include <stdio.h> int main () {printf ("Hello world");}"
The problem is with the license manager contact IBM to make sure
you've got the latest PTF.

------------------------------

2.08: What's with malloc()?

 
malloc() uses a late allocation algorithm based on 4.3 BSD's malloc()
for speed.  This lets you allocate very large sparse memory spaces,
since the pages are not actually allocated until they are touched for
the first time.  Unfortunately, it doesn't die gracefully in the face of
loss of available memory.  See the "Paging Space Overview" under
InfoExplorer, and see the notes on the linker in this document for an
example of an ungraceful death.

If you want your program to get notified when running out of memory, you
should handle the SIGDANGER signal.  The default is to ignore it. 
SIGDANGER is sent to all processes when paging space gets low, and if
paging space gets even lower, processes with the highest paging space
usage are sent the SIGKILL signal.

malloc() is substantially different in 3.2, allocating memory more
tightly.  If you have problems running re-compiled programs on 3.2,
try running them with MALLOCTYPE=3.1.

Early Page Space Allocation (EPSA) added to AIX 3.2: see
/usr/lpp/bos/README.PSALLOC - IX38211 / U422496 Allows setting of
early allocation (vs. default late allocation) on a per-process basis.

------------------------------

2.09: Why does xlc complain about 'extern char *strcpy()'


The header <string.h> has a strcpy macro that expands strcpy(x,y) to
__strcpy(x,y), and the latter is then used by the compiler to generate
inline code for strcpy.  Because of the macro, your extern declaration
contains an invalid macro expansion.  The real cure is to remove your
extern declaration but adding -U__STR__ to your xlc will also do the
trick, although your program might run a bit more slowly as the compiler
cannot inline the string functions any more.

------------------------------

2.10: Why do I get 'Parameter list cannot contain fewer ....'


This is the same as above (2.9).

------------------------------

2.11: Why does xlc complain about

               '(sometype *)somepointer = something'

Software that is developed using gcc may have this construct. However,
standard C does not permit casts to be lvalues, so you will need to
change the cast and move it to the right side of the assignment. If you
compile with 'cc', removing the cast completely will give you a warning,
'xlc' will give you an error (provided somepointer and something are of
different types - but else, why would the cast be there in the first place?)

------------------------------

2.12: Some more common errors


Here are a few other common errors with xlc:

305 |     switch((((np)->navigation_type) ? (*((np)->navigation_type)) :
      ((void *)0)))
      .a...........  
a - 1506-226: (S) The second and third operands of the conditional
operator must be of the same type.

The reason for this is that xlc defines NULL as (void *)0, and it does
not allow two different types as the second and third operand of ?:. 
The second argument above is not a pointer and the code used NULL
incorrectly as a scalar. NULL is a nil pointer constant in ANSI C and
in some traditional compilers.

You should change NULL in the third argument above to an integer 0.


------------------------------

2.13: Can the compiler generate assembler code?


Starting with version 1.3 of xlc and xlf the -S option will generate a
.s assembly code file prior to optimization. The option -qlist will
generate a human readable one in a .lst file.

There is also a disassembler in /usr/lpp/xlc/bin/dis include with the
1.3 version of xlc (and in /usr/lpp/xlC/bin/dis with the 2.1 version
of xlC) that will disassemble existing object or executable files.

------------------------------

2.14: Curses


Curses based applications should be linked with -lcurses and _not_ with
-ltermlib. It has also been reported that some problems with curses are
avoided if your application is compiled with -DNLS.

Peter Jeffe <peter@ski.austin.ibm.com> also notes:

>the escape sequences for cursor and function keys are *sometimes*
>treated as several characters: eg. the getch() - call does not return
>KEY_UP but 'ESC [ C.'

You're correct in your analysis: this has to do with the timing of the
escape sequence as it arrives from the net. There is an environment
variable called ESCDELAY that can change the fudge factor used to decide
when an escape is just an escape. The default value is 500; boosting
this a bit should solve your problems.

Christopher Carlyle O'Callaghan <asdfjkl@wam.umd.edu> has more comments
concerning extended curses:

1) The sample program in User Interface Programming Concepts, page 7-13
   is WRONG. Here is the correct use of panes and panels.

#include <cur01.h>
#include <cur05.h>

main()
{
PANE *A, *B, *C, *D, *E, *F, *G, *H;
PANEL *P;

initscr();

A = ecbpns (24, 79, NULL, NULL, 0, 2500, Pdivszp, Pbordry, NULL, NULL);
D = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
E = ecbpns (24, 79, D,    NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
B = ecbpns (24, 79, A, D, Pdivtyh, 3000, Pdivszp, Pbordry, NULL, NULL);
F = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
G = ecbpns (24, 79, F,    NULL, 0, 5000, Pdivszp, Pbordry, NULL, NULL);
H = ecbpns (24, 79, G,    NULL, 0, 3000, Pdivszp, Pbordry, NULL, NULL);
C = ecbpns (24, 79, B, F, Pdivtyh, 0, Pdivszf, Pbordry, NULL, NULL);
P = ecbpls (24, 79, 0, 0, "MAIN PANEL", Pdivtyv, Pbordry, A);

ecdvpl (P);
ecdfpl (P, FALSE);
ecshpl (P); 
ecrfpl (P);
endwin();
}

2) DO NOT include <curses.h> and any other <cur0x.h> file together.
   You will get a bunch of redefined statements.

3) There is CURSES and EXTENDED CURSES. Use only one or the other. If the
   manual says that they're backwards compatible or some other indication 
   that you can use CURSES routines with EXTENDED, don't believe it. To 
   use CURSES you need to include <curses.h> and you can't (see above).

4) If you use -lcur and -lcurses in the same link command, you will get
   Memory fault (core dump) error. You CANNOT use both of them at the same
   time. -lcur is for extended curses, -lcurses is for regular curses.

5) When creating PANEs, when you supply a value (other than 0) for the
   'ds' parameter and use Pdivszf value for the 'du' parameter, the 'ds'
   will be ignored (the sample program on page 7-13 in User Interface
   Programming Concepts is wrong.) For reasons as yet undetermined,
   Pdivszc doesn't seem to work (or at least I can't figure out how to
   use it.)

6) If you're running into bugs and can't figure out what is happening,
   try the following:
   include -qextchk -g in your compile line
	-qextchk will check to make sure you're passing the right number of
  	 parameters to the functions
	-g enables debug

7) Do not use 80 as the number of columns if you want to use the whole
   screen. The lower right corner will get erased.  Use 79 instead.

8) If you create a panel, you must create at least 1 pane, otherwise you
   will get a Memory fault (core dump).

9) When creating a panel, if you don't have a border around it, any title
   you want will not show up.

10) to make the screen scroll down:
    wmove (win, 0, 0);
    winsertln (win)

11) delwin(win) doesn't work in EXTENDED WINDOWS

    To make it appear as if a window is deleted, you need to do the following:
    for every window that you want to appear on the screen
	touchwin(win)
	wrefresh(win)

    you must make sure that you do it in the exact same order as you put
    them on the screen (i.e., if you called newwin with A, then C, then B,
    then you must do the loop with A, then C, then B, otherwise you won't
    get the same screen back).  The best thing to do is to put them into
    an array and keep track of the last window index.

12) mvwin(win, line, col) implies that it is only used for viewports and
    subwindows. It can also be used for the actual windows themselves.

13) If you specify the attribute of a window using wcolorout(win), any
    subsequent calls to chgat(numchars, mode) or any of its relatives
    will not work. (or at least they get very picky.)

------------------------------

2.15: How do I speed up linking


Please refer to sections 2.03 and 2.06 above.

From: losecco@undpdk.hep.nd.edu (John LoSecco) and
      hook@chaco.aix.dfw.ibm.com (Gary R. Hook)

From oahu.cern.ch in /pub/aix3 you can get a wrapper for the existing
linker called tld which can reduce link times with large libraries by
factors of 3 to 4.

------------------------------

2.16: What is deadbeef?


When running the debugger (dbx), you may have wondered what the
'deadbeef' is you occasionally see in registers.  Do note, that
0xdeadbeef is a hexadecimal number that also happens to be some kind
of word (the RS/6000 was built in Texas!), and this hexadecimal number
is simply put into unused registers at some time, probably during
program startup.


------------------------------

2.17: How do I make an export list from a library archive?

From: d.dennerline@bull.com (Dave Dennerline)

[ This script has been moved to section 8.10 ]

------------------------------

2.19: Building imake, makedepend

From: crow@austin.ibm.com (David L. Crow)

[Editor's note: if you have AIX 4.x,  you need the X11.adt.imake LPP
and probably most if not all of the X11.adt.* LPPs.  Imake, xmkmf and
other utilities are delivered precompiled.]

    You need X11dev.src release 1.2.3.0 (ie the R5 release) [on AIX 3.2].


     Unless you have an R5 release of AIXwindows, there is no xmkmf.
  These are the steps that I use to make imake, makedepend and all
  of it's config files, and then install them in the working tree
  (ie not the Xamples) for daily use:
  
      cd /usr/lpp/X11/Xamples
      make Makefile
      make SUBDIRS="config util" Makefiles
      make SUBDIRS="config util" linklibs
      make SUBDIRS="config util" depend
      make SUBDIRS="config util" 
      make SUBDIRS="config util" install
      
  Then redo the steps everytime you apply an X11 update.

------------------------------

2.20: How can tell what shared libraries a binary is linked with?


Use "dump -H <execfilename>" and see if anything other than /unix is
listed in the loader section (at the bottom).  The first example is
/bin/sh (statically linked) and the second example is
/usr/local/bin/bash (shared).

INDEX  PATH                          BASE                MEMBER              
0      /usr/lib:/lib                                                         
1      /                             unix                                    

INDEX  PATH                          BASE                MEMBER              
0      ./lib/readline/:./lib/glob/:/usr/lib:/lib               
1                                    libc.a              shr.o               
2                                    libcurses.a         shr.o               

The freeware tool "ldd" lists all the shared libraries needed
by an executable, including those recursively included by other
shared libraries. See question 2.27 "Where can I find ldd for AIX?".

------------------------------

2.21: Can I get a PTF for my C/C++ compiler from the net?


<http://service.software.ibm.com/>  contains pointers to most PTFs, including
compilers.  You'll need the fixdist program (see 1.142) to retrieve them.

------------------------------

2.22: Why does "install"ing software I got from the net fail?


Note that the RS/6000 has two install programs, one with System V flavor
in the default PATH (/etc/install with links from /usr/bin and /usr/usg),
and one with BSD behavior in /usr/ucb/install.

------------------------------

2.23: What is Linker TOC overflow error 12?


There is a hard coded limit in the AIX 3.2.5 linker that is fixed in
AIX 4.1.  A kind soul donated the following information to help people
get the 3.2.5 fix

    The LPS (paperwork) 
      AIX TOC Data Binder/6000 #P91128
      Version 1.1
      Program Number 5799-QDY
      Reference No. GC23-2604-00, FC 5615
    Pre Reqs listed were AIX 3.2.5
      IBM C Set++ V2 (5765-186)

The above is not available any longer, see section 1.006.

You could also put some of the application code into shared libraries
or, in the case of gcc, use -mminimal-toc.

------------------------------

2.24: What is the limit on number of shared memory segments

               I can attach?

Each process has 16 segments.  One is used for private code, one for
stack, one for heap; those, if memory serves, are segments 0, 1, and
2.  (If you look in sys/shm.h, you'll see that SHMLOSEG is 3 -- the
lowest segment, in number and in the process' virtual address space,
available to shmat.)

SHMHISEG, the highest segment you can attach to (also defined in
sys/shm.h), is 12.  Segments 3 through 12 are available to shmat,
giving the 10 segments your program used successfully.  (NSHMSEGS in
sys/shm.h will give you this value, though it's of limited use, since
most platforms that I've seen don't define it.)

Segment 13 is used by shared code your program has attached to;
I think one of the others might be for kernel-mode data.

See also mmap.

------------------------------

2.25: I deleted libc.a by accident --- how do I recover?

From: Ed Ravin <eravin@panix.com>

You can recover from this without rebooting or reinstalling, if you
have another copy of libc.a available that is also named "libc.a".  If
you moved libc.a to a different directory, you're in luck -- do the
following:

export LIBPATH=/other/directory


And your future commands will work.  But if you renamed libc.a, this
won't do it.  If you have an NFS mounted directory somewhere, you can
put libc.a on the that host, and point LIBPATH to that directory as
shown above.

Failing that, turn off your machine, reboot off floppies or other
media, and get a root shell.  I don't think you should do "getrootfs"
as you usually do when accessing the root vg this way -- AIX may start
looking for libc.a on the disk, and you'll just run into the same
problem.  So do an importvg, varyonvg, and then mount /usr somewhere,
then manually move libc.a back or copy in a new one from floppy.

------------------------------

2.26: Where can I find dlopen, dlclose, and dlsym for AIX?


An implementation of these dynamic code loading functions was written by
Jens-Uwe Mager <jum@anubis.han.de> and can be found at
<ftp://anubis.han.de/pub/aix/dlfcn.shar>

From: Gary R. Hook <hook@austin.ibm.com>

Starting with AIX 4.2 a dlopen et. al. are included in the base OS in
the libdl.a library. Under AIX 4.1 this is available as SLHS (Shared
Library Hookable Symbols) as APAR IX IX71849 for the runtime package and
APAR IX IX72973 for the development tools.

------------------------------

2.27: Where can I find ldd for AIX?

From: Jens-Uwe Mager <jum@anubis.han.de>

Try <ftp://anubis.han.de/pub/aix/ldd.c>. Also the "aix.tools"
package from <http://www-frec.bull.com>

------------------------------

2.28: How do I make my program binary executable on the

                POWER, POWER2, and POWERPC architecures?

AIX will emulate those instructions not available in POWERPC processors, but
you can avoid this emulation and consequent performance degradtation by
using only the common to all.

If you are using IBM's xlc (cc) compiler, the default is to use the common
instruction set.  If you want to be explicit, use the -qarch=com option.

The option -mcpu=common makes GCC use the common instruction set.  Please
note that (unlike xlc) this is *not* the default with GCC on AIX.

------------------------------

2.29: How do I access more than 256 Megabytes of memory?


By default each program gets one segment register (see 2.24) for its
data segment. As each segment register covers 256 MB, any calls to
malloc more will fail. Also programs that declare large global or static
arrays may fail to load. To allocate more segment registers to your
program, use the linker option -bmaxdata to specify the number of bytes
you need in the data segment as follows:

cc -o myprog -bmaxdata:0x20000000 myprog.c

The example above would allocate an additional segment register to allow
for 512MB of data.

------------------------------

2.30: How do I use POSIX threads with gcc 2.7.x?

From: David Edelsohn <dje@watson.ibm.com>

The code generated by GCC is compatible with threads, but gcc-2.7 
was released so long ago that it did not provide an option to perform
the extra link steps necessary to support threads:

1) Compile all source files with "-D_THREAD_SAFE" macro defined.
2) Link with "-L/usr/lib/threads -lpthreads -lc_r /usr/lib/libc.a"
   to obtain the pthreads support 
   and add "-nostartfiles /usr/lib/crt0_r.o" to the beginning of the
   link command line (using gcc to link!) to initialize threads.

------------------------------

2.00: C/C++


Contrary to many people's belief, the C environment on the RS/6000 is
not very special.  The C compiler has quite a number of options that can
be used to control how it works, which "dialect" of C it compiles, how
it interprets certain language constructs, etc.  InfoExplorer includes a
Users Guide and a Reference Manual.

The compiler can be invoked with either xlc for strict ANSI mode and cc
for RT compatible mode (i.e. IBM 6150 with AIX 2).  The default options
for each mode are set in the /etc/xlc.cfg file, and you can actually add
another stanza and create a link to the /bin/xlc executable.

The file /usr/lpp/xlc/bin/README.xlc has information about the C
compiler, and the file /usr/lpp/bos/bsdport (AIX 3 only) contains useful
information, in particular for users from a BSD background.

The file /etc/xlc.cfg also shows the symbol _IBMR2 that is predefined,
and therefore can be used for #ifdef'ing RS/6000 specific code.

------------------------------

2.01: I cannot make alloca work


A famous routine, in particular in GNU context, is the allocation
routine alloca().  Alloca allocates memory in such a way that it is
automatically free'd when the block is exited.  Most implementations
does this by adjusting the stack pointer.  Since not all C environments
can support it, its use is discouraged, but it is included in the xlc
compiler.  In order to make the compiler aware that you intend to use
alloca, you must put the line

#pragma alloca

before any other statements in the C source module(s) where alloca is
called.  If you don't do this, xlc will not recognize alloca as anything
special, and you will get errors during linking.

For AIX 3.2, it may be easier to use the -ma flag.

------------------------------

2.02: How do I compile my BSD programs?


The file /usr/lpp/bos/bsdport contains information on how to port
programs written for BSD to AIX 3.  This file may be very useful for
others as well.

A quick cc command for most "standard" BSD programs is:
  
  $ cc -D_BSD -D_BSD_INCLUDES  -o [loadfile] [sourcefile.c] -lbsd

If your software has system calls predefined with no prototype
parameters, also use the -D_NO_PROTO flag.

------------------------------

2.03: Isn't the linker different from what I am used to?


Yes.  It is not at all like what you are used to:

- The order of objects and libraries is normally _not_ important.  The
  linker reads _all_ objects including those from libraries into memory
  and does the actual linking in one go.  Even if you need to put a
  library of your own twice on the ld command line on other systems, it
  is not needed on the RS/6000 - doing so will even make your linking slower.

- One of the features of the linker is that it will replace an object in
  an executable with a new version of the same object:

  $ cc -o prog prog1.o prog2.o prog3.o		# make prog
  $ cc -c prog2.c				# recompile prog2.c
  $ cc -o prog.new prog2.o prog			# make prog.new from prog
						# by replacing prog2.o
  
- The standard C library /lib/libc.a is linked shared, which means that
  the actual code is not linked into your program, but is loaded only
  once and linked dynamically during loading of your program.

- The ld program actually calls the binder in /usr/lib/bind, and you can
  give ld special options to get details about the invocation of the
  binder.  These are found on the ld man page or in InfoExplorer.

- If your program normally links using a number of libraries (.a files),
  you can 'prelink' each of these into an object, which will make your
  final linking faster.  E.g. do:

  $ cc -c prog1.c prog2.c prog3.c
  $ ar cv libprog.a prog1.o prog2.o prog3.o
  $ ld -r -o libprog.o libprog.a
  $ cc -o someprog someprog.c libprog.o

This will solve all internal references between prog1.o, prog2.o and
prog3.o and save this in libprog.o Then using libprog.o to link your
program instead of libprog.a will increase linking speed, and even if
someprog.c only uses, say prog1.o and prog2.o, only those two modules
will be in your final program.  This is also due to the fact that the
binder can handle single objects inside one object module as noted above.

If you are using an -lprog option (for libprog.a) above, and still want
to be able to do so, you should name the prelinked object with a
standard library name, e.g. libprogP.a (P identifying a prelinked
object), that can be specified by -lprogP.  You cannot use the archiver
(ar) on such an object.

You should also have a look at section 3.01 of this article, in
particular if you have mixed Fortran/C programs.

Dave Dennerline (d.dennerline@bull.com) claims that his experiences
in prelinking on AIX does not save much time since most people have
separate libraries which do not have many dependencies between them,
thus not many symbols to resolve.

------------------------------

2.04: How do I statically link my program?


  cc -o prog -bnoso -bI:/lib/syscalls.exp obj1.o obj2.o obj3.o

will do that for a program consisting of the three objects obj1.o, etc.

[Editor's note: You should never link programs statically that are
supposed to leave your local environment, e.g. intended for
distribution. Statically linked programs may fail to work after
installing a new AIX version or even after installing a PTF.]

From: Marc Pawliger (marc@sti.com)

As of AIX 3.2.5, you can install a speedup for AIXwindows called
Shared Memory Transport.  To static link an X application after the
SMT PTF has been installed, you must link with
-bI:/usr/lpp/X11/bin/smt.exp and the executable will NOT run on a
machine where SMT is not installed.  See /usr/lpp/X11/README.SMT
Newsgroups: comp.unix.aix,comp.answers,news.answers
Path: news.univie.ac.at!aconews.univie.ac.at!newscore.univie.ac.at!fu-berlin.de!news-ber1.dfn.de!news-ham1.dfn.de!newsserver.rrzn.uni-hannover.de!baghira.han.de!jum
From: jum@anubis.han.de
Approved: news-answers-request@mit.edu
Followup-To: comp.unix.aix
Supersedes: <aix-faq-4-886305604@anubis.han.de>
Reply-To: jum@anubis.han.de (Jens-Uwe Mager)
Keywords: AIX RS/6000 questions answers
Sender: jum@baghira.han.de (Jens-Uwe Mager)
Expires: Sun, 5 Apr 1998 05:01:07 GMT
Organization: At Home
Message-ID: <aix-faq-4-888724807@anubis.han.de>
References: <aix-faq-1-888724807@anubis.han.de> 
Date: Sun, 1 Mar 1998 04:00:24 GMT
         and their answers.  AIX is IBM's version of Unix.
Lines: 1806
Xref: news.univie.ac.at comp.unix.aix:125562 comp.answers:29712 news.answers:39490

Posted-By: auto-faq 3.3 (Perl 4.035)
Archive-name: aix-faq/part4
Posting-Frequency: monthly


------------------------------

2.05: How do I make my own shared library?


To make your own shared object or library of shared objects, you should
know that a shared object cannot have undefined symbols.  Thus, if your
code uses any externals from /lib/libc.a, the latter MUST be linked with
your code to make a shared object.  Mike Heath (mike@pencom.com) said it
is possible to split code into more than one shared object when externals
in one object refer to another one.  You must be very good at
import/export files.  Perhaps he or someone can provide an example. 

Assume you have one file, sub1.c, containing a routine with no external
references, and another one, sub2.c, calling stuff in /lib/libc.a.  You
will also need two export files, sub1.exp, sub2.exp.  Read the example
below together with the examples on the ld man page. 

---- sub1.c ----
    int addint(int a, int b)
    {
      return a + b;
    }
---- sub2.c ----
    #include <stdio.h>

    void printint(int a)
    {
      printf("The integer is: %d\n", a);
    }
---- sub1.exp ----
    #!
    addint
---- sub2.exp ----
    #!
    printint
---- usesub.c ----
    main()
    {
      printint( addint(5,8) );
    }

The following commands will build your libshr.a, and compile/link the
program usesub to use it.  Note that you need the ld option -lc for
sub2shr.o since it calls printf from /lib/libc.a.  [Note that you can leave
out the "-T512 -H512" on AIX 4. -- Ed.]

  $ cc  -c sub1.c
  $ ld -o sub1shr.o sub1.o -bE:sub1.exp -bM:SRE -T512 -H512 
  $ cc  -c sub2.c
  $ ld -o sub2shr.o sub2.o -bE:sub2.exp -bM:SRE -T512 -H512  -lc
  $ ar r libshr.a sub1shr.o sub2shr.o
  $ cc -o usesub usesub.c -L: libshr.a
  $ usesub
  The integer is: 13
  $

------------------------------

2.06: Linking my program fails with strange errors. Why?


Very simple, the linker (actually called the binder), cannot get the
memory it needs, either because your ulimits are too low or because you
don't have sufficient paging space.  Since the linker is quite different
>from normal Unix linkers and actually does much more than these, it also
uses a lot of virtual memory.  It is not unusual to need 10000 pages (of
4k) or more to execute a fairly complex linking.

If you get 'BUMP error', either ulimits or paging is too low, if you get
'Binder killed by signal 9' your paging is too low.

First, check your memory and data ulimits; in korn shell 'ulimit -a' will
show all limits and 'ulimit -m 99999' and 'ulimit -d 99999' will
increase the maximum memory and data respectively to some high values. 
If this was not your problem, you don't have enough paging space.

If you will or can not increase your paging space, you could try this:

- Do you duplicate libraries on the ld command line? That is never
  necessary.

- Do more users link simultaneously? Try having only one linking going
  on at any time.

- Do a partwise linking, i.e. you link some objects/libraries with the
  -r option to allow the temporary output to have unresolved references,
  then link with the rest of your objects/libraries.  This can be split
  up as much as you want, and will make each step use less virtual memory.

  If you follow this scheme, only adding one object or archive at a
  time, you will actually emulate the behavior of other Unix linkers.

If you decide to add more paging space, you should consider adding a new
paging space on a second hard disk, as opposed to just increasing the
existing one.  Doing the latter could make you run out of free space on
your first harddisk. It is more involved to shrink a paging space
but easier to delete one.

------------------------------

2.07: Why does it take so long to compile "hello world" with xlc?


Some systems have experienced delays of more than 60 seconds in
compiling "#include <stdio.h> int main () {printf ("Hello world");}"
The problem is with the license manager contact IBM to make sure
you've got the latest PTF.

------------------------------

2.08: What's with malloc()?

 
malloc() uses a late allocation algorithm based on 4.3 BSD's malloc()
for speed.  This lets you allocate very large sparse memory spaces,
since the pages are not actually allocated until they are touched for
the first time.  Unfortunately, it doesn't die gracefully in the face of
loss of available memory.  See the "Paging Space Overview" under
InfoExplorer, and see the notes on the linker in this document for an
example of an ungraceful death.

If you want your program to get notified when running out of memory, you
should handle the SIGDANGER signal.  The default is to ignore it. 
SIGDANGER is sent to all processes when paging space gets low, and if
paging space gets even lower, processes with the highest paging space
usage are sent the SIGKILL signal.

malloc() is substantially different in 3.2, allocating memory more
tightly.  If you have problems running re-compiled programs on 3.2,
try running them with MALLOCTYPE=3.1.

Early Page Space Allocation (EPSA) added to AIX 3.2: see
/usr/lpp/bos/README.PSALLOC - IX38211 / U422496 Allows setting of
early allocation (vs. default late allocation) on a per-process basis.

------------------------------

2.09: Why does xlc complain about 'extern char *strcpy()'


The header <string.h> has a strcpy macro that expands strcpy(x,y) to
__strcpy(x,y), and the latter is then used by the compiler to generate
inline code for strcpy.  Because of the macro, your extern declaration
contains an invalid macro expansion.  The real cure is to remove your
extern declaration but adding -U__STR__ to your xlc will also do the
trick, although your program might run a bit more slowly as the compiler
cannot inline the string functions any more.

------------------------------

2.10: Why do I get 'Parameter list cannot contain fewer ....'


This is the same as above (2.9).

------------------------------

2.11: Why does xlc complain about

               '(sometype *)somepointer = something'

Software that is developed using gcc may have this construct. However,
standard C does not permit casts to be lvalues, so you will need to
change the cast and move it to the right side of the assignment. If you
compile with 'cc', removing the cast completely will give you a warning,
'xlc' will give you an error (provided somepointer and something are of
different types - but else, why would the cast be there in the first place?)

------------------------------

2.12: Some more common errors


Here are a few other common errors with xlc:

305 |     switch((((np)->navigation_type) ? (*((np)->navigation_type)) :
      ((void *)0)))
      .a...........  
a - 1506-226: (S) The second and third operands of the conditional
operator must be of the same type.

The reason for this is that xlc defines NULL as (void *)0, and it does
not allow two different types as the second and third operand of ?:. 
The second argument above is not a pointer and the code used NULL
incorrectly as a scalar. NULL is a nil pointer constant in ANSI C and
in some traditional compilers.

You should change NULL in the third argument above to an integer 0.


------------------------------

2.13: Can the compiler generate assembler code?


Starting with version 1.3 of xlc and xlf the -S option will generate a
.s assembly code file prior to optimization. The option -qlist will
generate a human readable one in a .lst file.

There is also a disassembler in /usr/lpp/xlc/bin/dis include with the
1.3 version of xlc (and in /usr/lpp/xlC/bin/dis with the 2.1 version
of xlC) that will disassemble existing object or executable files.

------------------------------

2.14: Curses


Curses based applications should be linked with -lcurses and _not_ with
-ltermlib. It has also been reported that some problems with curses are
avoided if your application is compiled with -DNLS.

Peter Jeffe <peter@ski.austin.ibm.com> also notes:

>the escape sequences for cursor and function keys are *sometimes*
>treated as several characters: eg. the getch() - call does not return
>KEY_UP but 'ESC [ C.'

You're correct in your analysis: this has to do with the timing of the
escape sequence as it arrives from the net. There is an environment
variable called ESCDELAY that can change the fudge factor used to decide
when an escape is just an escape. The default value is 500; boosting
this a bit should solve your problems.

Christopher Carlyle O'Callaghan <asdfjkl@wam.umd.edu> has more comments
concerning extended curses:

1) The sample program in User Interface Programming Concepts, page 7-13
   is WRONG. Here is the correct use of panes and panels.

#include <cur01.h>
#include <cur05.h>

main()
{
PANE *A, *B, *C, *D, *E, *F, *G, *H;
PANEL *P;

initscr();

A = ecbpns (24, 79, NULL, NULL, 0, 2500, Pdivszp, Pbordry, NULL, NULL);
D = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
E = ecbpns (24, 79, D,    NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
B = ecbpns (24, 79, A, D, Pdivtyh, 3000, Pdivszp, Pbordry, NULL, NULL);
F = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
G = ecbpns (24, 79, F,    NULL, 0, 5000, Pdivszp, Pbordry, NULL, NULL);
H = ecbpns (24, 79, G,    NULL, 0, 3000, Pdivszp, Pbordry, NULL, NULL);
C = ecbpns (24, 79, B, F, Pdivtyh, 0, Pdivszf, Pbordry, NULL, NULL);
P = ecbpls (24, 79, 0, 0, "MAIN PANEL", Pdivtyv, Pbordry, A);

ecdvpl (P);
ecdfpl (P, FALSE);
ecshpl (P); 
ecrfpl (P);
endwin();
}

2) DO NOT include <curses.h> and any other <cur0x.h> file together.
   You will get a bunch of redefined statements.

3) There is CURSES and EXTENDED CURSES. Use only one or the other. If the
   manual says that they're backwards compatible or some other indication 
   that you can use CURSES routines with EXTENDED, don't believe it. To 
   use CURSES you need to include <curses.h> and you can't (see above).

4) If you use -lcur and -lcurses in the same link command, you will get
   Memory fault (core dump) error. You CANNOT use both of them at the same
   time. -lcur is for extended curses, -lcurses is for regular curses.

5) When creating PANEs, when you supply a value (other than 0) for the
   'ds' parameter and use Pdivszf value for the 'du' parameter, the 'ds'
   will be ignored (the sample program on page 7-13 in User Interface
   Programming Concepts is wrong.) For reasons as yet undetermined,
   Pdivszc doesn't seem to work (or at least I can't figure out how to
   use it.)

6) If you're running into bugs and can't figure out what is happening,
   try the following:
   include -qextchk -g in your compile line
	-qextchk will check to make sure you're passing the right number of
  	 parameters to the functions
	-g enables debug

7) Do not use 80 as the number of columns if you want to use the whole
   screen. The lower right corner will get erased.  Use 79 instead.

8) If you create a panel, you must create at least 1 pane, otherwise you
   will get a Memory fault (core dump).

9) When creating a panel, if you don't have a border around it, any title
   you want will not show up.

10) to make the screen scroll down:
    wmove (win, 0, 0);
    winsertln (win)

11) delwin(win) doesn't work in EXTENDED WINDOWS

    To make it appear as if a window is deleted, you need to do the following:
    for every window that you want to appear on the screen
	touchwin(win)
	wrefresh(win)

    you must make sure that you do it in the exact same order as you put
    them on the screen (i.e., if you called newwin with A, then C, then B,
    then you must do the loop with A, then C, then B, otherwise you won't
    get the same screen back).  The best thing to do is to put them into
    an array and keep track of the last window index.

12) mvwin(win, line, col) implies that it is only used for viewports and
    subwindows. It can also be used for the actual windows themselves.

13) If you specify the attribute of a window using wcolorout(win), any
    subsequent calls to chgat(numchars, mode) or any of its relatives
    will not work. (or at least they get very picky.)

------------------------------

2.15: How do I speed up linking


Please refer to sections 2.03 and 2.06 above.

From: losecco@undpdk.hep.nd.edu (John LoSecco) and
      hook@chaco.aix.dfw.ibm.com (Gary R. Hook)

From oahu.cern.ch in /pub/aix3 you can get a wrapper for the existing
linker called tld which can reduce link times with large libraries by
factors of 3 to 4.

------------------------------

2.16: What is deadbeef?


When running the debugger (dbx), you may have wondered what the
'deadbeef' is you occasionally see in registers.  Do note, that
0xdeadbeef is a hexadecimal number that also happens to be some kind
of word (the RS/6000 was built in Texas!), and this hexadecimal number
is simply put into unused registers at some time, probably during
program startup.


------------------------------

2.17: How do I make an export list from a library archive?

From: d.dennerline@bull.com (Dave Dennerline)

[ This script has been moved to section 8.10 ]

------------------------------

2.19: Building imake, makedepend

From: crow@austin.ibm.com (David L. Crow)

[Editor's note: if you have AIX 4.x,  you need the X11.adt.imake LPP
and probably most if not all of the X11.adt.* LPPs.  Imake, xmkmf and
other utilities are delivered precompiled.]

    You need X11dev.src release 1.2.3.0 (ie the R5 release) [on AIX 3.2].


     Unless you have an R5 release of AIXwindows, there is no xmkmf.
  These are the steps that I use to make imake, makedepend and all
  of it's config files, and then install them in the working tree
  (ie not the Xamples) for daily use:
  
      cd /usr/lpp/X11/Xamples
      make Makefile
      make SUBDIRS="config util" Makefiles
      make SUBDIRS="config util" linklibs
      make SUBDIRS="config util" depend
      make SUBDIRS="config util" 
      make SUBDIRS="config util" install
      
  Then redo the steps everytime you apply an X11 update.

------------------------------

2.20: How can tell what shared libraries a binary is linked with?


Use "dump -H <execfilename>" and see if anything other than /unix is
listed in the loader section (at the bottom).  The first example is
/bin/sh (statically linked) and the second example is
/usr/local/bin/bash (shared).

INDEX  PATH                          BASE                MEMBER              
0      /usr/lib:/lib                                                         
1      /                             unix                                    

INDEX  PATH                          BASE                MEMBER              
0      ./lib/readline/:./lib/glob/:/usr/lib:/lib               
1                                    libc.a              shr.o               
2                                    libcurses.a         shr.o               

The freeware tool "ldd" lists all the shared libraries needed
by an executable, including those recursively included by other
shared libraries. See question 2.27 "Where can I find ldd for AIX?".

------------------------------

2.21: Can I get a PTF for my C/C++ compiler from the net?


<http://service.software.ibm.com/>  contains pointers to most PTFs, including
compilers.  You'll need the fixdist program (see 1.142) to retrieve them.

------------------------------

2.22: Why does "install"ing software I got from the net fail?


Note that the RS/6000 has two install programs, one with System V flavor
in the default PATH (/etc/install with links from /usr/bin and /usr/usg),
and one with BSD behavior in /usr/ucb/install.

------------------------------

2.23: What is Linker TOC overflow error 12?


There is a hard coded limit in the AIX 3.2.5 linker that is fixed in
AIX 4.1.  A kind soul donated the following information to help people
get the 3.2.5 fix

    The LPS (paperwork) 
      AIX TOC Data Binder/6000 #P91128
      Version 1.1
      Program Number 5799-QDY
      Reference No. GC23-2604-00, FC 5615
    Pre Reqs listed were AIX 3.2.5
      IBM C Set++ V2 (5765-186)

The above is not available any longer, see section 1.006.

You could also put some of the application code into shared libraries
or, in the case of gcc, use -mminimal-toc.

------------------------------

2.24: What is the limit on number of shared memory segments

               I can attach?

Each process has 16 segments.  One is used for private code, one for
stack, one for heap; those, if memory serves, are segments 0, 1, and
2.  (If you look in sys/shm.h, you'll see that SHMLOSEG is 3 -- the
lowest segment, in number and in the process' virtual address space,
available to shmat.)

SHMHISEG, the highest segment you can attach to (also defined in
sys/shm.h), is 12.  Segments 3 through 12 are available to shmat,
giving the 10 segments your program used successfully.  (NSHMSEGS in
sys/shm.h will give you this value, though it's of limited use, since
most platforms that I've seen don't define it.)

Segment 13 is used by shared code your program has attached to;
I think one of the others might be for kernel-mode data.

See also mmap.

------------------------------

2.25: I deleted libc.a by accident --- how do I recover?

From: Ed Ravin <eravin@panix.com>

You can recover from this without rebooting or reinstalling, if you
have another copy of libc.a available that is also named "libc.a".  If
you moved libc.a to a different directory, you're in luck -- do the
following:

export LIBPATH=/other/directory


And your future commands will work.  But if you renamed libc.a, this
won't do it.  If you have an NFS mounted directory somewhere, you can
put libc.a on the that host, and point LIBPATH to that directory as
shown above.

Failing that, turn off your machine, reboot off floppies or other
media, and get a root shell.  I don't think you should do "getrootfs"
as you usually do when accessing the root vg this way -- AIX may start
looking for libc.a on the disk, and you'll just run into the same
problem.  So do an importvg, varyonvg, and then mount /usr somewhere,
then manually move libc.a back or copy in a new one from floppy.

------------------------------

2.26: Where can I find dlopen, dlclose, and dlsym for AIX?


An implementation of these dynamic code loading functions was written by
Jens-Uwe Mager <jum@anubis.han.de> and can be found at
<ftp://anubis.han.de/pub/aix/dlfcn.shar>

From: Gary R. Hook <hook@austin.ibm.com>

Starting with AIX 4.2 a dlopen et. al. are included in the base OS in
the libdl.a library. Under AIX 4.1 this is available as SLHS (Shared
Library Hookable Symbols) as APAR IX IX71849 for the runtime package and
APAR IX IX72973 for the development tools.

------------------------------

2.27: Where can I find ldd for AIX?

From: Jens-Uwe Mager <jum@anubis.han.de>

Try <ftp://anubis.han.de/pub/aix/ldd.c>. Also the "aix.tools"
package from <http://www-frec.bull.com>

------------------------------

2.28: How do I make my program binary executable on the

                POWER, POWER2, and POWERPC architecures?

AIX will emulate those instructions not available in POWERPC processors, but
you can avoid this emulation and consequent performance degradtation by
using only the common to all.

If you are using IBM's xlc (cc) compiler, the default is to use the common
instruction set.  If you want to be explicit, use the -qarch=com option.

The option -mcpu=common makes GCC use the common instruction set.  Please
note that (unlike xlc) this is *not* the default with GCC on AIX.

------------------------------

2.29: How do I access more than 256 Megabytes of memory?


By default each program gets one segment register (see 2.24) for its
data segment. As each segment register covers 256 MB, any calls to
malloc more will fail. Also programs that declare large global or static
arrays may fail to load. To allocate more segment registers to your
program, use the linker option -bmaxdata to specify the number of bytes
you need in the data segment as follows:

cc -o myprog -bmaxdata:0x20000000 myprog.c

The example above would allocate an additional segment register to allow
for 512MB of data.

------------------------------

2.30: How do I use POSIX threads with gcc 2.7.x?

From: David Edelsohn <dje@watson.ibm.com>

The code generated by GCC is compatible with threads, but gcc-2.7 
was released so long ago that it did not provide an option to perform
the extra link steps necessary to support threads:

1) Compile all source files with "-D_THREAD_SAFE" macro defined.
2) Link with "-L/usr/lib/threads -lpthreads -lc_r /usr/lib/libc.a"
   to obtain the pthreads support 
   and add "-nostartfiles /usr/lib/crt0_r.o" to the beginning of the
   link command line (using gcc to link!) to initialize threads.

------------------------------

2.00: C/C++


Contrary to many people's belief, the C environment on the RS/6000 is
not very special.  The C compiler has quite a number of options that can
be used to control how it works, which "dialect" of C it compiles, how
it interprets certain language constructs, etc.  InfoExplorer includes a
Users Guide and a Reference Manual.

The compiler can be invoked with either xlc for strict ANSI mode and cc
for RT compatible mode (i.e. IBM 6150 with AIX 2).  The default options
for each mode are set in the /etc/xlc.cfg file, and you can actually add
another stanza and create a link to the /bin/xlc executable.

The file /usr/lpp/xlc/bin/README.xlc has information about the C
compiler, and the file /usr/lpp/bos/bsdport (AIX 3 only) contains useful
information, in particular for users from a BSD background.

The file /etc/xlc.cfg also shows the symbol _IBMR2 that is predefined,
and therefore can be used for #ifdef'ing RS/6000 specific code.

------------------------------

2.01: I cannot make alloca work


A famous routine, in particular in GNU context, is the allocation
routine alloca().  Alloca allocates memory in such a way that it is
automatically free'd when the block is exited.  Most implementations
does this by adjusting the stack pointer.  Since not all C environments
can support it, its use is discouraged, but it is included in the xlc
compiler.  In order to make the compiler aware that you intend to use
alloca, you must put the line

#pragma alloca

before any other statements in the C source module(s) where alloca is
called.  If you don't do this, xlc will not recognize alloca as anything
special, and you will get errors during linking.

For AIX 3.2, it may be easier to use the -ma flag.

------------------------------

2.02: How do I compile my BSD programs?


The file /usr/lpp/bos/bsdport contains information on how to port
programs written for BSD to AIX 3.  This file may be very useful for
others as well.

A quick cc command for most "standard" BSD programs is:
  
  $ cc -D_BSD -D_BSD_INCLUDES  -o [loadfile] [sourcefile.c] -lbsd

If your software has system calls predefined with no prototype
parameters, also use the -D_NO_PROTO flag.

------------------------------

2.03: Isn't the linker different from what I am used to?


Yes.  It is not at all like what you are used to:

- The order of objects and libraries is normally _not_ important.  The
  linker reads _all_ objects including those from libraries into memory
  and does the actual linking in one go.  Even if you need to put a
  library of your own twice on the ld command line on other systems, it
  is not needed on the RS/6000 - doing so will even make your linking slower.

- One of the features of the linker is that it will replace an object in
  an executable with a new version of the same object:

  $ cc -o prog prog1.o prog2.o prog3.o		# make prog
  $ cc -c prog2.c				# recompile prog2.c
  $ cc -o prog.new prog2.o prog			# make prog.new from prog
						# by replacing prog2.o
  
- The standard C library /lib/libc.a is linked shared, which means that
  the actual code is not linked into your program, but is loaded only
  once and linked dynamically during loading of your program.

- The ld program actually calls the binder in /usr/lib/bind, and you can
  give ld special options to get details about the invocation of the
  binder.  These are found on the ld man page or in InfoExplorer.

- If your program normally links using a number of libraries (.a files),
  you can 'prelink' each of these into an object, which will make your
  final linking faster.  E.g. do:

  $ cc -c prog1.c prog2.c prog3.c
  $ ar cv libprog.a prog1.o prog2.o prog3.o
  $ ld -r -o libprog.o libprog.a
  $ cc -o someprog someprog.c libprog.o

This will solve all internal references between prog1.o, prog2.o and
prog3.o and save this in libprog.o Then using libprog.o to link your
program instead of libprog.a will increase linking speed, and even if
someprog.c only uses, say prog1.o and prog2.o, only those two modules
will be in your final program.  This is also due to the fact that the
binder can handle single objects inside one object module as noted above.

If you are using an -lprog option (for libprog.a) above, and still want
to be able to do so, you should name the prelinked object with a
standard library name, e.g. libprogP.a (P identifying a prelinked
object), that can be specified by -lprogP.  You cannot use the archiver
(ar) on such an object.

You should also have a look at section 3.01 of this article, in
particular if you have mixed Fortran/C programs.

Dave Dennerline (d.dennerline@bull.com) claims that his experiences
in prelinking on AIX does not save much time since most people have
separate libraries which do not have many dependencies between them,
thus not many symbols to resolve.

------------------------------

2.04: How do I statically link my program?


  cc -o prog -bnoso -bI:/lib/syscalls.exp obj1.o obj2.o obj3.o

will do that for a program consisting of the three objects obj1.o, etc.

[Editor's note: You should never link programs statically that are
supposed to leave your local environment, e.g. intended for
distribution. Statically linked programs may fail to work after
installing a new AIX version or even after installing a PTF.]

From: Marc Pawliger (marc@sti.com)

As of AIX 3.2.5, you can install a speedup for AIXwindows called
Shared Memory Transport.  To static link an X application after the
SMT PTF has been installed, you must link with
-bI:/usr/lpp/X11/bin/smt.exp and the executable will NOT run on a
machine where SMT is not installed.  See /usr/lpp/X11/README.SMT
Newsgroups: comp.unix.aix,comp.answers,news.answers
Path: news.univie.ac.at!aconews.univie.ac.at!newscore.univie.ac.at!fu-berlin.de!news-ber1.dfn.de!news-ham1.dfn.de!newsserver.rrzn.uni-hannover.de!baghira.han.de!jum
From: jum@anubis.han.de
Approved: news-answers-request@mit.edu
Followup-To: comp.unix.aix
Supersedes: <aix-faq-4-886305604@anubis.han.de>
Reply-To: jum@anubis.han.de (Jens-Uwe Mager)
Keywords: AIX RS/6000 questions answers
Sender: jum@baghira.han.de (Jens-Uwe Mager)
Expires: Sun, 5 Apr 1998 05:01:07 GMT
Organization: At Home
Message-ID: <aix-faq-4-888724807@anubis.han.de>
References: <aix-faq-1-888724807@anubis.han.de> 
Date: Sun, 1 Mar 1998 04:00:24 GMT
         and their answers.  AIX is IBM's version of Unix.
Lines: 1806
Xref: news.univie.ac.at comp.unix.aix:125562 comp.answers:29712 news.answers:39490

Posted-By: auto-faq 3.3 (Perl 4.035)
Archive-name: aix-faq/part4
Posting-Frequency: monthly


------------------------------

2.05: How do I make my own shared library?


To make your own shared object or library of shared objects, you should
know that a shared object cannot have undefined symbols.  Thus, if your
code uses any externals from /lib/libc.a, the latter MUST be linked with
your code to make a shared object.  Mike Heath (mike@pencom.com) said it
is possible to split code into more than one shared object when externals
in one object refer to another one.  You must be very good at
import/export files.  Perhaps he or someone can provide an example. 

Assume you have one file, sub1.c, containing a routine with no external
references, and another one, sub2.c, calling stuff in /lib/libc.a.  You
will also need two export files, sub1.exp, sub2.exp.  Read the example
below together with the examples on the ld man page. 

---- sub1.c ----
    int addint(int a, int b)
    {
      return a + b;
    }
---- sub2.c ----
    #include <stdio.h>

    void printint(int a)
    {
      printf("The integer is: %d\n", a);
    }
---- sub1.exp ----
    #!
    addint
---- sub2.exp ----
    #!
    printint
---- usesub.c ----
    main()
    {
      printint( addint(5,8) );
    }

The following commands will build your libshr.a, and compile/link the
program usesub to use it.  Note that you need the ld option -lc for
sub2shr.o since it calls printf from /lib/libc.a.  [Note that you can leave
out the "-T512 -H512" on AIX 4. -- Ed.]

  $ cc  -c sub1.c
  $ ld -o sub1shr.o sub1.o -bE:sub1.exp -bM:SRE -T512 -H512 
  $ cc  -c sub2.c
  $ ld -o sub2shr.o sub2.o -bE:sub2.exp -bM:SRE -T512 -H512  -lc
  $ ar r libshr.a sub1shr.o sub2shr.o
  $ cc -o usesub usesub.c -L: libshr.a
  $ usesub
  The integer is: 13
  $

------------------------------

2.06: Linking my program fails with strange errors. Why?


Very simple, the linker (actually called the binder), cannot get the
memory it needs, either because your ulimits are too low or because you
don't have sufficient paging space.  Since the linker is quite different
>from normal Unix linkers and actually does much more than these, it also
uses a lot of virtual memory.  It is not unusual to need 10000 pages (of
4k) or more to execute a fairly complex linking.

If you get 'BUMP error', either ulimits or paging is too low, if you get
'Binder killed by signal 9' your paging is too low.

First, check your memory and data ulimits; in korn shell 'ulimit -a' will
show all limits and 'ulimit -m 99999' and 'ulimit -d 99999' will
increase the maximum memory and data respectively to some high values. 
If this was not your problem, you don't have enough paging space.

If you will or can not increase your paging space, you could try this:

- Do you duplicate libraries on the ld command line? That is never
  necessary.

- Do more users link simultaneously? Try having only one linking going
  on at any time.

- Do a partwise linking, i.e. you link some objects/libraries with the
  -r option to allow the temporary output to have unresolved references,
  then link with the rest of your objects/libraries.  This can be split
  up as much as you want, and will make each step use less virtual memory.

  If you follow this scheme, only adding one object or archive at a
  time, you will actually emulate the behavior of other Unix linkers.

If you decide to add more paging space, you should consider adding a new
paging space on a second hard disk, as opposed to just increasing the
existing one.  Doing the latter could make you run out of free space on
your first harddisk. It is more involved to shrink a paging space
but easier to delete one.

------------------------------

2.07: Why does it take so long to compile "hello world" with xlc?


Some systems have experienced delays of more than 60 seconds in
compiling "#include <stdio.h> int main () {printf ("Hello world");}"
The problem is with the license manager contact IBM to make sure
you've got the latest PTF.

------------------------------

2.08: What's with malloc()?

 
malloc() uses a late allocation algorithm based on 4.3 BSD's malloc()
for speed.  This lets you allocate very large sparse memory spaces,
since the pages are not actually allocated until they are touched for
the first time.  Unfortunately, it doesn't die gracefully in the face of
loss of available memory.  See the "Paging Space Overview" under
InfoExplorer, and see the notes on the linker in this document for an
example of an ungraceful death.

If you want your program to get notified when running out of memory, you
should handle the SIGDANGER signal.  The default is to ignore it. 
SIGDANGER is sent to all processes when paging space gets low, and if
paging space gets even lower, processes with the highest paging space
usage are sent the SIGKILL signal.

malloc() is substantially different in 3.2, allocating memory more
tightly.  If you have problems running re-compiled programs on 3.2,
try running them with MALLOCTYPE=3.1.

Early Page Space Allocation (EPSA) added to AIX 3.2: see
/usr/lpp/bos/README.PSALLOC - IX38211 / U422496 Allows setting of
early allocation (vs. default late allocation) on a per-process basis.

------------------------------

2.09: Why does xlc complain about 'extern char *strcpy()'


The header <string.h> has a strcpy macro that expands strcpy(x,y) to
__strcpy(x,y), and the latter is then used by the compiler to generate
inline code for strcpy.  Because of the macro, your extern declaration
contains an invalid macro expansion.  The real cure is to remove your
extern declaration but adding -U__STR__ to your xlc will also do the
trick, although your program might run a bit more slowly as the compiler
cannot inline the string functions any more.

------------------------------

2.10: Why do I get 'Parameter list cannot contain fewer ....'


This is the same as above (2.9).

------------------------------

2.11: Why does xlc complain about

               '(sometype *)somepointer = something'

Software that is developed using gcc may have this construct. However,
standard C does not permit casts to be lvalues, so you will need to
change the cast and move it to the right side of the assignment. If you
compile with 'cc', removing the cast completely will give you a warning,
'xlc' will give you an error (provided somepointer and something are of
different types - but else, why would the cast be there in the first place?)

------------------------------

2.12: Some more common errors


Here are a few other common errors with xlc:

305 |     switch((((np)->navigation_type) ? (*((np)->navigation_type)) :
      ((void *)0)))
      .a...........  
a - 1506-226: (S) The second and third operands of the conditional
operator must be of the same type.

The reason for this is that xlc defines NULL as (void *)0, and it does
not allow two different types as the second and third operand of ?:. 
The second argument above is not a pointer and the code used NULL
incorrectly as a scalar. NULL is a nil pointer constant in ANSI C and
in some traditional compilers.

You should change NULL in the third argument above to an integer 0.


------------------------------

2.13: Can the compiler generate assembler code?


Starting with version 1.3 of xlc and xlf the -S option will generate a
.s assembly code file prior to optimization. The option -qlist will
generate a human readable one in a .lst file.

There is also a disassembler in /usr/lpp/xlc/bin/dis include with the
1.3 version of xlc (and in /usr/lpp/xlC/bin/dis with the 2.1 version
of xlC) that will disassemble existing object or executable files.

------------------------------

2.14: Curses


Curses based applications should be linked with -lcurses and _not_ with
-ltermlib. It has also been reported that some problems with curses are
avoided if your application is compiled with -DNLS.

Peter Jeffe <peter@ski.austin.ibm.com> also notes:

>the escape sequences for cursor and function keys are *sometimes*
>treated as several characters: eg. the getch() - call does not return
>KEY_UP but 'ESC [ C.'

You're correct in your analysis: this has to do with the timing of the
escape sequence as it arrives from the net. There is an environment
variable called ESCDELAY that can change the fudge factor used to decide
when an escape is just an escape. The default value is 500; boosting
this a bit should solve your problems.

Christopher Carlyle O'Callaghan <asdfjkl@wam.umd.edu> has more comments
concerning extended curses:

1) The sample program in User Interface Programming Concepts, page 7-13
   is WRONG. Here is the correct use of panes and panels.

#include <cur01.h>
#include <cur05.h>

main()
{
PANE *A, *B, *C, *D, *E, *F, *G, *H;
PANEL *P;

initscr();

A = ecbpns (24, 79, NULL, NULL, 0, 2500, Pdivszp, Pbordry, NULL, NULL);
D = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
E = ecbpns (24, 79, D,    NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
B = ecbpns (24, 79, A, D, Pdivtyh, 3000, Pdivszp, Pbordry, NULL, NULL);
F = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
G = ecbpns (24, 79, F,    NULL, 0, 5000, Pdivszp, Pbordry, NULL, NULL);
H = ecbpns (24, 79, G,    NULL, 0, 3000, Pdivszp, Pbordry, NULL, NULL);
C = ecbpns (24, 79, B, F, Pdivtyh, 0, Pdivszf, Pbordry, NULL, NULL);
P = ecbpls (24, 79, 0, 0, "MAIN PANEL", Pdivtyv, Pbordry, A);

ecdvpl (P);
ecdfpl (P, FALSE);
ecshpl (P); 
ecrfpl (P);
endwin();
}

2) DO NOT include <curses.h> and any other <cur0x.h> file together.
   You will get a bunch of redefined statements.

3) There is CURSES and EXTENDED CURSES. Use only one or the other. If the
   manual says that they're backwards compatible or some other indication 
   that you can use CURSES routines with EXTENDED, don't believe it. To 
   use CURSES you need to include <curses.h> and you can't (see above).

4) If you use -lcur and -lcurses in the same link command, you will get
   Memory fault (core dump) error. You CANNOT use both of them at the same
   time. -lcur is for extended curses, -lcurses is for regular curses.

5) When creating PANEs, when you supply a value (other than 0) for the
   'ds' parameter and use Pdivszf value for the 'du' parameter, the 'ds'
   will be ignored (the sample program on page 7-13 in User Interface
   Programming Concepts is wrong.) For reasons as yet undetermined,
   Pdivszc doesn't seem to work (or at least I can't figure out how to
   use it.)

6) If you're running into bugs and can't figure out what is happening,
   try the following:
   include -qextchk -g in your compile line
	-qextchk will check to make sure you're passing the right number of
  	 parameters to the functions
	-g enables debug

7) Do not use 80 as the number of columns if you want to use the whole
   screen. The lower right corner will get erased.  Use 79 instead.

8) If you create a panel, you must create at least 1 pane, otherwise you
   will get a Memory fault (core dump).

9) When creating a panel, if you don't have a border around it, any title
   you want will not show up.

10) to make the screen scroll down:
    wmove (win, 0, 0);
    winsertln (win)

11) delwin(win) doesn't work in EXTENDED WINDOWS

    To make it appear as if a window is deleted, you need to do the following:
    for every window that you want to appear on the screen
	touchwin(win)
	wrefresh(win)

    you must make sure that you do it in the exact same order as you put
    them on the screen (i.e., if you called newwin with A, then C, then B,
    then you must do the loop with A, then C, then B, otherwise you won't
    get the same screen back).  The best thing to do is to put them into
    an array and keep track of the last window index.

12) mvwin(win, line, col) implies that it is only used for viewports and
    subwindows. It can also be used for the actual windows themselves.

13) If you specify the attribute of a window using wcolorout(win), any
    subsequent calls to chgat(numchars, mode) or any of its relatives
    will not work. (or at least they get very picky.)

------------------------------

2.15: How do I speed up linking


Please refer to sections 2.03 and 2.06 above.

From: losecco@undpdk.hep.nd.edu (John LoSecco) and
      hook@chaco.aix.dfw.ibm.com (Gary R. Hook)

From oahu.cern.ch in /pub/aix3 you can get a wrapper for the existing
linker called tld which can reduce link times with large libraries by
factors of 3 to 4.

------------------------------

2.16: What is deadbeef?


When running the debugger (dbx), you may have wondered what the
'deadbeef' is you occasionally see in registers.  Do note, that
0xdeadbeef is a hexadecimal number that also happens to be some kind
of word (the RS/6000 was built in Texas!), and this hexadecimal number
is simply put into unused registers at some time, probably during
program startup.


------------------------------

2.17: How do I make an export list from a library archive?

From: d.dennerline@bull.com (Dave Dennerline)

[ This script has been moved to section 8.10 ]

------------------------------

2.19: Building imake, makedepend

From: crow@austin.ibm.com (David L. Crow)

[Editor's note: if you have AIX 4.x,  you need the X11.adt.imake LPP
and probably most if not all of the X11.adt.* LPPs.  Imake, xmkmf and
other utilities are delivered precompiled.]

    You need X11dev.src release 1.2.3.0 (ie the R5 release) [on AIX 3.2].


     Unless you have an R5 release of AIXwindows, there is no xmkmf.
  These are the steps that I use to make imake, makedepend and all
  of it's config files, and then install them in the working tree
  (ie not the Xamples) for daily use:
  
      cd /usr/lpp/X11/Xamples
      make Makefile
      make SUBDIRS="config util" Makefiles
      make SUBDIRS="config util" linklibs
      make SUBDIRS="config util" depend
      make SUBDIRS="config util" 
      make SUBDIRS="config util" install
      
  Then redo the steps everytime you apply an X11 update.

------------------------------

2.20: How can tell what shared libraries a binary is linked with?


Use "dump -H <execfilename>" and see if anything other than /unix is
listed in the loader section (at the bottom).  The first example is
/bin/sh (statically linked) and the second example is
/usr/local/bin/bash (shared).

INDEX  PATH                          BASE                MEMBER              
0      /usr/lib:/lib                                                         
1      /                             unix                                    

INDEX  PATH                          BASE                MEMBER              
0      ./lib/readline/:./lib/glob/:/usr/lib:/lib               
1                                    libc.a              shr.o               
2                                    libcurses.a         shr.o               

The freeware tool "ldd" lists all the shared libraries needed
by an executable, including those recursively included by other
shared libraries. See question 2.27 "Where can I find ldd for AIX?".

------------------------------

2.21: Can I get a PTF for my C/C++ compiler from the net?


<http://service.software.ibm.com/>  contains pointers to most PTFs, including
compilers.  You'll need the fixdist program (see 1.142) to retrieve them.

------------------------------

2.22: Why does "install"ing software I got from the net fail?


Note that the RS/6000 has two install programs, one with System V flavor
in the default PATH (/etc/install with links from /usr/bin and /usr/usg),
and one with BSD behavior in /usr/ucb/install.

------------------------------

2.23: What is Linker TOC overflow error 12?


There is a hard coded limit in the AIX 3.2.5 linker that is fixed in
AIX 4.1.  A kind soul donated the following information to help people
get the 3.2.5 fix

    The LPS (paperwork) 
      AIX TOC Data Binder/6000 #P91128
      Version 1.1
      Program Number 5799-QDY
      Reference No. GC23-2604-00, FC 5615
    Pre Reqs listed were AIX 3.2.5
      IBM C Set++ V2 (5765-186)

The above is not available any longer, see section 1.006.

You could also put some of the application code into shared libraries
or, in the case of gcc, use -mminimal-toc.

------------------------------

2.24: What is the limit on number of shared memory segments

               I can attach?

Each process has 16 segments.  One is used for private code, one for
stack, one for heap; those, if memory serves, are segments 0, 1, and
2.  (If you look in sys/shm.h, you'll see that SHMLOSEG is 3 -- the
lowest segment, in number and in the process' virtual address space,
available to shmat.)

SHMHISEG, the highest segment you can attach to (also defined in
sys/shm.h), is 12.  Segments 3 through 12 are available to shmat,
giving the 10 segments your program used successfully.  (NSHMSEGS in
sys/shm.h will give you this value, though it's of limited use, since
most platforms that I've seen don't define it.)

Segment 13 is used by shared code your program has attached to;
I think one of the others might be for kernel-mode data.

See also mmap.

------------------------------

2.25: I deleted libc.a by accident --- how do I recover?

From: Ed Ravin <eravin@panix.com>

You can recover from this without rebooting or reinstalling, if you
have another copy of libc.a available that is also named "libc.a".  If
you moved libc.a to a different directory, you're in luck -- do the
following:

export LIBPATH=/other/directory


And your future commands will work.  But if you renamed libc.a, this
won't do it.  If you have an NFS mounted directory somewhere, you can
put libc.a on the that host, and point LIBPATH to that directory as
shown above.

Failing that, turn off your machine, reboot off floppies or other
media, and get a root shell.  I don't think you should do "getrootfs"
as you usually do when accessing the root vg this way -- AIX may start
looking for libc.a on the disk, and you'll just run into the same
problem.  So do an importvg, varyonvg, and then mount /usr somewhere,
then manually move libc.a back or copy in a new one from floppy.

------------------------------

2.26: Where can I find dlopen, dlclose, and dlsym for AIX?


An implementation of these dynamic code loading functions was written by
Jens-Uwe Mager <jum@anubis.han.de> and can be found at
<ftp://anubis.han.de/pub/aix/dlfcn.shar>

From: Gary R. Hook <hook@austin.ibm.com>

Starting with AIX 4.2 a dlopen et. al. are included in the base OS in
the libdl.a library. Under AIX 4.1 this is available as SLHS (Shared
Library Hookable Symbols) as APAR IX IX71849 for the runtime package and
APAR IX IX72973 for the development tools.

------------------------------

2.27: Where can I find ldd for AIX?

From: Jens-Uwe Mager <jum@anubis.han.de>

Try <ftp://anubis.han.de/pub/aix/ldd.c>. Also the "aix.tools"
package from <http://www-frec.bull.com>

------------------------------

2.28: How do I make my program binary executable on the

                POWER, POWER2, and POWERPC architecures?

AIX will emulate those instructions not available in POWERPC processors, but
you can avoid this emulation and consequent performance degradtation by
using only the common to all.

If you are using IBM's xlc (cc) compiler, the default is to use the common
instruction set.  If you want to be explicit, use the -qarch=com option.

The option -mcpu=common makes GCC use the common instruction set.  Please
note that (unlike xlc) this is *not* the default with GCC on AIX.

------------------------------

2.29: How do I access more than 256 Megabytes of memory?


By default each program gets one segment register (see 2.24) for its
data segment. As each segment register covers 256 MB, any calls to
malloc more will fail. Also programs that declare large global or static
arrays may fail to load. To allocate more segment registers to your
program, use the linker option -bmaxdata to specify the number of bytes
you need in the data segment as follows:

cc -o myprog -bmaxdata:0x20000000 myprog.c

The example above would allocate an additional segment register to allow
for 512MB of data.

------------------------------

2.30: How do I use POSIX threads with gcc 2.7.x?

From: David Edelsohn <dje@watson.ibm.com>

The code generated by GCC is compatible with threads, but gcc-2.7 
was released so long ago that it did not provide an option to perform
the extra link steps necessary to support threads:

1) Compile all source files with "-D_THREAD_SAFE" macro defined.
2) Link with "-L/usr/lib/threads -lpthreads -lc_r /usr/lib/libc.a"
   to obtain the pthreads support 
   and add "-nostartfiles /usr/lib/crt0_r.o" to the beginning of the
   link command line (using gcc to link!) to initialize threads.

------------------------------

2.00: C/C++


Contrary to many people's belief, the C environment on the RS/6000 is
not very special.  The C compiler has quite a number of options that can
be used to control how it works, which "dialect" of C it compiles, how
it interprets certain language constructs, etc.  InfoExplorer includes a
Users Guide and a Reference Manual.

The compiler can be invoked with either xlc for strict ANSI mode and cc
for RT compatible mode (i.e. IBM 6150 with AIX 2).  The default options
for each mode are set in the /etc/xlc.cfg file, and you can actually add
another stanza and create a link to the /bin/xlc executable.

The file /usr/lpp/xlc/bin/README.xlc has information about the C
compiler, and the file /usr/lpp/bos/bsdport (AIX 3 only) contains useful
information, in particular for users from a BSD background.

The file /etc/xlc.cfg also shows the symbol _IBMR2 that is predefined,
and therefore can be used for #ifdef'ing RS/6000 specific code.

------------------------------

2.01: I cannot make alloca work


A famous routine, in particular in GNU context, is the allocation
routine alloca().  Alloca allocates memory in such a way that it is
automatically free'd when the block is exited.  Most implementations
does this by adjusting the stack pointer.  Since not all C environments
can support it, its use is discouraged, but it is included in the xlc
compiler.  In order to make the compiler aware that you intend to use
alloca, you must put the line

#pragma alloca

before any other statements in the C source module(s) where alloca is
called.  If you don't do this, xlc will not recognize alloca as anything
special, and you will get errors during linking.

For AIX 3.2, it may be easier to use the -ma flag.

------------------------------

2.02: How do I compile my BSD programs?


The file /usr/lpp/bos/bsdport contains information on how to port
programs written for BSD to AIX 3.  This file may be very useful for
others as well.

A quick cc command for most "standard" BSD programs is:
  
  $ cc -D_BSD -D_BSD_INCLUDES  -o [loadfile] [sourcefile.c] -lbsd

If your software has system calls predefined with no prototype
parameters, also use the -D_NO_PROTO flag.

------------------------------

2.03: Isn't the linker different from what I am used to?


Yes.  It is not at all like what you are used to:

- The order of objects and libraries is normally _not_ important.  The
  linker reads _all_ objects including those from libraries into memory
  and does the actual linking in one go.  Even if you need to put a
  library of your own twice on the ld command line on other systems, it
  is not needed on the RS/6000 - doing so will even make your linking slower.

- One of the features of the linker is that it will replace an object in
  an executable with a new version of the same object:

  $ cc -o prog prog1.o prog2.o prog3.o		# make prog
  $ cc -c prog2.c				# recompile prog2.c
  $ cc -o prog.new prog2.o prog			# make prog.new from prog
						# by replacing prog2.o
  
- The standard C library /lib/libc.a is linked shared, which means that
  the actual code is not linked into your program, but is loaded only
  once and linked dynamically during loading of your program.

- The ld program actually calls the binder in /usr/lib/bind, and you can
  give ld special options to get details about the invocation of the
  binder.  These are found on the ld man page or in InfoExplorer.

- If your program normally links using a number of libraries (.a files),
  you can 'prelink' each of these into an object, which will make your
  final linking faster.  E.g. do:

  $ cc -c prog1.c prog2.c prog3.c
  $ ar cv libprog.a prog1.o prog2.o prog3.o
  $ ld -r -o libprog.o libprog.a
  $ cc -o someprog someprog.c libprog.o

This will solve all internal references between prog1.o, prog2.o and
prog3.o and save this in libprog.o Then using libprog.o to link your
program instead of libprog.a will increase linking speed, and even if
someprog.c only uses, say prog1.o and prog2.o, only those two modules
will be in your final program.  This is also due to the fact that the
binder can handle single objects inside one object module as noted above.

If you are using an -lprog option (for libprog.a) above, and still want
to be able to do so, you should name the prelinked object with a
standard library name, e.g. libprogP.a (P identifying a prelinked
object), that can be specified by -lprogP.  You cannot use the archiver
(ar) on such an object.

You should also have a look at section 3.01 of this article, in
particular if you have mixed Fortran/C programs.

Dave Dennerline (d.dennerline@bull.com) claims that his experiences
in prelinking on AIX does not save much time since most people have
separate libraries which do not have many dependencies between them,
thus not many symbols to resolve.

------------------------------

2.04: How do I statically link my program?


  cc -o prog -bnoso -bI:/lib/syscalls.exp obj1.o obj2.o obj3.o

will do that for a program consisting of the three objects obj1.o, etc.

[Editor's note: You should never link programs statically that are
supposed to leave your local environment, e.g. intended for
distribution. Statically linked programs may fail to work after
installing a new AIX version or even after installing a PTF.]

From: Marc Pawliger (marc@sti.com)

As of AIX 3.2.5, you can install a speedup for AIXwindows called
Shared Memory Transport.  To static link an X application after the
SMT PTF has been installed, you must link with
-bI:/usr/lpp/X11/bin/smt.exp and the executable will NOT run on a
machine where SMT is not installed.  See /usr/lpp/X11/README.SMT

2.05: How do I make my own shared library?


To make your own shared object or library of shared objects, you should
know that a shared object cannot have undefined symbols.  Thus, if your
code uses any externals from /lib/libc.a, the latter MUST be linked with
your code to make a shared object.  Mike Heath (mike@pencom.com) said it
is possible to split code into more than one shared object when externals
in one object refer to another one.  You must be very good at
import/export files.  Perhaps he or someone can provide an example. 

Assume you have one file, sub1.c, containing a routine with no external
references, and another one, sub2.c, calling stuff in /lib/libc.a.  You
will also need two export files, sub1.exp, sub2.exp.  Read the example
below together with the examples on the ld man page. 

---- sub1.c ----
    int addint(int a, int b)
    {
      return a + b;
    }
---- sub2.c ----
    #include <stdio.h>

    void printint(int a)
    {
      printf("The integer is: %d\n", a);
    }
---- sub1.exp ----
    #!
    addint
---- sub2.exp ----
    #!
    printint
---- usesub.c ----
    main()
    {
      printint( addint(5,8) );
    }

The following commands will build your libshr.a, and compile/link the
program usesub to use it.  Note that you need the ld option -lc for
sub2shr.o since it calls printf from /lib/libc.a.  [Note that you can leave
out the "-T512 -H512" on AIX 4. -- Ed.]

  $ cc  -c sub1.c
  $ ld -o sub1shr.o sub1.o -bE:sub1.exp -bM:SRE -T512 -H512 
  $ cc  -c sub2.c
  $ ld -o sub2shr.o sub2.o -bE:sub2.exp -bM:SRE -T512 -H512  -lc
  $ ar r libshr.a sub1shr.o sub2shr.o
  $ cc -o usesub usesub.c -L: libshr.a
  $ usesub
  The integer is: 13
  $

------------------------------

2.06: Linking my program fails with strange errors. Why?


Very simple, the linker (actually called the binder), cannot get the
memory it needs, either because your ulimits are too low or because you
don't have sufficient paging space.  Since the linker is quite different
>from normal Unix linkers and actually does much more than these, it also
uses a lot of virtual memory.  It is not unusual to need 10000 pages (of
4k) or more to execute a fairly complex linking.

If you get 'BUMP error', either ulimits or paging is too low, if you get
'Binder killed by signal 9' your paging is too low.

First, check your memory and data ulimits; in korn shell 'ulimit -a' will
show all limits and 'ulimit -m 99999' and 'ulimit -d 99999' will
increase the maximum memory and data respectively to some high values. 
If this was not your problem, you don't have enough paging space.

If you will or can not increase your paging space, you could try this:

- Do you duplicate libraries on the ld command line? That is never
  necessary.

- Do more users link simultaneously? Try having only one linking going
  on at any time.

- Do a partwise linking, i.e. you link some objects/libraries with the
  -r option to allow the temporary output to have unresolved references,
  then link with the rest of your objects/libraries.  This can be split
  up as much as you want, and will make each step use less virtual memory.

  If you follow this scheme, only adding one object or archive at a
  time, you will actually emulate the behavior of other Unix linkers.

If you decide to add more paging space, you should consider adding a new
paging space on a second hard disk, as opposed to just increasing the
existing one.  Doing the latter could make you run out of free space on
your first harddisk. It is more involved to shrink a paging space
but easier to delete one.

------------------------------

2.07: Why does it take so long to compile "hello world" with xlc?


Some systems have experienced delays of more than 60 seconds in
compiling "#include <stdio.h> int main () {printf ("Hello world");}"
The problem is with the license manager contact IBM to make sure
you've got the latest PTF.

------------------------------

2.08: What's with malloc()?

 
malloc() uses a late allocation algorithm based on 4.3 BSD's malloc()
for speed.  This lets you allocate very large sparse memory spaces,
since the pages are not actually allocated until they are touched for
the first time.  Unfortunately, it doesn't die gracefully in the face of
loss of available memory.  See the "Paging Space Overview" under
InfoExplorer, and see the notes on the linker in this document for an
example of an ungraceful death.

If you want your program to get notified when running out of memory, you
should handle the SIGDANGER signal.  The default is to ignore it. 
SIGDANGER is sent to all processes when paging space gets low, and if
paging space gets even lower, processes with the highest paging space
usage are sent the SIGKILL signal.

malloc() is substantially different in 3.2, allocating memory more
tightly.  If you have problems running re-compiled programs on 3.2,
try running them with MALLOCTYPE=3.1.

Early Page Space Allocation (EPSA) added to AIX 3.2: see
/usr/lpp/bos/README.PSALLOC - IX38211 / U422496 Allows setting of
early allocation (vs. default late allocation) on a per-process basis.

------------------------------

2.09: Why does xlc complain about 'extern char *strcpy()'


The header <string.h> has a strcpy macro that expands strcpy(x,y) to
__strcpy(x,y), and the latter is then used by the compiler to generate
inline code for strcpy.  Because of the macro, your extern declaration
contains an invalid macro expansion.  The real cure is to remove your
extern declaration but adding -U__STR__ to your xlc will also do the
trick, although your program might run a bit more slowly as the compiler
cannot inline the string functions any more.

------------------------------

2.10: Why do I get 'Parameter list cannot contain fewer ....'


This is the same as above (2.9).

------------------------------

2.11: Why does xlc complain about

               '(sometype *)somepointer = something'

Software that is developed using gcc may have this construct. However,
standard C does not permit casts to be lvalues, so you will need to
change the cast and move it to the right side of the assignment. If you
compile with 'cc', removing the cast completely will give you a warning,
'xlc' will give you an error (provided somepointer and something are of
different types - but else, why would the cast be there in the first place?)

------------------------------

2.12: Some more common errors


Here are a few other common errors with xlc:

305 |     switch((((np)->navigation_type) ? (*((np)->navigation_type)) :
      ((void *)0)))
      .a...........  
a - 1506-226: (S) The second and third operands of the conditional
operator must be of the same type.

The reason for this is that xlc defines NULL as (void *)0, and it does
not allow two different types as the second and third operand of ?:. 
The second argument above is not a pointer and the code used NULL
incorrectly as a scalar. NULL is a nil pointer constant in ANSI C and
in some traditional compilers.

You should change NULL in the third argument above to an integer 0.


------------------------------

2.13: Can the compiler generate assembler code?


Starting with version 1.3 of xlc and xlf the -S option will generate a
.s assembly code file prior to optimization. The option -qlist will
generate a human readable one in a .lst file.

There is also a disassembler in /usr/lpp/xlc/bin/dis include with the
1.3 version of xlc (and in /usr/lpp/xlC/bin/dis with the 2.1 version
of xlC) that will disassemble existing object or executable files.

------------------------------

2.14: Curses


Curses based applications should be linked with -lcurses and _not_ with
-ltermlib. It has also been reported that some problems with curses are
avoided if your application is compiled with -DNLS.

Peter Jeffe <peter@ski.austin.ibm.com> also notes:

>the escape sequences for cursor and function keys are *sometimes*
>treated as several characters: eg. the getch() - call does not return
>KEY_UP but 'ESC [ C.'

You're correct in your analysis: this has to do with the timing of the
escape sequence as it arrives from the net. There is an environment
variable called ESCDELAY that can change the fudge factor used to decide
when an escape is just an escape. The default value is 500; boosting
this a bit should solve your problems.

Christopher Carlyle O'Callaghan <asdfjkl@wam.umd.edu> has more comments
concerning extended curses:

1) The sample program in User Interface Programming Concepts, page 7-13
   is WRONG. Here is the correct use of panes and panels.

#include <cur01.h>
#include <cur05.h>

main()
{
PANE *A, *B, *C, *D, *E, *F, *G, *H;
PANEL *P;

initscr();

A = ecbpns (24, 79, NULL, NULL, 0, 2500, Pdivszp, Pbordry, NULL, NULL);
D = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
E = ecbpns (24, 79, D,    NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
B = ecbpns (24, 79, A, D, Pdivtyh, 3000, Pdivszp, Pbordry, NULL, NULL);
F = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
G = ecbpns (24, 79, F,    NULL, 0, 5000, Pdivszp, Pbordry, NULL, NULL);
H = ecbpns (24, 79, G,    NULL, 0, 3000, Pdivszp, Pbordry, NULL, NULL);
C = ecbpns (24, 79, B, F, Pdivtyh, 0, Pdivszf, Pbordry, NULL, NULL);
P = ecbpls (24, 79, 0, 0, "MAIN PANEL", Pdivtyv, Pbordry, A);

ecdvpl (P);
ecdfpl (P, FALSE);
ecshpl (P); 
ecrfpl (P);
endwin();
}

2) DO NOT include <curses.h> and any other <cur0x.h> file together.
   You will get a bunch of redefined statements.

3) There is CURSES and EXTENDED CURSES. Use only one or the other. If the
   manual says that they're backwards compatible or some other indication 
   that you can use CURSES routines with EXTENDED, don't believe it. To 
   use CURSES you need to include <curses.h> and you can't (see above).

4) If you use -lcur and -lcurses in the same link command, you will get
   Memory fault (core dump) error. You CANNOT use both of them at the same
   time. -lcur is for extended curses, -lcurses is for regular curses.

5) When creating PANEs, when you supply a value (other than 0) for the
   'ds' parameter and use Pdivszf value for the 'du' parameter, the 'ds'
   will be ignored (the sample program on page 7-13 in User Interface
   Programming Concepts is wrong.) For reasons as yet undetermined,
   Pdivszc doesn't seem to work (or at least I can't figure out how to
   use it.)

6) If you're running into bugs and can't figure out what is happening,
   try the following:
   include -qextchk -g in your compile line
	-qextchk will check to make sure you're passing the right number of
  	 parameters to the functions
	-g enables debug

7) Do not use 80 as the number of columns if you want to use the whole
   screen. The lower right corner will get erased.  Use 79 instead.

8) If you create a panel, you must create at least 1 pane, otherwise you
   will get a Memory fault (core dump).

9) When creating a panel, if you don't have a border around it, any title
   you want will not show up.

10) to make the screen scroll down:
    wmove (win, 0, 0);
    winsertln (win)

11) delwin(win) doesn't work in EXTENDED WINDOWS

    To make it appear as if a window is deleted, you need to do the following:
    for every window that you want to appear on the screen
	touchwin(win)
	wrefresh(win)

    you must make sure that you do it in the exact same order as you put
    them on the screen (i.e., if you called newwin with A, then C, then B,
    then you must do the loop with A, then C, then B, otherwise you won't
    get the same screen back).  The best thing to do is to put them into
    an array and keep track of the last window index.

12) mvwin(win, line, col) implies that it is only used for viewports and
    subwindows. It can also be used for the actual windows themselves.

13) If you specify the attribute of a window using wcolorout(win), any
    subsequent calls to chgat(numchars, mode) or any of its relatives
    will not work. (or at least they get very picky.)

------------------------------

2.15: How do I speed up linking


Please refer to sections 2.03 and 2.06 above.

From: losecco@undpdk.hep.nd.edu (John LoSecco) and
      hook@chaco.aix.dfw.ibm.com (Gary R. Hook)

From oahu.cern.ch in /pub/aix3 you can get a wrapper for the existing
linker called tld which can reduce link times with large libraries by
factors of 3 to 4.

------------------------------

2.16: What is deadbeef?


When running the debugger (dbx), you may have wondered what the
'deadbeef' is you occasionally see in registers.  Do note, that
0xdeadbeef is a hexadecimal number that also happens to be some kind
of word (the RS/6000 was built in Texas!), and this hexadecimal number
is simply put into unused registers at some time, probably during
program startup.


------------------------------

2.17: How do I make an export list from a library archive?

From: d.dennerline@bull.com (Dave Dennerline)

[ This script has been moved to section 8.10 ]

------------------------------

2.19: Building imake, makedepend

From: crow@austin.ibm.com (David L. Crow)

[Editor's note: if you have AIX 4.x,  you need the X11.adt.imake LPP
and probably most if not all of the X11.adt.* LPPs.  Imake, xmkmf and
other utilities are delivered precompiled.]

    You need X11dev.src release 1.2.3.0 (ie the R5 release) [on AIX 3.2].


     Unless you have an R5 release of AIXwindows, there is no xmkmf.
  These are the steps that I use to make imake, makedepend and all
  of it's config files, and then install them in the working tree
  (ie not the Xamples) for daily use:
  
      cd /usr/lpp/X11/Xamples
      make Makefile
      make SUBDIRS="config util" Makefiles
      make SUBDIRS="config util" linklibs
      make SUBDIRS="config util" depend
      make SUBDIRS="config util" 
      make SUBDIRS="config util" install
      
  Then redo the steps everytime you apply an X11 update.

------------------------------

2.20: How can tell what shared libraries a binary is linked with?


Use "dump -H <execfilename>" and see if anything other than /unix is
listed in the loader section (at the bottom).  The first example is
/bin/sh (statically linked) and the second example is
/usr/local/bin/bash (shared).

INDEX  PATH                          BASE                MEMBER              
0      /usr/lib:/lib                                                         
1      /                             unix                                    

INDEX  PATH                          BASE                MEMBER              
0      ./lib/readline/:./lib/glob/:/usr/lib:/lib               
1                                    libc.a              shr.o               
2                                    libcurses.a         shr.o               

The freeware tool "ldd" lists all the shared libraries needed
by an executable, including those recursively included by other
shared libraries. See question 2.27 "Where can I find ldd for AIX?".

------------------------------

2.21: Can I get a PTF for my C/C++ compiler from the net?


<http://service.software.ibm.com/>  contains pointers to most PTFs, including
compilers.  You'll need the fixdist program (see 1.142) to retrieve them.

------------------------------

2.22: Why does "install"ing software I got from the net fail?


Note that the RS/6000 has two install programs, one with System V flavor
in the default PATH (/etc/install with links from /usr/bin and /usr/usg),
and one with BSD behavior in /usr/ucb/install.

------------------------------

2.23: What is Linker TOC overflow error 12?


There is a hard coded limit in the AIX 3.2.5 linker that is fixed in
AIX 4.1.  A kind soul donated the following information to help people
get the 3.2.5 fix

    The LPS (paperwork) 
      AIX TOC Data Binder/6000 #P91128
      Version 1.1
      Program Number 5799-QDY
      Reference No. GC23-2604-00, FC 5615
    Pre Reqs listed were AIX 3.2.5
      IBM C Set++ V2 (5765-186)

The above is not available any longer, see section 1.006.

You could also put some of the application code into shared libraries
or, in the case of gcc, use -mminimal-toc.

------------------------------

2.24: What is the limit on number of shared memory segments

               I can attach?

Each process has 16 segments.  One is used for private code, one for
stack, one for heap; those, if memory serves, are segments 0, 1, and
2.  (If you look in sys/shm.h, you'll see that SHMLOSEG is 3 -- the
lowest segment, in number and in the process' virtual address space,
available to shmat.)

SHMHISEG, the highest segment you can attach to (also defined in
sys/shm.h), is 12.  Segments 3 through 12 are available to shmat,
giving the 10 segments your program used successfully.  (NSHMSEGS in
sys/shm.h will give you this value, though it's of limited use, since
most platforms that I've seen don't define it.)

Segment 13 is used by shared code your program has attached to;
I think one of the others might be for kernel-mode data.

See also mmap.

------------------------------

2.25: I deleted libc.a by accident --- how do I recover?

From: Ed Ravin <eravin@panix.com>

You can recover from this without rebooting or reinstalling, if you
have another copy of libc.a available that is also named "libc.a".  If
you moved libc.a to a different directory, you're in luck -- do the
following:

export LIBPATH=/other/directory


And your future commands will work.  But if you renamed libc.a, this
won't do it.  If you have an NFS mounted directory somewhere, you can
put libc.a on the that host, and point LIBPATH to that directory as
shown above.

Failing that, turn off your machine, reboot off floppies or other
media, and get a root shell.  I don't think you should do "getrootfs"
as you usually do when accessing the root vg this way -- AIX may start
looking for libc.a on the disk, and you'll just run into the same
problem.  So do an importvg, varyonvg, and then mount /usr somewhere,
then manually move libc.a back or copy in a new one from floppy.

------------------------------

2.26: Where can I find dlopen, dlclose, and dlsym for AIX?


An implementation of these dynamic code loading functions was written by
Jens-Uwe Mager <jum@anubis.han.de> and can be found at
<http://www.han.de/~jum/aix/dlfcn.shar>

From: Gary R. Hook <hook@austin.ibm.com>

Starting with AIX 4.2 a dlopen et. al. are included in the base OS in
the libdl.a library. Under AIX 4.1 this is available as SLHS (Shared
Library Hookable Symbols) as APAR IX IX71849 for the runtime package and
APAR IX IX72973 for the development tools.

------------------------------

2.27: Where can I find ldd for AIX?

From: Jens-Uwe Mager <jum@anubis.han.de>

Try <http://www.han.de/~jum/aix/ldd.c>. Also the "aix.tools"
package from <http://www-frec.bull.com>

------------------------------

2.28: How do I make my program binary executable on the

                POWER, POWER2, and POWERPC architecures?

AIX will emulate those instructions not available in POWERPC processors, but
you can avoid this emulation and consequent performance degradtation by
using only the common to all.

If you are using IBM's xlc (cc) compiler, the default is to use the common
instruction set.  If you want to be explicit, use the -qarch=com option.

The option -mcpu=common makes GCC use the common instruction set.  Please
note that (unlike xlc) this is *not* the default with GCC on AIX.

------------------------------

2.29: How do I access more than 256 Megabytes of memory?


By default each program gets one segment register (see 2.24) for its
data segment. As each segment register covers 256 MB, any calls to
malloc more will fail. Also programs that declare large global or static
arrays may fail to load. To allocate more segment registers to your
program, use the linker option -bmaxdata to specify the number of bytes
you need in the data segment as follows:

cc -o myprog -bmaxdata:0x20000000 myprog.c

The example above would allocate an additional segment register to allow
for 512MB of data.

------------------------------

2.30: How do I use POSIX threads with gcc 2.7.x?

From: David Edelsohn <dje@watson.ibm.com>

The code generated by GCC is compatible with threads, but gcc-2.7 
was released so long ago that it did not provide an option to perform
the extra link steps necessary to support threads:

1) Compile all source files with "-D_THREAD_SAFE" macro defined.
2) Link with "-L/usr/lib/threads -lpthreads -lc_r /usr/lib/libc.a"
   to obtain the pthreads support 
   and add "-nostartfiles /usr/lib/crt0_r.o" to the beginning of the
   link command line (using gcc to link!) to initialize threads.

------------------------------

2.31: Why does pthread_create return the error code 22?


Using Posix threads under AIX requires a special C runtime startup
initialization as well as special versions of some libraries. The IBM C
compiler includes these special libraries if called by the name xlc_r
(or xlC_r for C++). There also other maing variations to support various
defaults, consult the file /etc/xlC.cf for details.

------------------------------

2.32: How do I build programs under a later AIX release that run

	under earlier releases as well?

IBM develops AIX only for binary compatibility with older AIX releases,
not the other way around. You will thus need to build programs on the
oldest AIX release the program is supposed to run on. You will also need
to link programs dynamically, if you link in the system libraries
statically the program will probably only run on the machine you
performed the link on.

With some preparation it is appearently possible to get around that
limitation. Bob Halblutzel has put together a web page describing the
detailed steps how to set up such a build environment at the following
web page:

<http://www.hablutzel.com/aix_compatibility_build.html>

Please not that this is not a supported way to build your programs, you
will probably receive not any support by IBM if you have problems with
that environment.

------------------------------

2.00: C/C++


Contrary to many people's belief, the C environment on the RS/6000 is
not very special.  The C compiler has quite a number of options that can
be used to control how it works, which "dialect" of C it compiles, how
it interprets certain language constructs, etc.  InfoExplorer includes a
Users Guide and a Reference Manual.

The compiler can be invoked with either xlc for strict ANSI mode and cc
for RT compatible mode (i.e. IBM 6150 with AIX 2).  The default options
for each mode are set in the /etc/xlc.cfg file, and you can actually add
another stanza and create a link to the /bin/xlc executable.

The file /usr/lpp/xlc/bin/README.xlc has information about the C
compiler, and the file /usr/lpp/bos/bsdport (AIX 3 only) contains useful
information, in particular for users from a BSD background.

The file /etc/xlc.cfg also shows the symbol _IBMR2 that is predefined,
and therefore can be used for #ifdef'ing RS/6000 specific code.

------------------------------

2.01: I cannot make alloca work


A famous routine, in particular in GNU context, is the allocation
routine alloca().  Alloca allocates memory in such a way that it is
automatically free'd when the block is exited.  Most implementations
does this by adjusting the stack pointer.  Since not all C environments
can support it, its use is discouraged, but it is included in the xlc
compiler.  In order to make the compiler aware that you intend to use
alloca, you must put the line

#pragma alloca

before any other statements in the C source module(s) where alloca is
called.  If you don't do this, xlc will not recognize alloca as anything
special, and you will get errors during linking.

For AIX 3.2, it may be easier to use the -ma flag.

------------------------------

2.02: How do I compile my BSD programs?


The file /usr/lpp/bos/bsdport contains information on how to port
programs written for BSD to AIX 3.  This file may be very useful for
others as well.

A quick cc command for most "standard" BSD programs is:
  
  $ cc -D_BSD -D_BSD_INCLUDES  -o [loadfile] [sourcefile.c] -lbsd

If your software has system calls predefined with no prototype
parameters, also use the -D_NO_PROTO flag.

------------------------------

2.03: Isn't the linker different from what I am used to?


Yes.  It is not at all like what you are used to:

- The order of objects and libraries is normally _not_ important.  The
  linker reads _all_ objects including those from libraries into memory
  and does the actual linking in one go.  Even if you need to put a
  library of your own twice on the ld command line on other systems, it
  is not needed on the RS/6000 - doing so will even make your linking slower.

- One of the features of the linker is that it will replace an object in
  an executable with a new version of the same object:

  $ cc -o prog prog1.o prog2.o prog3.o		# make prog
  $ cc -c prog2.c				# recompile prog2.c
  $ cc -o prog.new prog2.o prog			# make prog.new from prog
						# by replacing prog2.o
  
- The standard C library /lib/libc.a is linked shared, which means that
  the actual code is not linked into your program, but is loaded only
  once and linked dynamically during loading of your program.

- The ld program actually calls the binder in /usr/lib/bind, and you can
  give ld special options to get details about the invocation of the
  binder.  These are found on the ld man page or in InfoExplorer.

- If your program normally links using a number of libraries (.a files),
  you can 'prelink' each of these into an object, which will make your
  final linking faster.  E.g. do:

  $ cc -c prog1.c prog2.c prog3.c
  $ ar cv libprog.a prog1.o prog2.o prog3.o
  $ ld -r -o libprog.o libprog.a
  $ cc -o someprog someprog.c libprog.o

This will solve all internal references between prog1.o, prog2.o and
prog3.o and save this in libprog.o Then using libprog.o to link your
program instead of libprog.a will increase linking speed, and even if
someprog.c only uses, say prog1.o and prog2.o, only those two modules
will be in your final program.  This is also due to the fact that the
binder can handle single objects inside one object module as noted above.

If you are using an -lprog option (for libprog.a) above, and still want
to be able to do so, you should name the prelinked object with a
standard library name, e.g. libprogP.a (P identifying a prelinked
object), that can be specified by -lprogP.  You cannot use the archiver
(ar) on such an object.

You should also have a look at section 3.01 of this article, in
particular if you have mixed Fortran/C programs.

Dave Dennerline (d.dennerline@bull.com) claims that his experiences
in prelinking on AIX does not save much time since most people have
separate libraries which do not have many dependencies between them,
thus not many symbols to resolve.

------------------------------

2.04: How do I statically link my program?


  cc -o prog -bnoso -bI:/lib/syscalls.exp obj1.o obj2.o obj3.o

will do that for a program consisting of the three objects obj1.o, etc.

[Editor's note: You should never link programs statically that are
supposed to leave your local environment, e.g. intended for
distribution. Statically linked programs may fail to work after
installing a new AIX version or even after installing a PTF.]

From: Marc Pawliger (marc@sti.com)

As of AIX 3.2.5, you can install a speedup for AIXwindows called
Shared Memory Transport.  To static link an X application after the
SMT PTF has been installed, you must link with
-bI:/usr/lpp/X11/bin/smt.exp and the executable will NOT run on a
machine where SMT is not installed.  See /usr/lpp/X11/README.SMT

2.05: How do I make my own shared library?


To make your own shared object or library of shared objects, you should
know that a shared object cannot have undefined symbols.  Thus, if your
code uses any externals from /lib/libc.a, the latter MUST be linked with
your code to make a shared object.  Mike Heath (mike@pencom.com) said it
is possible to split code into more than one shared object when externals
in one object refer to another one.  You must be very good at
import/export files.  Perhaps he or someone can provide an example. 

Assume you have one file, sub1.c, containing a routine with no external
references, and another one, sub2.c, calling stuff in /lib/libc.a.  You
will also need two export files, sub1.exp, sub2.exp.  Read the example
below together with the examples on the ld man page. 

---- sub1.c ----
    int addint(int a, int b)
    {
      return a + b;
    }
---- sub2.c ----
    #include <stdio.h>

    void printint(int a)
    {
      printf("The integer is: %d\n", a);
    }
---- sub1.exp ----
    #!
    addint
---- sub2.exp ----
    #!
    printint
---- usesub.c ----
    main()
    {
      printint( addint(5,8) );
    }

The following commands will build your libshr.a, and compile/link the
program usesub to use it.  Note that you need the ld option -lc for
sub2shr.o since it calls printf from /lib/libc.a.  [Note that you can leave
out the "-T512 -H512" on AIX 4. -- Ed.]

  $ cc  -c sub1.c
  $ ld -o sub1shr.o sub1.o -bE:sub1.exp -bM:SRE -T512 -H512 
  $ cc  -c sub2.c
  $ ld -o sub2shr.o sub2.o -bE:sub2.exp -bM:SRE -T512 -H512  -lc
  $ ar r libshr.a sub1shr.o sub2shr.o
  $ cc -o usesub usesub.c -L: libshr.a
  $ usesub
  The integer is: 13
  $

------------------------------

2.06: Linking my program fails with strange errors. Why?


Very simple, the linker (actually called the binder), cannot get the
memory it needs, either because your ulimits are too low or because you
don't have sufficient paging space.  Since the linker is quite different
>from normal Unix linkers and actually does much more than these, it also
uses a lot of virtual memory.  It is not unusual to need 10000 pages (of
4k) or more to execute a fairly complex linking.

If you get 'BUMP error', either ulimits or paging is too low, if you get
'Binder killed by signal 9' your paging is too low.

First, check your memory and data ulimits; in korn shell 'ulimit -a' will
show all limits and 'ulimit -m 99999' and 'ulimit -d 99999' will
increase the maximum memory and data respectively to some high values. 
If this was not your problem, you don't have enough paging space.

If you will or can not increase your paging space, you could try this:

- Do you duplicate libraries on the ld command line? That is never
  necessary.

- Do more users link simultaneously? Try having only one linking going
  on at any time.

- Do a partwise linking, i.e. you link some objects/libraries with the
  -r option to allow the temporary output to have unresolved references,
  then link with the rest of your objects/libraries.  This can be split
  up as much as you want, and will make each step use less virtual memory.

  If you follow this scheme, only adding one object or archive at a
  time, you will actually emulate the behavior of other Unix linkers.

If you decide to add more paging space, you should consider adding a new
paging space on a second hard disk, as opposed to just increasing the
existing one.  Doing the latter could make you run out of free space on
your first harddisk. It is more involved to shrink a paging space
but easier to delete one.

------------------------------

2.07: Why does it take so long to compile "hello world" with xlc?


Some systems have experienced delays of more than 60 seconds in
compiling "#include <stdio.h> int main () {printf ("Hello world");}"
The problem is with the license manager contact IBM to make sure
you've got the latest PTF.

------------------------------

2.08: What's with malloc()?

 
malloc() uses a late allocation algorithm based on 4.3 BSD's malloc()
for speed.  This lets you allocate very large sparse memory spaces,
since the pages are not actually allocated until they are touched for
the first time.  Unfortunately, it doesn't die gracefully in the face of
loss of available memory.  See the "Paging Space Overview" under
InfoExplorer, and see the notes on the linker in this document for an
example of an ungraceful death.

If you want your program to get notified when running out of memory, you
should handle the SIGDANGER signal.  The default is to ignore it. 
SIGDANGER is sent to all processes when paging space gets low, and if
paging space gets even lower, processes with the highest paging space
usage are sent the SIGKILL signal.

malloc() is substantially different in 3.2, allocating memory more
tightly.  If you have problems running re-compiled programs on 3.2,
try running them with MALLOCTYPE=3.1.

Early Page Space Allocation (EPSA) added to AIX 3.2: see
/usr/lpp/bos/README.PSALLOC - IX38211 / U422496 Allows setting of
early allocation (vs. default late allocation) on a per-process basis.

------------------------------

2.09: Why does xlc complain about 'extern char *strcpy()'


The header <string.h> has a strcpy macro that expands strcpy(x,y) to
__strcpy(x,y), and the latter is then used by the compiler to generate
inline code for strcpy.  Because of the macro, your extern declaration
contains an invalid macro expansion.  The real cure is to remove your
extern declaration but adding -U__STR__ to your xlc will also do the
trick, although your program might run a bit more slowly as the compiler
cannot inline the string functions any more.

------------------------------

2.10: Why do I get 'Parameter list cannot contain fewer ....'


This is the same as above (2.9).

------------------------------

2.11: Why does xlc complain about

               '(sometype *)somepointer = something'

Software that is developed using gcc may have this construct. However,
standard C does not permit casts to be lvalues, so you will need to
change the cast and move it to the right side of the assignment. If you
compile with 'cc', removing the cast completely will give you a warning,
'xlc' will give you an error (provided somepointer and something are of
different types - but else, why would the cast be there in the first place?)

------------------------------

2.12: Some more common errors


Here are a few other common errors with xlc:

305 |     switch((((np)->navigation_type) ? (*((np)->navigation_type)) :
      ((void *)0)))
      .a...........  
a - 1506-226: (S) The second and third operands of the conditional
operator must be of the same type.

The reason for this is that xlc defines NULL as (void *)0, and it does
not allow two different types as the second and third operand of ?:. 
The second argument above is not a pointer and the code used NULL
incorrectly as a scalar. NULL is a nil pointer constant in ANSI C and
in some traditional compilers.

You should change NULL in the third argument above to an integer 0.


------------------------------

2.13: Can the compiler generate assembler code?


Starting with version 1.3 of xlc and xlf the -S option will generate a
.s assembly code file prior to optimization. The option -qlist will
generate a human readable one in a .lst file.

There is also a disassembler in /usr/lpp/xlc/bin/dis include with the
1.3 version of xlc (and in /usr/lpp/xlC/bin/dis with the 2.1 version
of xlC) that will disassemble existing object or executable files.

------------------------------

2.14: Curses


Curses based applications should be linked with -lcurses and _not_ with
-ltermlib. It has also been reported that some problems with curses are
avoided if your application is compiled with -DNLS.

Peter Jeffe <peter@ski.austin.ibm.com> also notes:

>the escape sequences for cursor and function keys are *sometimes*
>treated as several characters: eg. the getch() - call does not return
>KEY_UP but 'ESC [ C.'

You're correct in your analysis: this has to do with the timing of the
escape sequence as it arrives from the net. There is an environment
variable called ESCDELAY that can change the fudge factor used to decide
when an escape is just an escape. The default value is 500; boosting
this a bit should solve your problems.

Christopher Carlyle O'Callaghan <asdfjkl@wam.umd.edu> has more comments
concerning extended curses:

1) The sample program in User Interface Programming Concepts, page 7-13
   is WRONG. Here is the correct use of panes and panels.

#include <cur01.h>
#include <cur05.h>

main()
{
PANE *A, *B, *C, *D, *E, *F, *G, *H;
PANEL *P;

initscr();

A = ecbpns (24, 79, NULL, NULL, 0, 2500, Pdivszp, Pbordry, NULL, NULL);
D = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
E = ecbpns (24, 79, D,    NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
B = ecbpns (24, 79, A, D, Pdivtyh, 3000, Pdivszp, Pbordry, NULL, NULL);
F = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
G = ecbpns (24, 79, F,    NULL, 0, 5000, Pdivszp, Pbordry, NULL, NULL);
H = ecbpns (24, 79, G,    NULL, 0, 3000, Pdivszp, Pbordry, NULL, NULL);
C = ecbpns (24, 79, B, F, Pdivtyh, 0, Pdivszf, Pbordry, NULL, NULL);
P = ecbpls (24, 79, 0, 0, "MAIN PANEL", Pdivtyv, Pbordry, A);

ecdvpl (P);
ecdfpl (P, FALSE);
ecshpl (P); 
ecrfpl (P);
endwin();
}

2) DO NOT include <curses.h> and any other <cur0x.h> file together.
   You will get a bunch of redefined statements.

3) There is CURSES and EXTENDED CURSES. Use only one or the other. If the
   manual says that they're backwards compatible or some other indication 
   that you can use CURSES routines with EXTENDED, don't believe it. To 
   use CURSES you need to include <curses.h> and you can't (see above).

4) If you use -lcur and -lcurses in the same link command, you will get
   Memory fault (core dump) error. You CANNOT use both of them at the same
   time. -lcur is for extended curses, -lcurses is for regular curses.

5) When creating PANEs, when you supply a value (other than 0) for the
   'ds' parameter and use Pdivszf value for the 'du' parameter, the 'ds'
   will be ignored (the sample program on page 7-13 in User Interface
   Programming Concepts is wrong.) For reasons as yet undetermined,
   Pdivszc doesn't seem to work (or at least I can't figure out how to
   use it.)

6) If you're running into bugs and can't figure out what is happening,
   try the following:
   include -qextchk -g in your compile line
	-qextchk will check to make sure you're passing the right number of
  	 parameters to the functions
	-g enables debug

7) Do not use 80 as the number of columns if you want to use the whole
   screen. The lower right corner will get erased.  Use 79 instead.

8) If you create a panel, you must create at least 1 pane, otherwise you
   will get a Memory fault (core dump).

9) When creating a panel, if you don't have a border around it, any title
   you want will not show up.

10) to make the screen scroll down:
    wmove (win, 0, 0);
    winsertln (win)

11) delwin(win) doesn't work in EXTENDED WINDOWS

    To make it appear as if a window is deleted, you need to do the following:
    for every window that you want to appear on the screen
	touchwin(win)
	wrefresh(win)

    you must make sure that you do it in the exact same order as you put
    them on the screen (i.e., if you called newwin with A, then C, then B,
    then you must do the loop with A, then C, then B, otherwise you won't
    get the same screen back).  The best thing to do is to put them into
    an array and keep track of the last window index.

12) mvwin(win, line, col) implies that it is only used for viewports and
    subwindows. It can also be used for the actual windows themselves.

13) If you specify the attribute of a window using wcolorout(win), any
    subsequent calls to chgat(numchars, mode) or any of its relatives
    will not work. (or at least they get very picky.)

------------------------------

2.15: How do I speed up linking


Please refer to sections 2.03 and 2.06 above.

From: losecco@undpdk.hep.nd.edu (John LoSecco) and
      hook@chaco.aix.dfw.ibm.com (Gary R. Hook)

From oahu.cern.ch in /pub/aix3 you can get a wrapper for the existing
linker called tld which can reduce link times with large libraries by
factors of 3 to 4.

------------------------------

2.16: What is deadbeef?


When running the debugger (dbx), you may have wondered what the
'deadbeef' is you occasionally see in registers.  Do note, that
0xdeadbeef is a hexadecimal number that also happens to be some kind
of word (the RS/6000 was built in Texas!), and this hexadecimal number
is simply put into unused registers at some time, probably during
program startup.


------------------------------

2.17: How do I make an export list from a library archive?

From: d.dennerline@bull.com (Dave Dennerline)

[ This script has been moved to section 8.10 ]

------------------------------

2.19: Building imake, makedepend

From: crow@austin.ibm.com (David L. Crow)

[Editor's note: if you have AIX 4.x,  you need the X11.adt.imake LPP
and probably most if not all of the X11.adt.* LPPs.  Imake, xmkmf and
other utilities are delivered precompiled.]

    You need X11dev.src release 1.2.3.0 (ie the R5 release) [on AIX 3.2].


     Unless you have an R5 release of AIXwindows, there is no xmkmf.
  These are the steps that I use to make imake, makedepend and all
  of it's config files, and then install them in the working tree
  (ie not the Xamples) for daily use:
  
      cd /usr/lpp/X11/Xamples
      make Makefile
      make SUBDIRS="config util" Makefiles
      make SUBDIRS="config util" linklibs
      make SUBDIRS="config util" depend
      make SUBDIRS="config util" 
      make SUBDIRS="config util" install
      
  Then redo the steps everytime you apply an X11 update.

------------------------------

2.20: How can tell what shared libraries a binary is linked with?


Use "dump -H <execfilename>" and see if anything other than /unix is
listed in the loader section (at the bottom).  The first example is
/bin/sh (statically linked) and the second example is
/usr/local/bin/bash (shared).

INDEX  PATH                          BASE                MEMBER              
0      /usr/lib:/lib                                                         
1      /                             unix                                    

INDEX  PATH                          BASE                MEMBER              
0      ./lib/readline/:./lib/glob/:/usr/lib:/lib               
1                                    libc.a              shr.o               
2                                    libcurses.a         shr.o               

The freeware tool "ldd" lists all the shared libraries needed
by an executable, including those recursively included by other
shared libraries. See question 2.27 "Where can I find ldd for AIX?".

------------------------------

2.21: Can I get a PTF for my C/C++ compiler from the net?


<http://service.software.ibm.com/>  contains pointers to most PTFs, including
compilers.  You'll need the fixdist program (see 1.142) to retrieve them.

------------------------------

2.22: Why does "install"ing software I got from the net fail?


Note that the RS/6000 has two install programs, one with System V flavor
in the default PATH (/etc/install with links from /usr/bin and /usr/usg),
and one with BSD behavior in /usr/ucb/install.

------------------------------

2.23: What is Linker TOC overflow error 12?


There is a hard coded limit in the AIX 3.2.5 linker that is fixed in
AIX 4.1.  A kind soul donated the following information to help people
get the 3.2.5 fix

    The LPS (paperwork) 
      AIX TOC Data Binder/6000 #P91128
      Version 1.1
      Program Number 5799-QDY
      Reference No. GC23-2604-00, FC 5615
    Pre Reqs listed were AIX 3.2.5
      IBM C Set++ V2 (5765-186)

The above is not available any longer, see section 1.006.

You could also put some of the application code into shared libraries
or, in the case of gcc, use -mminimal-toc.

------------------------------

2.24: What is the limit on number of shared memory segments

               I can attach?

Each process has 16 segments.  One is used for private code, one for
stack, one for heap; those, if memory serves, are segments 0, 1, and
2.  (If you look in sys/shm.h, you'll see that SHMLOSEG is 3 -- the
lowest segment, in number and in the process' virtual address space,
available to shmat.)

SHMHISEG, the highest segment you can attach to (also defined in
sys/shm.h), is 12.  Segments 3 through 12 are available to shmat,
giving the 10 segments your program used successfully.  (NSHMSEGS in
sys/shm.h will give you this value, though it's of limited use, since
most platforms that I've seen don't define it.)

Segment 13 is used by shared code your program has attached to;
I think one of the others might be for kernel-mode data.

See also mmap.

------------------------------

2.25: I deleted libc.a by accident --- how do I recover?

From: Ed Ravin <eravin@panix.com>

You can recover from this without rebooting or reinstalling, if you
have another copy of libc.a available that is also named "libc.a".  If
you moved libc.a to a different directory, you're in luck -- do the
following:

export LIBPATH=/other/directory


And your future commands will work.  But if you renamed libc.a, this
won't do it.  If you have an NFS mounted directory somewhere, you can
put libc.a on the that host, and point LIBPATH to that directory as
shown above.

Failing that, turn off your machine, reboot off floppies or other
media, and get a root shell.  I don't think you should do "getrootfs"
as you usually do when accessing the root vg this way -- AIX may start
looking for libc.a on the disk, and you'll just run into the same
problem.  So do an importvg, varyonvg, and then mount /usr somewhere,
then manually move libc.a back or copy in a new one from floppy.

------------------------------

2.26: Where can I find dlopen, dlclose, and dlsym for AIX?


An implementation of these dynamic code loading functions was written by
Jens-Uwe Mager <jum@anubis.han.de> and can be found at
<http://www.han.de/~jum/aix/dlfcn.shar>

From: Gary R. Hook <hook@austin.ibm.com>

Starting with AIX 4.2 a dlopen et. al. are included in the base OS in
the libdl.a library. Under AIX 4.1 this is available as SLHS (Shared
Library Hookable Symbols) as APAR IX IX71849 for the runtime package and
APAR IX IX72973 for the development tools.

------------------------------

2.27: Where can I find ldd for AIX?

From: Jens-Uwe Mager <jum@anubis.han.de>

Try <http://www.han.de/~jum/aix/ldd.c>. Also the "aix.tools"
package from <http://www-frec.bull.com>

------------------------------

2.28: How do I make my program binary executable on the

                POWER, POWER2, and POWERPC architecures?

AIX will emulate those instructions not available in POWERPC processors, but
you can avoid this emulation and consequent performance degradtation by
using only the common to all.

If you are using IBM's xlc (cc) compiler, the default is to use the common
instruction set.  If you want to be explicit, use the -qarch=com option.

The option -mcpu=common makes GCC use the common instruction set.  Please
note that (unlike xlc) this is *not* the default with GCC on AIX.

------------------------------

2.29: How do I access more than 256 Megabytes of memory?


By default each program gets one segment register (see 2.24) for its
data segment. As each segment register covers 256 MB, any calls to
malloc more will fail. Also programs that declare large global or static
arrays may fail to load. To allocate more segment registers to your
program, use the linker option -bmaxdata to specify the number of bytes
you need in the data segment as follows:

cc -o myprog -bmaxdata:0x20000000 myprog.c

The example above would allocate an additional segment register to allow
for 512MB of data.

------------------------------

2.30: How do I use POSIX threads with gcc 2.7.x?

From: David Edelsohn <dje@watson.ibm.com>

The code generated by GCC is compatible with threads, but gcc-2.7 
was released so long ago that it did not provide an option to perform
the extra link steps necessary to support threads:

1) Compile all source files with "-D_THREAD_SAFE" macro defined.
2) Link with "-L/usr/lib/threads -lpthreads -lc_r /usr/lib/libc.a"
   to obtain the pthreads support 
   and add "-nostartfiles /usr/lib/crt0_r.o" to the beginning of the
   link command line (using gcc to link!) to initialize threads.

------------------------------

2.31: Why does pthread_create return the error code 22?


Using Posix threads under AIX requires a special C runtime startup
initialization as well as special versions of some libraries. The IBM C
compiler includes these special libraries if called by the name xlc_r
(or xlC_r for C++). There also other maing variations to support various
defaults, consult the file /etc/xlC.cf for details.

------------------------------

2.32: How do I build programs under a later AIX release that run

	under earlier releases as well?

IBM develops AIX only for binary compatibility with older AIX releases,
not the other way around. You will thus need to build programs on the
oldest AIX release the program is supposed to run on. You will also need
to link programs dynamically, if you link in the system libraries
statically the program will probably only run on the machine you
performed the link on.

With some preparation it is appearently possible to get around that
limitation. Bob Halblutzel has put together a web page describing the
detailed steps how to set up such a build environment at the following
web page:

<http://www.hablutzel.com/aix_compatibility_build.html>

Please not that this is not a supported way to build your programs, you
will probably receive not any support by IBM if you have problems with
that environment.

------------------------------

2.00: C/C++


Contrary to many people's belief, the C environment on the RS/6000 is
not very special.  The C compiler has quite a number of options that can
be used to control how it works, which "dialect" of C it compiles, how
it interprets certain language constructs, etc.  InfoExplorer includes a
Users Guide and a Reference Manual.

The compiler can be invoked with either xlc for strict ANSI mode and cc
for RT compatible mode (i.e. IBM 6150 with AIX 2).  The default options
for each mode are set in the /etc/xlc.cfg file, and you can actually add
another stanza and create a link to the /bin/xlc executable.

The file /usr/lpp/xlc/bin/README.xlc has information about the C
compiler, and the file /usr/lpp/bos/bsdport (AIX 3 only) contains useful
information, in particular for users from a BSD background.

The file /etc/xlc.cfg also shows the symbol _IBMR2 that is predefined,
and therefore can be used for #ifdef'ing RS/6000 specific code.

------------------------------

2.01: I cannot make alloca work


A famous routine, in particular in GNU context, is the allocation
routine alloca().  Alloca allocates memory in such a way that it is
automatically free'd when the block is exited.  Most implementations
does this by adjusting the stack pointer.  Since not all C environments
can support it, its use is discouraged, but it is included in the xlc
compiler.  In order to make the compiler aware that you intend to use
alloca, you must put the line

#pragma alloca

before any other statements in the C source module(s) where alloca is
called.  If you don't do this, xlc will not recognize alloca as anything
special, and you will get errors during linking.

For AIX 3.2, it may be easier to use the -ma flag.

------------------------------

2.02: How do I compile my BSD programs?


The file /usr/lpp/bos/bsdport contains information on how to port
programs written for BSD to AIX 3.  This file may be very useful for
others as well.

A quick cc command for most "standard" BSD programs is:
  
  $ cc -D_BSD -D_BSD_INCLUDES  -o [loadfile] [sourcefile.c] -lbsd

If your software has system calls predefined with no prototype
parameters, also use the -D_NO_PROTO flag.

------------------------------

2.03: Isn't the linker different from what I am used to?


Yes.  It is not at all like what you are used to:

- The order of objects and libraries is normally _not_ important.  The
  linker reads _all_ objects including those from libraries into memory
  and does the actual linking in one go.  Even if you need to put a
  library of your own twice on the ld command line on other systems, it
  is not needed on the RS/6000 - doing so will even make your linking slower.

- One of the features of the linker is that it will replace an object in
  an executable with a new version of the same object:

  $ cc -o prog prog1.o prog2.o prog3.o		# make prog
  $ cc -c prog2.c				# recompile prog2.c
  $ cc -o prog.new prog2.o prog			# make prog.new from prog
						# by replacing prog2.o
  
- The standard C library /lib/libc.a is linked shared, which means that
  the actual code is not linked into your program, but is loaded only
  once and linked dynamically during loading of your program.

- The ld program actually calls the binder in /usr/lib/bind, and you can
  give ld special options to get details about the invocation of the
  binder.  These are found on the ld man page or in InfoExplorer.

- If your program normally links using a number of libraries (.a files),
  you can 'prelink' each of these into an object, which will make your
  final linking faster.  E.g. do:

  $ cc -c prog1.c prog2.c prog3.c
  $ ar cv libprog.a prog1.o prog2.o prog3.o
  $ ld -r -o libprog.o libprog.a
  $ cc -o someprog someprog.c libprog.o

This will solve all internal references between prog1.o, prog2.o and
prog3.o and save this in libprog.o Then using libprog.o to link your
program instead of libprog.a will increase linking speed, and even if
someprog.c only uses, say prog1.o and prog2.o, only those two modules
will be in your final program.  This is also due to the fact that the
binder can handle single objects inside one object module as noted above.

If you are using an -lprog option (for libprog.a) above, and still want
to be able to do so, you should name the prelinked object with a
standard library name, e.g. libprogP.a (P identifying a prelinked
object), that can be specified by -lprogP.  You cannot use the archiver
(ar) on such an object.

You should also have a look at section 3.01 of this article, in
particular if you have mixed Fortran/C programs.

Dave Dennerline (d.dennerline@bull.com) claims that his experiences
in prelinking on AIX does not save much time since most people have
separate libraries which do not have many dependencies between them,
thus not many symbols to resolve.

------------------------------

2.04: How do I statically link my program?


  cc -o prog -bnoso -bI:/lib/syscalls.exp obj1.o obj2.o obj3.o

will do that for a program consisting of the three objects obj1.o, etc.

[Editor's note: You should never link programs statically that are
supposed to leave your local environment, e.g. intended for
distribution. Statically linked programs may fail to work after
installing a new AIX version or even after installing a PTF.]

From: Marc Pawliger (marc@sti.com)

As of AIX 3.2.5, you can install a speedup for AIXwindows called
Shared Memory Transport.  To static link an X application after the
SMT PTF has been installed, you must link with
-bI:/usr/lpp/X11/bin/smt.exp and the executable will NOT run on a
machine where SMT is not installed.  See /usr/lpp/X11/README.SMT

2.05: How do I make my own shared library?


To make your own shared object or library of shared objects, you should
know that a shared object cannot have undefined symbols.  Thus, if your
code uses any externals from /lib/libc.a, the latter MUST be linked with
your code to make a shared object.  Mike Heath (mike@pencom.com) said it
is possible to split code into more than one shared object when externals
in one object refer to another one.  You must be very good at
import/export files.  Perhaps he or someone can provide an example. 

Assume you have one file, sub1.c, containing a routine with no external
references, and another one, sub2.c, calling stuff in /lib/libc.a.  You
will also need two export files, sub1.exp, sub2.exp.  Read the example
below together with the examples on the ld man page. 

---- sub1.c ----
    int addint(int a, int b)
    {
      return a + b;
    }
---- sub2.c ----
    #include <stdio.h>

    void printint(int a)
    {
      printf("The integer is: %d\n", a);
    }
---- sub1.exp ----
    #!
    addint
---- sub2.exp ----
    #!
    printint
---- usesub.c ----
    main()
    {
      printint( addint(5,8) );
    }

The following commands will build your libshr.a, and compile/link the
program usesub to use it.  Note that you need the ld option -lc for
sub2shr.o since it calls printf from /lib/libc.a.  [Note that you can leave
out the "-T512 -H512" on AIX 4. -- Ed.]

  $ cc  -c sub1.c
  $ ld -o sub1shr.o sub1.o -bE:sub1.exp -bM:SRE -T512 -H512 
  $ cc  -c sub2.c
  $ ld -o sub2shr.o sub2.o -bE:sub2.exp -bM:SRE -T512 -H512  -lc
  $ ar r libshr.a sub1shr.o sub2shr.o
  $ cc -o usesub usesub.c -L: libshr.a
  $ usesub
  The integer is: 13
  $

------------------------------

2.06: Linking my program fails with strange errors. Why?


Very simple, the linker (actually called the binder), cannot get the
memory it needs, either because your ulimits are too low or because you
don't have sufficient paging space.  Since the linker is quite different
>from normal Unix linkers and actually does much more than these, it also
uses a lot of virtual memory.  It is not unusual to need 10000 pages (of
4k) or more to execute a fairly complex linking.

If you get 'BUMP error', either ulimits or paging is too low, if you get
'Binder killed by signal 9' your paging is too low.

First, check your memory and data ulimits; in korn shell 'ulimit -a' will
show all limits and 'ulimit -m 99999' and 'ulimit -d 99999' will
increase the maximum memory and data respectively to some high values. 
If this was not your problem, you don't have enough paging space.

If you will or can not increase your paging space, you could try this:

- Do you duplicate libraries on the ld command line? That is never
  necessary.

- Do more users link simultaneously? Try having only one linking going
  on at any time.

- Do a partwise linking, i.e. you link some objects/libraries with the
  -r option to allow the temporary output to have unresolved references,
  then link with the rest of your objects/libraries.  This can be split
  up as much as you want, and will make each step use less virtual memory.

  If you follow this scheme, only adding one object or archive at a
  time, you will actually emulate the behavior of other Unix linkers.

If you decide to add more paging space, you should consider adding a new
paging space on a second hard disk, as opposed to just increasing the
existing one.  Doing the latter could make you run out of free space on
your first harddisk. It is more involved to shrink a paging space
but easier to delete one.

------------------------------

2.07: Why does it take so long to compile "hello world" with xlc?


Some systems have experienced delays of more than 60 seconds in
compiling "#include <stdio.h> int main () {printf ("Hello world");}"
The problem is with the license manager contact IBM to make sure
you've got the latest PTF.

------------------------------

2.08: What's with malloc()?

 
malloc() uses a late allocation algorithm based on 4.3 BSD's malloc()
for speed.  This lets you allocate very large sparse memory spaces,
since the pages are not actually allocated until they are touched for
the first time.  Unfortunately, it doesn't die gracefully in the face of
loss of available memory.  See the "Paging Space Overview" under
InfoExplorer, and see the notes on the linker in this document for an
example of an ungraceful death.

If you want your program to get notified when running out of memory, you
should handle the SIGDANGER signal.  The default is to ignore it. 
SIGDANGER is sent to all processes when paging space gets low, and if
paging space gets even lower, processes with the highest paging space
usage are sent the SIGKILL signal.

malloc() is substantially different in 3.2, allocating memory more
tightly.  If you have problems running re-compiled programs on 3.2,
try running them with MALLOCTYPE=3.1.

Early Page Space Allocation (EPSA) added to AIX 3.2: see
/usr/lpp/bos/README.PSALLOC - IX38211 / U422496 Allows setting of
early allocation (vs. default late allocation) on a per-process basis.

------------------------------

2.09: Why does xlc complain about 'extern char *strcpy()'


The header <string.h> has a strcpy macro that expands strcpy(x,y) to
__strcpy(x,y), and the latter is then used by the compiler to generate
inline code for strcpy.  Because of the macro, your extern declaration
contains an invalid macro expansion.  The real cure is to remove your
extern declaration but adding -U__STR__ to your xlc will also do the
trick, although your program might run a bit more slowly as the compiler
cannot inline the string functions any more.

------------------------------

2.10: Why do I get 'Parameter list cannot contain fewer ....'


This is the same as above (2.9).

------------------------------

2.11: Why does xlc complain about

               '(sometype *)somepointer = something'

Software that is developed using gcc may have this construct. However,
standard C does not permit casts to be lvalues, so you will need to
change the cast and move it to the right side of the assignment. If you
compile with 'cc', removing the cast completely will give you a warning,
'xlc' will give you an error (provided somepointer and something are of
different types - but else, why would the cast be there in the first place?)

------------------------------

2.12: Some more common errors


Here are a few other common errors with xlc:

305 |     switch((((np)->navigation_type) ? (*((np)->navigation_type)) :
      ((void *)0)))
      .a...........  
a - 1506-226: (S) The second and third operands of the conditional
operator must be of the same type.

The reason for this is that xlc defines NULL as (void *)0, and it does
not allow two different types as the second and third operand of ?:. 
The second argument above is not a pointer and the code used NULL
incorrectly as a scalar. NULL is a nil pointer constant in ANSI C and
in some traditional compilers.

You should change NULL in the third argument above to an integer 0.


------------------------------

2.13: Can the compiler generate assembler code?


Starting with version 1.3 of xlc and xlf the -S option will generate a
.s assembly code file prior to optimization. The option -qlist will
generate a human readable one in a .lst file.

There is also a disassembler in /usr/lpp/xlc/bin/dis include with the
1.3 version of xlc (and in /usr/lpp/xlC/bin/dis with the 2.1 version
of xlC) that will disassemble existing object or executable files.

------------------------------

2.14: Curses


Curses based applications should be linked with -lcurses and _not_ with
-ltermlib. It has also been reported that some problems with curses are
avoided if your application is compiled with -DNLS.

Peter Jeffe <peter@ski.austin.ibm.com> also notes:

>the escape sequences for cursor and function keys are *sometimes*
>treated as several characters: eg. the getch() - call does not return
>KEY_UP but 'ESC [ C.'

You're correct in your analysis: this has to do with the timing of the
escape sequence as it arrives from the net. There is an environment
variable called ESCDELAY that can change the fudge factor used to decide
when an escape is just an escape. The default value is 500; boosting
this a bit should solve your problems.

Christopher Carlyle O'Callaghan <asdfjkl@wam.umd.edu> has more comments
concerning extended curses:

1) The sample program in User Interface Programming Concepts, page 7-13
   is WRONG. Here is the correct use of panes and panels.

#include <cur01.h>
#include <cur05.h>

main()
{
PANE *A, *B, *C, *D, *E, *F, *G, *H;
PANEL *P;

initscr();

A = ecbpns (24, 79, NULL, NULL, 0, 2500, Pdivszp, Pbordry, NULL, NULL);
D = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
E = ecbpns (24, 79, D,    NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
B = ecbpns (24, 79, A, D, Pdivtyh, 3000, Pdivszp, Pbordry, NULL, NULL);
F = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
G = ecbpns (24, 79, F,    NULL, 0, 5000, Pdivszp, Pbordry, NULL, NULL);
H = ecbpns (24, 79, G,    NULL, 0, 3000, Pdivszp, Pbordry, NULL, NULL);
C = ecbpns (24, 79, B, F, Pdivtyh, 0, Pdivszf, Pbordry, NULL, NULL);
P = ecbpls (24, 79, 0, 0, "MAIN PANEL", Pdivtyv, Pbordry, A);

ecdvpl (P);
ecdfpl (P, FALSE);
ecshpl (P); 
ecrfpl (P);
endwin();
}

2) DO NOT include <curses.h> and any other <cur0x.h> file together.
   You will get a bunch of redefined statements.

3) There is CURSES and EXTENDED CURSES. Use only one or the other. If the
   manual says that they're backwards compatible or some other indication 
   that you can use CURSES routines with EXTENDED, don't believe it. To 
   use CURSES you need to include <curses.h> and you can't (see above).

4) If you use -lcur and -lcurses in the same link command, you will get
   Memory fault (core dump) error. You CANNOT use both of them at the same
   time. -lcur is for extended curses, -lcurses is for regular curses.

5) When creating PANEs, when you supply a value (other than 0) for the
   'ds' parameter and use Pdivszf value for the 'du' parameter, the 'ds'
   will be ignored (the sample program on page 7-13 in User Interface
   Programming Concepts is wrong.) For reasons as yet undetermined,
   Pdivszc doesn't seem to work (or at least I can't figure out how to
   use it.)

6) If you're running into bugs and can't figure out what is happening,
   try the following:
   include -qextchk -g in your compile line
	-qextchk will check to make sure you're passing the right number of
  	 parameters to the functions
	-g enables debug

7) Do not use 80 as the number of columns if you want to use the whole
   screen. The lower right corner will get erased.  Use 79 instead.

8) If you create a panel, you must create at least 1 pane, otherwise you
   will get a Memory fault (core dump).

9) When creating a panel, if you don't have a border around it, any title
   you want will not show up.

10) to make the screen scroll down:
    wmove (win, 0, 0);
    winsertln (win)

11) delwin(win) doesn't work in EXTENDED WINDOWS

    To make it appear as if a window is deleted, you need to do the following:
    for every window that you want to appear on the screen
	touchwin(win)
	wrefresh(win)

    you must make sure that you do it in the exact same order as you put
    them on the screen (i.e., if you called newwin with A, then C, then B,
    then you must do the loop with A, then C, then B, otherwise you won't
    get the same screen back).  The best thing to do is to put them into
    an array and keep track of the last window index.

12) mvwin(win, line, col) implies that it is only used for viewports and
    subwindows. It can also be used for the actual windows themselves.

13) If you specify the attribute of a window using wcolorout(win), any
    subsequent calls to chgat(numchars, mode) or any of its relatives
    will not work. (or at least they get very picky.)

------------------------------

2.15: How do I speed up linking


Please refer to sections 2.03 and 2.06 above.

From: losecco@undpdk.hep.nd.edu (John LoSecco) and
      hook@chaco.aix.dfw.ibm.com (Gary R. Hook)

From oahu.cern.ch in /pub/aix3 you can get a wrapper for the existing
linker called tld which can reduce link times with large libraries by
factors of 3 to 4.

------------------------------

2.16: What is deadbeef?


When running the debugger (dbx), you may have wondered what the
'deadbeef' is you occasionally see in registers.  Do note, that
0xdeadbeef is a hexadecimal number that also happens to be some kind
of word (the RS/6000 was built in Texas!), and this hexadecimal number
is simply put into unused registers at some time, probably during
program startup.


------------------------------

2.17: How do I make an export list from a library archive?

From: d.dennerline@bull.com (Dave Dennerline)

[ This script has been moved to section 8.10 ]

------------------------------

2.19: Building imake, makedepend

From: crow@austin.ibm.com (David L. Crow)

[Editor's note: if you have AIX 4.x,  you need the X11.adt.imake LPP
and probably most if not all of the X11.adt.* LPPs.  Imake, xmkmf and
other utilities are delivered precompiled.]

    You need X11dev.src release 1.2.3.0 (ie the R5 release) [on AIX 3.2].


     Unless you have an R5 release of AIXwindows, there is no xmkmf.
  These are the steps that I use to make imake, makedepend and all
  of it's config files, and then install them in the working tree
  (ie not the Xamples) for daily use:
  
      cd /usr/lpp/X11/Xamples
      make Makefile
      make SUBDIRS="config util" Makefiles
      make SUBDIRS="config util" linklibs
      make SUBDIRS="config util" depend
      make SUBDIRS="config util" 
      make SUBDIRS="config util" install
      
  Then redo the steps everytime you apply an X11 update.

------------------------------

2.20: How can tell what shared libraries a binary is linked with?


Use "dump -H <execfilename>" and see if anything other than /unix is
listed in the loader section (at the bottom).  The first example is
/bin/sh (statically linked) and the second example is
/usr/local/bin/bash (shared).

INDEX  PATH                          BASE                MEMBER              
0      /usr/lib:/lib                                                         
1      /                             unix                                    

INDEX  PATH                          BASE                MEMBER              
0      ./lib/readline/:./lib/glob/:/usr/lib:/lib               
1                                    libc.a              shr.o               
2                                    libcurses.a         shr.o               

The freeware tool "ldd" lists all the shared libraries needed
by an executable, including those recursively included by other
shared libraries. See question 2.27 "Where can I find ldd for AIX?".

------------------------------

2.21: Can I get a PTF for my C/C++ compiler from the net?


<http://service.software.ibm.com/>  contains pointers to most PTFs, including
compilers.  You'll need the fixdist program (see 1.142) to retrieve them.

------------------------------

2.22: Why does "install"ing software I got from the net fail?


Note that the RS/6000 has two install programs, one with System V flavor
in the default PATH (/etc/install with links from /usr/bin and /usr/usg),
and one with BSD behavior in /usr/ucb/install.

------------------------------

2.23: What is Linker TOC overflow error 12?


There is a hard coded limit in the AIX 3.2.5 linker that is fixed in
AIX 4.1.  A kind soul donated the following information to help people
get the 3.2.5 fix

    The LPS (paperwork) 
      AIX TOC Data Binder/6000 #P91128
      Version 1.1
      Program Number 5799-QDY
      Reference No. GC23-2604-00, FC 5615
    Pre Reqs listed were AIX 3.2.5
      IBM C Set++ V2 (5765-186)

The above is not available any longer, see section 1.006.

You could also put some of the application code into shared libraries
or, in the case of gcc, use -mminimal-toc.

------------------------------

2.24: What is the limit on number of shared memory segments

               I can attach?

Each process has 16 segments.  One is used for private code, one for
stack, one for heap; those, if memory serves, are segments 0, 1, and
2.  (If you look in sys/shm.h, you'll see that SHMLOSEG is 3 -- the
lowest segment, in number and in the process' virtual address space,
available to shmat.)

SHMHISEG, the highest segment you can attach to (also defined in
sys/shm.h), is 12.  Segments 3 through 12 are available to shmat,
giving the 10 segments your program used successfully.  (NSHMSEGS in
sys/shm.h will give you this value, though it's of limited use, since
most platforms that I've seen don't define it.)

Segment 13 is used by shared code your program has attached to;
I think one of the others might be for kernel-mode data.

See also mmap.

------------------------------

2.25: I deleted libc.a by accident --- how do I recover?

From: Ed Ravin <eravin@panix.com>

You can recover from this without rebooting or reinstalling, if you
have another copy of libc.a available that is also named "libc.a".  If
you moved libc.a to a different directory, you're in luck -- do the
following:

export LIBPATH=/other/directory


And your future commands will work.  But if you renamed libc.a, this
won't do it.  If you have an NFS mounted directory somewhere, you can
put libc.a on the that host, and point LIBPATH to that directory as
shown above.

Failing that, turn off your machine, reboot off floppies or other
media, and get a root shell.  I don't think you should do "getrootfs"
as you usually do when accessing the root vg this way -- AIX may start
looking for libc.a on the disk, and you'll just run into the same
problem.  So do an importvg, varyonvg, and then mount /usr somewhere,
then manually move libc.a back or copy in a new one from floppy.

------------------------------

2.26: Where can I find dlopen, dlclose, and dlsym for AIX?


An implementation of these dynamic code loading functions was written by
Jens-Uwe Mager <jum@anubis.han.de> and can be found at
<http://www.han.de/~jum/aix/dlfcn.shar>

From: Gary R. Hook <hook@austin.ibm.com>

Starting with AIX 4.2 a dlopen et. al. are included in the base OS in
the libdl.a library. Under AIX 4.1 this is available as SLHS (Shared
Library Hookable Symbols) as APAR IX IX71849 for the runtime package and
APAR IX IX72973 for the development tools.

------------------------------

2.27: Where can I find ldd for AIX?

From: Jens-Uwe Mager <jum@anubis.han.de>

Try <http://www.han.de/~jum/aix/ldd.c>. Also the "aix.tools"
package from <http://www-frec.bull.com>

------------------------------

2.28: How do I make my program binary executable on the

                POWER, POWER2, and POWERPC architecures?

AIX will emulate those instructions not available in POWERPC processors, but
you can avoid this emulation and consequent performance degradtation by
using only the common to all.

If you are using IBM's xlc (cc) compiler, the default is to use the common
instruction set.  If you want to be explicit, use the -qarch=com option.

The option -mcpu=common makes GCC use the common instruction set.  Please
note that (unlike xlc) this is *not* the default with GCC on AIX.

------------------------------

2.29: How do I access more than 256 Megabytes of memory?


By default each program gets one segment register (see 2.24) for its
data segment. As each segment register covers 256 MB, any calls to
malloc more will fail. Also programs that declare large global or static
arrays may fail to load. To allocate more segment registers to your
program, use the linker option -bmaxdata to specify the number of bytes
you need in the data segment as follows:

cc -o myprog -bmaxdata:0x20000000 myprog.c

The example above would allocate an additional segment register to allow
for 512MB of data.

------------------------------

2.30: How do I use POSIX threads with gcc 2.7.x?

From: David Edelsohn <dje@watson.ibm.com>

The code generated by GCC is compatible with threads, but gcc-2.7 
was released so long ago that it did not provide an option to perform
the extra link steps necessary to support threads:

1) Compile all source files with "-D_THREAD_SAFE" macro defined.
2) Link with "-L/usr/lib/threads -lpthreads -lc_r /usr/lib/libc.a"
   to obtain the pthreads support 
   and add "-nostartfiles /usr/lib/crt0_r.o" to the beginning of the
   link command line (using gcc to link!) to initialize threads.

------------------------------

2.31: Why does pthread_create return the error code 22?


Using Posix threads under AIX requires a special C runtime startup
initialization as well as special versions of some libraries. The IBM C
compiler includes these special libraries if called by the name xlc_r
(or xlC_r for C++). There also other maing variations to support various
defaults, consult the file /etc/xlC.cf for details.

------------------------------

2.32: How do I build programs under a later AIX release that run

	under earlier releases as well?

IBM develops AIX only for binary compatibility with older AIX releases,
not the other way around. You will thus need to build programs on the
oldest AIX release the program is supposed to run on. You will also need
to link programs dynamically, if you link in the system libraries
statically the program will probably only run on the machine you
performed the link on.

With some preparation it is appearently possible to get around that
limitation. Bob Halblutzel has put together a web page describing the
detailed steps how to set up such a build environment at the following
web page:

<http://www.hablutzel.com/aix_compatibility_build.html>

Please not that this is not a supported way to build your programs, you
will probably receive not any support by IBM if you have problems with
that environment.

------------------------------

2.00: C/C++


Contrary to many people's belief, the C environment on the RS/6000 is
not very special.  The C compiler has quite a number of options that can
be used to control how it works, which "dialect" of C it compiles, how
it interprets certain language constructs, etc.  InfoExplorer includes a
Users Guide and a Reference Manual.

The compiler can be invoked with either xlc for strict ANSI mode and cc
for RT compatible mode (i.e. IBM 6150 with AIX 2).  The default options
for each mode are set in the /etc/xlc.cfg file, and you can actually add
another stanza and create a link to the /bin/xlc executable.

The file /usr/lpp/xlc/bin/README.xlc has information about the C
compiler, and the file /usr/lpp/bos/bsdport (AIX 3 only) contains useful
information, in particular for users from a BSD background.

The file /etc/xlc.cfg also shows the symbol _IBMR2 that is predefined,
and therefore can be used for #ifdef'ing RS/6000 specific code.

------------------------------

2.01: I cannot make alloca work


A famous routine, in particular in GNU context, is the allocation
routine alloca().  Alloca allocates memory in such a way that it is
automatically free'd when the block is exited.  Most implementations
does this by adjusting the stack pointer.  Since not all C environments
can support it, its use is discouraged, but it is included in the xlc
compiler.  In order to make the compiler aware that you intend to use
alloca, you must put the line

#pragma alloca

before any other statements in the C source module(s) where alloca is
called.  If you don't do this, xlc will not recognize alloca as anything
special, and you will get errors during linking.

For AIX 3.2, it may be easier to use the -ma flag.

------------------------------

2.02: How do I compile my BSD programs?


The file /usr/lpp/bos/bsdport contains information on how to port
programs written for BSD to AIX 3.  This file may be very useful for
others as well.

A quick cc command for most "standard" BSD programs is:
  
  $ cc -D_BSD -D_BSD_INCLUDES  -o [loadfile] [sourcefile.c] -lbsd

If your software has system calls predefined with no prototype
parameters, also use the -D_NO_PROTO flag.

------------------------------

2.03: Isn't the linker different from what I am used to?


Yes.  It is not at all like what you are used to:

- The order of objects and libraries is normally _not_ important.  The
  linker reads _all_ objects including those from libraries into memory
  and does the actual linking in one go.  Even if you need to put a
  library of your own twice on the ld command line on other systems, it
  is not needed on the RS/6000 - doing so will even make your linking slower.

- One of the features of the linker is that it will replace an object in
  an executable with a new version of the same object:

  $ cc -o prog prog1.o prog2.o prog3.o		# make prog
  $ cc -c prog2.c				# recompile prog2.c
  $ cc -o prog.new prog2.o prog			# make prog.new from prog
						# by replacing prog2.o
  
- The standard C library /lib/libc.a is linked shared, which means that
  the actual code is not linked into your program, but is loaded only
  once and linked dynamically during loading of your program.

- The ld program actually calls the binder in /usr/lib/bind, and you can
  give ld special options to get details about the invocation of the
  binder.  These are found on the ld man page or in InfoExplorer.

- If your program normally links using a number of libraries (.a files),
  you can 'prelink' each of these into an object, which will make your
  final linking faster.  E.g. do:

  $ cc -c prog1.c prog2.c prog3.c
  $ ar cv libprog.a prog1.o prog2.o prog3.o
  $ ld -r -o libprog.o libprog.a
  $ cc -o someprog someprog.c libprog.o

This will solve all internal references between prog1.o, prog2.o and
prog3.o and save this in libprog.o Then using libprog.o to link your
program instead of libprog.a will increase linking speed, and even if
someprog.c only uses, say prog1.o and prog2.o, only those two modules
will be in your final program.  This is also due to the fact that the
binder can handle single objects inside one object module as noted above.

If you are using an -lprog option (for libprog.a) above, and still want
to be able to do so, you should name the prelinked object with a
standard library name, e.g. libprogP.a (P identifying a prelinked
object), that can be specified by -lprogP.  You cannot use the archiver
(ar) on such an object.

You should also have a look at section 3.01 of this article, in
particular if you have mixed Fortran/C programs.

Dave Dennerline (d.dennerline@bull.com) claims that his experiences
in prelinking on AIX does not save much time since most people have
separate libraries which do not have many dependencies between them,
thus not many symbols to resolve.

------------------------------

2.04: How do I statically link my program?


  cc -o prog -bnoso -bI:/lib/syscalls.exp obj1.o obj2.o obj3.o

will do that for a program consisting of the three objects obj1.o, etc.

[Editor's note: You should never link programs statically that are
supposed to leave your local environment, e.g. intended for
distribution. Statically linked programs may fail to work after
installing a new AIX version or even after installing a PTF.]

From: Marc Pawliger (marc@sti.com)

As of AIX 3.2.5, you can install a speedup for AIXwindows called
Shared Memory Transport.  To static link an X application after the
SMT PTF has been installed, you must link with
-bI:/usr/lpp/X11/bin/smt.exp and the executable will NOT run on a
machine where SMT is not installed.  See /usr/lpp/X11/README.SMT

2.05: How do I make my own shared library?


To make your own shared object or library of shared objects, you should
know that a shared object cannot have undefined symbols.  Thus, if your
code uses any externals from /lib/libc.a, the latter MUST be linked with
your code to make a shared object.  Mike Heath (mike@pencom.com) said it
is possible to split code into more than one shared object when externals
in one object refer to another one.  You must be very good at
import/export files.  Perhaps he or someone can provide an example. 

Assume you have one file, sub1.c, containing a routine with no external
references, and another one, sub2.c, calling stuff in /lib/libc.a.  You
will also need two export files, sub1.exp, sub2.exp.  Read the example
below together with the examples on the ld man page. 

---- sub1.c ----
    int addint(int a, int b)
    {
      return a + b;
    }
---- sub2.c ----
    #include <stdio.h>

    void printint(int a)
    {
      printf("The integer is: %d\n", a);
    }
---- sub1.exp ----
    #!
    addint
---- sub2.exp ----
    #!
    printint
---- usesub.c ----
    main()
    {
      printint( addint(5,8) );
    }

The following commands will build your libshr.a, and compile/link the
program usesub to use it.  Note that you need the ld option -lc for
sub2shr.o since it calls printf from /lib/libc.a.  [Note that you can leave
out the "-T512 -H512" on AIX 4. -- Ed.]

  $ cc  -c sub1.c
  $ ld -o sub1shr.o sub1.o -bE:sub1.exp -bM:SRE -T512 -H512 
  $ cc  -c sub2.c
  $ ld -o sub2shr.o sub2.o -bE:sub2.exp -bM:SRE -T512 -H512  -lc
  $ ar r libshr.a sub1shr.o sub2shr.o
  $ cc -o usesub usesub.c -L: libshr.a
  $ usesub
  The integer is: 13
  $

------------------------------

2.06: Linking my program fails with strange errors. Why?


Very simple, the linker (actually called the binder), cannot get the
memory it needs, either because your ulimits are too low or because you
don't have sufficient paging space.  Since the linker is quite different
>from normal Unix linkers and actually does much more than these, it also
uses a lot of virtual memory.  It is not unusual to need 10000 pages (of
4k) or more to execute a fairly complex linking.

If you get 'BUMP error', either ulimits or paging is too low, if you get
'Binder killed by signal 9' your paging is too low.

First, check your memory and data ulimits; in korn shell 'ulimit -a' will
show all limits and 'ulimit -m 99999' and 'ulimit -d 99999' will
increase the maximum memory and data respectively to some high values. 
If this was not your problem, you don't have enough paging space.

If you will or can not increase your paging space, you could try this:

- Do you duplicate libraries on the ld command line? That is never
  necessary.

- Do more users link simultaneously? Try having only one linking going
  on at any time.

- Do a partwise linking, i.e. you link some objects/libraries with the
  -r option to allow the temporary output to have unresolved references,
  then link with the rest of your objects/libraries.  This can be split
  up as much as you want, and will make each step use less virtual memory.

  If you follow this scheme, only adding one object or archive at a
  time, you will actually emulate the behavior of other Unix linkers.

If you decide to add more paging space, you should consider adding a new
paging space on a second hard disk, as opposed to just increasing the
existing one.  Doing the latter could make you run out of free space on
your first harddisk. It is more involved to shrink a paging space
but easier to delete one.

------------------------------

2.07: Why does it take so long to compile "hello world" with xlc?


Some systems have experienced delays of more than 60 seconds in
compiling "#include <stdio.h> int main () {printf ("Hello world");}"
The problem is with the license manager contact IBM to make sure
you've got the latest PTF.

------------------------------

2.08: What's with malloc()?

 
malloc() uses a late allocation algorithm based on 4.3 BSD's malloc()
for speed.  This lets you allocate very large sparse memory spaces,
since the pages are not actually allocated until they are touched for
the first time.  Unfortunately, it doesn't die gracefully in the face of
loss of available memory.  See the "Paging Space Overview" under
InfoExplorer, and see the notes on the linker in this document for an
example of an ungraceful death.

If you want your program to get notified when running out of memory, you
should handle the SIGDANGER signal.  The default is to ignore it. 
SIGDANGER is sent to all processes when paging space gets low, and if
paging space gets even lower, processes with the highest paging space
usage are sent the SIGKILL signal.

malloc() is substantially different in 3.2, allocating memory more
tightly.  If you have problems running re-compiled programs on 3.2,
try running them with MALLOCTYPE=3.1.

Early Page Space Allocation (EPSA) added to AIX 3.2: see
/usr/lpp/bos/README.PSALLOC - IX38211 / U422496 Allows setting of
early allocation (vs. default late allocation) on a per-process basis.

------------------------------

2.09: Why does xlc complain about 'extern char *strcpy()'


The header <string.h> has a strcpy macro that expands strcpy(x,y) to
__strcpy(x,y), and the latter is then used by the compiler to generate
inline code for strcpy.  Because of the macro, your extern declaration
contains an invalid macro expansion.  The real cure is to remove your
extern declaration but adding -U__STR__ to your xlc will also do the
trick, although your program might run a bit more slowly as the compiler
cannot inline the string functions any more.

------------------------------

2.10: Why do I get 'Parameter list cannot contain fewer ....'


This is the same as above (2.9).

------------------------------

2.11: Why does xlc complain about

               '(sometype *)somepointer = something'

Software that is developed using gcc may have this construct. However,
standard C does not permit casts to be lvalues, so you will need to
change the cast and move it to the right side of the assignment. If you
compile with 'cc', removing the cast completely will give you a warning,
'xlc' will give you an error (provided somepointer and something are of
different types - but else, why would the cast be there in the first place?)

------------------------------

2.12: Some more common errors


Here are a few other common errors with xlc:

305 |     switch((((np)->navigation_type) ? (*((np)->navigation_type)) :
      ((void *)0)))
      .a...........  
a - 1506-226: (S) The second and third operands of the conditional
operator must be of the same type.

The reason for this is that xlc defines NULL as (void *)0, and it does
not allow two different types as the second and third operand of ?:. 
The second argument above is not a pointer and the code used NULL
incorrectly as a scalar. NULL is a nil pointer constant in ANSI C and
in some traditional compilers.

You should change NULL in the third argument above to an integer 0.


------------------------------

2.13: Can the compiler generate assembler code?


Starting with version 1.3 of xlc and xlf the -S option will generate a
.s assembly code file prior to optimization. The option -qlist will
generate a human readable one in a .lst file.

There is also a disassembler in /usr/lpp/xlc/bin/dis include with the
 1.3 version of xlc (and in /usr/lpp/xlC/bin/dis with the 2.1 version
of xlC) that will disassemble existing object or executable files.

------------------------------

2.14: Curses


Curses based applications should be linked with -lcurses and _not_ with
-ltermlib. It has also been reported that some problems with curses are
avoided if your application is compiled with -DNLS.

Peter Jeffe <peter@ski.austin.ibm.com> also notes:

>the escape sequences for cursor and function keys are *sometimes*
>treated as several characters: eg. the getch() - call does not return
>KEY_UP but 'ESC [ C.'

You're correct in your analysis: this has to do with the timing of the
escape sequence as it arrives from the net. There is an environment
variable called ESCDELAY that can change the fudge factor used to decide
when an escape is just an escape. The default value is 500; boosting
this a bit should solve your problems.

Christopher Carlyle O'Callaghan <asdfjkl@wam.umd.edu> has more comments
concerning extended curses:

1) The sample program in User Interface Programming Concepts, page 7-13
   is WRONG. Here is the correct use of panes and panels.

#include <cur01.h>
#include <cur05.h>

main()
{
PANE *A, *B, *C, *D, *E, *F, *G, *H;
PANEL *P;

initscr();

A = ecbpns (24, 79, NULL, NULL, 0, 2500, Pdivszp, Pbordry, NULL, NULL);
D = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
E = ecbpns (24, 79, D,    NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
B = ecbpns (24, 79, A, D, Pdivtyh, 3000, Pdivszp, Pbordry, NULL, NULL);
F = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
G = ecbpns (24, 79, F,    NULL, 0, 5000, Pdivszp, Pbordry, NULL, NULL);
H = ecbpns (24, 79, G,    NULL, 0, 3000, Pdivszp, Pbordry, NULL, NULL);
C = ecbpns (24, 79, B, F, Pdivtyh, 0, Pdivszf, Pbordry, NULL, NULL);
P = ecbpls (24, 79, 0, 0, "MAIN PANEL", Pdivtyv, Pbordry, A);

ecdvpl (P);
ecdfpl (P, FALSE);
ecshpl (P); 
ecrfpl (P);
endwin();
}

2) DO NOT include <curses.h> and any other <cur0x.h> file together.
   You will get a bunch of redefined statements.

3) There is CURSES and EXTENDED CURSES. Use only one or the other. If the
   manual says that they're backwards compatible or some other indication 
   that you can use CURSES routines with EXTENDED, don't believe it. To 
   use CURSES you need to include <curses.h> and you can't (see above).

4) If you use -lcur and -lcurses in the same link command, you will get
   Memory fault (core dump) error. You CANNOT use both of them at the same
   time. -lcur is for extended curses, -lcurses is for regular curses.

5) When creating PANEs, when you supply a value (other than 0) for the
   'ds' parameter and use Pdivszf value for the 'du' parameter, the 'ds'
   will be ignored (the sample program on page 7-13 in User Interface
   Programming Concepts is wrong.) For reasons as yet undetermined,
   Pdivszc doesn't seem to work (or at least I can't figure out how to
   use it.)

6) If you're running into bugs and can't figure out what is happening,
   try the following:
   include -qextchk -g in your compile line
	-qextchk will check to make sure you're passing the right number of
  	 parameters to the functions
	-g enables debug

7) Do not use 80 as the number of columns if you want to use the whole
   screen. The lower right corner will get erased.  Use 79 instead.

8) If you create a panel, you must create at least 1 pane, otherwise you
   will get a Memory fault (core dump).

9) When creating a panel, if you don't have a border around it, any title
   you want will not show up.

10) to make the screen scroll down:
    wmove (win, 0, 0);
    winsertln (win)

11) delwin(win) doesn't work in EXTENDED WINDOWS

    To make it appear as if a window is deleted, you need to do the following:
    for every window that you want to appear on the screen
	touchwin(win)
	wrefresh(win)

    you must make sure that you do it in the exact same order as you put
    them on the screen (i.e., if you called newwin with A, then C, then B,
    then you must do the loop with A, then C, then B, otherwise you won't
    get the same screen back).  The best thing to do is to put them into
    an array and keep track of the last window index.

12) mvwin(win, line, col) implies that it is only used for viewports and
    subwindows. It can also be used for the actual windows themselves.

13) If you specify the attribute of a window using wcolorout(win), any
    subsequent calls to chgat(numchars, mode) or any of its relatives
    will not work. (or at least they get very picky.)

------------------------------

2.15: How do I speed up linking


Please refer to sections 2.03 and 2.06 above.

From: losecco@undpdk.hep.nd.edu (John LoSecco) and
      hook@chaco.aix.dfw.ibm.com (Gary R. Hook)

From oahu.cern.ch in /pub/aix3 you can get a wrapper for the existing
linker called tld which can reduce link times with large libraries by
factors of 3 to 4.

------------------------------

2.16: What is deadbeef?


When running the debugger (dbx), you may have wondered what the
'deadbeef' is you occasionally see in registers.  Do note, that
0xdeadbeef is a hexadecimal number that also happens to be some kind
of word (the RS/6000 was built in Texas!), and this hexadecimal number
is simply put into unused registers at some time, probably during
program startup.


------------------------------

2.17: How do I make an export list from a library archive?

From: d.dennerline@bull.com (Dave Dennerline)

[ This script has been moved to section 8.10 ]

------------------------------

2.19: Building imake, makedepend

From: crow@austin.ibm.com (David L. Crow)

[Editor's note: if you have AIX 4.x,  you need the X11.adt.imake LPP
and probably most if not all of the X11.adt.* LPPs.  Imake, xmkmf and
other utilities are delivered precompiled.]

    You need X11dev.src release 1.2.3.0 (ie the R5 release) [on AIX 3.2].


     Unless you have an R5 release of AIXwindows, there is no xmkmf.
  These are the steps that I use to make imake, makedepend and all
  of it's config files, and then install them in the working tree
  (ie not the Xamples) for daily use:
  
      cd /usr/lpp/X11/Xamples
      make Makefile
      make SUBDIRS="config util" Makefiles
      make SUBDIRS="config util" linklibs
      make SUBDIRS="config util" depend
      make SUBDIRS="config util" 
      make SUBDIRS="config util" install
      
  Then redo the steps everytime you apply an X11 update.

------------------------------

2.20: How can tell what shared libraries a binary is linked with?


Use "dump -H <execfilename>" and see if anything other than /unix is
listed in the loader section (at the bottom).  The first example is
/bin/sh (statically linked) and the second example is
/usr/local/bin/bash (shared).

INDEX  PATH                          BASE                MEMBER              
0      /usr/lib:/lib                                                         
1      /                             unix                                    

INDEX  PATH                          BASE                MEMBER              
0      ./lib/readline/:./lib/glob/:/usr/lib:/lib               
1                                    libc.a              shr.o               
2                                    libcurses.a         shr.o               

The freeware tool "ldd" lists all the shared libraries needed
by an executable, including those recursively included by other
shared libraries. See question 2.27 "Where can I find ldd for AIX?".

------------------------------

2.21: Can I get a PTF for my C/C++ compiler from the net?


<http://service.software.ibm.com/>  contains pointers to most PTFs, including
compilers.  You'll need the fixdist program (see 1.142) to retrieve them.

------------------------------

2.22: Why does "install"ing software I got from the net fail?


Note that the RS/6000 has two install programs, one with System V flavor
in the default PATH (/etc/install with links from /usr/bin and /usr/usg),
and one with BSD behavior in /usr/ucb/install.

------------------------------

2.23: What is Linker TOC overflow error 12?


There is a hard coded limit in the AIX 3.2.5 linker that is fixed in
AIX 4.1.  A kind soul donated the following information to help people
get the 3.2.5 fix

    The LPS (paperwork) 
      AIX TOC Data Binder/6000 #P91128
      Version 1.1
      Program Number 5799-QDY
      Reference No. GC23-2604-00, FC 5615
    Pre Reqs listed were AIX 3.2.5
      IBM C Set++ V2 (5765-186)

The above is not available any longer, see section 1.006.

You could also put some of the application code into shared libraries
or, in the case of gcc, use -mminimal-toc.

------------------------------

2.24: What is the limit on number of shared memory segments

               I can attach?

Each process has 16 segments.  One is used for private code, one for
stack, one for heap; those, if memory serves, are segments 0, 1, and
2.  (If you look in sys/shm.h, you'll see that SHMLOSEG is 3 -- the
lowest segment, in number and in the process' virtual address space,
available to shmat.)

SHMHISEG, the highest segment you can attach to (also defined in
sys/shm.h), is 12.  Segments 3 through 12 are available to shmat,
giving the 10 segments your program used successfully.  (NSHMSEGS in
sys/shm.h will give you this value, though it's of limited use, since
most platforms that I've seen don't define it.)

Segment 13 is used by shared code your program has attached to;
I think one of the others might be for kernel-mode data.

See also mmap.

------------------------------

2.25: I deleted libc.a by accident --- how do I recover?

From: Ed Ravin <eravin@panix.com>

You can recover from this without rebooting or reinstalling, if you
have another copy of libc.a available that is also named "libc.a".  If
you moved libc.a to a different directory, you're in luck -- do the
following:

export LIBPATH=/other/directory


And your future commands will work.  But if you renamed libc.a, this
won't do it.  If you have an NFS mounted directory somewhere, you can
put libc.a on the that host, and point LIBPATH to that directory as
shown above.

Failing that, turn off your machine, reboot off floppies or other
media, and get a root shell.  I don't think you should do "getrootfs"
as you usually do when accessing the root vg this way -- AIX may start
looking for libc.a on the disk, and you'll just run into the same
problem.  So do an importvg, varyonvg, and then mount /usr somewhere,
then manually move libc.a back or copy in a new one from floppy.

------------------------------

2.26: Where can I find dlopen, dlclose, and dlsym for AIX?


An implementation of these dynamic code loading functions was written by
Jens-Uwe Mager <jum@anubis.han.de> and can be found at
<http://www.han.de/~jum/aix/dlfcn.shar>

From: Gary R. Hook <hook@austin.ibm.com>

Starting with AIX 4.2 a dlopen et. al. are included in the base OS in
the libdl.a library. Under AIX 4.1 this is available as SLHS (Shared
Library Hookable Symbols) as APAR IX IX71849 for the runtime package and
APAR IX IX72973 for the development tools.

------------------------------

2.27: Where can I find ldd for AIX?

From: Jens-Uwe Mager <jum@anubis.han.de>

Try <http://www.han.de/~jum/aix/ldd.c>. Also the "aix.tools"
package from <http://www-frec.bull.com>

------------------------------

2.28: How do I make my program binary executable on the

                POWER, POWER2, and POWERPC architecures?

AIX will emulate those instructions not available in POWERPC processors, but
you can avoid this emulation and consequent performance degradtation by
using only the common to all.

If you are using IBM's xlc (cc) compiler, the default is to use the common
instruction set.  If you want to be explicit, use the -qarch=com option.

The option -mcpu=common makes GCC use the common instruction set.  Please
note that (unlike xlc) this is *not* the default with GCC on AIX.

------------------------------

2.29: How do I access more than 256 Megabytes of memory?


By default each program gets one segment register (see 2.24) for its
data segment. As each segment register covers 256 MB, any calls to
malloc more will fail. Also programs that declare large global or static
arrays may fail to load. To allocate more segment registers to your
program, use the linker option -bmaxdata to specify the number of bytes
you need in the data segment as follows:

cc -o myprog -bmaxdata:0x20000000 myprog.c

The example above would allocate an additional segment register to allow
for 512MB of data.

------------------------------

2.30: How do I use POSIX threads with gcc 2.7.x?

From: David Edelsohn <dje@watson.ibm.com>

The code generated by GCC is compatible with threads, but gcc-2.7 
was released so long ago that it did not provide an option to perform
the extra link steps necessary to support threads:

1) Compile all source files with "-D_THREAD_SAFE" macro defined.
2) Link with "-L/usr/lib/threads -lpthreads -lc_r /usr/lib/libc.a"
   to obtain the pthreads support 
   and add "-nostartfiles /usr/lib/crt0_r.o" to the beginning of the
   link command line (using gcc to link!) to initialize threads.

------------------------------

2.31: Why does pthread_create return the error code 22?


Using Posix threads under AIX requires a special C runtime startup
initialization as well as special versions of some libraries. The IBM C
compiler includes these special libraries if called by the name xlc_r
(or xlC_r for C++). There also other maing variations to support various
defaults, consult the file /etc/xlC.cf for details.

------------------------------

2.32: How do I build programs under a later AIX release that run

	under earlier releases as well?

IBM develops AIX only for binary compatibility with older AIX releases,
not the other way around. You will thus need to build programs on the
oldest AIX release the program is supposed to run on. You will also need
to link programs dynamically, if you link in the system libraries
statically the program will probably only run on the machine you
performed the link on.

With some preparation it is appearently possible to get around that
limitation. Bob Halblutzel has put together a web page describing the
detailed steps how to set up such a build environment at the following
web page:

<http://www.hablutzel.com/aix_compatibility_build.html>

Please not that this is not a supported way to build your programs, you
will probably receive not any support by IBM if you have problems with
that environment.

------------------------------

2.00: C/C++


Contrary to many people's belief, the C environment on the RS/6000 is
not very special.  The C compiler has quite a number of options that can
be used to control how it works, which "dialect" of C it compiles, how
it interprets certain language constructs, etc.  InfoExplorer includes a
Users Guide and a Reference Manual.

The compiler can be invoked with either xlc for strict ANSI mode and cc
for RT compatible mode (i.e. IBM 6150 with AIX 2).  The default options
for each mode are set in the /etc/xlc.cfg file, and you can actually add
another stanza and create a link to the /bin/xlc executable.

The file /usr/lpp/xlc/bin/README.xlc has information about the C
compiler, and the file /usr/lpp/bos/bsdport (AIX 3 only) contains useful
information, in particular for users from a BSD background.

The file /etc/xlc.cfg also shows the symbol _IBMR2 that is predefined,
and therefore can be used for #ifdef'ing RS/6000 specific code.

------------------------------

2.01: I cannot make alloca work


A famous routine, in particular in GNU context, is the allocation
routine alloca().  Alloca allocates memory in such a way that it is
automatically free'd when the block is exited.  Most implementations
does this by adjusting the stack pointer.  Since not all C environments
can support it, its use is discouraged, but it is included in the xlc
compiler.  In order to make the compiler aware that you intend to use
alloca, you must put the line

#pragma alloca

before any other statements in the C source module(s) where alloca is
called.  If you don't do this, xlc will not recognize alloca as anything
special, and you will get errors during linking.

For AIX 3.2, it may be easier to use the -ma flag.

------------------------------

2.02: How do I compile my BSD programs?


The file /usr/lpp/bos/bsdport contains information on how to port
programs written for BSD to AIX 3.  This file may be very useful for
others as well.

A quick cc command for most "standard" BSD programs is:
  
  $ cc -D_BSD -D_BSD_INCLUDES  -o [loadfile] [sourcefile.c] -lbsd

If your software has system calls predefined with no prototype
parameters, also use the -D_NO_PROTO flag.

------------------------------

2.03: Isn't the linker different from what I am used to?


Yes.  It is not at all like what you are used to:

- The order of objects and libraries is normally _not_ important.  The
  linker reads _all_ objects including those from libraries into memory
  and does the actual linking in one go.  Even if you need to put a
  library of your own twice on the ld command line on other systems, it
  is not needed on the RS/6000 - doing so will even make your linking slower.

- One of the features of the linker is that it will replace an object in
  an executable with a new version of the same object:

  $ cc -o prog prog1.o prog2.o prog3.o		# make prog
  $ cc -c prog2.c				# recompile prog2.c
  $ cc -o prog.new prog2.o prog			# make prog.new from prog
						# by replacing prog2.o
  
- The standard C library /lib/libc.a is linked shared, which means that
  the actual code is not linked into your program, but is loaded only
  once and linked dynamically during loading of your program.

- The ld program actually calls the binder in /usr/lib/bind, and you can
  give ld special options to get details about the invocation of the
  binder.  These are found on the ld man page or in InfoExplorer.

- If your program normally links using a number of libraries (.a files),
  you can 'prelink' each of these into an object, which will make your
  final linking faster.  E.g. do:

  $ cc -c prog1.c prog2.c prog3.c
  $ ar cv libprog.a prog1.o prog2.o prog3.o
  $ ld -r -o libprog.o libprog.a
  $ cc -o someprog someprog.c libprog.o

This will solve all internal references between prog1.o, prog2.o and
prog3.o and save this in libprog.o Then using libprog.o to link your
program instead of libprog.a will increase linking speed, and even if
someprog.c only uses, say prog1.o and prog2.o, only those two modules
will be in your final program.  This is also due to the fact that the
binder can handle single objects inside one object module as noted above.

If you are using an -lprog option (for libprog.a) above, and still want
to be able to do so, you should name the prelinked object with a
standard library name, e.g. libprogP.a (P identifying a prelinked
object), that can be specified by -lprogP.  You cannot use the archiver
(ar) on such an object.

You should also have a look at section 3.01 of this article, in
particular if you have mixed Fortran/C programs.

Dave Dennerline (d.dennerline@bull.com) claims that his experiences
in prelinking on AIX does not save much time since most people have
separate libraries which do not have many dependencies between them,
thus not many symbols to resolve.

------------------------------

2.04: How do I statically link my program?


  cc -o prog -bnoso -bI:/lib/syscalls.exp obj1.o obj2.o obj3.o

will do that for a program consisting of the three objects obj1.o, etc.

[Editor's note: You should never link programs statically that are
supposed to leave your local environment, e.g. intended for
distribution. Statically linked programs may fail to work after
installing a new AIX version or even after installing a PTF.]

From: Marc Pawliger (marc@sti.com)

As of AIX 3.2.5, you can install a speedup for AIXwindows called
Shared Memory Transport.  To static link an X application after the
SMT PTF has been installed, you must link with
-bI:/usr/lpp/X11/bin/smt.exp and the executable will NOT run on a
machine where SMT is not installed.  See /usr/lpp/X11/README.SMT

2.05: How do I make my own shared library?


To make your own shared object or library of shared objects, you should
know that a shared object cannot have undefined symbols.  Thus, if your
code uses any externals from /lib/libc.a, the latter MUST be linked with
your code to make a shared object.  Mike Heath (mike@pencom.com) said it
is possible to split code into more than one shared object when externals
in one object refer to another one.  You must be very good at
import/export files.  Perhaps he or someone can provide an example. 

Assume you have one file, sub1.c, containing a routine with no external
references, and another one, sub2.c, calling stuff in /lib/libc.a.  You
will also need two export files, sub1.exp, sub2.exp.  Read the example
below together with the examples on the ld man page. 

---- sub1.c ----
    int addint(int a, int b)
    {
      return a + b;
    }
---- sub2.c ----
    #include <stdio.h>

    void printint(int a)
    {
      printf("The integer is: %d\n", a);
    }
---- sub1.exp ----
    #!
    addint
---- sub2.exp ----
    #!
    printint
---- usesub.c ----
    main()
    {
      printint( addint(5,8) );
    }

The following commands will build your libshr.a, and compile/link the
program usesub to use it.  Note that you need the ld option -lc for
sub2shr.o since it calls printf from /lib/libc.a.  [Note that you can leave
out the "-T512 -H512" on AIX 4. -- Ed.]

  $ cc  -c sub1.c
  $ ld -o sub1shr.o sub1.o -bE:sub1.exp -bM:SRE -T512 -H512 
  $ cc  -c sub2.c
  $ ld -o sub2shr.o sub2.o -bE:sub2.exp -bM:SRE -T512 -H512  -lc
  $ ar r libshr.a sub1shr.o sub2shr.o
  $ cc -o usesub usesub.c -L: libshr.a
  $ usesub
  The integer is: 13
  $

------------------------------

2.06: Linking my program fails with strange errors. Why?


Very simple, the linker (actually called the binder), cannot get the
memory it needs, either because your ulimits are too low or because you
don't have sufficient paging space.  Since the linker is quite different
>from normal Unix linkers and actually does much more than these, it also
uses a lot of virtual memory.  It is not unusual to need 10000 pages (of
4k) or more to execute a fairly complex linking.

If you get 'BUMP error', either ulimits or paging is too low, if you get
'Binder killed by signal 9' your paging is too low.

First, check your memory and data ulimits; in korn shell 'ulimit -a' will
show all limits and 'ulimit -m 99999' and 'ulimit -d 99999' will
increase the maximum memory and data respectively to some high values. 
If this was not your problem, you don't have enough paging space.

If you will or can not increase your paging space, you could try this:

- Do you duplicate libraries on the ld command line? That is never
  necessary.

- Do more users link simultaneously? Try having only one linking going
  on at any time.

- Do a partwise linking, i.e. you link some objects/libraries with the
  -r option to allow the temporary output to have unresolved references,
  then link with the rest of your objects/libraries.  This can be split
  up as much as you want, and will make each step use less virtual memory.

  If you follow this scheme, only adding one object or archive at a
  time, you will actually emulate the behavior of other Unix linkers.

If you decide to add more paging space, you should consider adding a new
paging space on a second hard disk, as opposed to just increasing the
existing one.  Doing the latter could make you run out of free space on
your first harddisk. It is more involved to shrink a paging space
but easier to delete one.

------------------------------

2.07: Why does it take so long to compile "hello world" with xlc?


Some systems have experienced delays of more than 60 seconds in
compiling "#include <stdio.h> int main () {printf ("Hello world");}"
The problem is with the license manager contact IBM to make sure
you've got the latest PTF.

------------------------------

2.08: What's with malloc()?

 
malloc() uses a late allocation algorithm based on 4.3 BSD's malloc()
for speed.  This lets you allocate very large sparse memory spaces,
since the pages are not actually allocated until they are touched for
the first time.  Unfortunately, it doesn't die gracefully in the face of
loss of available memory.  See the "Paging Space Overview" under
InfoExplorer, and see the notes on the linker in this document for an
example of an ungraceful death.

If you want your program to get notified when running out of memory, you
should handle the SIGDANGER signal.  The default is to ignore it. 
SIGDANGER is sent to all processes when paging space gets low, and if
paging space gets even lower, processes with the highest paging space
usage are sent the SIGKILL signal.

malloc() is substantially different in 3.2, allocating memory more
tightly.  If you have problems running re-compiled programs on 3.2,
try running them with MALLOCTYPE=3.1.

Early Page Space Allocation (EPSA) added to AIX 3.2: see
/usr/lpp/bos/README.PSALLOC - IX38211 / U422496 Allows setting of
early allocation (vs. default late allocation) on a per-process basis.

------------------------------

2.09: Why does xlc complain about 'extern char *strcpy()'


The header <string.h> has a strcpy macro that expands strcpy(x,y) to
__strcpy(x,y), and the latter is then used by the compiler to generate
inline code for strcpy.  Because of the macro, your extern declaration
contains an invalid macro expansion.  The real cure is to remove your
extern declaration but adding -U__STR__ to your xlc will also do the
trick, although your program might run a bit more slowly as the compiler
cannot inline the string functions any more.

------------------------------

2.10: Why do I get 'Parameter list cannot contain fewer ....'


This is the same as above (2.9).

------------------------------

2.11: Why does xlc complain about

               '(sometype *)somepointer = something'

Software that is developed using gcc may have this construct. However,
standard C does not permit casts to be lvalues, so you will need to
change the cast and move it to the right side of the assignment. If you
compile with 'cc', removing the cast completely will give you a warning,
'xlc' will give you an error (provided somepointer and something are of
different types - but else, why would the cast be there in the first place?)

------------------------------

2.12: Some more common errors


Here are a few other common errors with xlc:

305 |     switch((((np)->navigation_type) ? (*((np)->navigation_type)) :
      ((void *)0)))
      .a...........  
a - 1506-226: (S) The second and third operands of the conditional
operator must be of the same type.

The reason for this is that xlc defines NULL as (void *)0, and it does
not allow two different types as the second and third operand of ?:. 
The second argument above is not a pointer and the code used NULL
incorrectly as a scalar. NULL is a nil pointer constant in ANSI C and
in some traditional compilers.

You should change NULL in the third argument above to an integer 0.


------------------------------

2.13: Can the compiler generate assembler code?


Starting with version 1.3 of xlc and xlf the -S option will generate a
.s assembly code file prior to optimization. The option -qlist will
generate a human readable one in a .lst file.

There is also a disassembler in /usr/lpp/xlc/bin/dis include with the
 1.3 version of xlc (and in /usr/lpp/xlC/bin/dis with the 2.1 version
of xlC) that will disassemble existing object or executable files.

------------------------------

2.14: Curses


Curses based applications should be linked with -lcurses and _not_ with
-ltermlib. It has also been reported that some problems with curses are
avoided if your application is compiled with -DNLS.

Peter Jeffe <peter@ski.austin.ibm.com> also notes:

>the escape sequences for cursor and function keys are *sometimes*
>treated as several characters: eg. the getch() - call does not return
>KEY_UP but 'ESC [ C.'

You're correct in your analysis: this has to do with the timing of the
escape sequence as it arrives from the net. There is an environment
variable called ESCDELAY that can change the fudge factor used to decide
when an escape is just an escape. The default value is 500; boosting
this a bit should solve your problems.

Christopher Carlyle O'Callaghan <asdfjkl@wam.umd.edu> has more comments
concerning extended curses:

1) The sample program in User Interface Programming Concepts, page 7-13
   is WRONG. Here is the correct use of panes and panels.

#include <cur01.h>
#include <cur05.h>

main()
{
PANE *A, *B, *C, *D, *E, *F, *G, *H;
PANEL *P;

initscr();

A = ecbpns (24, 79, NULL, NULL, 0, 2500, Pdivszp, Pbordry, NULL, NULL);
D = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
E = ecbpns (24, 79, D,    NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
B = ecbpns (24, 79, A, D, Pdivtyh, 3000, Pdivszp, Pbordry, NULL, NULL);
F = ecbpns (24, 79, NULL, NULL, 0, 0,    Pdivszf, Pbordry, NULL, NULL);
G = ecbpns (24, 79, F,    NULL, 0, 5000, Pdivszp, Pbordry, NULL, NULL);
H = ecbpns (24, 79, G,    NULL, 0, 3000, Pdivszp, Pbordry, NULL, NULL);
C = ecbpns (24, 79, B, F, Pdivtyh, 0, Pdivszf, Pbordry, NULL, NULL);
P = ecbpls (24, 79, 0, 0, "MAIN PANEL", Pdivtyv, Pbordry, A);

ecdvpl (P);
ecdfpl (P, FALSE);
ecshpl (P); 
ecrfpl (P);
endwin();
}

2) DO NOT include <curses.h> and any other <cur0x.h> file together.
   You will get a bunch of redefined statements.

3) There is CURSES and EXTENDED CURSES. Use only one or the other. If the
   manual says that they're backwards compatible or some other indication 
   that you can use CURSES routines with EXTENDED, don't believe it. To 
   use CURSES you need to include <curses.h> and you can't (see above).

4) If you use -lcur and -lcurses in the same link command, you will get
   Memory fault (core dump) error. You CANNOT use both of them at the same
   time. -lcur is for extended curses, -lcurses is for regular curses.

5) When creating PANEs, when you supply a value (other than 0) for the
   'ds' parameter and use Pdivszf value for the 'du' parameter, the 'ds'
   will be ignored (the sample program on page 7-13 in User Interface
   Programming Concepts is wrong.) For reasons as yet undetermined,
   Pdivszc doesn't seem to work (or at least I can't figure out how to
   use it.)

6) If you're running into bugs and can't figure out what is happening,
   try the following:
   include -qextchk -g in your compile line
	-qextchk will check to make sure you're passing the right number of
  	 parameters to the functions
	-g enables debug

7) Do not use 80 as the number of columns if you want to use the whole
   screen. The lower right corner will get erased.  Use 79 instead.

8) If you create a panel, you must create at least 1 pane, otherwise you
   will get a Memory fault (core dump).

9) When creating a panel, if you don't have a border around it, any title
   you want will not show up.

10) to make the screen scroll down:
    wmove (win, 0, 0);
    winsertln (win)

11) delwin(win) doesn't work in EXTENDED WINDOWS

    To make it appear as if a window is deleted, you need to do the following:
    for every window that you want to appear on the screen
	touchwin(win)
	wrefresh(win)

    you must make sure that you do it in the exact same order as you put
    them on the screen (i.e., if you called newwin with A, then C, then B,
    then you must do the loop with A, then C, then B, otherwise you won't
    get the same screen back).  The best thing to do is to put them into
    an array and keep track of the last window index.

12) mvwin(win, line, col) implies that it is only used for viewports and
    subwindows. It can also be used for the actual windows themselves.

13) If you specify the attribute of a window using wcolorout(win), any
    subsequent calls to chgat(numchars, mode) or any of its relatives
    will not work. (or at least they get very picky.)

------------------------------

2.15: How do I speed up linking


Please refer to sections 2.03 and 2.06 above.

From: losecco@undpdk.hep.nd.edu (John LoSecco) and
      hook@chaco.aix.dfw.ibm.com (Gary R. Hook)

From oahu.cern.ch in /pub/aix3 you can get a wrapper for the existing
linker called tld which can reduce link times with large libraries by
factors of 3 to 4.

------------------------------

2.16: What is deadbeef?


When running the debugger (dbx), you may have wondered what the
'deadbeef' is you occasionally see in registers.  Do note, that
0xdeadbeef is a hexadecimal number that also happens to be some kind
of word (the RS/6000 was built in Texas!), and this hexadecimal number
is simply put into unused registers at some time, probably during
program startup.


------------------------------

2.17: How do I make an export list from a library archive?

From: d.dennerline@bull.com (Dave Dennerline)

[ This script has been moved to section 8.10 ]

------------------------------

2.19: Building imake, makedepend

From: crow@austin.ibm.com (David L. Crow)

[Editor's note: if you have AIX 4.x,  you need the X11.adt.imake LPP
and probably most if not all of the X11.adt.* LPPs.  Imake, xmkmf and
other utilities are delivered precompiled.]

    You need X11dev.src release 1.2.3.0 (ie the R5 release) [on AIX 3.2].


     Unless you have an R5 release of AIXwindows, there is no xmkmf.
  These are the steps that I use to make imake, makedepend and all
  of it's config files, and then install them in the working tree
  (ie not the Xamples) for daily use:
  
      cd /usr/lpp/X11/Xamples
      make Makefile
      make SUBDIRS="config util" Makefiles
      make SUBDIRS="config util" linklibs
      make SUBDIRS="config util" depend
      make SUBDIRS="config util" 
      make SUBDIRS="config util" install
      
  Then redo the steps everytime you apply an X11 update.

------------------------------

2.20: How can tell what shared libraries a binary is linked with?


Use "dump -H <execfilename>" and see if anything other than /unix is
listed in the loader section (at the bottom).  The first example is
/bin/sh (statically linked) and the second example is
/usr/local/bin/bash (shared).

INDEX  PATH                          BASE                MEMBER              
0      /usr/lib:/lib                                                         
1      /                             unix                                    

INDEX  PATH                          BASE                MEMBER              
0      ./lib/readline/:./lib/glob/:/usr/lib:/lib               
1                                    libc.a              shr.o               
2                                    libcurses.a         shr.o               

The freeware tool "ldd" lists all the shared libraries needed
by an executable, including those recursively included by other
shared libraries. See question 2.27 "Where can I find ldd for AIX?".

------------------------------

2.21: Can I get a PTF for my C/C++ compiler from the net?


<http://service.software.ibm.com/>  contains pointers to most PTFs, including
compilers.  You'll need the fixdist program (see 1.142) to retrieve them.

------------------------------

2.22: Why does "install"ing software I got from the net fail?


Note that the RS/6000 has two install programs, one with System V flavor
in the default PATH (/etc/install with links from /usr/bin and /usr/usg),
and one with BSD behavior in /usr/ucb/install.

------------------------------

2.23: What is Linker TOC overflow error 12?


There is a hard coded limit in the AIX 3.2.5 linker that is fixed in
AIX 4.1.  A kind soul donated the following information to help people
get the 3.2.5 fix

    The LPS (paperwork) 
      AIX TOC Data Binder/6000 #P91128
      Version 1.1
      Program Number 5799-QDY
      Reference No. GC23-2604-00, FC 5615
    Pre Reqs listed were AIX 3.2.5
      IBM C Set++ V2 (5765-186)

The above is not available any longer, see section 1.006.

You could also put some of the application code into shared libraries
or, in the case of gcc, use -mminimal-toc.

------------------------------

2.24: What is the limit on number of shared memory segments

               I can attach?

Each process has 16 segments.  One is used for private code, one for
stack, one for heap; those, if memory serves, are segments 0, 1, and
2.  (If you look in sys/shm.h, you'll see that SHMLOSEG is 3 -- the
lowest segment, in number and in the process' virtual address space,
available to shmat.)

SHMHISEG, the highest segment you can attach to (also defined in
sys/shm.h), is 12.  Segments 3 through 12 are available to shmat,
giving the 10 segments your program used successfully.  (NSHMSEGS in
sys/shm.h will give you this value, though it's of limited use, since
most platforms that I've seen don't define it.)

Segment 13 is used by shared code your program has attached to;
I think one of the others might be for kernel-mode data.

See also mmap.

------------------------------

2.25: I deleted libc.a by accident --- how do I recover?

From: Ed Ravin <eravin@panix.com>

You can recover from this without rebooting or reinstalling, if you
have another copy of libc.a available that is also named "libc.a".  If
you moved libc.a to a different directory, you're in luck -- do the
following:

export LIBPATH=/other/directory


And your future commands will work.  But if you renamed libc.a, this
won't do it.  If you have an NFS mounted directory somewhere, you can
put libc.a on the that host, and point LIBPATH to that directory as
shown above.

Failing that, turn off your machine, reboot off floppies or other
media, and get a root shell.  I don't think you should do "getrootfs"
as you usually do when accessing the root vg this way -- AIX may start
looking for libc.a on the disk, and you'll just run into the same
problem.  So do an importvg, varyonvg, and then mount /usr somewhere,
then manually move libc.a back or copy in a new one from floppy.

------------------------------

2.26: Where can I find dlopen, dlclose, and dlsym for AIX?


An implementation of these dynamic code loading functions was written by
Jens-Uwe Mager <jum@anubis.han.de> and can be found at
<http://www.han.de/~jum/aix/dlfcn.shar>

From: Gary R. Hook <hook@austin.ibm.com>

Starting with AIX 4.2 a dlopen et. al. are included in the base OS in
the libdl.a library. Under AIX 4.1 this is available as SLHS (Shared
Library Hookable Symbols) as APAR IX IX71849 for the runtime package and
APAR IX IX72973 for the development tools.

------------------------------

2.27: Where can I find ldd for AIX?

From: Jens-Uwe Mager <jum@anubis.han.de>

Try <http://www.han.de/~jum/aix/ldd.c>. Also the "aix.tools"
package from <http://www-frec.bull.com>

------------------------------

2.28: How do I make my program binary executable on the

                POWER, POWER2, and POWERPC architecures?

AIX will emulate those instructions not available in POWERPC processors, but
you can avoid this emulation and consequent performance degradtation by
using only the common to all.

If you are using IBM's xlc (cc) compiler, the default is to use the common
instruction set.  If you want to be explicit, use the -qarch=com option.

The option -mcpu=common makes GCC use the common instruction set.  Please
note that (unlike xlc) this is *not* the default with GCC on AIX.

------------------------------

2.29: How do I access more than 256 Megabytes of memory?


By default each program gets one segment register (see 2.24) for its
data segment. As each segment register covers 256 MB, any calls to
malloc more will fail. Also programs that declare large global or static
arrays may fail to load. To allocate more segment registers to your
program, use the linker option -bmaxdata to specify the number of bytes
you need in the data segment as follows:

cc -o myprog -bmaxdata:0x20000000 myprog.c

The example above would allocate an additional segment register to allow
for 512MB of data.

------------------------------

2.30: How do I use POSIX threads with gcc 2.7.x?

From: David Edelsohn <dje@watson.ibm.com>

The code generated by GCC is compatible with threads, but gcc-2.7 
was released so long ago that it did not provide an option to perform
the extra link steps necessary to support threads:

1) Compile all source files with "-D_THREAD_SAFE" macro defined.
2) Link with "-L/usr/lib/threads -lpthreads -lc_r /usr/lib/libc.a"
   to obtain the pthreads support 
   and add "-nostartfiles /usr/lib/crt0_r.o" to the beginning of the
   link command line (using gcc to link!) to initialize threads.

------------------------------

2.31: Why does pthread_create return the error code 22?


Using Posix threads under AIX requires a special C runtime startup
initialization as well as special versions of some libraries. The IBM C
compiler includes these special libraries if called by the name xlc_r
(or xlC_r for C++). There also other maing variations to support various
defaults, consult the file /etc/xlC.cf for details.

------------------------------

2.32: How do I build programs under a later AIX release that run

	under earlier releases as well?

IBM develops AIX only for binary compatibility with older AIX releases,
not the other way around. You will thus need to build programs on the
oldest AIX release the program is supposed to run on. You will also need
to link programs dynamically, if you link in the system libraries
statically the program will probably only run on the machine you
performed the link on.

With some preparation it is appearently possible to get around that
limitation. Bob Halblutzel has put together a web page describing the
detailed steps how to set up such a build environment at the following
web page:

<http://www.hablutzel.com/aix_compatibility_build.html>

Please not that this is not a supported way to build your programs, you
will probably receive not any support by IBM if you have problems with
that environment.

------------------------------