Notes on libpawlib2-dev ----------------------- 1) This package does not include the Lesstif-dependent parts of Pawlib. Those can be found in the package libpawlib2-lesstif-dev. 2) Note that much of this library is functional on 64-bit machines only when statically linked. Please see the file README.64-bit for more information. 3) On 32-bit architectures, please read this note carefully if you link against pawlib dynamically so that the COMIS interpreter works correctly in your application. This is especially applicable if your application dies with this error message: CSALLO: heap below bss?! If you link statically, this note does not concern you. The default output of the "cernlib" script includes the -static compiler flag, so a program linked via a command like one of these: g77 myprogram.F -o myprogram `cernlib pawlib` gcc file1.o file2.o file3.o -o myprogram `cernlib pawlib` is statically linked to pawlib. If you have doubts, run ldd on your executable; a statically linked program should NOT have the output of ldd include a line similar to this: libpawlib.so.2 => /usr/lib/libpawlib.so.2 (0x0f7eb000) Executive summary ----------------- a) If your executable's main source code file is written in FORTRAN, it should #include immediately after the " PROGRAM programname" line. b) If your executable's main source code file is written in C or C++, it should #include at the top of the source code. It is only necessary for one file of your source code to include mdpool.inc or mdpool.h, and may in fact cause linking problems if more than one file does so. Do not include mdpool.inc or mdpool.h in a header file unless that file is itself only #included by one source file. Technical details ----------------- The authors of COMIS (the PAW interpreter) used two memory allocation areas; one is the integer array IQ (size: 50006 integers) in the COMMON block MDPOOL, and the other is dynamically allocated by malloc() in the CSALLO function. The difference between the malloc()ed pointer address and the address of the common block is returned to FORTRAN code, so it can access the new memory by using the appropriate array subscript in MDPOOL/IQ. The idea is similar to that expressed in the following C code: #include typedef struct { int iq[50006]; } mdpool_def; mdpool_def mdpool; int main() { unsigned long iqpntr = (unsigned long)mdpool.iq; unsigned long lpntr = (unsigned long)malloc(sizeof(int)); int index = (lpntr - iqpntr) / sizeof(int); mdpool.iq[index] = 5; return mdpool.iq[index]; } The problem is that the FORTRAN code in pawlib expects the address difference (the variable "index" in the above example) to be positive. This is fine when an executable is statically linked to pawlib, since then the malloc()ed space in the heap is always at a larger address than MDPOOL in the binary's bss segment. But on some (most?) architectures, shared libraries, including MDPOOL in libpawlib.so, are mapped into memory beyond the program stack, yielding a negative address offset. After a lot of trying, I concluded that tracking down all the places in the FORTRAN code that expected a positive pointer offset from MDPOOL would be very difficult and error-prone, so the solution is to attack the problem from the other end. That is, declare MDPOOL/IQ in the dynamically linked executable. Then MDPOOL will always be present in these executables' bss segments, whose address is always less than that of space allocated on the heap. This is accomplished by #include'ing or in the source code for the executable. See, e.g., the file /usr/share/doc/libpaw1-dev/examples/pamain.c . -- Kevin McCarty , Mon, 29 Nov 2004