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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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 ------------------------------
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 $ ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
This is the same as above (2.9). ------------------------------
'(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?) ------------------------------
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. ------------------------------
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. ------------------------------
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.) ------------------------------
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. ------------------------------
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. ------------------------------
From: d.dennerline@bull.com (Dave Dennerline) [ This script has been moved to section 8.10 ] ------------------------------
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. ------------------------------
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?". ------------------------------
<http://service.software.ibm.com/> contains pointers to most PTFs, including compilers. You'll need the fixdist program (see 1.142) to retrieve them. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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> ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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 ------------------------------
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 $ ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
This is the same as above (2.9). ------------------------------
'(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?) ------------------------------
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. ------------------------------
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. ------------------------------
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.) ------------------------------
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. ------------------------------
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. ------------------------------
From: d.dennerline@bull.com (Dave Dennerline) [ This script has been moved to section 8.10 ] ------------------------------
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. ------------------------------
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?". ------------------------------
<http://service.software.ibm.com/> contains pointers to most PTFs, including compilers. You'll need the fixdist program (see 1.142) to retrieve them. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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> ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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 ------------------------------
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 $ ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
This is the same as above (2.9). ------------------------------
'(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?) ------------------------------
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. ------------------------------
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. ------------------------------
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.) ------------------------------
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. ------------------------------
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. ------------------------------
From: d.dennerline@bull.com (Dave Dennerline) [ This script has been moved to section 8.10 ] ------------------------------
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. ------------------------------
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?". ------------------------------
<http://service.software.ibm.com/> contains pointers to most PTFs, including compilers. You'll need the fixdist program (see 1.142) to retrieve them. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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> ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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 ------------------------------
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 $ ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
This is the same as above (2.9). ------------------------------
'(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?) ------------------------------
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. ------------------------------
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. ------------------------------
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.) ------------------------------
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. ------------------------------
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. ------------------------------
From: d.dennerline@bull.com (Dave Dennerline) [ This script has been moved to section 8.10 ] ------------------------------
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. ------------------------------
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?". ------------------------------
<http://service.software.ibm.com/> contains pointers to most PTFs, including compilers. You'll need the fixdist program (see 1.142) to retrieve them. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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> ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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
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 $ ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
This is the same as above (2.9). ------------------------------
'(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?) ------------------------------
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. ------------------------------
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. ------------------------------
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.) ------------------------------
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. ------------------------------
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. ------------------------------
From: d.dennerline@bull.com (Dave Dennerline) [ This script has been moved to section 8.10 ] ------------------------------
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. ------------------------------
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?". ------------------------------
<http://service.software.ibm.com/> contains pointers to most PTFs, including compilers. You'll need the fixdist program (see 1.142) to retrieve them. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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> ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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
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 $ ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
This is the same as above (2.9). ------------------------------
'(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?) ------------------------------
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. ------------------------------
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. ------------------------------
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.) ------------------------------
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. ------------------------------
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. ------------------------------
From: d.dennerline@bull.com (Dave Dennerline) [ This script has been moved to section 8.10 ] ------------------------------
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. ------------------------------
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?". ------------------------------
<http://service.software.ibm.com/> contains pointers to most PTFs, including compilers. You'll need the fixdist program (see 1.142) to retrieve them. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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> ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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
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 $ ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
This is the same as above (2.9). ------------------------------
'(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?) ------------------------------
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. ------------------------------
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. ------------------------------
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.) ------------------------------
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. ------------------------------
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. ------------------------------
From: d.dennerline@bull.com (Dave Dennerline) [ This script has been moved to section 8.10 ] ------------------------------
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. ------------------------------
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?". ------------------------------
<http://service.software.ibm.com/> contains pointers to most PTFs, including compilers. You'll need the fixdist program (see 1.142) to retrieve them. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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> ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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
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 $ ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
This is the same as above (2.9). ------------------------------
'(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?) ------------------------------
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. ------------------------------
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. ------------------------------
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.) ------------------------------
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. ------------------------------
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. ------------------------------
From: d.dennerline@bull.com (Dave Dennerline) [ This script has been moved to section 8.10 ] ------------------------------
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. ------------------------------
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?". ------------------------------
<http://service.software.ibm.com/> contains pointers to most PTFs, including compilers. You'll need the fixdist program (see 1.142) to retrieve them. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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> ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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
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 $ ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
This is the same as above (2.9). ------------------------------
'(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?) ------------------------------
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. ------------------------------
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. ------------------------------
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.) ------------------------------
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. ------------------------------
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. ------------------------------
From: d.dennerline@bull.com (Dave Dennerline) [ This script has been moved to section 8.10 ] ------------------------------
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. ------------------------------
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?". ------------------------------
<http://service.software.ibm.com/> contains pointers to most PTFs, including compilers. You'll need the fixdist program (see 1.142) to retrieve them. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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> ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------
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. ------------------------------