debian/0000755000000000000000000000000011773153613007175 5ustar debian/copyright0000644000000000000000000001364011773153613011134 0ustar This package was debianized by Bdale Garbee in June 2012, as a fork from the SDCC 2.9 packaging that originated with Aurelien Jarno on Sat, 01 Dec 2001 17:42:52 +0100. It was downloaded from http://sdcc.sourceforge.net Upstream author: Borut Razem Copyright: The SDCC distribution aggregates contributions from many copyright holders, including: Copyright (c) 1989-1995 Alan R. Baldwin Copyright (c) 2009 AT&T Copyright (c) 2004 Bjorn Bringert Copyright (c) 1984-1990 Bob Corbett and Richard Stallman Copyright (c) 2002-2009 Borut Razem Copyright (c) 2000-2003 Dallas Semiconductor Corporation Copyright (c) 1990 Debby Ayers Copyright (c) 1999-2002 Drotos Daniel, Talker Bt Copyright (c) 2004 Erik Petrich Copyright (c) 1989-1991 Free Software Foundation, Inc Copyright (c) 2005-2007 Frieder Ferlemann Copyright (c) 2007-2009 Gudjon I. Gudjonsson Copyright (c) 2002-2003 Jesus Calvino-Fraga Copyright (c) 2004 Juan Gonzalez Copyright (c) 2002 Kevin L. Pauba Copyright (c) 2007 Kyle Guinn Copyright (c) 2005 Llewellyn van Zyl Copyright (c) 2004 Lucas Loizaga Copyright (c) 2003-2009 Maarten Brock Copyright (c) Microsoft Corporation Copyright (c) 2005 Omar Espinosa Copyright (c) 2005 Paul Hsieh Copyright (c) 1997-2002 Paul Stoffregen Copyright (c) 2006 Philippe Latu Copyright (c) 1991 Pipeline Associates, Inc Copyright (c) 2002-2007 Quantum Leaps, LLC Copyright (c) 2007 Raphael Neider Copyright (c) 1998-2000 Red Hat, Inc. Copyright (c) 2009 Rheinhold Weicker Copyright (c) 1996-1999 Robin Friedrich Copyright (c) 1999 Sandeep Dutta Copyright (c) 2008 Steven Borley Copyright (c) 2009 The Regents of the University of California Copyright (c) 1994-1995 Tinker Systems and INS Engineering Corp Copyright (c) 1991-2005 Unicode, Inc Copyright (c) 1994 X Consortium License: The bulk of the compiler is licensed under the GPL version 2 or later, while the assemblers originating from Alan R. Baldwin are licensed GPL version 3 or later. Various files associated with support for specific processors carry other licenses, all of which appear to be compatible with both versions 2 and 3 of the GPL. On Debian systems, the complete text of both GPL versions can be found in the directory /usr/share/common-licenses. The sdcc library is licenced either as GPL or LGPL. A few specific files carry other (GPL compatible) licenses, including: as/asxxsrc/strcmpi.c is licensed under LGPL as/link/getline.* is licensed under a BSD-style license several files under device/lib/ are licensed under LGPL ----- Example programs for Dallas Semiconductor MCU's --------------------- Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of Dallas Semiconductor shall not be used except as stated in the Dallas Semiconductor Branding Policy. --------------------------------------------------------------------------- ---------- install.sh file ------------------------------------------------ This originates from X11R5 (mit/util/scripts/install.sh), which was later released in X11R6 (xc/config/util/install.sh) with the following copyright and license. Copyright (C) 1994 X Consortium Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other deal- ings in this Software without prior written authorization from the X Consor- tium. FSF changes to this file are in the public domain. Calling this script install-sh is preferred over install.sh, to prevent `make' implicit rules from creating a file called install from it when there is no Makefile. This script is compatible with the BSD install script, but was written from scratch. ---------------------------------------------------------------------------- debian/cc1111.manpages0000644000000000000000000000041711773153613011605 0ustar debian/manpages/aslink.1 debian/manpages/asxxxx.1 debian/manpages/asx8051.1 debian/manpages/makebin.1 debian/manpages/packihx.1 debian/manpages/sdcc.1 debian/manpages/sdcclib.1 debian/manpages/sdcpp.1 debian/manpages/s51.1 debian/manpages/sdcdb.1 debian/manpages/ucsim.1 debian/lk_readnl.h0000644000000000000000000000234611773153613011306 0ustar /* lk_readnl.h - read a line from file into a buffer version 1.0.0, Aprile 25th, 2008 Copyright (c) 2008 Borut Razem This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Borut Razem borut.razem@siol.net */ #ifndef __LK_READNL_H #define __LK_READNL_H #include #ifdef __cplusplus extern "C" { #endif char *lk_readnl (char *s, int size, FILE * stream); #ifdef __cplusplus } #endif #endif /* __LK_READNL_H */ debian/lk_readnl.c0000644000000000000000000000460711773153613011303 0ustar /* lk_readnl.c - read a line from file into a buffer version 1.0.0, April 25th, 2008 Copyright (c) 2008 Borut Razem This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Borut Razem borut.razem@siol.net */ #include "lk_readnl.h" /******************************************************************************* lk_readnl lk_readnl() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. The newline character is not stored into the buffer. A '\0' is stored after the last character in the buffer. All the characters between size and the newline or EOF are skipped. lk_readnl() return s on success, and NULL on error or when end of file occurs while no characters have been read. *******************************************************************************/ char * lk_readnl (char *s, int size, FILE * stream) { static char eof_f = 0; int c = '\0'; char *s_o; char prev_c; if (eof_f) { eof_f = 0; return NULL; } s_o = s; --size; /* for null terminator */ while (size > 0) { prev_c = c; if ((c = getc (stream)) == '\n' || c == EOF) break; if (prev_c == '\r') { *s++ = prev_c; if (--size <= 0) break; } if (c != '\r') { *s++ = c; --size; } } *s = '\0'; while (c != '\n' && c != EOF) c = getc (stream); if (c == EOF) { if (s == s_o) return NULL; eof_f = 1; } return s_o; } debian/rules0000755000000000000000000001312411773153613010256 0ustar #!/usr/bin/make -f export DH_VERBOSE=1 # These are used for cross-compiling and for saving the configure script # from having to guess our platform (since we know it already) DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) export HOME=$(CURDIR)/build CFLAGS = `dpkg-buildflags --get CFLAGS` CFLAGS += -Wall -Wno-comment LDFLAGS = `dpkg-buildflags --get LDFLAGS` CPPFLAGS = `dpkg-buildflags --get CPPFLAGS` ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) CFLAGS += -g -O0 export STRIP=true endif ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) INSTALL_PROGRAM += -s endif clean: dh_testdir dh_testroot # Clean up files that Makefile should have cleaned rm -rf $(CURDIR)/build rm -f support/cpp/configargs.h,.log rm -f support/cpp/config.log rm -f support/cpp/config.status rm -f sim/ucsim/config.guess rm -f sim/ucsim/config.sub rm -f sim/ucsim/config.status rm -f sim/ucsim/config.log rm -f config.log rm -f device/lib/small-stack-auto/Makefile rm -f as/link/asxxxx_config.h rm -f device/lib/large/*.asm rm -f device/lib/medium/*.asm rm -f device/lib/small/*.asm rm -f device/lib/small-stack-auto/*.asm rm -f support/cpp/configargs.h find -type f -name '*.o' -exec rm -f {} \; find -type f -name '.stamp' -exec rm -f {} \; find . -name '*.rel' -exec rm -f {} \; #find 'device/lib/{small*,large,medium}' -name *.asm -exec rm -f {} \; find . -name '*.sym' -exec rm -f {} \; find . -name '*.lst' -exec rm -f {} \; # Clean up the Debian specific files rm -f config.status doc/sdccman.ps rm -f build-stamp configure-stamp install-arch-stamp install-indep-stamp install-stamp rm -f as/link/lk_readnl.c # Remove in next version rm -f as/link/lk_readnl.h # Remove in next version [ ! -f Makefile ] || $(MAKE) distclean dh_clean configure: configure-stamp configure-stamp: dh_testdir mkdir -p $(CURDIR)/build cp /usr/share/misc/config.sub sim/ucsim/config.sub cp /usr/share/misc/config.guess sim/ucsim/config.guess cp debian/lk_readnl.h as/link/lk_readnl.h # Remove in next version cp debian/lk_readnl.c as/link/lk_readnl.c # Remove in next version ./configure \ --host=$(DEB_HOST_GNU_TYPE) \ --build=$(DEB_BUILD_GNU_TYPE) \ --prefix=/usr \ --disable-avr-port \ --disable-ds390-port \ --disable-ds400-port \ --disable-gbz80-port \ --disable-hc08-port \ --enable-mcs51-port \ --disable-pic-port \ --disable-pic16-port \ --disable-xa51-port \ --disable-z80-port \ --disable-z80-port touch $@ build: build-arch build-indep build-arch: build-stamp build-indep: build-stamp build-stamp: configure-stamp dh_testdir $(MAKE) # cd doc && lyx -e ps sdccman.lyx touch $@ install: install-stamp install-stamp: build dh_testdir dh_testroot dh_installdirs dh_prep $(MAKE) install prefix=$(CURDIR)/debian/tmp/usr mkdir -p debian/tmp/usr/share/doc/cc1111 # install -o root -g root -m 644 doc/sdccman.ps debian/tmp/usr/share/doc/cc1111 mv debian/tmp/usr/share/doc/sdcc/* debian/tmp/usr/share/doc/cc1111/ # Add some scripts mkdir -p debian/tmp/usr/share/sdcc/scripts install -o root -g root -m 755 support/scripts/inc2h.pl debian/tmp/usr/share/sdcc/scripts install -o root -g root -m 755 support/scripts/keil2sdcc.pl debian/tmp/usr/share/sdcc/scripts #Remove extra license file rm -f $(CURDIR)/debian/tmp/usr/share/sdcc/lib/src/pic16/COPYING # Remove empty dirs: find $(CURDIR)/debian/tmp -type d -empty -delete #Clean up unnecessary directories rm -rf `find $(CURDIR)/debian/tmp -type d -name .deps` dh_install --sourcedir=debian/tmp mkdir -p $(CURDIR)/debian/cc1111/usr/share/lintian/overrides/ install -p -o root -g root -m 644 $(CURDIR)/debian/cc1111.overrides \ $(CURDIR)/debian/cc1111/usr/share/lintian/overrides/cc1111 # Install examples cp -a device/examples $(CURDIR)/debian/cc1111/usr/share/doc/cc1111 rm -rf $(CURDIR)/debian/cc1111/usr/share/doc/cc1111/examples/ds400 rm -rf $(CURDIR)/debian/cc1111/usr/share/doc/cc1111/examples/ds390 rm -rf $(CURDIR)/debian/cc1111/usr/share/doc/cc1111/examples/xa51 # clean up things cc1111 doesn't need rm -rf $(CURDIR)/debian/cc1111/usr/share/sdcc/lib/src/pic rm -rf $(CURDIR)/debian/cc1111/usr/share/sdcc/lib/src/pic16 rm -rf $(CURDIR)/debian/cc1111/usr/share/sdcc/lib/src/ds400 rm -rf $(CURDIR)/debian/cc1111/usr/share/sdcc/lib/src/hc08 rm -rf $(CURDIR)/debian/cc1111/usr/share/sdcc/lib/src/z80 rm -rf $(CURDIR)/debian/cc1111/usr/share/sdcc/lib/src/ds390 rm -rf $(CURDIR)/debian/cc1111/usr/share/sdcc/lib/src/gbz80 rm -rf $(CURDIR)/debian/cc1111/usr/share/sdcc/include/ds400rom.h rm -rf $(CURDIR)/debian/cc1111/usr/share/sdcc/include/*390* rm -rf $(CURDIR)/debian/cc1111/usr/share/sdcc/include/asm/pic rm -rf $(CURDIR)/debian/cc1111/usr/share/sdcc/include/asm/pic16 rm -rf $(CURDIR)/debian/cc1111/usr/share/sdcc/include/asm/z80 rm -rf $(CURDIR)/debian/cc1111/usr/share/sdcc/include/asm/gbz80 touch $@ # Must not depend on anything. This is to be called by binary-arch/binary-indep # in another 'make' thread. binary-common: dh_testdir dh_testroot dh_installchangelogs ChangeLog dh_installdocs dh_installman dh_installemacsen dh_link dh_strip -Xusr/share/sdcc/lib/ dh_compress dh_fixperms dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb # Build architecture-independent files here. binary-indep: install $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common # Build architecture-dependent files here. binary-arch: install $(MAKE) -f debian/rules DH_OPTIONS=-s binary-common binary: binary-arch binary-indep .PHONY: build-indep build-arch build clean binary-indep binary-arch binary install install-arch install-indep debian/source/0000755000000000000000000000000011773153613010475 5ustar debian/source/format0000644000000000000000000000001411773153613011703 0ustar 3.0 (quilt) debian/control0000644000000000000000000000203211773153613010575 0ustar Source: cc1111 Section: electronics Priority: optional Maintainer: Bdale Garbee Uploaders: Keith Packard Build-Depends: debhelper (>=7), autoconf, autotools-dev, libtool, flex, bison, libncurses5-dev Standards-Version: 3.9.3 Homepage: http://sdcc.sourceforge.net Package: cc1111 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Conflicts: sdcc, sdcc-libraries, sdcc-ucsim, sdcc-doc Description: C Compiler for TI/Chipcon 8051-based RF SOCs This is a C compiler and related tools for developing firmware for TI/Chipcon RF System on Chip (SOC) parts based on the 8051 processing core. These include at least the CC1110, CC1111, CC2510, and CC2511, CC2530, CC2531, CC2533, CC2543, and CC2544. . This package started as a fork of Debian SDCC 2.9.0-5, motivated both as a workaround for increases in the size of 8051 code generated by later versions of SDCC that cause AltOS to fail to build successfully, and a desire to incorporate support for source-level debugging on real hardware. debian/cc1111.install0000644000000000000000000000063611773153613011463 0ustar usr/bin/aslink usr/bin/asx8051 usr/bin/asranlib usr/bin/makebin usr/bin/packihx usr/bin/sdcc usr/bin/sdcclib usr/bin/sdcpp usr/share/sdcc/scripts usr/share/sdcc/include/ usr/share/sdcc/lib/ usr/bin/s51 usr/bin/sdcdb usr/bin/*.el usr/share/emacs/site-lisp/sdcc-ucsim/ usr/share/doc/ucsim/*.html usr/share/doc/cc1111/ usr/share/doc/ucsim/*.gif usr/share/doc/cc1111/ usr/share/doc/ucsim/*.jpg usr/share/doc/cc1111/ debian/cc1111.overrides0000644000000000000000000000332211773153613012012 0ustar # These files are binary files, but are in an arch-independent package # because they are compiled for a non Debian target processor cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/large/libfloat.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/large/libint.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/large/liblong.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/large/libsdcc.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/large/mcs51.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/medium/libfloat.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/medium/libint.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/medium/liblong.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/medium/libsdcc.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/medium/mcs51.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/small-stack-auto/libfloat.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/small-stack-auto/libint.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/small-stack-auto/liblong.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/small-stack-auto/libsdcc.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/small-stack-auto/mcs51.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/small/libfloat.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/small/libint.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/small/liblong.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/small/libsdcc.lib cc1111: arch-dependent-file-in-usr-share usr/share/sdcc/lib/small/mcs51.lib debian/manpages/0000755000000000000000000000000011773153613010770 5ustar debian/manpages/asxxxx.10000644000000000000000000000513611773153613012422 0ustar .TH ASxxxx 1 .SH NAME ASxxxx \- Series of microprocessor cross assemblers for SDCC. .SH SYNOPSIS .B asx8051 .I "[options] file1 [file2 file3 ... file6]" .br .B as-gbz80 .I "[options] file1 [file2 file3 ... file6]" .br .B as-z80 .I "[options] file1 [file2 file3 ... file6]" .br .SH WARNING The information in this man page is an extract from the full documentation of .B SDCC\c \&, and is limited to the meaning of the options. .PP For complete and current documentation, refer to the .B ASxxxx Cross Assembler Documentation\c \&, available in /usr/share/doc/sdcc-doc/aslink. .SH "DESCRIPTION" The .B ASxxxx\c \& assemblers are a series of microprocessor assemblers. Each assembler has a device specific section. .PP .B MCS51\c \& family is supported by .B asx8051\c \&. .br .B Z80\c \&family is supported by .B as-z80\c \&. .br .B GBZ80\c \& (GameBoy Z80-like CPU) is supported by .B as-gbz80\c \&. .SH OPTIONS The ASxxxx assemblers are command line oriented. The PC assemblers are started with the appropriate option(s) and file(s) to assemble following the assembler name. .TP .BI "\-d" decimal listing. .TP .BI "\-q" octal listing. .TP .BI "\-x" hex listing (default) .PP The listing radix affects the .lst, .rel, and .sym files. .TP .BI "\-j" add line number and debug information to file. .TP .BI "\-g" undefined symbols made global. .TP .BI "\-a" all user symbols made global. .TP .BI "\-l" create list output file1.lst. .TP .BI "\-o" create object output file1.rel. .TP .BI "\-s" create symbol output file1.sym. .TP .BI "\-p" disable listing pagination. .TP .BI "\-w" wide listing format for symbol table. .TP .BI "\-z" enable case sensitivity for symbols. .TP .BI "\-f" flag relocatable references by ` in the listing file. .TP .BI "\-ff" flag relocatable reference by mode in the listing file. .PP The file name for the .lst, .rel, and .sym files is the first file name specified in the command line. All output files are ascii text files which may be edited, copied, etc. The output files are the concatenation of all the input files, if files are to be assembled independently invoke the assembler for each file. .PP The .rel file contains a radix directive so that the linker will use the proper conversion for this file. Linked files may have different radices. .PP If the list .B (l)\c \& option is specified without the symbol table .B (s)\c \& option, the symbol table is placed at the end of the listing file. .SH SEE ALSO sdcc(1), aslink(1), asx8051, as-z80(1), as-gbz80(1). .SH AUTHOR This manual page was written by Aurelien Jarno , for the Debian GNU/Linux system (but may be used by others). debian/manpages/sdcc.10000644000000000000000000003756311773153613012004 0ustar .TH SDCC 1 .SH NAME sdcc \- Small Device C Compiler .SH SYNOPSIS .B sdcc .I "[options] filename" .SH WARNING The information in this man page is an extract from the full documentation of SDCC, and is limited to the meaning of the options. .PP For complete and current documentation, refer to the .B SDCC Compiler User Guide\c \&. .SH "DESCRIPTION" .B SDCC is a Freeware, retargettable, optimizing ANSI-C compiler. The current version targets Intel MCS51 based Microprocessors(8051, 8052, etc), Zilog Z80 based MCUs, and the Dallas DS80C390 variant. It can be retargetted for other microprocessors, support for PIC, AVR and 186 is under development. .PP .B SDCC\c \& uses .B ASXXXX\c \& & .B ASLINK\c \&, a Freeware, retargettable assembler & linker. .B SDCC\c \& has extensive language extensions suitable for utilizing various microcontrollers and underlying hardware effectively. .PP The compiler also allows inline assembler code to be embedded anywhere in a function. In addition, routines developed in assembly can also be called. .SH PROCESSOR SELECTION OPTIONS .TP .BI "\-mmcs51" Generate code for the MCS51 (8051) family of processors. This is the default processor target. .TP .BI "\-mds390" Generate code for the DS80C390 processor. .TP .BI "\-mds400" Generate code for the DS80C400 processor. .TP .BI "\-mz80" Generate code for the Z80 family of processors. .TP .BI "\-mgbz80" Generate code for the GameBoy Z80 processor. .TP .BI "\-mavr" Generate code for the Atmel AVR processor (In development, not complete). .TP .BI "\-mpic14" Generate code for the PIC 14-bit processors (In development, not complete). .TP .BI "\-mpic16" Generate code for the PIC 14-bit processors (In development, not complete). .TP .BI "\-mtlcs900h" Generate code for the Toshiba TLCS-900H processor (In development, not complete). .BI "\-mxa51" Generate code for the Phillips XA51 processor (In development, not complete). .SH PREPROCESSOR OPTIONS .TP .BI "\-I" "" The additional location where the pre processor will look for `<..h>' or `..h' files. .TP .BI "\-D " "" Command line definition of macros. Passed to the pre processor. .TP .BI "\-M" Tell the preprocessor to output a rule suitable for make describing the dependencies of each object file. For each source file, the preprocessor outputs one make-rule whose target is the object file name for that source file and whose dependencies are all the files `#include'd in it. This rule may be a single line or may be continued with `\\'-newline if it is long. The list of rules is printed on standard output instead of the preprocessed C program. .B `-M'\c \& implies .B `-E'\c \&. .TP .BI "-C" Tell the preprocessor not to discard comments. Used with the .B `-E' option. .TP .BI "\-MM" Like .B `-M'\c \& but the output mentions only the user header files included with `#include "file"'. System header files included with `#include ' are omitted. .TP .BI "\-A " "question(answer)" Assert the answer answer for question, in case it is tested with a preprocessor conditional such as `#if #question(answer)'. .B `-A-'\c \& disables the standard assertions that normally describe the target machine. .TP .BI "\-A " "question" (answer) Assert the answer answer for question, in case it is tested with a preprocessor conditional such as `#if #question(answer)'. .B `-A-'\c \& disables the standard assertions that normally describe the target machine. .TP .BI "-Umacro" Undefine macro macro. .B `-U'\c \& options are evaluated after all .B `-D'\c \& options, but before any .B `-include'\c \& and .B `-imacros'\c \& options. .TP .BI "\-dM" Tell the preprocessor to output only a list of the macro definitions that are in effect at the end of preprocessing. Used with the .B '-E'\c \& option. .TP .BI "\-dD" Tell the preprocessor to pass all macro definitions into the output, in their proper sequence in the rest of the output. .TP .BI "\-dN" Like .B `-dD'\c \&except that the macro arguments and contents are omitted. Only `#define name' is included in the output. .SH LINKER OPTIONS .TP .BI "\-L, \-lib\-path" "" This option is passed to the linkage editor's additional libraries search path. The path name must be absolute. Additional library files may be specified in the command line. See section Compiling programs for more details. .TP .BI "\-\-xram-loc " "" The start location of the external ram, default value is 0. The value entered can be in Hexadecimal or Decimal format, e.g.: .B --xram-loc 0x8000\c \& or .B --xram-loc 32768\c \&. .TP .BI "\-\-code-loc " "" The start location of the code segment, default value 0. Note when this option is used the interrupt vector table is also relocated to the given address. The value entered can be in Hexadecimal or Decimal format, e.g.: .B --code-loc 0x8000\c \& or .B --code-loc 32768\c \&. .TP .BI "\-\-stack-loc " "" The initial value of the stack pointer. The default value of the stack pointer is .B 0x07\c \& if only register bank 0 is used, if other register banks are used then the stack pointer is initialized to the location above the highest register bank used. eg. if register banks 1 & 2 are used the stack pointer will default to location .B 0x18\c \&. The value entered can be in Hexadecimal or Decimal format, eg. .B --stack-loc 0x20 or .B --stack-loc 32\c \&. If all four register banks are used the stack will be placed after the data segment (equivalent to .B --stack-after-data\c \&) .TP .BI "\-\-stack-after-data" This option will cause the stack to be located in the internal ram after the data segment. .TP .BI "\-\-data-loc " "" The start location of the internal ram data segment, the default value is .B 0x30\c \&. The value entered can be in Hexadecimal or Decimal format, eg. .B --data-loc 0x20\c \& or .B --data-loc 32\c \&. .TP .BI "--idata-loc " "" The start location of the indirectly addressable internal ram, default value is .B 0x80\c \&. The value entered can be in Hexadecimal or Decimal format, eg. .B --idata-loc 0x88\c \& or .B --idata-loc 136\c \&. .TP .BI "\-\-out\-fmt\-ihx" The linker output (final object code) is in Intel Hex format. (This is the default option). .TP .BI "\-\-out\-fmt\-s19" The linker output (final object code) is in Motorola S19 format. .SH MCS51 OPTIONS .TP .BI "\-\-model\-large" Generate code for Large model programs see section Memory Models for more details. If this option is used all source files in the project should be compiled with this option. In addition the standard library routines are compiled with small model, they will need to be recompiled. .TP .BI "\-\-model\-small" Generate code for Small Model programs see section Memory Models for more details. This is the default model. .SH DS390 / DS400 OPTIONS .TP .BI "\-\-model\-flat24" Generate 24-bit flat mode code. This is the one and only that the ds390 code generator supports right now and is default when using .B -mds390\c \&. .TP .BI "\-\-protect\-sp\-update" Disable interrupts during ESP:SP updates. .TP .BI "\_-\-stack\-10bit" Generate code for the 10 bit stack mode of the Dallas DS80C390 part. This is the one and only that the ds390 code generator supports right now and is default when using .B -mds390\c \&. In this mode, the stack is located in the lower 1K of the internal RAM, which is mapped to .B 0x400000 \&. Note that the support is incomplete, since it still uses a single byte as the stack pointer. This means that only the lower 256 bytes of the potential 1K stack space will actually be used. However, this does allow you to reclaim the precious 256 bytes of low RAM for use for the DATA and IDATA segments. The compiler will not generate any code to put the processor into 10 bit stack mode. It is important to ensure that the processor is in this mode before calling any re-entrant functions compiled with this option. In principle, this should work with the .B --stack-auto option\c \&, but that has not been tested. It is incompatible with the .B --xstack\c \& option. It also only makes sense if the processor is in 24 bit contiguous addressing mode (see the .B --model-flat24\c \& option). .SH Z80 Options .TP .BI "\-\-callee\-saves\-bc" Force a called function to always save BC. .TP .BI "\-\-no\-std\-crt0" When linking, skip the standard crt0.o object file. You must provide your own crt0.o for your system when linking. .SH OPTIMIZATIONS OPTIONS .TP .BI "\-\-nogcse" Will not do global subexpression elimination, this option may be used when the compiler creates undesirably large stack/data spaces to store compiler temporaries. A warning message will be generated when this happens and the compiler will indicate the number of extra bytes it allocated. It recommended that this option NOT be used, .B #pragma NOGCSE\c \& can be used to turn off global subexpression elimination for a given function only. .TP .BI "\-\-noinvariant" Will not do loop invariant optimizations, this may be turned off for reasons explained for the previous option. For more details of loop optimizations performed see section Loop Invariants.It recommended that this option NOT be used, .B #pragma NOINVARIANT\c \& can be used to turn off invariant optimizations for a given function only. .TP .BI "\-\-noinduction" Will not do loop induction optimizations, see section strength reduction for more details. It is recommended that this option is NOT used, .B #pragma NOINDUCTION\c \& can be used to turn off induction optimizations for a given function only. .TP .BI "\-\-nojtbound" Will not generate boundary condition check when switch statements are implemented using jump-tables. It is recommended that this option is NOT used, .B #pragma NOJTBOUND\c \& can be used to turn off boundary checking for jump tables for a given function only. .TP .BI "\-\-noloopreverse" Will not do loop reversal optimization. .SH OTHER OPTIONS .TP .BI "\-c, \-\-compile\-only" will compile and assemble the source, but will not call the linkage editor. .TP .BI "\-E" Run only the C preprocessor. Preprocess all the C source files specified and output the results to standard output. .TP .BI "\-\-stack-auto" All functions in the source file will be compiled as reentrant, i.e. the parameters and local variables will be allocated on the stack. If this option is used all source files in the project should be compiled with this option. .TP .BI "\-\-xstack" Uses a pseudo stack in the first 256 bytes in the external ram for allocating variables and passing parameters. .TP .BI "\-\-callee-saves " "function1[,function2][,function3]...." The compiler by default uses a caller saves convention for register saving across function calls, however this can cause unneccessary register pushing & popping when calling small functions from larger functions. This option can be used to switch the register saving convention for the function names specified. The compiler will not save registers when calling these functions, no extra code will be generated at the entry & exit for these functions to save & restore the registers used by these functions, this can .I SUBSTANTIALLY\c \& reduce code & improve run time performance of the generated code. In the future the compiler (with interprocedural analysis) will be able to determine the appropriate scheme to use for each function call. .I DO NOT\c \& use this option for built-in functions such as .B _muluint\c \&..., if this option is used for a library function the appropriate library function needs to be recompiled with the same option. If the project consists of multiple source files then all the source file should be compiled with the same .B --callee-saves\c \& option string. .TP .BI "\-\-debug" When this option is used the compiler will generate debug information, that can be used with the .B SDCDB\c \&. The debug information is collected in a file with .cdb extension. .TP .BI "\-\-regextend" This option is obsolete and isn't supported anymore. .TP .BI "\-\-noregparms" This option is obsolete and isn't supported anymore. .TP .BI "\-\-peep-file" " This option can be used to use additional rules to be used by the peep hole optimizer. .TP .BI "\-S" Stop after the stage of compilation proper; do not assemble. The output is an assembler code file for the input file specified. .TP .BI "\-Wa_" "asmOption[,asmOption]...]" Pass the asmOption to the assembler. .TP .BI "\-Wl_" "linkOption[,linkOption]...]" Pass the linkOption to the linker. .TP .BI "\-\-int-long-reent" Integer (16 bit) and long (32 bit) libraries have been compiled as reentrant. Note by default these libraries are compiled as non-reentrant. .TP .BI "\-\-cyclomatic" This option will cause the compiler to generate an information message for each function in the source file. The message contains some important information about the function. The number of edges and nodes the compiler detected in the control flow graph of the function, and most importantly the cyclomatic complexity. .TP .BI "\-\-float\-reent" Floating point library is compiled as reentrant. .TP .BI "\-\-nooverlay" The compiler will not overlay parameters and local variables of any function, see section Parameters and local variables for more details. .TP .BI "\-\-main\-return" This option can be used when the code generated is called by a monitor program. The compiler will generate a 'ret' upon return from the 'main' function. The default option is to lock up i.e. generate a 'ljmp '. .TP .BI "\-\-no\-peep" Disable peep-hole optimization. .TP .BI "\-\-peep\-asm" Pass the inline assembler code through the peep hole optimizer. This can cause unexpected changes to inline assembler code, please go through the peephole optimizer rules defined in the source file tree '/peeph.def' before using this option. .TP .BI "\-\-iram\-size " "" Causes the linker to check if the interal ram usage is within limits of the given value. .TP .BI "\-\-nostdincl" This will prevent the compiler from passing on the default include path to the preprocessor. .TP .BI "\-\-nostdlib" This will prevent the compiler from passing on the default library path to the linker. .TP .BI "\-\-verbose" Shows the various actions the compiler is performing. .TP .BI "\-V" Shows the actual commands the compiler is executing. .SH INTERMEDIATE DUMP OPTIONS The following options are provided for the purpose of retargetting and debugging the compiler. These provided a means to dump the intermediate code (iCode) generated by the compiler in human readable form at various stages of the compilation process. .TP .BI "\-\-dumpraw" This option will cause the compiler to dump the intermediate code into a file of named . .B dumpraw\c \& just after the intermediate code has been generated for a function, i.e. before any optimizations are done. The basic blocks at this stage ordered in the depth first number, so they may not be in sequence of execution. .TP .BI "\-\-dumpgcse" Will create a dump of iCode's, after global subexpression elimination, into a file named .dumpgcse. .TP .BI "\-\-dumpdeadcode" Will create a dump of iCode's, after deadcode elimination, into a file named .dumpdeadcode. .TP .BI "\-\-dumploop" Will create a dump of iCode's, after loop optimizations, into a file named .dumploop. .TP .BI "\-\-dumprange" Will create a dump of iCode's, after live range analysis, into a file named .dumprange. .TP .BI "\-\-dumlrange" Will dump the life ranges for all symbols. .TP .BI "\-\-dumpregassign" Will create a dump of iCode's, after register assignment, into a file named .dumprassgn. .TP .BI "\-\-dumplrange" Will create a dump of the live ranges of iTemp's .TP .BI "\-\-dumpall" Will cause all the above mentioned dumps to be created. .SH COPYING The entire source code for the compiler is distributed under GNU General Public License. .SH SEE ALSO sdcpp(1), asxxxx(1), aslink(1). .SH AUTHOR This manual page was written by Aurelien Jarno , for the Debian GNU/Linux system (but may be used by others). debian/manpages/packihx.10000644000000000000000000000115111773153613012477 0ustar .TH PACKIHX 1 .SH NAME packihx \- A tool to pack Intel hex files for SDCC .SH SYNOPSIS .B packihx .SH "DESCRIPTION" This manual page documents briefly the .BR packihx command. This manual page was written for the Debian GNU/Linux distribution because the original program does not have a manual page. Instead, you can read the documentation in /usr/share/doc/sdcc-doc. .PP .B SDCC is a Freeware, retargettable, optimizing ANSI-C compiler designed for 8 bit Microprocessors. .SH AUTHOR This manual page was written by Aurelien Jarno , for the Debian GNU/Linux system (but may be used by others). debian/manpages/ucsim.10000644000000000000000000000763211773153613012202 0ustar .TH UCSIM 1 .SH NAME s51, savr, sz80 \- 8051, AVR and Z80 microcontrollers simulator for SDCC. .SH SYNOPSIS .B s51 .I "[options] filenames" .br .B savr .I "[options] filenames" .br .B sz80 .I "[options] filenames" .SH WARNING The information in this man page is an extract from the full documentation of .B SDCC\c \&, and is limited to the meaning of the options. .PP For complete and current documentation, refer to the .B ucSim simulator User Guide\c \&. .SH "DESCRIPTION" .B ucSim\c \& is a microcontroller simulator. It is extensible to support different microcontroller families. .PP .B MCS51\c \& family is simulated by\c .B s51\c \&. .br .B AVR\c \& family is simulated by .B savr\c \&. .br .B Z80\c \& processor is simulated by .B sz80\c \&. .PP Specified files must be names of Intel hex files. Simulator loads them in specified order into the ROM of the simulated system. .SH OPTIONS .TP .BI "\-t " "CPU" Type of CPU. Recognized types are: 51, 8051, 8751, C51, 80C51, 87C51, 31, 8031, C31, 80C31, 52, 8052, 8752, C52, 80C52, 87C52, 32, 8032, C32, 80C32, 51R, 51RA, 51RB, 51RC, C51R, C51RA, C51RB, C51RC, 89C51R, 251, C251, DS390, DS390F. Note that recongition of a CPU type as option does not mean that the simulator can simulate that kind of CPU. Default type is C51. DS390 supports Dallas DS80C390 dual-dptr operations, DS390F supports minimal flat24 mode code and dual-dptr operations. .TP .BI "\-X " "freq[k|M]" XTAL frequency is .I freq\c \& Hertz. .B k\c \& or .B M\c \& can be used to specify frequency in kHZ or MHz. Space is not allowed between the number and the .B k\c \& or .B M\c \&. Default value is 11059200 Hz. .TP .BI "\-c " "file" Open command console on .I file\c \&. Command consoles are on standard input and output by default. Using this option the console can be opened on any file for example on the serial interface of the computer. .TP .BI "\-Z " "portnum" Listen for incoming connections on port .I portnum\c \&. Using this option uCsim can serve multiple consoles. You can get a console by simply telnet into machine running .B uCsim\c \&to port .I portnumber\c \&. This option is not available on platforms which doesn't support BSD networking. .TP .BI "\-s " "file" Connect serial interface of the simulated microcontroller to the .I file\c \&. Nothing is used by default which means that characters transmitted by serial interface of the simulated microcontroller go to nowhere and it will never receive anything. If you are going to communicate with serial interface interactively the best idea is to specify a teminal with .B -s\c \& option. .TP .BI "-S " "in=file,out=file" Using this option you can specify different files for input and output streams that .B uCsim\c \& uses to simulate microprocessor's serial interface. .TP .BI "\-p prompt" Using this option you can specify any string to be the prompt of command interpreter, for example: .nf $ s51 -p "s51> " ucsim 0.2.12, Copyright (C) 1997 Daniel Drotos, Talker Bt. ucsim comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. s51> .fi .TP .BI "\-P" Prompt will be a null ('\\0') character. This feature can be useful for programs which controlls simulator through a pipe. .TP .BI "\-V" Verbose mode. The simulator notifies you about some kind of internal actions for example interrupts. Messages are printed on command console. .TP .BI "\-v" Print out version number and stop. .TP .BI "\-H" Print out types of known CPUs. Names printed out by this option can be used to determine CPU type using -t option. .TP .BI "\-h" Print out a short help about the options and stop. .SH COPYING ucSim is distributed under the GNU General Public License. .SH SEE ALSO sdcc(1), s51(1), savr(1), sz80(1). .SH AUTHOR This manual page was written by Aurelien Jarno , for the Debian GNU/Linux system (but may be used by others). debian/manpages/sdcpp.10000644000000000000000000001155411773153613012171 0ustar .TH SDCPP 1 .SH NAME sdcpp \- C preprocessor for SDCC .SH SYNOPSIS .B sdcppold .I "[options] filename" .SH "DESCRIPTION" This manual page documents briefly the .BR sdccp command. This manual page was written for the Debian GNU/Linux distribution because the original program does not have a manual page. Instead, you can read the documentation in /usr/share/doc/sdcc-doc. .PP .B SDCC is a Freeware, retargettable, optimizing ANSI-C compiler designed for 8 bit Microprocessors. .SH OPTIONS .TP .BI "\-include " "" Include the contents of .I \c \& before other files. .TP .BI "\-imacros " "" Accept definition of macros in .I \c \&. .TP .BI "\-iprefix " "" Specify .I \c \& as a prefix for next two options. .TP .BI "\-iwithprefix " "" Add .I \c \& to the end of the system include path. .TP .BI "\-iwithprefixbefore " "" Add .I \c \& to the end of the main include path. .TP .BI "\-isystem " "" Add .I \c \& to the start of the system include path. .TP .BI "\-idirafter " "" Add .I \c \& to the end of the system include path. .TP .BI "-I " "" Add .I \c \& to the end of the main include path. .TP .B "\-I\-" Fine-grained include path control; see info docs. .TP .B "\-nostdinc" Do not search system include directories (dirs specified with .B -isystem\c \& will still be used). .TP .B "\-nostdinc++" Do not search system include directories for C++. .TP .BI "-o " "" Put output into .I \c \&. .TP .B "\-pedantic" Issue all warnings demanded by strict ISO C. .TP .B "\-pedantic-errors" Issue .I \-pedantic\c \& warnings as errors instead. .TP .B "\-trigraphs" Support ISO C trigraphs. .TP .B "\-lang-c" Assume that the input sources are in C. .TP .B "\-lang-c89" Assume that the input sources are in C89. .TP .B "\-lang-c++" Assume that the input sources are in C++. .TP .B "\-lang-objc" Assume that the input sources are in ObjectiveC. .TP .B "\-lang-objc++" Assume that the input sources are in ObjectiveC++. .TP .B "\-lang-asm" Assume that the input sources are in assembler. .TP .BI "\-std=" "" Specify the conformance standard; one of: gnu89, gnu99, c89, c99, iso9899:1990, iso9899:199409, iso9899:1999 .TP .B "\-+" Allow parsing of C++ style features. .TP .B "\-w" Inhibit warning messages. .TP .B "\-Wtrigraphs" Warn if trigraphs are encountered. .TP .B "\-Wno-trigraphs" Do not warn about trigraphs. .TP .B "\-Wcomment{s}" Warn if one comment starts inside another. .TP .B "\-Wno-comment{s}" Do not warn about comments. .TP .B "\-Wtraditional" Warn about features not present in traditional C; .TP .B "\-Wno-traditional" Do not warn about traditional C; .TP .B "\-Wundef" Warn if an undefined macro is used by #if. .TP .B "\-Wno-undef" Do not warn about testing undefined macros. .TP .B "\-Wimport" Warn about the use of the #import directive. .TP .B "\-Wno-import" Do not warn about the use of #import. .TP .B "\-Werror" Treat all warnings as errors. .TP .B "\-Wno-error" Do not treat warnings as errors. .TP .B "\-Wsystem-headers" Do not suppress warnings from system headers. .TP .B "\-Wno-system-headers" Suppress warnings from system headers. .TP .B "\-Wall" Enable all preprocessor warnings. .TP .B "\-M" Generate make dependencies. .TP .B "\-MM" As .B "\-M"\c \&, but ignore system header files. .TP .BI "\-MF " "" Write dependency output to the given file. .TP .B "\-MG" Treat missing header file as generated files. .TP .B "\-MP" Generate phony targets for all headers. .TP .BI "\-MQ " "" Add a MAKE-quoted target. .TP .BI "\-MT " "" Add an unquoted target. .TP .BI "\-D" "" Define a .I \c \& with string '1' as its value. .TP .BI "\-D" "=" Define a .I \c \& with .I \c \& as its value. .TP .BI "\-A" " ()" Assert the .I \c \& to .I \c \&. .TP .BI "\-A\-" " ()" Disable .I \c \& to .I \c \&. .TP .BI "-U" "" Undefine .I \c \&. .TP .B "\-H" Print the name of header files as they are used. .TP .B "\-C" Do not discard comments. .TP .B "\-dM" Display a list of macro definitions active at end. .TP .B "\-dD" Preserve macro definitions in output. .TP .B "\-dN" As .B \-dD\c \& except that only the names are preserved. .TP .B "\-dI" Include #include directives in the output. .TP .B "\-fpreprocessed" Treat the input file as already preprocessed. .TP .BI "\-ftabstop=" "" Distance between tab stops for column reporting. .TP .B "\-P" Do not generate #line directives. .TP .B "\-$" Do not allow '$' in identifiers. .TP .B "\-remap" Remap file names when including files. .TP .B "\-v or \-\-version" Display the version number. .TP .B "\-h or \-\-help" Show summary of options. .SH AUTHOR This manual page was written by Aurelien Jarno , for the Debian GNU/Linux system (but may be used by others). debian/manpages/makebin.10000644000000000000000000000130411773153613012456 0ustar .TH MAKEBIN 1 .SH NAME makebin \- convert a Intel IHX file to binary .SH SYNOPSIS .B makebin .I "[options] filename" .SH "DESCRIPTION" This manual page documents briefly the .BR makebin command. This manual page was written for the Debian GNU/Linux distribution because the original program does not have a manual page. Instead, you can read the documentation in /usr/share/doc/sdcc-doc. .PP .B makebin convert a Intel IHX file to binary. .SH OPTIONS .TP .B \-h Show summary of options. .TP .B \-p Pack the file. .TP .BI \-s " romsize" Specify the size of the ROM. .SH AUTHOR This manual page was written by Aurelien Jarno , for the Debian GNU/Linux system (but may be used by others). debian/manpages/sdcdb.10000644000000000000000000000460711773153613012140 0ustar .TH SDCDB 1 .SH NAME sdcdb \- Source debugger for SDCC .SH SYNOPSIS .B sdcdb [options] filename .SH WARNING The information in this man page is an extract from the full documentation of SDCC, and is limited to the meaning of the options. .PP For complete and current documentation, refer to the .B SDCC Compiler User Guide\c \&. .SH "DESCRIPTION" .B sdcdb\c \& is a source debugger for .B SDCC\c \&. It uses .B ucSim\c \& to execute the program, the programm execution is controlled by the debugger. .PP The command interface for the debugger has been deliberately kept as close the GNU debugger gdb, as possible. This will help the integration with existing graphical user interfaces (like ddd, xxgdb or xemacs) existing for the GNU debugger. .SH STARTING THE DEBUGGER The debugger can be started using the following command line (Assume the file you are debugging has the file name foo): .PP .B sdcdb foo .PP The debugger will look for the following files: .PP .nf foo.c - the source file. foo.cdb - the debugger symbol information file. foo.ihx - the intel hex format object file. .fi .SH OPTIONS .TP .BI "\-directory=" "" This option can used to specify the directory search list. The debugger will look into the directory list specified for source, cdb & ihx files. The items in the directory list must be separated by ':', e.g. if the source files can be in the directories /home/src1 and /home/src2, the .B -directory\c \& option should be .B -directory=/home/src1:/home/src2\c \&. Note there can be no spaces in the option. .TP .BI "\-cd " "" Change to the . .TP .BI "\-fullname" Used by GUI front ends. .TP .BI "\-cpu " "" This argument is passed to the simulator. Please see the simulator docs for details. .TP .BI "\-X " "" This option is passed to the simulator. Please see the simulator docs for details. .TP .BI "\-s " "" This option is passed to simulator. Please see the simulator docs for details. .TP .BI "\-S " "" This argument is passed to simulator. Please see the simulator docs for details. .SH COPYING The entire source code for the debugger is distributed under GNU General Public License. .SH SEE ALSO sdcc(1), ucsim(1), s51(1), savr(1), sz80(1). .SH AUTHOR This manual page was written by Aurelien Jarno , for the Debian GNU/Linux system (but may be used by others). debian/manpages/link-hc08.10000644000000000000000000000002211773153613012541 0ustar .so man1/aslink.1 debian/manpages/aslink.10000644000000000000000000000600011773153613012327 0ustar .TH ASLINK 1 .SH NAME ASLINK \- companion linker for the ASxxxx assemblers. .SH SYNOPSIS .B aslink .I "[options] filenames" .br .B link-gbz80 .I "[options] filenames" .br .B link-z80 .I "[options] filenames" .br .SH WARNING The information in this man page is an extract from the full documentation of .B SDCC\c \&, and is limited to the meaning of the options. .PP For complete and current documentation, refer to the .B ASxxxx Cross Assembler Documentation\c \&, available in /usr/share/doc/sdcc-doc/aslink. .SH "DESCRIPTION" The .B ASLINK\c \& is general relocating companion linker for the .B ASxxx\c \& assemblers. .PP .B MCS51\c \& family is supported by .B aslink\c \&. .br .B Z80\c \&family is supported by .B link-z80\c \&. .br .B GBZ80\c \& (GameBoy Z80-like CPU) is supported by .B link-gbz80\c \&. .SH OPTIONS The linker may run in the command line mode or command file modes. The allowed startup linker commands are: .TP .BI "\-c/\-f" command line / command file modes .TP .BI "\-p/\-n" enable/disable echo file.lnk input to stdout .PP If command line mode is selected, all linker commands come from stdin, if the command file mode is selected the commands are input from the specified file (extension must be .lnk). .PP After invoking the linker the valid options are: .TP .BI .TP .BI "\-i/\-s" Intel Hex (file.ihx) or Motorola S19 (file.s19) image output file. .TP .BI "\-z" Specifies that symbol names are case sensitive. .TP .BI "\-m" Generate a map file (file.map). This file contains a list of the symbols (by area) with absolute addresses, sizes of linked areas, and other linking information. .TP .BI "\-w" Specifies that a wide listing format be used for the map file. .TP .BI "\-xdq" Specifies the number radix for the map file (Hexidecimal, Decimal, or Octal). .TP .BI "\-u" Generate an updated listing file (file.rst) derived from the relocated addresses and data from the linker. .TP .BI "fileN" Files to be linked. Files may be on the same line as the above options or on a separate line(s) one file per line or multiple files separated by spaces or tabs. .TP .BI "-b " "area = expression" " (one definition per line)" This specifies an area base address where the expression may contain constants and/or defined symbols from the linked files. .TP .BI "-g " "symbol = expression" " (one definition per line)" This specifies the value for the symbol where the expression may contain constants and/or defined symbols from the linked files. .TP .BI "-k " "library directory path" " (one definition per line)" This specifies one possible path to an object library. More than one path is allowed. .TP .BI "-l " "library file specification" " (one definition per line)" This specifies a possible library file. More than one file is allowed. .TP .BI "-e " or null line, terminates input to the linker. .SH SEE ALSO sdcc(1), asxxxx(1), link-z80(1), link-gbz80(1). .SH AUTHOR This manual page was written by Aurelien Jarno , for the Debian GNU/Linux system (but may be used by others). debian/manpages/shc08.10000644000000000000000000000002111773153613011770 0ustar .so man1/ucsim.1 debian/manpages/sz80.10000644000000000000000000000002111773153613011647 0ustar .so man1/ucsim.1 debian/manpages/asx8051.10000644000000000000000000000002211773153613012155 0ustar .so man1/asxxxx.1 debian/manpages/sdcclib.10000644000000000000000000000202111773153613012450 0ustar .TH SDCCLIB 1 .SH NAME sdcclib \- SDCC librarian .SH SYNOPSIS .B sdcclib .I " [-options] library relfile" .SH WARNING The information in this man page is an extract from the full documentation of SDCC, and is limited to the meaning of the options. .PP For complete and current documentation, refer to the .B SDCC Compiler User Guide\c \&. .SH DESCRIPTION sdcclib can be used to embed all the modules belonging to a library in the library file itself. This results in a larger library file, but it greatly reduces the number of disk files accessed by the linker. .SH OPTIONS .TP .B "\-a" Adds relfile to library. If relfile exists, replaces it. .TP .B "\-d" Deletes relfile from library. .TP .B "\-e" Extracts relfile from library. .TP .B "\-s" Dumps symbols of library. .TP .B "\-m" Dumps modules of library. .TP .B "\-v" Displays program version. .TP .B "\-h" Displays help. .SH SEE ALSO sdcc(1). .SH AUTHOR This manual page was written by Aurelien Jarno , for the Debian GNU/Linux system (but may be used by others). debian/manpages/as-gbz80.10000644000000000000000000000002211773153613012377 0ustar .so man1/asxxxx.1 debian/manpages/as-z80.10000644000000000000000000000002211773153613012066 0ustar .so man1/asxxxx.1 debian/manpages/link-gbz80.10000644000000000000000000000002211773153613012731 0ustar .so man1/aslink.1 debian/manpages/link-z80.10000644000000000000000000000002211773153613012420 0ustar .so man1/aslink.1 debian/manpages/savr.10000644000000000000000000000002111773153613012016 0ustar .so man1/ucsim.1 debian/manpages/s51.10000644000000000000000000000002111773153613011453 0ustar .so man1/ucsim.1 debian/manpages/as-hc08.10000644000000000000000000000002211773153613012207 0ustar .so man1/asxxxx.1 debian/cc1111.dirs0000644000000000000000000000004111773153613010744 0ustar usr/bin usr/share/cc1111/scripts debian/patches/0000755000000000000000000000000011773153613010624 5ustar debian/patches/02_result_type_gptr0000644000000000000000000000177611773153613014476 0ustar --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -863,6 +863,8 @@ ftype = (*actParm)->ftype; + resultType = RESULT_TYPE_NONE; + /* If it's a char, upcast to int. */ if (IS_INTEGRAL (ftype) && (getSize (ftype) < (unsigned) INTSIZE)) @@ -874,12 +876,14 @@ { newType = newAst_LINK (copyLinkChain(ftype)); DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer; + resultType = RESULT_TYPE_GPTR; } if (IS_AGGREGATE (ftype)) { newType = newAst_LINK (copyLinkChain (ftype)); DCL_TYPE (newType->opval.lnk) = port->unqualified_pointer; + resultType = RESULT_TYPE_GPTR; } if (newType) @@ -890,7 +894,7 @@ (*actParm)->filename = (*actParm)->right->filename; (*actParm)->lineno = (*actParm)->right->lineno; - decorateType (*actParm, RESULT_TYPE_NONE); + decorateType (*actParm, resultType); } return 0; } /* vararg */ debian/patches/01_fix_getline0000644000000000000000000001367511773153613013360 0ustar --- a/as/link/hc08/Makefile.in +++ b/as/link/hc08/Makefile.in @@ -46,7 +46,7 @@ ASXXLIBSRC = strcmpi.c -LKLIBSRC = getline.c lkaomf51.c lkar.c lkdata.c lkeval.c \ +LKLIBSRC = lk_readnl.c lkaomf51.c lkar.c lkdata.c lkeval.c \ lkhead.c lklex.c lklib.c lklibr.c lklist.c \ lknoice.c lkrel.c lksdcclib.c lkstore.c lksym.c --- a/as/link/lklib.c +++ b/as/link/lklib.c @@ -31,7 +31,7 @@ #include -#include "getline.h" +#include "lk_readnl.h" #include "aslink.h" #include "lklibr.h" #include "lkrel.h" @@ -51,7 +51,7 @@ { char relfil[NINPUT]; - while (getline (relfil, sizeof (relfil), libfp) != NULL) + while (lk_readnl (relfil, sizeof (relfil), libfp) != NULL) { FILE *fp; char str[PATH_MAX]; @@ -126,7 +126,7 @@ D ("Searching symbol: %s\n", name); - while (getline (relfil, sizeof (relfil), libfp) != NULL) + while (lk_readnl (relfil, sizeof (relfil), libfp) != NULL) { char str[PATH_MAX]; FILE *fp; @@ -206,7 +206,7 @@ * * functions called: * int fclose() c_library - * char *getline() getline.c + * char *lk_readnl() lk_readnl.c * FILE * fopen() c_library * VOID link_main() lkmain.c * int strlen() c_library --- a/as/link/lksdcclib.c +++ b/as/link/lksdcclib.c @@ -32,13 +32,13 @@ #include #include -#include "getline.h" +#include "lk_readnl.h" #include "aslink.h" #include "lklibr.h" #include "lkrel.h" #define EQ(A,B) !strcmp((A),(B)) -#define MAXLINE 254 /*when using getline */ +#define MAXLINE 254 /*when using lk_readnl */ static int @@ -72,14 +72,14 @@ char str[NINPUT]; int state = 0; - while (getline (str, sizeof (str), libfp) != NULL) + while (lk_readnl (str, sizeof (str), libfp) != NULL) { switch (state) { case 0: if (EQ (str, "")) { - if (NULL != getline (str, sizeof (str), libfp) && EQ (str, ModName)) + if (NULL != lk_readnl (str, sizeof (str), libfp) && EQ (str, ModName)) state = 1; else return 0; @@ -105,7 +105,7 @@ long IndexOffset = 0; pmlibrarysymbol ThisSym = NULL; - while (getline (FLine, sizeof (FLine), libfp)) + while (lk_readnl (FLine, sizeof (FLine), libfp)) { switch (state) { @@ -113,7 +113,7 @@ if (EQ (FLine, "")) { /*The next line has the size of the index */ - getline (FLine, sizeof (FLine), libfp); + lk_readnl (FLine, sizeof (FLine), libfp); IndexOffset = atol (FLine); state = 1; } @@ -128,7 +128,7 @@ /* The next line has the name of the module and the offset of the corresponding embedded file in the library */ - getline (FLine, sizeof (FLine), libfp); + lk_readnl (FLine, sizeof (FLine), libfp); sscanf (FLine, "%s %ld", ModName, &FileOffset); state = 2; @@ -205,7 +205,7 @@ int state = 0; int ret = 0; - while (getline (str, sizeof (str), libfp) != NULL) + while (lk_readnl (str, sizeof (str), libfp) != NULL) { switch (state) { @@ -239,7 +239,7 @@ int state = 0; long IndexOffset = 0, FileOffset; - while (getline (FLine, sizeof (FLine), libfp)) + while (lk_readnl (FLine, sizeof (FLine), libfp)) { char filspc[PATH_MAX]; @@ -260,7 +260,7 @@ if (EQ (FLine, "")) { /* The next line has the size of the index */ - getline (FLine, sizeof (FLine), libfp); + lk_readnl (FLine, sizeof (FLine), libfp); IndexOffset = atol (FLine); state = 1; } @@ -271,7 +271,7 @@ { /* The next line has the name of the module and the offset of the corresponding embedded file in the library */ - getline (FLine, sizeof (FLine), libfp); + lk_readnl (FLine, sizeof (FLine), libfp); sscanf (FLine, "%s %ld", ModName, &FileOffset); state = 2; } --- a/sim/ucsim/cmd.src/newcmdposix.cc +++ b/sim/ucsim/cmd.src/newcmdposix.cc @@ -207,7 +207,7 @@ char *s= NULL; #ifdef HAVE_GETLINE - if (getline(&s, 0, in) < 0) + if (lk_readln(&s, 0, in) < 0) return(0); #elif defined HAVE_GETDELIM size_t n= 30; --- a/as/link/lkrel.c +++ b/as/link/lkrel.c @@ -32,7 +32,7 @@ #include #include -#include "getline.h" +#include "lk_readnl.h" #include "aslink.h" #include "lkrel.h" @@ -79,7 +79,7 @@ end = (size >= 0) ? ftell (libfp) + size : -1; - while ((end < 0 || ftell (libfp) < end) && getline (str, sizeof (str), libfp) != NULL) + while ((end < 0 || ftell (libfp) < end) && lk_readnl (str, sizeof (str), libfp) != NULL) { if (0 == strcmp (str, "")) return 1; @@ -110,7 +110,7 @@ * our object file and don't go into the next one. */ - while ((end < 0 || ftell (fp) < end) && getline (buf, sizeof (buf), fp) != NULL) + while ((end < 0 || ftell (fp) < end) && lk_readnl (buf, sizeof (buf), fp) != NULL) { char symname[NINPUT]; char c; --- a/as/link/mcs51/Makefile.in +++ b/as/link/mcs51/Makefile.in @@ -46,7 +46,7 @@ ASXXLIBSRC = strcmpi.c -LKLIBSRC = getline.c lkaomf51.c lkar.c lkdata.c lkeval.c \ +LKLIBSRC = lk_readnl.c lkaomf51.c lkar.c lkdata.c lkeval.c \ lkhead.c lklex.c lklib.c lklibr.c lklist.c \ lknoice.c lkrel.c lksdcclib.c lkstore.c lksym.c --- a/as/link/z80/Makefile.in +++ b/as/link/z80/Makefile.in @@ -13,7 +13,7 @@ LKLIB = $(srcdir)/.. -LKLIBSRC = getline.c lkaomf51.c lkar.c lkdata.c lkeval.c \ +LKLIBSRC = lk_readnl.c lkaomf51.c lkar.c lkdata.c lkeval.c \ lkhead.c lklex.c lklib.c lklibr.c lklist.c \ lknoice.c lkrel.c lksdcclib.c lkstore.c lksym.c debian/patches/04_libtool_fix0000644000000000000000000041066211773153613013375 0ustar --- a/sim/ucsim/libltdl/ltdl.c +++ b/sim/ucsim/libltdl/ltdl.c @@ -1,1821 +1,267 @@ /* ltdl.c -- system independent dlopen wrapper - Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. - Originally by Thomas Tanner - This file is part of GNU Libtool. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -As a special exception to the GNU Lesser General Public License, -if you distribute this file as part of a program or library that -is built using GNU libtool, you may include it under the same -distribution terms that you use for the rest of that program. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA - -*/ - -#if HAVE_CONFIG_H -# include -#endif - -#if HAVE_UNISTD_H -# include -#endif - -#if HAVE_STDIO_H -# include -#endif - -#if HAVE_STDLIB_H -# include -#endif - -#if HAVE_STRING_H -# include -#else -# if HAVE_STRINGS_H -# include -# endif -#endif - -#if HAVE_CTYPE_H -# include -#endif - -#if HAVE_MALLOC_H -# include -#endif - -#if HAVE_MEMORY_H -# include -#endif - -#if HAVE_ERRNO_H -# include -#endif - -#if HAVE_DIRENT_H -# include -# define LT_D_NAMLEN(dirent) (strlen((dirent)->d_name)) -#else -# define dirent direct -# define LT_D_NAMLEN(dirent) ((dirent)->d_namlen) -# if HAVE_SYS_NDIR_H -# include -# endif -# if HAVE_SYS_DIR_H -# include -# endif -# if HAVE_NDIR_H -# include -# endif -#endif - -#if HAVE_ARGZ_H -# include -#endif - -#if HAVE_ASSERT_H -# include -#else -# define assert(arg) ((void) 0) -#endif - -#include "ltdl.h" - -#if WITH_DMALLOC -# include -#endif - - - - -/* --- WINDOWS SUPPORT --- */ - - -#ifdef DLL_EXPORT -# define LT_GLOBAL_DATA __declspec(dllexport) -#else -# define LT_GLOBAL_DATA -#endif - -/* fopen() mode flags for reading a text file */ -#undef LT_READTEXT_MODE -#ifdef __WINDOWS__ -# define LT_READTEXT_MODE "rt" -#else -# define LT_READTEXT_MODE "r" -#endif - - - - -/* --- MANIFEST CONSTANTS --- */ - - -/* Standard libltdl search path environment variable name */ -#undef LTDL_SEARCHPATH_VAR -#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH" - -/* Standard libtool archive file extension. */ -#undef LTDL_ARCHIVE_EXT -#define LTDL_ARCHIVE_EXT ".la" - -/* max. filename length */ -#ifndef LT_FILENAME_MAX -# define LT_FILENAME_MAX 1024 -#endif - -/* This is the maximum symbol size that won't require malloc/free */ -#undef LT_SYMBOL_LENGTH -#define LT_SYMBOL_LENGTH 128 - -/* This accounts for the _LTX_ separator */ -#undef LT_SYMBOL_OVERHEAD -#define LT_SYMBOL_OVERHEAD 5 - - - - -/* --- MEMORY HANDLING --- */ - - -/* These are the functions used internally. In addition to making - use of the associated function pointers above, they also perform - error handling. */ -static char *lt_estrdup LT_PARAMS((const char *str)); -static lt_ptr lt_emalloc LT_PARAMS((size_t size)); -static lt_ptr lt_erealloc LT_PARAMS((lt_ptr addr, size_t size)); - -static lt_ptr rpl_realloc LT_PARAMS((lt_ptr ptr, size_t size)); - -/* These are the pointers that can be changed by the caller: */ -LT_GLOBAL_DATA lt_ptr (*lt_dlmalloc) LT_PARAMS((size_t size)) - = (lt_ptr (*) LT_PARAMS((size_t))) malloc; -LT_GLOBAL_DATA lt_ptr (*lt_dlrealloc) LT_PARAMS((lt_ptr ptr, size_t size)) - = (lt_ptr (*) LT_PARAMS((lt_ptr, size_t))) rpl_realloc; -LT_GLOBAL_DATA void (*lt_dlfree) LT_PARAMS((lt_ptr ptr)) - = (void (*) LT_PARAMS((lt_ptr))) free; - -/* The following macros reduce the amount of typing needed to cast - assigned memory. */ -#if WITH_DMALLOC - -#define LT_DLMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp))) -#define LT_DLREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp))) -#define LT_DLFREE(p) \ - LT_STMT_START { if (p) (p) = (xfree (p), (lt_ptr) 0); } LT_STMT_END - -#define LT_EMALLOC(tp, n) ((tp *) xmalloc ((n) * sizeof(tp))) -#define LT_EREALLOC(tp, p, n) ((tp *) xrealloc ((p), (n) * sizeof(tp))) - -#else - -#define LT_DLMALLOC(tp, n) ((tp *) lt_dlmalloc ((n) * sizeof(tp))) -#define LT_DLREALLOC(tp, p, n) ((tp *) rpl_realloc ((p), (n) * sizeof(tp))) -#define LT_DLFREE(p) \ - LT_STMT_START { if (p) (p) = (lt_dlfree (p), (lt_ptr) 0); } LT_STMT_END - -#define LT_EMALLOC(tp, n) ((tp *) lt_emalloc ((n) * sizeof(tp))) -#define LT_EREALLOC(tp, p, n) ((tp *) lt_erealloc ((p), (n) * sizeof(tp))) - -#endif - -#define LT_DLMEM_REASSIGN(p, q) LT_STMT_START { \ - if ((p) != (q)) { if (p) lt_dlfree (p); (p) = (q); (q) = 0; } \ - } LT_STMT_END - - -/* --- REPLACEMENT FUNCTIONS --- */ - - -#undef strdup -#define strdup rpl_strdup - -static char *strdup LT_PARAMS((const char *str)); - -static char * -strdup(str) - const char *str; -{ - char *tmp = 0; - - if (str) - { - tmp = LT_DLMALLOC (char, 1+ strlen (str)); - if (tmp) - { - strcpy(tmp, str); - } - } - - return tmp; -} - - -#if ! HAVE_STRCMP - -#undef strcmp -#define strcmp rpl_strcmp - -static int strcmp LT_PARAMS((const char *str1, const char *str2)); - -static int -strcmp (str1, str2) - const char *str1; - const char *str2; -{ - if (str1 == str2) - return 0; - if (str1 == 0) - return -1; - if (str2 == 0) - return 1; - - for (;*str1 && *str2; ++str1, ++str2) - { - if (*str1 != *str2) - break; - } - - return (int)(*str1 - *str2); -} -#endif - - -#if ! HAVE_STRCHR - -# if HAVE_INDEX -# define strchr index -# else -# define strchr rpl_strchr - -static const char *strchr LT_PARAMS((const char *str, int ch)); - -static const char* -strchr(str, ch) - const char *str; - int ch; -{ - const char *p; - - for (p = str; *p != (char)ch && *p != LT_EOS_CHAR; ++p) - /*NOWORK*/; - - return (*p == (char)ch) ? p : 0; -} - -# endif -#endif /* !HAVE_STRCHR */ - - -#if ! HAVE_STRRCHR - -# if HAVE_RINDEX -# define strrchr rindex -# else -# define strrchr rpl_strrchr - -static const char *strrchr LT_PARAMS((const char *str, int ch)); - -static const char* -strrchr(str, ch) - const char *str; - int ch; -{ - const char *p, *q = 0; - - for (p = str; *p != LT_EOS_CHAR; ++p) - { - if (*p == (char) ch) - { - q = p; - } - } - - return q; -} - -# endif -#endif - -/* NOTE: Neither bcopy nor the memcpy implementation below can - reliably handle copying in overlapping areas of memory. Use - memmove (for which there is a fallback implmentation below) - if you need that behaviour. */ -#if ! HAVE_MEMCPY - -# if HAVE_BCOPY -# define memcpy(dest, src, size) bcopy (src, dest, size) -# else -# define memcpy rpl_memcpy - -static lt_ptr memcpy LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size)); - -static lt_ptr -memcpy (dest, src, size) - lt_ptr dest; - const lt_ptr src; - size_t size; -{ - size_t i = 0; - - for (i = 0; i < size; ++i) - { - dest[i] = src[i]; - } - - return dest; -} - -# endif /* !HAVE_BCOPY */ -#endif /* !HAVE_MEMCPY */ - -#if ! HAVE_MEMMOVE -# define memmove rpl_memmove - -static lt_ptr memmove LT_PARAMS((lt_ptr dest, const lt_ptr src, size_t size)); - -static lt_ptr -memmove (dest, src, size) - lt_ptr dest; - const lt_ptr src; - size_t size; -{ - size_t i; - - if (dest < src) - for (i = 0; i < size; ++i) - { - dest[i] = src[i]; - } - else if (dest > src) - for (i = size -1; i >= 0; --i) - { - dest[i] = src[i]; - } - - return dest; -} - -#endif /* !HAVE_MEMMOVE */ - - -/* According to Alexandre Oliva , - ``realloc is not entirely portable'' - In any case we want to use the allocator supplied by the user without - burdening them with an lt_dlrealloc function pointer to maintain. - Instead implement our own version (with known boundary conditions) - using lt_dlmalloc and lt_dlfree. */ - -#undef realloc -#define realloc rpl_realloc - -static lt_ptr -realloc (ptr, size) - lt_ptr ptr; - size_t size; -{ - if (size == 0) - { - /* For zero or less bytes, free the original memory */ - if (ptr != 0) - { - lt_dlfree (ptr); - } - - return (lt_ptr) 0; - } - else if (ptr == 0) - { - /* Allow reallocation of a NULL pointer. */ - return lt_dlmalloc (size); - } - else - { - /* Allocate a new block, copy and free the old block. */ - lt_ptr mem = lt_dlmalloc (size); - - if (mem) - { - memcpy (mem, ptr, size); - lt_dlfree (ptr); - } - - /* Note that the contents of PTR are not damaged if there is - insufficient memory to realloc. */ - return mem; - } -} - - -#if ! HAVE_ARGZ_APPEND -# define argz_append rpl_argz_append - -static error_t argz_append LT_PARAMS((char **pargz, size_t *pargz_len, - const char *buf, size_t buf_len)); - -static error_t -argz_append (pargz, pargz_len, buf, buf_len) - char **pargz; - size_t *pargz_len; - const char *buf; - size_t buf_len; -{ - size_t argz_len; - char *argz; - - assert (pargz); - assert (pargz_len); - assert ((*pargz && *pargz_len) || (!*pargz && !*pargz_len)); - - /* If nothing needs to be appended, no more work is required. */ - if (buf_len == 0) - return 0; - - /* Ensure there is enough room to append BUF_LEN. */ - argz_len = *pargz_len + buf_len; - argz = LT_DLREALLOC (char, *pargz, argz_len); - if (!argz) - return ENOMEM; - - /* Copy characters from BUF after terminating '\0' in ARGZ. */ - memcpy (argz + *pargz_len, buf, buf_len); - - /* Assign new values. */ - *pargz = argz; - *pargz_len = argz_len; - - return 0; -} -#endif /* !HAVE_ARGZ_APPEND */ - - -#if ! HAVE_ARGZ_CREATE_SEP -# define argz_create_sep rpl_argz_create_sep - -static error_t argz_create_sep LT_PARAMS((const char *str, int delim, - char **pargz, size_t *pargz_len)); - -static error_t -argz_create_sep (str, delim, pargz, pargz_len) - const char *str; - int delim; - char **pargz; - size_t *pargz_len; -{ - size_t argz_len; - char *argz = 0; - - assert (str); - assert (pargz); - assert (pargz_len); - - /* Make a copy of STR, but replacing each occurence of - DELIM with '\0'. */ - argz_len = 1+ LT_STRLEN (str); - if (argz_len) - { - const char *p; - char *q; - - argz = LT_DLMALLOC (char, argz_len); - if (!argz) - return ENOMEM; - - for (p = str, q = argz; *p != LT_EOS_CHAR; ++p) - { - if (*p == delim) - { - /* Ignore leading delimiters, and fold consecutive - delimiters in STR into a single '\0' in ARGZ. */ - if ((q > argz) && (q[-1] != LT_EOS_CHAR)) - *q++ = LT_EOS_CHAR; - else - --argz_len; - } - else - *q++ = *p; - } - /* Copy terminating LT_EOS_CHAR. */ - *q = *p; - } - - /* If ARGZ_LEN has shrunk to nothing, release ARGZ's memory. */ - if (!argz_len) - LT_DLFREE (argz); - - /* Assign new values. */ - *pargz = argz; - *pargz_len = argz_len; - - return 0; -} -#endif /* !HAVE_ARGZ_CREATE_SEP */ - - -#if ! HAVE_ARGZ_INSERT -# define argz_insert rpl_argz_insert - -static error_t argz_insert LT_PARAMS((char **pargz, size_t *pargz_len, - char *before, const char *entry)); - -static error_t -argz_insert (pargz, pargz_len, before, entry) - char **pargz; - size_t *pargz_len; - char *before; - const char *entry; -{ - assert (pargz); - assert (pargz_len); - assert (entry && *entry); - - /* Either PARGZ/PARGZ_LEN is empty and BEFORE is NULL, - or BEFORE points into an address within the ARGZ vector. */ - assert ((!*pargz && !*pargz_len && !before) - || ((*pargz <= before) && (before < (*pargz + *pargz_len)))); - - /* No BEFORE address indicates ENTRY should be inserted after the - current last element. */ - if (!before) - return argz_append (pargz, pargz_len, entry, 1+ LT_STRLEN (entry)); - - /* This probably indicates a programmer error, but to preserve - semantics, scan back to the start of an entry if BEFORE points - into the middle of it. */ - while ((before >= *pargz) && (before[-1] != LT_EOS_CHAR)) - --before; - - { - size_t entry_len = 1+ LT_STRLEN (entry); - size_t argz_len = *pargz_len + entry_len; - size_t offset = before - *pargz; - char *argz = LT_DLREALLOC (char, *pargz, argz_len); - - if (!argz) - return ENOMEM; - - /* Make BEFORE point to the equivalent offset in ARGZ that it - used to have in *PARGZ incase realloc() moved the block. */ - before = argz + offset; - - /* Move the ARGZ entries starting at BEFORE up into the new - space at the end -- making room to copy ENTRY into the - resulting gap. */ - memmove (before + entry_len, before, *pargz_len - offset); - memcpy (before, entry, entry_len); - - /* Assign new values. */ - *pargz = argz; - *pargz_len = argz_len; - } - - return 0; -} -#endif /* !HAVE_ARGZ_INSERT */ - - -#if ! HAVE_ARGZ_NEXT -# define argz_next rpl_argz_next - -static char *argz_next LT_PARAMS((char *argz, size_t argz_len, - const char *entry)); - -static char * -argz_next (argz, argz_len, entry) - char *argz; - size_t argz_len; - const char *entry; -{ - assert ((argz && argz_len) || (!argz && !argz_len)); - - if (entry) - { - /* Either ARGZ/ARGZ_LEN is empty, or ENTRY points into an address - within the ARGZ vector. */ - assert ((!argz && !argz_len) - || ((argz <= entry) && (entry < (argz + argz_len)))); - - /* Move to the char immediately after the terminating - '\0' of ENTRY. */ - entry = 1+ strchr (entry, LT_EOS_CHAR); - - /* Return either the new ENTRY, or else NULL if ARGZ is - exhausted. */ - return (entry >= argz + argz_len) ? 0 : (char *) entry; - } - else - { - /* This should probably be flagged as a programmer error, - since starting an argz_next loop with the iterator set - to ARGZ is safer. To preserve semantics, handle the NULL - case by returning the start of ARGZ (if any). */ - if (argz_len > 0) - return argz; - else - return 0; - } -} -#endif /* !HAVE_ARGZ_NEXT */ - - - -#if ! HAVE_ARGZ_STRINGIFY -# define argz_stringify rpl_argz_stringify - -static void argz_stringify LT_PARAMS((char *argz, size_t argz_len, - int sep)); - -static void -argz_stringify (argz, argz_len, sep) - char *argz; - size_t argz_len; - int sep; -{ - assert ((argz && argz_len) || (!argz && !argz_len)); - - if (sep) - { - --argz_len; /* don't stringify the terminating EOS */ - while (--argz_len > 0) - { - if (argz[argz_len] == LT_EOS_CHAR) - argz[argz_len] = sep; - } - } -} -#endif /* !HAVE_ARGZ_STRINGIFY */ - - - - -/* --- TYPE DEFINITIONS -- */ - - -/* This type is used for the array of caller data sets in each handler. */ -typedef struct { - lt_dlcaller_id key; - lt_ptr data; -} lt_caller_data; - - - - -/* --- OPAQUE STRUCTURES DECLARED IN LTDL.H --- */ - - -/* Extract the diagnostic strings from the error table macro in the same - order as the enumerated indices in ltdl.h. */ - -static const char *lt_dlerror_strings[] = - { -#define LT_ERROR(name, diagnostic) (diagnostic), - lt_dlerror_table -#undef LT_ERROR - - 0 - }; - -/* This structure is used for the list of registered loaders. */ -struct lt_dlloader { - struct lt_dlloader *next; - const char *loader_name; /* identifying name for each loader */ - const char *sym_prefix; /* prefix for symbols */ - lt_module_open *module_open; - lt_module_close *module_close; - lt_find_sym *find_sym; - lt_dlloader_exit *dlloader_exit; - lt_user_data dlloader_data; -}; - -struct lt_dlhandle_struct { - struct lt_dlhandle_struct *next; - lt_dlloader *loader; /* dlopening interface */ - lt_dlinfo info; - int depcount; /* number of dependencies */ - lt_dlhandle *deplibs; /* dependencies */ - lt_module module; /* system module handle */ - lt_ptr system; /* system specific data */ - lt_caller_data *caller_data; /* per caller associated data */ - int flags; /* various boolean stats */ -}; - -/* Various boolean flags can be stored in the flags field of an - lt_dlhandle_struct... */ -#define LT_DLGET_FLAG(handle, flag) (((handle)->flags & (flag)) == (flag)) -#define LT_DLSET_FLAG(handle, flag) ((handle)->flags |= (flag)) - -#define LT_DLRESIDENT_FLAG (0x01 << 0) -/* ...add more flags here... */ - -#define LT_DLIS_RESIDENT(handle) LT_DLGET_FLAG(handle, LT_DLRESIDENT_FLAG) - - -#define LT_DLSTRERROR(name) lt_dlerror_strings[LT_CONC(LT_ERROR_,name)] - -static const char objdir[] = LTDL_OBJDIR; -static const char archive_ext[] = LTDL_ARCHIVE_EXT; -#ifdef LTDL_SHLIB_EXT -static const char shlib_ext[] = LTDL_SHLIB_EXT; -#endif -#ifdef LTDL_SYSSEARCHPATH -static const char sys_search_path[] = LTDL_SYSSEARCHPATH; -#endif - - - - -/* --- MUTEX LOCKING --- */ - - -/* Macros to make it easier to run the lock functions only if they have - been registered. The reason for the complicated lock macro is to - ensure that the stored error message from the last error is not - accidentally erased if the current function doesn't generate an - error of its own. */ -#define LT_DLMUTEX_LOCK() LT_STMT_START { \ - if (lt_dlmutex_lock_func) (*lt_dlmutex_lock_func)(); \ - } LT_STMT_END -#define LT_DLMUTEX_UNLOCK() LT_STMT_START { \ - if (lt_dlmutex_unlock_func) (*lt_dlmutex_unlock_func)();\ - } LT_STMT_END -#define LT_DLMUTEX_SETERROR(errormsg) LT_STMT_START { \ - if (lt_dlmutex_seterror_func) \ - (*lt_dlmutex_seterror_func) (errormsg); \ - else lt_dllast_error = (errormsg); } LT_STMT_END -#define LT_DLMUTEX_GETERROR(errormsg) LT_STMT_START { \ - if (lt_dlmutex_seterror_func) \ - (errormsg) = (*lt_dlmutex_geterror_func) (); \ - else (errormsg) = lt_dllast_error; } LT_STMT_END - -/* The mutex functions stored here are global, and are necessarily the - same for all threads that wish to share access to libltdl. */ -static lt_dlmutex_lock *lt_dlmutex_lock_func = 0; -static lt_dlmutex_unlock *lt_dlmutex_unlock_func = 0; -static lt_dlmutex_seterror *lt_dlmutex_seterror_func = 0; -static lt_dlmutex_geterror *lt_dlmutex_geterror_func = 0; -static const char *lt_dllast_error = 0; - - -/* Either set or reset the mutex functions. Either all the arguments must - be valid functions, or else all can be NULL to turn off locking entirely. - The registered functions should be manipulating a static global lock - from the lock() and unlock() callbacks, which needs to be reentrant. */ -int -lt_dlmutex_register (lock, unlock, seterror, geterror) - lt_dlmutex_lock *lock; - lt_dlmutex_unlock *unlock; - lt_dlmutex_seterror *seterror; - lt_dlmutex_geterror *geterror; -{ - lt_dlmutex_unlock *old_unlock = unlock; - int errors = 0; - - /* Lock using the old lock() callback, if any. */ - LT_DLMUTEX_LOCK (); - - if ((lock && unlock && seterror && geterror) - || !(lock || unlock || seterror || geterror)) - { - lt_dlmutex_lock_func = lock; - lt_dlmutex_unlock_func = unlock; - lt_dlmutex_geterror_func = geterror; - } - else - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_MUTEX_ARGS)); - ++errors; - } - - /* Use the old unlock() callback we saved earlier, if any. Otherwise - record any errors using internal storage. */ - if (old_unlock) - (*old_unlock) (); - - /* Return the number of errors encountered during the execution of - this function. */ - return errors; -} - - - - -/* --- ERROR HANDLING --- */ - - -static const char **user_error_strings = 0; -static int errorcount = LT_ERROR_MAX; - -int -lt_dladderror (diagnostic) - const char *diagnostic; -{ - int errindex = 0; - int result = -1; - const char **temp = (const char **) 0; - - assert (diagnostic); - - LT_DLMUTEX_LOCK (); - - errindex = errorcount - LT_ERROR_MAX; - temp = LT_EREALLOC (const char *, user_error_strings, 1 + errindex); - if (temp) - { - user_error_strings = temp; - user_error_strings[errindex] = diagnostic; - result = errorcount++; - } - - LT_DLMUTEX_UNLOCK (); - - return result; -} - -int -lt_dlseterror (errindex) - int errindex; -{ - int errors = 0; - - LT_DLMUTEX_LOCK (); - - if (errindex >= errorcount || errindex < 0) - { - /* Ack! Error setting the error message! */ - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_ERRORCODE)); - ++errors; - } - else if (errindex < LT_ERROR_MAX) - { - /* No error setting the error message! */ - LT_DLMUTEX_SETERROR (lt_dlerror_strings[errindex]); - } - else - { - /* No error setting the error message! */ - LT_DLMUTEX_SETERROR (user_error_strings[errindex - LT_ERROR_MAX]); - } - - LT_DLMUTEX_UNLOCK (); - - return errors; -} - -static lt_ptr -lt_emalloc (size) - size_t size; -{ - lt_ptr mem = lt_dlmalloc (size); - if (size && !mem) - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - return mem; -} - -static lt_ptr -lt_erealloc (addr, size) - lt_ptr addr; - size_t size; -{ - lt_ptr mem = realloc (addr, size); - if (size && !mem) - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - return mem; -} - -static char * -lt_estrdup (str) - const char *str; -{ - char *copy = strdup (str); - if (LT_STRLEN (str) && !copy) - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - return copy; -} - - - - -/* --- DLOPEN() INTERFACE LOADER --- */ - - -/* The Cygwin dlopen implementation prints a spurious error message to - stderr if its call to LoadLibrary() fails for any reason. We can - mitigate this by not using the Cygwin implementation, and falling - back to our own LoadLibrary() wrapper. */ -#if HAVE_LIBDL && !defined(__CYGWIN__) - -/* dynamic linking with dlopen/dlsym */ - -#if HAVE_DLFCN_H -# include -#endif - -#if HAVE_SYS_DL_H -# include -#endif - -#ifdef RTLD_GLOBAL -# define LT_GLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_GLOBAL DL_GLOBAL -# endif -#endif /* !RTLD_GLOBAL */ -#ifndef LT_GLOBAL -# define LT_GLOBAL 0 -#endif /* !LT_GLOBAL */ - -/* We may have to define LT_LAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_LAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_LAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_LAZY_OR_NOW DL_LAZY -# endif -# endif /* !RTLD_LAZY */ -#endif -#ifndef LT_LAZY_OR_NOW -# ifdef RTLD_NOW -# define LT_LAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_LAZY_OR_NOW DL_NOW -# endif -# endif /* !RTLD_NOW */ -#endif -#ifndef LT_LAZY_OR_NOW -# define LT_LAZY_OR_NOW 0 -#endif /* !LT_LAZY_OR_NOW */ - -#if HAVE_DLERROR -# define DLERROR(arg) dlerror () -#else -# define DLERROR(arg) LT_DLSTRERROR (arg) -#endif - -static lt_module -sys_dl_open (loader_data, filename) - lt_user_data loader_data; - const char *filename; -{ - lt_module module = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW); - - if (!module) - { - LT_DLMUTEX_SETERROR (DLERROR (CANNOT_OPEN)); - } - - return module; -} - -static int -sys_dl_close (loader_data, module) - lt_user_data loader_data; - lt_module module; -{ - int errors = 0; - - if (dlclose (module) != 0) - { - LT_DLMUTEX_SETERROR (DLERROR (CANNOT_CLOSE)); - ++errors; - } - - return errors; -} - -static lt_ptr -sys_dl_sym (loader_data, module, symbol) - lt_user_data loader_data; - lt_module module; - const char *symbol; -{ - lt_ptr address = dlsym (module, symbol); - - if (!address) - { - LT_DLMUTEX_SETERROR (DLERROR (SYMBOL_NOT_FOUND)); - } - - return address; -} - -static struct lt_user_dlloader sys_dl = - { -# ifdef NEED_USCORE - "_", -# else - 0, -# endif - sys_dl_open, sys_dl_close, sys_dl_sym, 0, 0 }; - - -#endif /* HAVE_LIBDL */ - - - -/* --- SHL_LOAD() INTERFACE LOADER --- */ - -#if HAVE_SHL_LOAD - -/* dynamic linking with shl_load (HP-UX) (comments from gmodule) */ - -#ifdef HAVE_DL_H -# include -#endif - -/* some flags are missing on some systems, so we provide - * harmless defaults. - * - * Mandatory: - * BIND_IMMEDIATE - Resolve symbol references when the library is loaded. - * BIND_DEFERRED - Delay code symbol resolution until actual reference. - * - * Optionally: - * BIND_FIRST - Place the library at the head of the symbol search - * order. - * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all - * unsatisfied symbols as fatal. This flag allows - * binding of unsatisfied code symbols to be deferred - * until use. - * [Perl: For certain libraries, like DCE, deferred - * binding often causes run time problems. Adding - * BIND_NONFATAL to BIND_IMMEDIATE still allows - * unresolved references in situations like this.] - * BIND_NOSTART - Do not call the initializer for the shared library - * when the library is loaded, nor on a future call to - * shl_unload(). - * BIND_VERBOSE - Print verbose messages concerning possible - * unsatisfied symbols. - * - * hp9000s700/hp9000s800: - * BIND_RESTRICTED - Restrict symbols visible by the library to those - * present at library load time. - * DYNAMIC_PATH - Allow the loader to dynamically search for the - * library specified by the path argument. - */ - -#ifndef DYNAMIC_PATH -# define DYNAMIC_PATH 0 -#endif -#ifndef BIND_RESTRICTED -# define BIND_RESTRICTED 0 -#endif - -#define LT_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH) - -static lt_module -sys_shl_open (loader_data, filename) - lt_user_data loader_data; - const char *filename; -{ - static shl_t self = (shl_t) 0; - lt_module module = shl_load (filename, LT_BIND_FLAGS, 0L); - - /* Since searching for a symbol against a NULL module handle will also - look in everything else that was already loaded and exported with - the -E compiler flag, we always cache a handle saved before any - modules are loaded. */ - if (!self) - { - lt_ptr address; - shl_findsym (&self, "main", TYPE_UNDEFINED, &address); - } - - if (!filename) - { - module = self; - } - else - { - module = shl_load (filename, LT_BIND_FLAGS, 0L); - - if (!module) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); - } - } - - return module; -} - -static int -sys_shl_close (loader_data, module) - lt_user_data loader_data; - lt_module module; -{ - int errors = 0; - - if (module && (shl_unload ((shl_t) (module)) != 0)) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); - ++errors; - } - - return errors; -} - -static lt_ptr -sys_shl_sym (loader_data, module, symbol) - lt_user_data loader_data; - lt_module module; - const char *symbol; -{ - lt_ptr address = 0; - - /* sys_shl_open should never return a NULL module handle */ - if (module == (lt_module) 0) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); - } - else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address)) - { - if (!address) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); - } - } - - return address; -} - -static struct lt_user_dlloader sys_shl = { - 0, sys_shl_open, sys_shl_close, sys_shl_sym, 0, 0 -}; - -#endif /* HAVE_SHL_LOAD */ - - - - -/* --- LOADLIBRARY() INTERFACE LOADER --- */ - -#ifdef __WINDOWS__ - -/* dynamic linking for Win32 */ - -#include - -/* Forward declaration; required to implement handle search below. */ -static lt_dlhandle handles; - -static lt_module -sys_wll_open (loader_data, filename) - lt_user_data loader_data; - const char *filename; -{ - lt_dlhandle cur; - lt_module module = 0; - const char *errormsg = 0; - char *searchname = 0; - char *ext; - char self_name_buf[MAX_PATH]; - - if (!filename) - { - /* Get the name of main module */ - *self_name_buf = 0; - GetModuleFileName (NULL, self_name_buf, sizeof (self_name_buf)); - filename = ext = self_name_buf; - } - else - { - ext = strrchr (filename, '.'); - } - - if (ext) - { - /* FILENAME already has an extension. */ - searchname = lt_estrdup (filename); - } - else - { - /* Append a `.' to stop Windows from adding an - implicit `.dll' extension. */ - searchname = LT_EMALLOC (char, 2+ LT_STRLEN (filename)); - if (searchname) - sprintf (searchname, "%s.", filename); - } - if (!searchname) - return 0; - -#if __CYGWIN__ - { - char wpath[MAX_PATH]; - cygwin_conv_to_full_win32_path(searchname, wpath); - module = LoadLibrary(wpath); - } -#else - module = LoadLibrary (searchname); -#endif - LT_DLFREE (searchname); - - /* libltdl expects this function to fail if it is unable - to physically load the library. Sadly, LoadLibrary - will search the loaded libraries for a match and return - one of them if the path search load fails. - - We check whether LoadLibrary is returning a handle to - an already loaded module, and simulate failure if we - find one. */ - LT_DLMUTEX_LOCK (); - cur = handles; - while (cur) - { - if (!cur->module) - { - cur = 0; - break; - } - - if (cur->module == module) - { - break; - } - - cur = cur->next; - } - LT_DLMUTEX_UNLOCK (); - - if (cur || !module) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); - module = 0; - } - - return module; -} - -static int -sys_wll_close (loader_data, module) - lt_user_data loader_data; - lt_module module; -{ - int errors = 0; - - if (FreeLibrary(module) == 0) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); - ++errors; - } - - return errors; -} - -static lt_ptr -sys_wll_sym (loader_data, module, symbol) - lt_user_data loader_data; - lt_module module; - const char *symbol; -{ - lt_ptr address = GetProcAddress (module, symbol); - - if (!address) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); - } - - return address; -} - -static struct lt_user_dlloader sys_wll = { - 0, sys_wll_open, sys_wll_close, sys_wll_sym, 0, 0 -}; - -#endif /* __WINDOWS__ */ + Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006, + 2007, 2008 Free Software Foundation, Inc. + Written by Thomas Tanner, 1998 + NOTE: The canonical source of this file is maintained with the + GNU Libtool package. Report bugs to bug-libtool@gnu.org. - -/* --- LOAD_ADD_ON() INTERFACE LOADER --- */ - - -#ifdef __BEOS__ - -/* dynamic linking for BeOS */ - -#include - -static lt_module -sys_bedl_open (loader_data, filename) - lt_user_data loader_data; - const char *filename; -{ - image_id image = 0; - - if (filename) - { - image = load_add_on (filename); - } - else - { - image_info info; - int32 cookie = 0; - if (get_next_image_info (0, &cookie, &info) == B_OK) - image = load_add_on (info.name); - } - - if (image <= 0) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); - image = 0; - } - - return (lt_module) image; -} - -static int -sys_bedl_close (loader_data, module) - lt_user_data loader_data; - lt_module module; -{ - int errors = 0; - - if (unload_add_on ((image_id) module) != B_OK) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); - ++errors; - } - - return errors; -} - -static lt_ptr -sys_bedl_sym (loader_data, module, symbol) - lt_user_data loader_data; - lt_module module; - const char *symbol; -{ - lt_ptr address = 0; - image_id image = (image_id) module; - - if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); - address = 0; - } +GNU Libltdl is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2 of the License, or (at your option) any later version. - return address; -} +As a special exception to the GNU Lesser General Public License, +if you distribute this file as part of a program or library that +is built using GNU Libtool, you may include this file under the +same distribution terms that you use for the rest of that program. -static struct lt_user_dlloader sys_bedl = { - 0, sys_bedl_open, sys_bedl_close, sys_bedl_sym, 0, 0 -}; +GNU Libltdl is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. -#endif /* __BEOS__ */ +You should have received a copy of the GNU Lesser General Public +License along with GNU Libltdl; see the file COPYING.LIB. If not, a +copy can be downloaded from http://www.gnu.org/licenses/lgpl.html, +or obtained by writing to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +#include "lt__private.h" +#include "lt_system.h" +#include "lt_dlloader.h" - -/* --- DLD_LINK() INTERFACE LOADER --- */ +/* --- MANIFEST CONSTANTS --- */ -#if HAVE_DLD +/* Standard libltdl search path environment variable name */ +#undef LTDL_SEARCHPATH_VAR +#define LTDL_SEARCHPATH_VAR "LTDL_LIBRARY_PATH" -/* dynamic linking with dld */ +/* Standard libtool archive file extension. */ +#undef LT_ARCHIVE_EXT +#define LT_ARCHIVE_EXT ".la" -#if HAVE_DLD_H -#include +/* max. filename length */ +#if !defined(LT_FILENAME_MAX) +# define LT_FILENAME_MAX 1024 #endif -static lt_module -sys_dld_open (loader_data, filename) - lt_user_data loader_data; - const char *filename; -{ - lt_module module = strdup (filename); - - if (dld_link (filename) != 0) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_OPEN)); - LT_DLFREE (module); - module = 0; - } - - return module; -} - -static int -sys_dld_close (loader_data, module) - lt_user_data loader_data; - lt_module module; -{ - int errors = 0; - - if (dld_unlink_by_file ((char*)(module), 1) != 0) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CANNOT_CLOSE)); - ++errors; - } - else - { - LT_DLFREE (module); - } - - return errors; -} +#if !defined(LT_LIBEXT) +# define LT_LIBEXT "a" +#endif -static lt_ptr -sys_dld_sym (loader_data, module, symbol) - lt_user_data loader_data; - lt_module module; - const char *symbol; -{ - lt_ptr address = dld_get_func (symbol); +/* This is the maximum symbol size that won't require malloc/free */ +#undef LT_SYMBOL_LENGTH +#define LT_SYMBOL_LENGTH 128 - if (!address) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); - } +/* This accounts for the _LTX_ separator */ +#undef LT_SYMBOL_OVERHEAD +#define LT_SYMBOL_OVERHEAD 5 - return address; -} +/* Various boolean flags can be stored in the flags field of an + lt_dlhandle... */ +#define LT_DLIS_RESIDENT(handle) ((handle)->info.is_resident) +#define LT_DLIS_SYMGLOBAL(handle) ((handle)->info.is_symglobal) +#define LT_DLIS_SYMLOCAL(handle) ((handle)->info.is_symlocal) -static struct lt_user_dlloader sys_dld = { - 0, sys_dld_open, sys_dld_close, sys_dld_sym, 0, 0 -}; -#endif /* HAVE_DLD */ +static const char objdir[] = LT_OBJDIR; +static const char archive_ext[] = LT_ARCHIVE_EXT; +static const char libext[] = LT_LIBEXT; +#if defined(LT_MODULE_EXT) +static const char shlib_ext[] = LT_MODULE_EXT; +#endif +#if defined(LT_DLSEARCH_PATH) +static const char sys_dlsearch_path[] = LT_DLSEARCH_PATH; +#endif -/* --- DLPREOPEN() INTERFACE LOADER --- */ - - -/* emulate dynamic linking using preloaded_symbols */ - -typedef struct lt_dlsymlists_t -{ - struct lt_dlsymlists_t *next; - const lt_dlsymlist *syms; -} lt_dlsymlists_t; - -static const lt_dlsymlist *default_preloaded_symbols = 0; -static lt_dlsymlists_t *preloaded_symbols = 0; - -static int -presym_init (loader_data) - lt_user_data loader_data; -{ - int errors = 0; - - LT_DLMUTEX_LOCK (); - - preloaded_symbols = 0; - if (default_preloaded_symbols) - { - errors = lt_dlpreload (default_preloaded_symbols); - } +/* --- DYNAMIC MODULE LOADING --- */ - LT_DLMUTEX_UNLOCK (); - return errors; +/* The type of a function used at each iteration of foreach_dirinpath(). */ +typedef int foreach_callback_func (char *filename, void *data1, + void *data2); +/* foreachfile_callback itself calls a function of this type: */ +typedef int file_worker_func (const char *filename, void *data); + + +static int foreach_dirinpath (const char *search_path, + const char *base_name, + foreach_callback_func *func, + void *data1, void *data2); +static int find_file_callback (char *filename, void *data1, + void *data2); +static int find_handle_callback (char *filename, void *data, + void *ignored); +static int foreachfile_callback (char *filename, void *data1, + void *data2); + + +static int canonicalize_path (const char *path, char **pcanonical); +static int argzize_path (const char *path, + char **pargz, size_t *pargz_len); +static FILE *find_file (const char *search_path, + const char *base_name, char **pdir); +static lt_dlhandle *find_handle (const char *search_path, + const char *base_name, + lt_dlhandle *handle, + lt_dladvise advise); +static int find_module (lt_dlhandle *handle, const char *dir, + const char *libdir, const char *dlname, + const char *old_name, int installed, + lt_dladvise advise); +static int has_library_ext (const char *filename); +static int load_deplibs (lt_dlhandle handle, char *deplibs); +static int trim (char **dest, const char *str); +static int try_dlopen (lt_dlhandle *handle, + const char *filename, const char *ext, + lt_dladvise advise); +static int tryall_dlopen (lt_dlhandle *handle, + const char *filename, + lt_dladvise padvise, + const lt_dlvtable *vtable); +static int unload_deplibs (lt_dlhandle handle); +static int lt_argz_insert (char **pargz, size_t *pargz_len, + char *before, const char *entry); +static int lt_argz_insertinorder (char **pargz, size_t *pargz_len, + const char *entry); +static int lt_argz_insertdir (char **pargz, size_t *pargz_len, + const char *dirnam, struct dirent *dp); +static int lt_dlpath_insertdir (char **ppath, char *before, + const char *dir); +static int list_files_by_dir (const char *dirnam, + char **pargz, size_t *pargz_len); +static int file_not_found (void); + +#ifdef HAVE_LIBDLLOADER +static int loader_init_callback (lt_dlhandle handle); +#endif /* HAVE_LIBDLLOADER */ + +static int loader_init (lt_get_vtable *vtable_func, + lt_user_data data); + +static char *user_search_path= 0; +static lt_dlhandle handles = 0; +static int initialized = 0; + +/* Our memory failure callback sets the error message to be passed back + up to the client, so we must be careful to return from mallocation + callers if allocation fails (as this callback returns!!). */ +void +lt__alloc_die_callback (void) +{ + LT__SETERROR (NO_MEMORY); +} + +#ifdef HAVE_LIBDLLOADER +/* This function is called to initialise each preloaded module loader, + and hook it into the list of loaders to be used when attempting to + dlopen an application module. */ +static int +loader_init_callback (lt_dlhandle handle) +{ + lt_get_vtable *vtable_func = (lt_get_vtable *) lt_dlsym (handle, "get_vtable"); + return loader_init (vtable_func, 0); } +#endif /* HAVE_LIBDLLOADER */ static int -presym_free_symlists () +loader_init (lt_get_vtable *vtable_func, lt_user_data data) { - lt_dlsymlists_t *lists; - - LT_DLMUTEX_LOCK (); + const lt_dlvtable *vtable = 0; + int errors = 0; - lists = preloaded_symbols; - while (lists) + if (vtable_func) { - lt_dlsymlists_t *tmp = lists; - - lists = lists->next; - LT_DLFREE (tmp); + vtable = (*vtable_func) (data); } - preloaded_symbols = 0; - - LT_DLMUTEX_UNLOCK (); - - return 0; -} - -static int -presym_exit (loader_data) - lt_user_data loader_data; -{ - presym_free_symlists (); - return 0; -} - -static int -presym_add_symlist (preloaded) - const lt_dlsymlist *preloaded; -{ - lt_dlsymlists_t *tmp; - lt_dlsymlists_t *lists; - int errors = 0; - LT_DLMUTEX_LOCK (); + /* lt_dlloader_add will LT__SETERROR if it fails. */ + errors += lt_dlloader_add (vtable); - lists = preloaded_symbols; - while (lists) - { - if (lists->syms == preloaded) - { - goto done; - } - lists = lists->next; - } + assert (errors || vtable); - tmp = LT_EMALLOC (lt_dlsymlists_t, 1); - if (tmp) - { - memset (tmp, 0, sizeof(lt_dlsymlists_t)); - tmp->syms = preloaded; - tmp->next = preloaded_symbols; - preloaded_symbols = tmp; - } - else + if ((!errors) && vtable->dlloader_init) { - ++errors; + if ((*vtable->dlloader_init) (vtable->dlloader_data)) + { + LT__SETERROR (INIT_LOADER); + ++errors; + } } - done: - LT_DLMUTEX_UNLOCK (); return errors; } -static lt_module -presym_open (loader_data, filename) - lt_user_data loader_data; - const char *filename; -{ - lt_dlsymlists_t *lists; - lt_module module = (lt_module) 0; - - LT_DLMUTEX_LOCK (); - lists = preloaded_symbols; - - if (!lists) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_SYMBOLS)); - goto done; - } - - /* Can't use NULL as the reflective symbol header, as NULL is - used to mark the end of the entire symbol list. Self-dlpreopened - symbols follow this magic number, chosen to be an unlikely - clash with a real module name. */ - if (!filename) - { - filename = "@PROGRAM@"; - } - - while (lists) - { - const lt_dlsymlist *syms = lists->syms; - - while (syms->name) - { - if (!syms->address && strcmp(syms->name, filename) == 0) - { - module = (lt_module) syms; - goto done; - } - ++syms; - } - - lists = lists->next; - } - - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); - - done: - LT_DLMUTEX_UNLOCK (); - return module; -} - -static int -presym_close (loader_data, module) - lt_user_data loader_data; - lt_module module; -{ - /* Just to silence gcc -Wall */ - module = 0; - return 0; -} - -static lt_ptr -presym_sym (loader_data, module, symbol) - lt_user_data loader_data; - lt_module module; - const char *symbol; -{ - lt_dlsymlist *syms = (lt_dlsymlist*) module; - - ++syms; - while (syms->address) - { - if (strcmp(syms->name, symbol) == 0) - { - return syms->address; - } - - ++syms; - } - - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); - - return 0; -} - -static struct lt_user_dlloader presym = { - 0, presym_open, presym_close, presym_sym, presym_exit, 0 -}; - - - - - -/* --- DYNAMIC MODULE LOADING --- */ - - -/* The type of a function used at each iteration of foreach_dirinpath(). */ -typedef int foreach_callback_func LT_PARAMS((char *filename, lt_ptr data1, - lt_ptr data2)); +/* Bootstrap the loader loading with the preopening loader. */ +#define get_vtable preopen_LTX_get_vtable +#define preloaded_symbols LT_CONC3(lt_, LTDLOPEN, _LTX_preloaded_symbols) -static int foreach_dirinpath LT_PARAMS((const char *search_path, - const char *base_name, - foreach_callback_func *func, - lt_ptr data1, lt_ptr data2)); - -static int find_file_callback LT_PARAMS((char *filename, lt_ptr data, - lt_ptr ignored)); -static int find_handle_callback LT_PARAMS((char *filename, lt_ptr data, - lt_ptr ignored)); -static int foreachfile_callback LT_PARAMS((char *filename, lt_ptr data1, - lt_ptr data2)); - - -static int canonicalize_path LT_PARAMS((const char *path, - char **pcanonical)); -static int argzize_path LT_PARAMS((const char *path, - char **pargz, - size_t *pargz_len)); -static FILE *find_file LT_PARAMS((const char *search_path, - const char *base_name, - char **pdir)); -static lt_dlhandle *find_handle LT_PARAMS((const char *search_path, - const char *base_name, - lt_dlhandle *handle)); -static int find_module LT_PARAMS((lt_dlhandle *handle, - const char *dir, - const char *libdir, - const char *dlname, - const char *old_name, - int installed)); -static int free_vars LT_PARAMS((char *dlname, char *oldname, - char *libdir, char *deplibs)); -static int load_deplibs LT_PARAMS((lt_dlhandle handle, - char *deplibs)); -static int trim LT_PARAMS((char **dest, - const char *str)); -static int try_dlopen LT_PARAMS((lt_dlhandle *handle, - const char *filename)); -static int tryall_dlopen LT_PARAMS((lt_dlhandle *handle, - const char *filename)); -static int unload_deplibs LT_PARAMS((lt_dlhandle handle)); -static int lt_argz_insert LT_PARAMS((char **pargz, - size_t *pargz_len, - char *before, - const char *entry)); -static int lt_argz_insertinorder LT_PARAMS((char **pargz, - size_t *pargz_len, - const char *entry)); -static int lt_argz_insertdir LT_PARAMS((char **pargz, - size_t *pargz_len, - const char *dirnam, - struct dirent *dp)); -static int lt_dlpath_insertdir LT_PARAMS((char **ppath, - char *before, - const char *dir)); -static int list_files_by_dir LT_PARAMS((const char *dirnam, - char **pargz, - size_t *pargz_len)); -static int file_not_found LT_PARAMS((void)); - -static char *user_search_path= 0; -static lt_dlloader *loaders = 0; -static lt_dlhandle handles = 0; -static int initialized = 0; +LT_BEGIN_C_DECLS +LT_SCOPE const lt_dlvtable * get_vtable (lt_user_data data); +LT_END_C_DECLS +#ifdef HAVE_LIBDLLOADER +extern lt_dlsymlist preloaded_symbols; +#endif /* Initialize libltdl. */ int -lt_dlinit () +lt_dlinit (void) { - int errors = 0; - - LT_DLMUTEX_LOCK (); + int errors = 0; /* Initialize only at first call. */ if (++initialized == 1) { - handles = 0; - user_search_path = 0; /* empty search path */ - -#if HAVE_LIBDL && !defined(__CYGWIN__) - errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dl, "dlopen"); -#endif -#if HAVE_SHL_LOAD - errors += lt_dlloader_add (lt_dlloader_next (0), &sys_shl, "dlopen"); -#endif -#ifdef __WINDOWS__ - errors += lt_dlloader_add (lt_dlloader_next (0), &sys_wll, "dlopen"); -#endif -#ifdef __BEOS__ - errors += lt_dlloader_add (lt_dlloader_next (0), &sys_bedl, "dlopen"); -#endif -#if HAVE_DLD - errors += lt_dlloader_add (lt_dlloader_next (0), &sys_dld, "dld"); -#endif - errors += lt_dlloader_add (lt_dlloader_next (0), &presym, "dlpreload"); - - if (presym_init (presym.dlloader_data)) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INIT_LOADER)); - ++errors; - } - else if (errors != 0) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (DLOPEN_NOT_SUPPORTED)); - ++errors; - } - } - - LT_DLMUTEX_UNLOCK (); - - return errors; -} - -int -lt_dlpreload (preloaded) - const lt_dlsymlist *preloaded; -{ - int errors = 0; - - if (preloaded) - { - errors = presym_add_symlist (preloaded); + lt__alloc_die = lt__alloc_die_callback; + handles = 0; + user_search_path = 0; /* empty search path */ + + /* First set up the statically loaded preload module loader, so + we can use it to preopen the other loaders we linked in at + compile time. */ + errors += loader_init (get_vtable, 0); + + /* Now open all the preloaded module loaders, so the application + can use _them_ to lt_dlopen its own modules. */ +#ifdef HAVE_LIBDLLOADER + if (!errors) + { + errors += lt_dlpreload (&preloaded_symbols); + } + + if (!errors) + { + errors += lt_dlpreload_open (LT_STR(LTDLOPEN), loader_init_callback); + } +#endif /* HAVE_LIBDLLOADER */ } - else - { - presym_free_symlists(); - LT_DLMUTEX_LOCK (); - if (default_preloaded_symbols) - { - errors = lt_dlpreload (default_preloaded_symbols); - } - LT_DLMUTEX_UNLOCK (); - } +#ifdef LT_DEBUG_LOADERS + lt_dlloader_dump(); +#endif return errors; } int -lt_dlpreload_default (preloaded) - const lt_dlsymlist *preloaded; -{ - LT_DLMUTEX_LOCK (); - default_preloaded_symbols = preloaded; - LT_DLMUTEX_UNLOCK (); - return 0; -} - -int -lt_dlexit () +lt_dlexit (void) { /* shut down libltdl */ - lt_dlloader *loader; - int errors = 0; - - LT_DLMUTEX_LOCK (); - loader = loaders; + lt_dlloader *loader = 0; + lt_dlhandle handle = handles; + int errors = 0; if (!initialized) { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SHUTDOWN)); + LT__SETERROR (SHUTDOWN); ++errors; goto done; } @@ -1823,171 +269,236 @@ /* shut down only at last call. */ if (--initialized == 0) { - int level; + int level; while (handles && LT_DLIS_RESIDENT (handles)) - { - handles = handles->next; - } + { + handles = handles->next; + } /* close all modules */ - for (level = 1; handles; ++level) - { - lt_dlhandle cur = handles; - int saw_nonresident = 0; - - while (cur) - { - lt_dlhandle tmp = cur; - cur = cur->next; - if (!LT_DLIS_RESIDENT (tmp)) - saw_nonresident = 1; - if (!LT_DLIS_RESIDENT (tmp) && tmp->info.ref_count <= level) - { - if (lt_dlclose (tmp)) - { - ++errors; - } - } - } - /* done if only resident modules are left */ - if (!saw_nonresident) - break; - } + for (level = 1; handle; ++level) + { + lt_dlhandle cur = handles; + int saw_nonresident = 0; + + while (cur) + { + lt_dlhandle tmp = cur; + cur = cur->next; + if (!LT_DLIS_RESIDENT (tmp)) + { + saw_nonresident = 1; + if (tmp->info.ref_count <= level) + { + if (lt_dlclose (tmp)) + { + ++errors; + } + /* Make sure that the handle pointed to by 'cur' still exists. + lt_dlclose recursively closes dependent libraries which removes + them from the linked list. One of these might be the one + pointed to by 'cur'. */ + if (cur) + { + for (tmp = handles; tmp; tmp = tmp->next) + if (tmp == cur) + break; + if (! tmp) + cur = handles; + } + } + } + } + /* done if only resident modules are left */ + if (!saw_nonresident) + break; + } + + /* When removing loaders, we can only find out failure by testing + the error string, so avoid a spurious one from an earlier + failed command. */ + if (!errors) + LT__SETERRORSTR (0); /* close all loaders */ - while (loader) - { - lt_dlloader *next = loader->next; - lt_user_data data = loader->dlloader_data; - if (loader->dlloader_exit && loader->dlloader_exit (data)) - { - ++errors; - } - - LT_DLMEM_REASSIGN (loader, next); - } - loaders = 0; + for (loader = (lt_dlloader *) lt_dlloader_next (NULL); loader;) + { + lt_dlloader *next = (lt_dlloader *) lt_dlloader_next (loader); + lt_dlvtable *vtable = (lt_dlvtable *) lt_dlloader_get (loader); + + if ((vtable = lt_dlloader_remove ((char *) vtable->name))) + { + FREE (vtable); + } + else + { + /* ignore errors due to resident modules */ + const char *err; + LT__GETERROR (err); + if (err) + ++errors; + } + + loader = next; + } + + FREE(user_search_path); } done: - LT_DLMUTEX_UNLOCK (); return errors; } + +/* Try VTABLE or, if VTABLE is NULL, all available loaders for FILENAME. + If the library is not successfully loaded, return non-zero. Otherwise, + the dlhandle is stored at the address given in PHANDLE. */ static int -tryall_dlopen (handle, filename) - lt_dlhandle *handle; - const char *filename; -{ - lt_dlhandle cur; - lt_dlloader *loader; - const char *saved_error; - int errors = 0; +tryall_dlopen (lt_dlhandle *phandle, const char *filename, + lt_dladvise advise, const lt_dlvtable *vtable) +{ + lt_dlhandle handle = handles; + const char * saved_error = 0; + int errors = 0; - LT_DLMUTEX_GETERROR (saved_error); - LT_DLMUTEX_LOCK (); +#ifdef LT_DEBUG_LOADERS + fprintf (stderr, "tryall_dlopen (%s, %s)\n", + filename ? filename : "(null)", + vtable ? vtable->name : "(ALL)"); +#endif - cur = handles; - loader = loaders; + LT__GETERROR (saved_error); /* check whether the module was already opened */ - while (cur) + for (;handle; handle = handle->next) { - /* try to dlopen the program itself? */ - if (!cur->info.filename && !filename) - { - break; - } - - if (cur->info.filename && filename - && strcmp (cur->info.filename, filename) == 0) - { - break; - } - - cur = cur->next; + if ((handle->info.filename == filename) /* dlopen self: 0 == 0 */ + || (handle->info.filename && filename + && streq (handle->info.filename, filename))) + { + break; + } } - if (cur) + if (handle) { - ++cur->info.ref_count; - *handle = cur; + ++handle->info.ref_count; + *phandle = handle; goto done; } - cur = *handle; + handle = *phandle; if (filename) { - cur->info.filename = lt_estrdup (filename); - if (!cur->info.filename) - { - ++errors; - goto done; - } + /* Comment out the check of file permissions using access. + This call seems to always return -1 with error EACCES. + */ + /* We need to catch missing file errors early so that + file_not_found() can detect what happened. + if (access (filename, R_OK) != 0) + { + LT__SETERROR (FILE_NOT_FOUND); + ++errors; + goto done; + } */ + + handle->info.filename = lt__strdup (filename); + if (!handle->info.filename) + { + ++errors; + goto done; + } } else { - cur->info.filename = 0; + handle->info.filename = 0; } - while (loader) - { - lt_user_data data = loader->dlloader_data; + { + lt_dlloader loader = lt_dlloader_next (0); + const lt_dlvtable *loader_vtable; - cur->module = loader->module_open (data, filename); + do + { + if (vtable) + loader_vtable = vtable; + else + loader_vtable = lt_dlloader_get (loader); + +#ifdef LT_DEBUG_LOADERS + fprintf (stderr, "Calling %s->module_open (%s)\n", + (loader_vtable && loader_vtable->name) ? loader_vtable->name : "(null)", + filename ? filename : "(null)"); +#endif + handle->module = (*loader_vtable->module_open) (loader_vtable->dlloader_data, + filename, advise); +#ifdef LT_DEBUG_LOADERS + fprintf (stderr, " Result: %s\n", + handle->module ? "Success" : "Failed"); +#endif + + if (handle->module != 0) + { + if (advise) + { + handle->info.is_resident = advise->is_resident; + handle->info.is_symglobal = advise->is_symglobal; + handle->info.is_symlocal = advise->is_symlocal; + } + break; + } + } + while (!vtable && (loader = lt_dlloader_next (loader))); - if (cur->module != 0) - { - break; - } - loader = loader->next; - } + /* If VTABLE was given but couldn't open the module, or VTABLE wasn't + given but we exhausted all loaders without opening the module, bail + out! */ + if ((vtable && !handle->module) + || (!vtable && !loader)) + { + FREE (handle->info.filename); + ++errors; + goto done; + } - if (!loader) - { - LT_DLFREE (cur->info.filename); - ++errors; - goto done; - } + handle->vtable = loader_vtable; + } - cur->loader = loader; - LT_DLMUTEX_SETERROR (saved_error); + LT__SETERRORSTR (saved_error); done: - LT_DLMUTEX_UNLOCK (); - return errors; } + static int -tryall_dlopen_module (handle, prefix, dirname, dlname) - lt_dlhandle *handle; - const char *prefix; - const char *dirname; - const char *dlname; -{ - int error = 0; - char *filename = 0; - size_t filename_len = 0; - size_t dirname_len = LT_STRLEN (dirname); +tryall_dlopen_module (lt_dlhandle *handle, const char *prefix, + const char *dirname, const char *dlname, + lt_dladvise advise) +{ + int error = 0; + char *filename = 0; + size_t filename_len = 0; + size_t dirname_len = LT_STRLEN (dirname); assert (handle); assert (dirname); assert (dlname); -#ifdef LT_DIRSEP_CHAR +#if defined(LT_DIRSEP_CHAR) /* Only canonicalized names (i.e. with DIRSEP chars already converted) should make it into this function: */ assert (strchr (dirname, LT_DIRSEP_CHAR) == 0); #endif - if (dirname[dirname_len -1] == '/') - --dirname_len; + if (dirname_len > 0) + if (dirname[dirname_len -1] == '/') + --dirname_len; filename_len = dirname_len + 1 + LT_STRLEN (dlname); /* Allocate memory, and combine DIRNAME and MODULENAME into it. The PREFIX (if any) is handled below. */ - filename = LT_EMALLOC (char, dirname_len + 1 + filename_len + 1); + filename = MALLOC (char, filename_len + 1); if (!filename) return 1; @@ -1998,31 +509,28 @@ shuffled. Otherwise, attempt to open FILENAME as a module. */ if (prefix) { - error += tryall_dlopen_module (handle, - (const char *) 0, prefix, filename); + error += tryall_dlopen_module (handle, (const char *) 0, + prefix, filename, advise); } - else if (tryall_dlopen (handle, filename) != 0) + else if (tryall_dlopen (handle, filename, advise, 0) != 0) { ++error; } - LT_DLFREE (filename); + FREE (filename); return error; } static int -find_module (handle, dir, libdir, dlname, old_name, installed) - lt_dlhandle *handle; - const char *dir; - const char *libdir; - const char *dlname; - const char *old_name; - int installed; +find_module (lt_dlhandle *handle, const char *dir, const char *libdir, + const char *dlname, const char *old_name, int installed, + lt_dladvise advise) { /* Try to open the old library first; if it was dlpreopened, we want the preopened version of it, even if a dlopenable module is available. */ - if (old_name && tryall_dlopen (handle, old_name) == 0) + if (old_name && tryall_dlopen (handle, old_name, + advise, lt_dlloader_find ("lt_preopen") ) == 0) { return 0; } @@ -2032,24 +540,25 @@ { /* try to open the installed module */ if (installed && libdir) - { - if (tryall_dlopen_module (handle, - (const char *) 0, libdir, dlname) == 0) - return 0; - } + { + if (tryall_dlopen_module (handle, (const char *) 0, + libdir, dlname, advise) == 0) + return 0; + } /* try to open the not-installed module */ if (!installed) - { - if (tryall_dlopen_module (handle, dir, objdir, dlname) == 0) - return 0; - } + { + if (tryall_dlopen_module (handle, dir, objdir, + dlname, advise) == 0) + return 0; + } /* maybe it was moved to another directory */ { - if (tryall_dlopen_module (handle, - (const char *) 0, dir, dlname) == 0) - return 0; + if (dir && (tryall_dlopen_module (handle, (const char *) 0, + dir, dlname, advise) == 0)) + return 0; } } @@ -2058,16 +567,14 @@ static int -canonicalize_path (path, pcanonical) - const char *path; - char **pcanonical; +canonicalize_path (const char *path, char **pcanonical) { char *canonical = 0; assert (path && *path); assert (pcanonical); - canonical = LT_EMALLOC (char, 1+ LT_STRLEN (path)); + canonical = MALLOC (char, 1+ LT_STRLEN (path)); if (!canonical) return 1; @@ -2076,38 +583,38 @@ size_t src; for (src = 0; path[src] != LT_EOS_CHAR; ++src) { - /* Path separators are not copied to the beginning or end of - the destination, or if another separator would follow - immediately. */ - if (path[src] == LT_PATHSEP_CHAR) - { - if ((dest == 0) - || (path[1+ src] == LT_PATHSEP_CHAR) - || (path[1+ src] == LT_EOS_CHAR)) - continue; - } - - /* Anything other than a directory separator is copied verbatim. */ - if ((path[src] != '/') -#ifdef LT_DIRSEP_CHAR - && (path[src] != LT_DIRSEP_CHAR) -#endif - ) - { - canonical[dest++] = path[src]; - } - /* Directory separators are converted and copied only if they are - not at the end of a path -- i.e. before a path separator or - NULL terminator. */ - else if ((path[1+ src] != LT_PATHSEP_CHAR) - && (path[1+ src] != LT_EOS_CHAR) -#ifdef LT_DIRSEP_CHAR - && (path[1+ src] != LT_DIRSEP_CHAR) -#endif - && (path[1+ src] != '/')) - { - canonical[dest++] = '/'; - } + /* Path separators are not copied to the beginning or end of + the destination, or if another separator would follow + immediately. */ + if (path[src] == LT_PATHSEP_CHAR) + { + if ((dest == 0) + || (path[1+ src] == LT_PATHSEP_CHAR) + || (path[1+ src] == LT_EOS_CHAR)) + continue; + } + + /* Anything other than a directory separator is copied verbatim. */ + if ((path[src] != '/') +#if defined(LT_DIRSEP_CHAR) + && (path[src] != LT_DIRSEP_CHAR) +#endif + ) + { + canonical[dest++] = path[src]; + } + /* Directory separators are converted and copied only if they are + not at the end of a path -- i.e. before a path separator or + NULL terminator. */ + else if ((path[1+ src] != LT_PATHSEP_CHAR) + && (path[1+ src] != LT_EOS_CHAR) +#if defined(LT_DIRSEP_CHAR) + && (path[1+ src] != LT_DIRSEP_CHAR) +#endif + && (path[1+ src] != '/')) + { + canonical[dest++] = '/'; + } } /* Add an end-of-string marker at the end. */ @@ -2121,10 +628,7 @@ } static int -argzize_path (path, pargz, pargz_len) - const char *path; - char **pargz; - size_t *pargz_len; +argzize_path (const char *path, char **pargz, size_t *pargz_len) { error_t error; @@ -2135,14 +639,14 @@ if ((error = argz_create_sep (path, LT_PATHSEP_CHAR, pargz, pargz_len))) { switch (error) - { - case ENOMEM: - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - break; - default: - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN)); - break; - } + { + case ENOMEM: + LT__SETERROR (NO_MEMORY); + break; + default: + LT__SETERROR (UNKNOWN); + break; + } return 1; } @@ -2155,26 +659,20 @@ non-zero or all elements are exhausted. If BASE_NAME is non-NULL, it is appended to each SEARCH_PATH element before FUNC is called. */ static int -foreach_dirinpath (search_path, base_name, func, data1, data2) - const char *search_path; - const char *base_name; - foreach_callback_func *func; - lt_ptr data1; - lt_ptr data2; -{ - int result = 0; - int filenamesize = 0; - size_t lenbase = LT_STRLEN (base_name); - size_t argz_len = 0; - char *argz = 0; - char *filename = 0; - char *canonical = 0; - - LT_DLMUTEX_LOCK (); +foreach_dirinpath (const char *search_path, const char *base_name, + foreach_callback_func *func, void *data1, void *data2) +{ + int result = 0; + size_t filenamesize = 0; + size_t lenbase = LT_STRLEN (base_name); + size_t argz_len = 0; + char *argz = 0; + char *filename = 0; + char *canonical = 0; if (!search_path || !*search_path) { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); + LT__SETERROR (FILE_NOT_FOUND); goto cleanup; } @@ -2188,38 +686,38 @@ char *dir_name = 0; while ((dir_name = argz_next (argz, argz_len, dir_name))) { - size_t lendir = LT_STRLEN (dir_name); + size_t lendir = LT_STRLEN (dir_name); - if (lendir +1 +lenbase >= filenamesize) - { - LT_DLFREE (filename); - filenamesize = lendir +1 +lenbase +1; /* "/d" + '/' + "f" + '\0' */ - filename = LT_EMALLOC (char, filenamesize); - if (!filename) - goto cleanup; - } - - strncpy (filename, dir_name, lendir); - if (base_name && *base_name) - { - if (filename[lendir -1] != '/') - filename[lendir++] = '/'; - strcpy (filename +lendir, base_name); - } - - if ((result = (*func) (filename, data1, data2))) - { - break; - } + if (1+ lendir + lenbase >= filenamesize) + { + FREE (filename); + filenamesize = 1+ lendir + 1+ lenbase; /* "/d" + '/' + "f" + '\0' */ + filename = MALLOC (char, filenamesize); + if (!filename) + goto cleanup; + } + + assert (filenamesize > lendir); + strcpy (filename, dir_name); + + if (base_name && *base_name) + { + if (filename[lendir -1] != '/') + filename[lendir++] = '/'; + strcpy (filename +lendir, base_name); + } + + if ((result = (*func) (filename, data1, data2))) + { + break; + } } } cleanup: - LT_DLFREE (argz); - LT_DLFREE (canonical); - LT_DLFREE (filename); - - LT_DLMUTEX_UNLOCK (); + FREE (argz); + FREE (canonical); + FREE (filename); return result; } @@ -2228,14 +726,11 @@ in DATA1, and the opened FILE* structure address in DATA2. Otherwise DATA1 is unchanged, but DATA2 is set to a pointer to NULL. */ static int -find_file_callback (filename, data1, data2) - char *filename; - lt_ptr data1; - lt_ptr data2; -{ - char **pdir = (char **) data1; - FILE **pfile = (FILE **) data2; - int is_done = 0; +find_file_callback (char *filename, void *data1, void *data2) +{ + char **pdir = (char **) data1; + FILE **pfile = (FILE **) data2; + int is_done = 0; assert (filename && *filename); assert (pdir); @@ -2246,10 +741,10 @@ char *dirend = strrchr (filename, '/'); if (dirend > filename) - *dirend = LT_EOS_CHAR; + *dirend = LT_EOS_CHAR; - LT_DLFREE (*pdir); - *pdir = lt_estrdup (filename); + FREE (*pdir); + *pdir = lt__strdup (filename); is_done = (*pdir == 0) ? -1 : 1; } @@ -2257,10 +752,7 @@ } static FILE * -find_file (search_path, base_name, pdir) - const char *search_path; - const char *base_name; - char **pdir; +find_file (const char *search_path, const char *base_name, char **pdir) { FILE *file = 0; @@ -2270,22 +762,20 @@ } static int -find_handle_callback (filename, data, ignored) - char *filename; - lt_ptr data; - lt_ptr ignored; +find_handle_callback (char *filename, void *data, void *data2) { - lt_dlhandle *handle = (lt_dlhandle *) data; - int found = access (filename, R_OK); + lt_dlhandle *phandle = (lt_dlhandle *) data; + int notfound = access (filename, R_OK); + lt_dladvise advise = (lt_dladvise) data2; /* Bail out if file cannot be read... */ - if (!found) + if (notfound) return 0; /* Try to dlopen the file, but do not continue searching in any case. */ - if (tryall_dlopen (handle, filename) != 0) - *handle = 0; + if (tryall_dlopen (phandle, filename, advise, 0) != 0) + *phandle = 0; return 1; } @@ -2293,91 +783,87 @@ /* If HANDLE was found return it, otherwise return 0. If HANDLE was found but could not be opened, *HANDLE will be set to 0. */ static lt_dlhandle * -find_handle (search_path, base_name, handle) - const char *search_path; - const char *base_name; - lt_dlhandle *handle; +find_handle (const char *search_path, const char *base_name, + lt_dlhandle *phandle, lt_dladvise advise) { if (!search_path) return 0; if (!foreach_dirinpath (search_path, base_name, find_handle_callback, - handle, 0)) + phandle, advise)) return 0; - return handle; + return phandle; +} + +#if !defined(LTDL_DLOPEN_DEPLIBS) +static int +load_deplibs (lt_dlhandle handle, char * LT__UNUSED deplibs) +{ + handle->depcount = 0; + return 0; } +#else /* defined(LTDL_DLOPEN_DEPLIBS) */ static int -load_deplibs (handle, deplibs) - lt_dlhandle handle; - char *deplibs; +load_deplibs (lt_dlhandle handle, char *deplibs) { -#if LTDL_DLOPEN_DEPLIBS - char *p, *save_search_path = 0; + char *p, *save_search_path = 0; int depcount = 0; - int i; - char **names = 0; -#endif - int errors = 0; + int i; + char **names = 0; + int errors = 0; handle->depcount = 0; -#if LTDL_DLOPEN_DEPLIBS if (!deplibs) { return errors; } ++errors; - LT_DLMUTEX_LOCK (); if (user_search_path) { - save_search_path = lt_estrdup (user_search_path); + save_search_path = lt__strdup (user_search_path); if (!save_search_path) - goto cleanup; + goto cleanup; } /* extract search paths and count deplibs */ p = deplibs; while (*p) { - if (!isspace ((int) *p)) - { - char *end = p+1; - while (*end && !isspace((int) *end)) - { - ++end; - } - - if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0) - { - char save = *end; - *end = 0; /* set a temporary string terminator */ - if (lt_dladdsearchdir(p+2)) - { - goto cleanup; - } - *end = save; - } - else - { - ++depcount; - } + if (!isspace ((unsigned char) *p)) + { + char *end = p+1; + while (*end && !isspace((unsigned char) *end)) + { + ++end; + } + + if (strncmp(p, "-L", 2) == 0 || strncmp(p, "-R", 2) == 0) + { + char save = *end; + *end = 0; /* set a temporary string terminator */ + if (lt_dladdsearchdir(p+2)) + { + goto cleanup; + } + *end = save; + } + else + { + ++depcount; + } - p = end; - } + p = end; + } else - { - ++p; - } + { + ++p; + } } - /* restore the old search path */ - LT_DLFREE (user_search_path); - user_search_path = save_search_path; - - LT_DLMUTEX_UNLOCK (); if (!depcount) { @@ -2385,7 +871,7 @@ goto cleanup; } - names = LT_EMALLOC (char *, depcount * sizeof (char*)); + names = MALLOC (char *, depcount); if (!names) goto cleanup; @@ -2395,40 +881,40 @@ while (*p) { if (isspace ((unsigned char) *p)) - { - ++p; - } + { + ++p; + } else - { - char *end = p+1; - while (*end && !isspace ((unsigned char) *end)) - { - ++end; - } - - if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0) - { - char *name; - char save = *end; - *end = 0; /* set a temporary string terminator */ - if (strncmp(p, "-l", 2) == 0) - { - size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2); - name = LT_EMALLOC (char, 1+ name_len); - if (name) - sprintf (name, "lib%s", p+2); - } - else - name = lt_estrdup(p); - - if (!name) - goto cleanup_names; - - names[depcount++] = name; - *end = save; - } - p = end; - } + { + char *end = p+1; + while (*end && !isspace ((unsigned char) *end)) + { + ++end; + } + + if (strncmp(p, "-L", 2) != 0 && strncmp(p, "-R", 2) != 0) + { + char *name; + char save = *end; + *end = 0; /* set a temporary string terminator */ + if (strncmp(p, "-l", 2) == 0) + { + size_t name_len = 3+ /* "lib" */ LT_STRLEN (p + 2); + name = MALLOC (char, 1+ name_len); + if (name) + sprintf (name, "lib%s", p+2); + } + else + name = lt__strdup(p); + + if (!name) + goto cleanup_names; + + names[depcount++] = name; + *end = save; + } + p = end; + } } /* load the deplibs (in reverse order) @@ -2438,80 +924,87 @@ later on if the loaded module cannot resolve all of its symbols. */ if (depcount) { - int j = 0; + lt_dlhandle cur = handle; + int j = 0; - handle->deplibs = (lt_dlhandle*) LT_EMALLOC (lt_dlhandle *, depcount); - if (!handle->deplibs) - goto cleanup; + cur->deplibs = MALLOC (lt_dlhandle, depcount); + if (!cur->deplibs) + goto cleanup_names; for (i = 0; i < depcount; ++i) - { - handle->deplibs[j] = lt_dlopenext(names[depcount-1-i]); - if (handle->deplibs[j]) - { - ++j; - } - } + { + cur->deplibs[j] = lt_dlopenext(names[depcount-1-i]); + if (cur->deplibs[j]) + { + ++j; + } + } - handle->depcount = j; /* Number of successfully loaded deplibs */ - errors = 0; + cur->depcount = j; /* Number of successfully loaded deplibs */ + errors = 0; } cleanup_names: for (i = 0; i < depcount; ++i) { - LT_DLFREE (names[i]); + FREE (names[i]); } cleanup: - LT_DLFREE (names); -#endif + FREE (names); + /* restore the old search path */ + if (save_search_path) { + MEMREASSIGN (user_search_path, save_search_path); + } return errors; } +#endif /* defined(LTDL_DLOPEN_DEPLIBS) */ static int -unload_deplibs (handle) - lt_dlhandle handle; +unload_deplibs (lt_dlhandle handle) { int i; int errors = 0; + lt_dlhandle cur = handle; - if (handle->depcount) + if (cur->depcount) { - for (i = 0; i < handle->depcount; ++i) - { - if (!LT_DLIS_RESIDENT (handle->deplibs[i])) - { - errors += lt_dlclose (handle->deplibs[i]); - } - } + for (i = 0; i < cur->depcount; ++i) + { + if (!LT_DLIS_RESIDENT (cur->deplibs[i])) + { + errors += lt_dlclose (cur->deplibs[i]); + } + } + FREE (cur->deplibs); } return errors; } static int -trim (dest, str) - char **dest; - const char *str; +trim (char **dest, const char *str) { /* remove the leading and trailing "'" from str and store the result in dest */ const char *end = strrchr (str, '\''); - size_t len = LT_STRLEN (str); + size_t len = LT_STRLEN (str); char *tmp; - LT_DLFREE (*dest); + FREE (*dest); + + if (!end) + return 1; if (len > 3 && str[0] == '\'') { - tmp = LT_EMALLOC (char, end - str); + tmp = MALLOC (char, end - str); if (!tmp) - return 1; + return 1; - strncpy(tmp, &str[1], (end - str) - 1); - tmp[len-3] = LT_EOS_CHAR; + memcpy(tmp, &str[1], (end - str) - 1); + tmp[(end - str) - 1] = LT_EOS_CHAR; *dest = tmp; } else @@ -2522,67 +1015,187 @@ return 0; } +/* Read the .la file FILE. */ static int -free_vars (dlname, oldname, libdir, deplibs) - char *dlname; - char *oldname; - char *libdir; - char *deplibs; -{ - LT_DLFREE (dlname); - LT_DLFREE (oldname); - LT_DLFREE (libdir); - LT_DLFREE (deplibs); +parse_dotla_file(FILE *file, char **dlname, char **libdir, char **deplibs, + char **old_name, int *installed) +{ + int errors = 0; + size_t line_len = LT_FILENAME_MAX; + char * line = MALLOC (char, line_len); - return 0; + if (!line) + { + LT__SETERROR (FILE_NOT_FOUND); + return 1; + } + + while (!feof (file)) + { + line[line_len-2] = '\0'; + if (!fgets (line, (int) line_len, file)) + { + break; + } + + /* Handle the case where we occasionally need to read a line + that is longer than the initial buffer size. + Behave even if the file contains NUL bytes due to corruption. */ + while (line[line_len-2] != '\0' && line[line_len-2] != '\n' && !feof (file)) + { + line = REALLOC (char, line, line_len *2); + if (!line) + { + ++errors; + goto cleanup; + } + line[line_len * 2 - 2] = '\0'; + if (!fgets (&line[line_len -1], (int) line_len +1, file)) + { + break; + } + line_len *= 2; + } + + if (line[0] == '\n' || line[0] == '#') + { + continue; + } + +#undef STR_DLNAME +#define STR_DLNAME "dlname=" + if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0) + { + errors += trim (dlname, &line[sizeof (STR_DLNAME) - 1]); + } + +#undef STR_OLD_LIBRARY +#define STR_OLD_LIBRARY "old_library=" + else if (strncmp (line, STR_OLD_LIBRARY, + sizeof (STR_OLD_LIBRARY) - 1) == 0) + { + errors += trim (old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]); + } +#undef STR_LIBDIR +#define STR_LIBDIR "libdir=" + else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0) + { + errors += trim (libdir, &line[sizeof(STR_LIBDIR) - 1]); + } + +#undef STR_DL_DEPLIBS +#define STR_DL_DEPLIBS "dependency_libs=" + else if (strncmp (line, STR_DL_DEPLIBS, + sizeof (STR_DL_DEPLIBS) - 1) == 0) + { + errors += trim (deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]); + } + else if (streq (line, "installed=yes\n")) + { + *installed = 1; + } + else if (streq (line, "installed=no\n")) + { + *installed = 0; + } + +#undef STR_LIBRARY_NAMES +#define STR_LIBRARY_NAMES "library_names=" + else if (!*dlname && strncmp (line, STR_LIBRARY_NAMES, + sizeof (STR_LIBRARY_NAMES) - 1) == 0) + { + char *last_libname; + errors += trim (dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); + if (!errors + && *dlname + && (last_libname = strrchr (*dlname, ' ')) != 0) + { + last_libname = lt__strdup (last_libname + 1); + if (!last_libname) + { + ++errors; + goto cleanup; + } + MEMREASSIGN (*dlname, last_libname); + } + } + + if (errors) + break; + } +cleanup: + FREE (line); + return errors; } + +/* Try to open FILENAME as a module. */ static int -try_dlopen (phandle, filename) - lt_dlhandle *phandle; - const char *filename; -{ - const char * ext = 0; - const char * saved_error = 0; - char * canonical = 0; - char * base_name = 0; - char * dir = 0; - char * name = 0; - int errors = 0; - lt_dlhandle newhandle; +try_dlopen (lt_dlhandle *phandle, const char *filename, const char *ext, + lt_dladvise advise) +{ + const char * saved_error = 0; + char * archive_name = 0; + char * canonical = 0; + char * base_name = 0; + char * dir = 0; + char * name = 0; + char * attempt = 0; + int errors = 0; + lt_dlhandle newhandle; assert (phandle); assert (*phandle == 0); - LT_DLMUTEX_GETERROR (saved_error); +#ifdef LT_DEBUG_LOADERS + fprintf (stderr, "try_dlopen (%s, %s)\n", + filename ? filename : "(null)", + ext ? ext : "(null)"); +#endif + + LT__GETERROR (saved_error); /* dlopen self? */ if (!filename) { - *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle)); if (*phandle == 0) - return 1; + return 1; - memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); - newhandle = *phandle; + newhandle = *phandle; /* lt_dlclose()ing yourself is very bad! Disallow it. */ - LT_DLSET_FLAG (*phandle, LT_DLRESIDENT_FLAG); + newhandle->info.is_resident = 1; - if (tryall_dlopen (&newhandle, 0) != 0) - { - LT_DLFREE (*phandle); - return 1; - } + if (tryall_dlopen (&newhandle, 0, advise, 0) != 0) + { + FREE (*phandle); + return 1; + } goto register_handle; } assert (filename && *filename); + if (ext) + { + attempt = MALLOC (char, LT_STRLEN (filename) + LT_STRLEN (ext) + 1); + if (!attempt) + return 1; + + sprintf(attempt, "%s%s", filename, ext); + } + else + { + attempt = lt__strdup (filename); + if (!attempt) + return 1; + } + /* Doing this immediately allows internal functions to safely assume only canonicalized paths are passed. */ - if (canonicalize_path (filename, &canonical) != 0) + if (canonicalize_path (attempt, &canonical) != 0) { ++errors; goto cleanup; @@ -2595,12 +1208,12 @@ { size_t dirlen = (1+ base_name) - canonical; - dir = LT_EMALLOC (char, 1+ dirlen); + dir = MALLOC (char, 1+ dirlen); if (!dir) - { - ++errors; - goto cleanup; - } + { + ++errors; + goto cleanup; + } strncpy (dir, canonical, dirlen); dir[dirlen] = LT_EOS_CHAR; @@ -2608,447 +1221,476 @@ ++base_name; } else - LT_DLMEM_REASSIGN (base_name, canonical); + MEMREASSIGN (base_name, canonical); assert (base_name && *base_name); - /* Check whether we are opening a libtool module (.la extension). */ ext = strrchr (base_name, '.'); - if (ext && strcmp (ext, archive_ext) == 0) + if (!ext) { - /* this seems to be a libtool module */ - FILE * file = 0; - char * dlname = 0; - char * old_name = 0; - char * libdir = 0; - char * deplibs = 0; - char * line = 0; - size_t line_len; + ext = base_name + LT_STRLEN (base_name); + } - /* if we can't find the installed flag, it is probably an - installed libtool archive, produced with an old version - of libtool */ - int installed = 1; - - /* extract the module name from the file name */ - name = LT_EMALLOC (char, ext - base_name + 1); - if (!name) - { - ++errors; - goto cleanup; - } + /* extract the module name from the file name */ + name = MALLOC (char, ext - base_name + 1); + if (!name) + { + ++errors; + goto cleanup; + } - /* canonicalize the module name */ + /* canonicalize the module name */ + { + int i; + for (i = 0; i < ext - base_name; ++i) { - size_t i; - for (i = 0; i < ext - base_name; ++i) - { - if (isalnum ((unsigned char)(base_name[i]))) - { - name[i] = base_name[i]; - } - else - { - name[i] = '_'; - } - } - name[ext - base_name] = LT_EOS_CHAR; + if (isalnum ((unsigned char)(base_name[i]))) + { + name[i] = base_name[i]; + } + else + { + name[i] = '_'; + } } + name[ext - base_name] = LT_EOS_CHAR; + } + + /* Before trawling through the filesystem in search of a module, + check whether we are opening a preloaded module. */ + if (!dir) + { + const lt_dlvtable *vtable = lt_dlloader_find ("lt_preopen"); + + if (vtable) + { + /* name + "." + libext + NULL */ + archive_name = MALLOC (char, LT_STRLEN (name) + LT_STRLEN (libext) + 2); + *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle)); + + if ((*phandle == NULL) || (archive_name == NULL)) + { + ++errors; + goto cleanup; + } + newhandle = *phandle; + + /* Preloaded modules are always named according to their old + archive name. */ + sprintf (archive_name, "%s.%s", name, libext); + + if (tryall_dlopen (&newhandle, archive_name, advise, vtable) == 0) + { + goto register_handle; + } + + /* If we're still here, there was no matching preloaded module, + so put things back as we found them, and continue searching. */ + FREE (*phandle); + newhandle = NULL; + } + } + + /* If we are allowing only preloaded modules, and we didn't find + anything yet, give up on the search here. */ + if (advise && advise->try_preload_only) + { + goto cleanup; + } + + /* Check whether we are opening a libtool module (.la extension). */ + if (ext && streq (ext, archive_ext)) + { + /* this seems to be a libtool module */ + FILE * file = 0; + char * dlname = 0; + char * old_name = 0; + char * libdir = 0; + char * deplibs = 0; + + /* if we can't find the installed flag, it is probably an + installed libtool archive, produced with an old version + of libtool */ + int installed = 1; /* Now try to open the .la file. If there is no directory name - component, try to find it first in user_search_path and then other - prescribed paths. Otherwise (or in any case if the module was not - yet found) try opening just the module name as passed. */ + component, try to find it first in user_search_path and then other + prescribed paths. Otherwise (or in any case if the module was not + yet found) try opening just the module name as passed. */ if (!dir) - { - const char *search_path; + { + const char *search_path = user_search_path; + + if (search_path) + file = find_file (user_search_path, base_name, &dir); - LT_DLMUTEX_LOCK (); - search_path = user_search_path; - if (search_path) - file = find_file (user_search_path, base_name, &dir); - LT_DLMUTEX_UNLOCK (); - - if (!file) - { - search_path = getenv (LTDL_SEARCHPATH_VAR); - if (search_path) - file = find_file (search_path, base_name, &dir); - } - -#ifdef LTDL_SHLIBPATH_VAR - if (!file) - { - search_path = getenv (LTDL_SHLIBPATH_VAR); - if (search_path) - file = find_file (search_path, base_name, &dir); - } -#endif -#ifdef LTDL_SYSSEARCHPATH - if (!file && sys_search_path) - { - file = find_file (sys_search_path, base_name, &dir); - } + if (!file) + { + search_path = getenv (LTDL_SEARCHPATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); + } + +#if defined(LT_MODULE_PATH_VAR) + if (!file) + { + search_path = getenv (LT_MODULE_PATH_VAR); + if (search_path) + file = find_file (search_path, base_name, &dir); + } +#endif +#if defined(LT_DLSEARCH_PATH) + if (!file && *sys_dlsearch_path) + { + file = find_file (sys_dlsearch_path, base_name, &dir); + } #endif - } - if (!file) - { - file = fopen (filename, LT_READTEXT_MODE); - } + } + else + { + file = fopen (attempt, LT_READTEXT_MODE); + } /* If we didn't find the file by now, it really isn't there. Set - the status flag, and bail out. */ + the status flag, and bail out. */ if (!file) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); - ++errors; - goto cleanup; - } - - line_len = LT_FILENAME_MAX; - line = LT_EMALLOC (char, line_len); - if (!line) - { - fclose (file); - ++errors; - goto cleanup; - } + { + LT__SETERROR (FILE_NOT_FOUND); + ++errors; + goto cleanup; + } /* read the .la file */ - while (!feof (file)) - { - if (!fgets (line, (int) line_len, file)) - { - break; - } - - /* Handle the case where we occasionally need to read a line - that is longer than the initial buffer size. */ - while (line[LT_STRLEN(line) -1] != '\n') - { - line = LT_DLREALLOC (char, line, line_len *2); - if (!fgets (&line[line_len -1], (int) line_len +1, file)) - { - break; - } - line_len *= 2; - } - - if (line[0] == '\n' || line[0] == '#') - { - continue; - } - -#undef STR_DLNAME -#define STR_DLNAME "dlname=" - if (strncmp (line, STR_DLNAME, sizeof (STR_DLNAME) - 1) == 0) - { - errors += trim (&dlname, &line[sizeof (STR_DLNAME) - 1]); - } - -#undef STR_OLD_LIBRARY -#define STR_OLD_LIBRARY "old_library=" - else if (strncmp (line, STR_OLD_LIBRARY, - sizeof (STR_OLD_LIBRARY) - 1) == 0) - { - errors += trim (&old_name, &line[sizeof (STR_OLD_LIBRARY) - 1]); - } -#undef STR_LIBDIR -#define STR_LIBDIR "libdir=" - else if (strncmp (line, STR_LIBDIR, sizeof (STR_LIBDIR) - 1) == 0) - { - errors += trim (&libdir, &line[sizeof(STR_LIBDIR) - 1]); - } - -#undef STR_DL_DEPLIBS -#define STR_DL_DEPLIBS "dependency_libs=" - else if (strncmp (line, STR_DL_DEPLIBS, - sizeof (STR_DL_DEPLIBS) - 1) == 0) - { - errors += trim (&deplibs, &line[sizeof (STR_DL_DEPLIBS) - 1]); - } - else if (strcmp (line, "installed=yes\n") == 0) - { - installed = 1; - } - else if (strcmp (line, "installed=no\n") == 0) - { - installed = 0; - } - -#undef STR_LIBRARY_NAMES -#define STR_LIBRARY_NAMES "library_names=" - else if (! dlname && strncmp (line, STR_LIBRARY_NAMES, - sizeof (STR_LIBRARY_NAMES) - 1) == 0) - { - char *last_libname; - errors += trim (&dlname, &line[sizeof (STR_LIBRARY_NAMES) - 1]); - if (!errors - && dlname - && (last_libname = strrchr (dlname, ' ')) != 0) - { - last_libname = lt_estrdup (last_libname + 1); - if (!last_libname) - { - ++errors; - goto cleanup; - } - LT_DLMEM_REASSIGN (dlname, last_libname); - } - } - - if (errors) - break; - } + if (parse_dotla_file(file, &dlname, &libdir, &deplibs, + &old_name, &installed) != 0) + ++errors; fclose (file); - LT_DLFREE (line); /* allocate the handle */ - *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle)); if (*phandle == 0) - ++errors; + ++errors; if (errors) - { - free_vars (dlname, old_name, libdir, deplibs); - LT_DLFREE (*phandle); - goto cleanup; - } + { + FREE (dlname); + FREE (old_name); + FREE (libdir); + FREE (deplibs); + FREE (*phandle); + goto cleanup; + } assert (*phandle); - memset (*phandle, 0, sizeof(struct lt_dlhandle_struct)); if (load_deplibs (*phandle, deplibs) == 0) - { - newhandle = *phandle; - /* find_module may replace newhandle */ - if (find_module (&newhandle, dir, libdir, dlname, old_name, installed)) - { - unload_deplibs (*phandle); - ++errors; - } - } + { + newhandle = *phandle; + /* find_module may replace newhandle */ + if (find_module (&newhandle, dir, libdir, dlname, old_name, + installed, advise)) + { + unload_deplibs (*phandle); + ++errors; + } + } else - { - ++errors; - } + { + ++errors; + } + + FREE (dlname); + FREE (old_name); + FREE (libdir); + FREE (deplibs); - free_vars (dlname, old_name, libdir, deplibs); if (errors) - { - LT_DLFREE (*phandle); - goto cleanup; - } + { + FREE (*phandle); + goto cleanup; + } if (*phandle != newhandle) - { - unload_deplibs (*phandle); - } + { + unload_deplibs (*phandle); + } } else { /* not a libtool module */ - *phandle = (lt_dlhandle) LT_EMALLOC (struct lt_dlhandle_struct, 1); + *phandle = (lt_dlhandle) lt__zalloc (sizeof (struct lt__handle)); if (*phandle == 0) - { - ++errors; - goto cleanup; - } + { + ++errors; + goto cleanup; + } - memset (*phandle, 0, sizeof (struct lt_dlhandle_struct)); newhandle = *phandle; /* If the module has no directory name component, try to find it - first in user_search_path and then other prescribed paths. - Otherwise (or in any case if the module was not yet found) try - opening just the module name as passed. */ - if ((dir || (!find_handle (user_search_path, base_name, &newhandle) - && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name, - &newhandle) -#ifdef LTDL_SHLIBPATH_VAR - && !find_handle (getenv (LTDL_SHLIBPATH_VAR), base_name, - &newhandle) -#endif -#ifdef LTDL_SYSSEARCHPATH - && !find_handle (sys_search_path, base_name, &newhandle) -#endif - ))) - { - tryall_dlopen (&newhandle, filename); - } + first in user_search_path and then other prescribed paths. + Otherwise (or in any case if the module was not yet found) try + opening just the module name as passed. */ + if ((dir || (!find_handle (user_search_path, base_name, + &newhandle, advise) + && !find_handle (getenv (LTDL_SEARCHPATH_VAR), base_name, + &newhandle, advise) +#if defined(LT_MODULE_PATH_VAR) + && !find_handle (getenv (LT_MODULE_PATH_VAR), base_name, + &newhandle, advise) +#endif +#if defined(LT_DLSEARCH_PATH) + && !find_handle (sys_dlsearch_path, base_name, + &newhandle, advise) +#endif + ))) + { + if (tryall_dlopen (&newhandle, attempt, advise, 0) != 0) + { + newhandle = NULL; + } + } if (!newhandle) - { - LT_DLFREE (*phandle); - ++errors; - goto cleanup; - } + { + FREE (*phandle); + ++errors; + goto cleanup; + } } register_handle: - LT_DLMEM_REASSIGN (*phandle, newhandle); + MEMREASSIGN (*phandle, newhandle); if ((*phandle)->info.ref_count == 0) { - (*phandle)->info.ref_count = 1; - LT_DLMEM_REASSIGN ((*phandle)->info.name, name); + (*phandle)->info.ref_count = 1; + MEMREASSIGN ((*phandle)->info.name, name); - LT_DLMUTEX_LOCK (); - (*phandle)->next = handles; - handles = *phandle; - LT_DLMUTEX_UNLOCK (); + (*phandle)->next = handles; + handles = *phandle; } - LT_DLMUTEX_SETERROR (saved_error); + LT__SETERRORSTR (saved_error); cleanup: - LT_DLFREE (dir); - LT_DLFREE (name); - LT_DLFREE (canonical); + FREE (dir); + FREE (attempt); + FREE (name); + if (!canonical) /* was MEMREASSIGNed */ + FREE (base_name); + FREE (canonical); + FREE (archive_name); return errors; } -lt_dlhandle -lt_dlopen (filename) - const char *filename; -{ - lt_dlhandle handle = 0; - - /* Just incase we missed a code path in try_dlopen() that reports - an error, but forgets to reset handle... */ - if (try_dlopen (&handle, filename) != 0) - return 0; - - return handle; -} /* If the last error messge store was `FILE_NOT_FOUND', then return non-zero. */ static int -file_not_found () +file_not_found (void) { const char *error = 0; - LT_DLMUTEX_GETERROR (error); - if (error == LT_DLSTRERROR (FILE_NOT_FOUND)) + LT__GETERROR (error); + if (error == LT__STRERROR (FILE_NOT_FOUND)) return 1; return 0; } -/* If FILENAME has an ARCHIVE_EXT or SHLIB_EXT extension, try to - open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT, - and if a file is still not found try again with SHLIB_EXT appended - instead. */ -lt_dlhandle -lt_dlopenext (filename) - const char *filename; -{ - lt_dlhandle handle = 0; - char * tmp = 0; - char * ext = 0; - size_t len; - int errors = 0; - if (!filename) - { - return lt_dlopen (filename); - } +/* Unless FILENAME already bears a suitable library extension, then + return 0. */ +static int +has_library_ext (const char *filename) +{ + char * ext = 0; assert (filename); - len = LT_STRLEN (filename); ext = strrchr (filename, '.'); - /* If FILENAME already bears a suitable extension, there is no need - to try appending additional extensions. */ - if (ext && ((strcmp (ext, archive_ext) == 0) -#ifdef LTDL_SHLIB_EXT - || (strcmp (ext, shlib_ext) == 0) + if (ext && ((streq (ext, archive_ext)) +#if defined(LT_MODULE_EXT) + || (streq (ext, shlib_ext)) #endif - )) + )) { - return lt_dlopen (filename); + return 1; } - /* First try appending ARCHIVE_EXT. */ - tmp = LT_EMALLOC (char, len + LT_STRLEN (archive_ext) + 1); - if (!tmp) - return 0; + return 0; +} - strcpy (tmp, filename); - strcat (tmp, archive_ext); - errors = try_dlopen (&handle, tmp); - - /* If we found FILENAME, stop searching -- whether we were able to - load the file as a module or not. If the file exists but loading - failed, it is better to return an error message here than to - report FILE_NOT_FOUND when the alternatives (foo.so etc) are not - in the module search path. */ - if (handle || ((errors > 0) && file_not_found ())) - { - LT_DLFREE (tmp); - return handle; - } -#ifdef LTDL_SHLIB_EXT - /* Try appending SHLIB_EXT. */ - if (LT_STRLEN (shlib_ext) > LT_STRLEN (archive_ext)) - { - LT_DLFREE (tmp); - tmp = LT_EMALLOC (char, len + LT_STRLEN (shlib_ext) + 1); - if (!tmp) - return 0; +/* Initialise and configure a user lt_dladvise opaque object. */ - strcpy (tmp, filename); - } - else +int +lt_dladvise_init (lt_dladvise *padvise) +{ + lt_dladvise advise = (lt_dladvise) lt__zalloc (sizeof (struct lt__advise)); + *padvise = advise; + return (advise ? 0 : 1); +} + +int +lt_dladvise_destroy (lt_dladvise *padvise) +{ + if (padvise) + FREE(*padvise); + return 0; +} + +int +lt_dladvise_ext (lt_dladvise *padvise) +{ + assert (padvise && *padvise); + (*padvise)->try_ext = 1; + return 0; +} + +int +lt_dladvise_resident (lt_dladvise *padvise) +{ + assert (padvise && *padvise); + (*padvise)->is_resident = 1; + return 0; +} + +int +lt_dladvise_local (lt_dladvise *padvise) +{ + assert (padvise && *padvise); + (*padvise)->is_symlocal = 1; + return 0; +} + +int +lt_dladvise_global (lt_dladvise *padvise) +{ + assert (padvise && *padvise); + (*padvise)->is_symglobal = 1; + return 0; +} + +int +lt_dladvise_preload (lt_dladvise *padvise) +{ + assert (padvise && *padvise); + (*padvise)->try_preload_only = 1; + return 0; +} + +/* Libtool-1.5.x interface for loading a new module named FILENAME. */ +lt_dlhandle +lt_dlopen (const char *filename) +{ + return lt_dlopenadvise (filename, NULL); +} + + +/* If FILENAME has an ARCHIVE_EXT or MODULE_EXT extension, try to + open the FILENAME as passed. Otherwise try appending ARCHIVE_EXT, + and if a file is still not found try again with MODULE_EXT appended + instead. */ +lt_dlhandle +lt_dlopenext (const char *filename) +{ + lt_dlhandle handle = 0; + lt_dladvise advise; + + if (!lt_dladvise_init (&advise) && !lt_dladvise_ext (&advise)) + handle = lt_dlopenadvise (filename, advise); + + lt_dladvise_destroy (&advise); + return handle; +} + + +lt_dlhandle +lt_dlopenadvise (const char *filename, lt_dladvise advise) +{ + lt_dlhandle handle = 0; + int errors = 0; + + /* Can't have symbols hidden and visible at the same time! */ + if (advise && advise->is_symlocal && advise->is_symglobal) { - tmp[len] = LT_EOS_CHAR; + LT__SETERROR (CONFLICTING_FLAGS); + return 0; } - strcat(tmp, shlib_ext); - errors = try_dlopen (&handle, tmp); + if (!filename + || !advise + || !advise->try_ext + || has_library_ext (filename)) + { + /* Just incase we missed a code path in try_dlopen() that reports + an error, but forgot to reset handle... */ + if (try_dlopen (&handle, filename, NULL, advise) != 0) + return 0; - /* As before, if the file was found but loading failed, return now - with the current error message. */ - if (handle || ((errors > 0) && file_not_found ())) - { - LT_DLFREE (tmp); return handle; } + else if (filename && *filename) + { + + /* First try appending ARCHIVE_EXT. */ + errors += try_dlopen (&handle, filename, archive_ext, advise); + + /* If we found FILENAME, stop searching -- whether we were able to + load the file as a module or not. If the file exists but loading + failed, it is better to return an error message here than to + report FILE_NOT_FOUND when the alternatives (foo.so etc) are not + in the module search path. */ + if (handle || ((errors > 0) && !file_not_found ())) + return handle; + +#if defined(LT_MODULE_EXT) + /* Try appending SHLIB_EXT. */ + errors = try_dlopen (&handle, filename, shlib_ext, advise); + + /* As before, if the file was found but loading failed, return now + with the current error message. */ + if (handle || ((errors > 0) && !file_not_found ())) + return handle; #endif + } /* Still here? Then we really did fail to locate any of the file names we tried. */ - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (FILE_NOT_FOUND)); - LT_DLFREE (tmp); + LT__SETERROR (FILE_NOT_FOUND); return 0; } static int -lt_argz_insert (pargz, pargz_len, before, entry) - char **pargz; - size_t *pargz_len; - char *before; - const char *entry; +lt_argz_insert (char **pargz, size_t *pargz_len, char *before, + const char *entry) { error_t error; - if ((error = argz_insert (pargz, pargz_len, before, entry))) + /* Prior to Sep 8, 2005, newlib had a bug where argz_insert(pargz, + pargz_len, NULL, entry) failed with EINVAL. */ + if (before) + error = argz_insert (pargz, pargz_len, before, entry); + else + error = argz_append (pargz, pargz_len, entry, 1 + strlen (entry)); + + if (error) { switch (error) - { - case ENOMEM: - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (NO_MEMORY)); - break; - default: - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (UNKNOWN)); - break; - } + { + case ENOMEM: + LT__SETERROR (NO_MEMORY); + break; + default: + LT__SETERROR (UNKNOWN); + break; + } return 1; } @@ -3056,10 +1698,7 @@ } static int -lt_argz_insertinorder (pargz, pargz_len, entry) - char **pargz; - size_t *pargz_len; - const char *entry; +lt_argz_insertinorder (char **pargz, size_t *pargz_len, const char *entry) { char *before = 0; @@ -3070,42 +1709,39 @@ if (*pargz) while ((before = argz_next (*pargz, *pargz_len, before))) { - int cmp = strcmp (entry, before); + int cmp = strcmp (entry, before); - if (cmp < 0) break; - if (cmp == 0) return 0; /* No duplicates! */ + if (cmp < 0) break; + if (cmp == 0) return 0; /* No duplicates! */ } return lt_argz_insert (pargz, pargz_len, before, entry); } static int -lt_argz_insertdir (pargz, pargz_len, dirnam, dp) - char **pargz; - size_t *pargz_len; - const char *dirnam; - struct dirent *dp; +lt_argz_insertdir (char **pargz, size_t *pargz_len, const char *dirnam, + struct dirent *dp) { - char *buf = 0; + char *buf = 0; size_t buf_len = 0; - char *end = 0; + char *end = 0; size_t end_offset = 0; size_t dir_len = 0; - int errors = 0; + int errors = 0; assert (pargz); assert (pargz_len); assert (dp); dir_len = LT_STRLEN (dirnam); - end = dp->d_name + LT_D_NAMLEN(dp); + end = dp->d_name + D_NAMLEN(dp); /* Ignore version numbers. */ { char *p; for (p = end; p -1 > dp->d_name; --p) if (strchr (".0123456789", p[-1]) == 0) - break; + break; if (*p == '.') end = p; @@ -3116,16 +1752,16 @@ char *p; for (p = end -1; p > dp->d_name; --p) if (*p == '.') - { - end = p; - break; - } + { + end = p; + break; + } } /* Prepend the directory name. */ - end_offset = end - dp->d_name; - buf_len = dir_len + 1+ end_offset; - buf = LT_EMALLOC (char, 1+ buf_len); + end_offset = end - dp->d_name; + buf_len = dir_len + 1+ end_offset; + buf = MALLOC (char, 1+ buf_len); if (!buf) return ++errors; @@ -3140,19 +1776,16 @@ if (lt_argz_insertinorder (pargz, pargz_len, buf) != 0) ++errors; - LT_DLFREE (buf); + FREE (buf); return errors; } static int -list_files_by_dir (dirnam, pargz, pargz_len) - const char *dirnam; - char **pargz; - size_t *pargz_len; +list_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len) { - DIR *dirp = 0; - int errors = 0; + DIR *dirp = 0; + int errors = 0; assert (dirnam && *dirnam); assert (pargz); @@ -3162,15 +1795,15 @@ dirp = opendir (dirnam); if (dirp) { - struct dirent *dp = 0; + struct dirent *dp = 0; while ((dp = readdir (dirp))) - if (dp->d_name[0] != '.') - if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp)) - { - ++errors; - break; - } + if (dp->d_name[0] != '.') + if (lt_argz_insertdir (pargz, pargz_len, dirnam, dp)) + { + ++errors; + break; + } closedir (dirp); } @@ -3184,15 +1817,11 @@ /* If there are any files in DIRNAME, call the function passed in DATA1 (with the name of each file and DATA2 as arguments). */ static int -foreachfile_callback (dirname, data1, data2) - char *dirname; - lt_ptr data1; - lt_ptr data2; +foreachfile_callback (char *dirname, void *data1, void *data2) { - int (*func) LT_PARAMS((const char *filename, lt_ptr data)) - = (int (*) LT_PARAMS((const char *filename, lt_ptr data))) data1; + file_worker_func *func = *(file_worker_func **) data1; - int is_done = 0; + int is_done = 0; char *argz = 0; size_t argz_len = 0; @@ -3205,11 +1834,11 @@ char *filename = 0; while ((filename = argz_next (argz, argz_len, filename))) if ((is_done = (*func) (filename, data2))) - break; + break; } cleanup: - LT_DLFREE (argz); + FREE (argz); return is_done; } @@ -3222,44 +1851,44 @@ libfoo.so, libfoo.so.1, libfoo.so.1.0.0). If SEARCH_PATH is NULL, then the same directories that lt_dlopen would search are examined. */ int -lt_dlforeachfile (search_path, func, data) - const char *search_path; - int (*func) LT_PARAMS ((const char *filename, lt_ptr data)); - lt_ptr data; +lt_dlforeachfile (const char *search_path, + int (*func) (const char *filename, void *data), + void *data) { int is_done = 0; + file_worker_func **fpptr = &func; if (search_path) { /* If a specific path was passed, search only the directories - listed in it. */ + listed in it. */ is_done = foreach_dirinpath (search_path, 0, - foreachfile_callback, func, data); + foreachfile_callback, fpptr, data); } else { /* Otherwise search the default paths. */ is_done = foreach_dirinpath (user_search_path, 0, - foreachfile_callback, func, data); + foreachfile_callback, fpptr, data); if (!is_done) - { - is_done = foreach_dirinpath (getenv("LTDL_LIBRARY_PATH"), 0, - foreachfile_callback, func, data); - } + { + is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0, + foreachfile_callback, fpptr, data); + } -#ifdef LTDL_SHLIBPATH_VAR - if (!is_done) - { - is_done = foreach_dirinpath (getenv(LTDL_SHLIBPATH_VAR), 0, - foreachfile_callback, func, data); - } -#endif -#ifdef LTDL_SYSSEARCHPATH +#if defined(LT_MODULE_PATH_VAR) if (!is_done) - { - is_done = foreach_dirinpath (getenv(LTDL_SYSSEARCHPATH), 0, - foreachfile_callback, func, data); - } + { + is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0, + foreachfile_callback, fpptr, data); + } +#endif +#if defined(LT_DLSEARCH_PATH) + if (!is_done && *sys_dlsearch_path) + { + is_done = foreach_dirinpath (sys_dlsearch_path, 0, + foreachfile_callback, fpptr, data); + } #endif } @@ -3267,14 +1896,11 @@ } int -lt_dlclose (handle) - lt_dlhandle handle; +lt_dlclose (lt_dlhandle handle) { lt_dlhandle cur, last; int errors = 0; - LT_DLMUTEX_LOCK (); - /* check whether the handle is valid */ last = cur = handles; while (cur && handle != cur) @@ -3285,80 +1911,80 @@ if (!cur) { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + LT__SETERROR (INVALID_HANDLE); ++errors; goto done; } - handle->info.ref_count--; + cur = handle; + cur->info.ref_count--; /* Note that even with resident modules, we must track the ref_count correctly incase the user decides to reset the residency flag later (even though the API makes no provision for that at the moment). */ - if (handle->info.ref_count <= 0 && !LT_DLIS_RESIDENT (handle)) + if (cur->info.ref_count <= 0 && !LT_DLIS_RESIDENT (cur)) { - lt_user_data data = handle->loader->dlloader_data; + lt_user_data data = cur->vtable->dlloader_data; - if (handle != handles) - { - last->next = handle->next; - } + if (cur != handles) + { + last->next = cur->next; + } else - { - handles = handle->next; - } + { + handles = cur->next; + } - errors += handle->loader->module_close (data, handle->module); - errors += unload_deplibs(handle); + errors += cur->vtable->module_close (data, cur->module); + errors += unload_deplibs (handle); /* It is up to the callers to free the data itself. */ - LT_DLFREE (handle->caller_data); + FREE (cur->interface_data); - LT_DLFREE (handle->info.filename); - LT_DLFREE (handle->info.name); - LT_DLFREE (handle); + FREE (cur->info.filename); + FREE (cur->info.name); + FREE (cur); goto done; } if (LT_DLIS_RESIDENT (handle)) { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (CLOSE_RESIDENT_MODULE)); + LT__SETERROR (CLOSE_RESIDENT_MODULE); ++errors; } done: - LT_DLMUTEX_UNLOCK (); - return errors; } -lt_ptr -lt_dlsym (handle, symbol) - lt_dlhandle handle; - const char *symbol; +void * +lt_dlsym (lt_dlhandle place, const char *symbol) { size_t lensym; - char lsym[LT_SYMBOL_LENGTH]; - char *sym; - lt_ptr address; + char lsym[LT_SYMBOL_LENGTH]; + char *sym; + void *address; lt_user_data data; + lt_dlhandle handle; - if (!handle) + if (!place) { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + LT__SETERROR (INVALID_HANDLE); return 0; } + handle = place; + if (!symbol) { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (SYMBOL_NOT_FOUND)); + LT__SETERROR (SYMBOL_NOT_FOUND); return 0; } - lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->loader->sym_prefix) - + LT_STRLEN (handle->info.name); + lensym = LT_STRLEN (symbol) + LT_STRLEN (handle->vtable->sym_prefix) + + LT_STRLEN (handle->info.name); if (lensym + LT_SYMBOL_OVERHEAD < LT_SYMBOL_LENGTH) { @@ -3366,52 +1992,52 @@ } else { - sym = LT_EMALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1); + sym = MALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1); if (!sym) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (BUFFER_OVERFLOW)); - return 0; - } + { + LT__SETERROR (BUFFER_OVERFLOW); + return 0; + } } - data = handle->loader->dlloader_data; + data = handle->vtable->dlloader_data; if (handle->info.name) { const char *saved_error; - LT_DLMUTEX_GETERROR (saved_error); + LT__GETERROR (saved_error); /* this is a libtool module */ - if (handle->loader->sym_prefix) - { - strcpy(sym, handle->loader->sym_prefix); - strcat(sym, handle->info.name); - } + if (handle->vtable->sym_prefix) + { + strcpy(sym, handle->vtable->sym_prefix); + strcat(sym, handle->info.name); + } else - { - strcpy(sym, handle->info.name); - } + { + strcpy(sym, handle->info.name); + } strcat(sym, "_LTX_"); strcat(sym, symbol); /* try "modulename_LTX_symbol" */ - address = handle->loader->find_sym (data, handle->module, sym); + address = handle->vtable->find_sym (data, handle->module, sym); if (address) - { - if (sym != lsym) - { - LT_DLFREE (sym); - } - return address; - } - LT_DLMUTEX_SETERROR (saved_error); + { + if (sym != lsym) + { + FREE (sym); + } + return address; + } + LT__SETERRORSTR (saved_error); } /* otherwise try "symbol" */ - if (handle->loader->sym_prefix) + if (handle->vtable->sym_prefix) { - strcpy(sym, handle->loader->sym_prefix); + strcpy(sym, handle->vtable->sym_prefix); strcat(sym, symbol); } else @@ -3419,36 +2045,33 @@ strcpy(sym, symbol); } - address = handle->loader->find_sym (data, handle->module, sym); + address = handle->vtable->find_sym (data, handle->module, sym); if (sym != lsym) { - LT_DLFREE (sym); + FREE (sym); } return address; } const char * -lt_dlerror () +lt_dlerror (void) { const char *error; - LT_DLMUTEX_GETERROR (error); - LT_DLMUTEX_SETERROR (0); + LT__GETERROR (error); + LT__SETERRORSTR (0); - return error ? error : LT_DLSTRERROR (UNKNOWN); + return error ? error : NULL; } static int -lt_dlpath_insertdir (ppath, before, dir) - char **ppath; - char *before; - const char *dir; +lt_dlpath_insertdir (char **ppath, char *before, const char *dir) { - int errors = 0; - char *canonical = 0; - char *argz = 0; - size_t argz_len = 0; + int errors = 0; + char *canonical = 0; + char *argz = 0; + size_t argz_len = 0; assert (ppath); assert (dir && *dir); @@ -3464,14 +2087,14 @@ /* If *PPATH is empty, set it to DIR. */ if (*ppath == 0) { - assert (!before); /* BEFORE cannot be set without PPATH. */ - assert (dir); /* Without DIR, don't call this function! */ + assert (!before); /* BEFORE cannot be set without PPATH. */ + assert (dir); /* Without DIR, don't call this function! */ - *ppath = lt_estrdup (dir); + *ppath = lt__strdup (dir); if (*ppath == 0) - ++errors; + ++errors; - return errors; + goto cleanup; } assert (ppath && *ppath); @@ -3490,7 +2113,7 @@ if (before) { assert (*ppath <= before); - assert (before - *ppath <= strlen (*ppath)); + assert ((int) (before - *ppath) <= (int) strlen (*ppath)); before = before - *ppath + argz; } @@ -3502,127 +2125,108 @@ } argz_stringify (argz, argz_len, LT_PATHSEP_CHAR); - LT_DLMEM_REASSIGN (*ppath, argz); + MEMREASSIGN(*ppath, argz); cleanup: - LT_DLFREE (canonical); - LT_DLFREE (argz); + FREE (argz); + FREE (canonical); return errors; } int -lt_dladdsearchdir (search_dir) - const char *search_dir; +lt_dladdsearchdir (const char *search_dir) { int errors = 0; if (search_dir && *search_dir) { - LT_DLMUTEX_LOCK (); if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0) - ++errors; - LT_DLMUTEX_UNLOCK (); + ++errors; } return errors; } int -lt_dlinsertsearchdir (before, search_dir) - const char *before; - const char *search_dir; +lt_dlinsertsearchdir (const char *before, const char *search_dir) { int errors = 0; if (before) { - LT_DLMUTEX_LOCK (); if ((before < user_search_path) - || (before >= user_search_path + LT_STRLEN (user_search_path))) - { - LT_DLMUTEX_UNLOCK (); - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_POSITION)); - return 1; - } - LT_DLMUTEX_UNLOCK (); + || (before >= user_search_path + LT_STRLEN (user_search_path))) + { + LT__SETERROR (INVALID_POSITION); + return 1; + } } if (search_dir && *search_dir) { - LT_DLMUTEX_LOCK (); if (lt_dlpath_insertdir (&user_search_path, - (char *) before, search_dir) != 0) - { - ++errors; - } - LT_DLMUTEX_UNLOCK (); + (char *) before, search_dir) != 0) + { + ++errors; + } } return errors; } int -lt_dlsetsearchpath (search_path) - const char *search_path; +lt_dlsetsearchpath (const char *search_path) { - int errors = 0; + int errors = 0; - LT_DLMUTEX_LOCK (); - LT_DLFREE (user_search_path); - LT_DLMUTEX_UNLOCK (); + FREE (user_search_path); if (!search_path || !LT_STRLEN (search_path)) { return errors; } - LT_DLMUTEX_LOCK (); if (canonicalize_path (search_path, &user_search_path) != 0) ++errors; - LT_DLMUTEX_UNLOCK (); return errors; } const char * -lt_dlgetsearchpath () +lt_dlgetsearchpath (void) { const char *saved_path; - LT_DLMUTEX_LOCK (); saved_path = user_search_path; - LT_DLMUTEX_UNLOCK (); return saved_path; } int -lt_dlmakeresident (handle) - lt_dlhandle handle; +lt_dlmakeresident (lt_dlhandle handle) { int errors = 0; if (!handle) { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + LT__SETERROR (INVALID_HANDLE); ++errors; } else { - LT_DLSET_FLAG (handle, LT_DLRESIDENT_FLAG); + handle->info.is_resident = 1; } return errors; } int -lt_dlisresident (handle) - lt_dlhandle handle; +lt_dlisresident (lt_dlhandle handle) { if (!handle) { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); + LT__SETERROR (INVALID_HANDLE); return -1; } @@ -3631,369 +2235,187 @@ - /* --- MODULE INFORMATION --- */ -const lt_dlinfo * -lt_dlgetinfo (handle) - lt_dlhandle handle; -{ - if (!handle) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_HANDLE)); - return 0; - } - - return &(handle->info); -} - -lt_dlhandle -lt_dlhandle_next (place) - lt_dlhandle place; -{ - return place ? place->next : handles; -} - -int -lt_dlforeach (func, data) - int (*func) LT_PARAMS((lt_dlhandle handle, lt_ptr data)); - lt_ptr data; -{ - int errors = 0; - lt_dlhandle cur; - - LT_DLMUTEX_LOCK (); - - cur = handles; - while (cur) - { - lt_dlhandle tmp = cur; - - cur = cur->next; - if ((*func) (tmp, data)) - { - ++errors; - break; - } +typedef struct { + const char *id_string; + lt_dlhandle_interface *iface; +} lt__interface_id; + +lt_dlinterface_id +lt_dlinterface_register (const char *id_string, lt_dlhandle_interface *iface) +{ + lt__interface_id *interface_id = (lt__interface_id *) lt__malloc (sizeof *interface_id); + + /* If lt__malloc fails, it will LT__SETERROR (NO_MEMORY), which + can then be detected with lt_dlerror() if we return 0. */ + if (interface_id) + { + interface_id->id_string = lt__strdup (id_string); + if (!interface_id->id_string) + FREE (interface_id); + else + interface_id->iface = iface; } - LT_DLMUTEX_UNLOCK (); - - return errors; + return (lt_dlinterface_id) interface_id; } -lt_dlcaller_id -lt_dlcaller_register () +void lt_dlinterface_free (lt_dlinterface_id key) { - static lt_dlcaller_id last_caller_id = 0; - int result; - - LT_DLMUTEX_LOCK (); - result = ++last_caller_id; - LT_DLMUTEX_UNLOCK (); - - return result; + lt__interface_id *interface_id = (lt__interface_id *)key; + FREE (interface_id->id_string); + FREE (interface_id); } -lt_ptr -lt_dlcaller_set_data (key, handle, data) - lt_dlcaller_id key; - lt_dlhandle handle; - lt_ptr data; +void * +lt_dlcaller_set_data (lt_dlinterface_id key, lt_dlhandle handle, void *data) { int n_elements = 0; - lt_ptr stale = (lt_ptr) 0; + void *stale = (void *) 0; + lt_dlhandle cur = handle; int i; - /* This needs to be locked so that the caller data can be updated - simultaneously by different threads. */ - LT_DLMUTEX_LOCK (); - - if (handle->caller_data) - while (handle->caller_data[n_elements].key) + if (cur->interface_data) + while (cur->interface_data[n_elements].key) ++n_elements; for (i = 0; i < n_elements; ++i) { - if (handle->caller_data[i].key == key) - { - stale = handle->caller_data[i].data; - break; - } + if (cur->interface_data[i].key == key) + { + stale = cur->interface_data[i].data; + break; + } } - /* Ensure that there is enough room in this handle's caller_data + /* Ensure that there is enough room in this handle's interface_data array to accept a new element (and an empty end marker). */ if (i == n_elements) { - lt_caller_data *temp - = LT_DLREALLOC (lt_caller_data, handle->caller_data, 2+ n_elements); + lt_interface_data *temp + = REALLOC (lt_interface_data, cur->interface_data, 2+ n_elements); if (!temp) - { - stale = 0; - goto done; - } + { + stale = 0; + goto done; + } - handle->caller_data = temp; + cur->interface_data = temp; - /* We only need this if we needed to allocate a new caller_data. */ - handle->caller_data[i].key = key; - handle->caller_data[1+ i].key = 0; + /* We only need this if we needed to allocate a new interface_data. */ + cur->interface_data[i].key = key; + cur->interface_data[1+ i].key = 0; } - handle->caller_data[i].data = data; + cur->interface_data[i].data = data; done: - LT_DLMUTEX_UNLOCK (); - return stale; } -lt_ptr -lt_dlcaller_get_data (key, handle) - lt_dlcaller_id key; - lt_dlhandle handle; -{ - lt_ptr result = (lt_ptr) 0; - - /* This needs to be locked so that the caller data isn't updated by - another thread part way through this function. */ - LT_DLMUTEX_LOCK (); +void * +lt_dlcaller_get_data (lt_dlinterface_id key, lt_dlhandle handle) +{ + void *result = (void *) 0; + lt_dlhandle cur = handle; /* Locate the index of the element with a matching KEY. */ - { - int i; - for (i = 0; handle->caller_data[i].key; ++i) - { - if (handle->caller_data[i].key == key) - { - result = handle->caller_data[i].data; - break; - } - } - } - - LT_DLMUTEX_UNLOCK (); + if (cur->interface_data) + { + int i; + for (i = 0; cur->interface_data[i].key; ++i) + { + if (cur->interface_data[i].key == key) + { + result = cur->interface_data[i].data; + break; + } + } + } return result; } - - -/* --- USER MODULE LOADER API --- */ - - -int -lt_dlloader_add (place, dlloader, loader_name) - lt_dlloader *place; - const struct lt_user_dlloader *dlloader; - const char *loader_name; +const lt_dlinfo * +lt_dlgetinfo (lt_dlhandle handle) { - int errors = 0; - lt_dlloader *node = 0, *ptr = 0; - - if ((dlloader == 0) /* diagnose null parameters */ - || (dlloader->module_open == 0) - || (dlloader->module_close == 0) - || (dlloader->find_sym == 0)) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); - return 1; - } - - /* Create a new dlloader node with copies of the user callbacks. */ - node = LT_EMALLOC (lt_dlloader, 1); - if (!node) - return 1; - - node->next = 0; - node->loader_name = loader_name; - node->sym_prefix = dlloader->sym_prefix; - node->dlloader_exit = dlloader->dlloader_exit; - node->module_open = dlloader->module_open; - node->module_close = dlloader->module_close; - node->find_sym = dlloader->find_sym; - node->dlloader_data = dlloader->dlloader_data; - - LT_DLMUTEX_LOCK (); - if (!loaders) - { - /* If there are no loaders, NODE becomes the list! */ - loaders = node; - } - else if (!place) - { - /* If PLACE is not set, add NODE to the end of the - LOADERS list. */ - for (ptr = loaders; ptr->next; ptr = ptr->next) - { - /*NOWORK*/; - } - - ptr->next = node; - } - else if (loaders == place) - { - /* If PLACE is the first loader, NODE goes first. */ - node->next = place; - loaders = node; - } - else + if (!handle) { - /* Find the node immediately preceding PLACE. */ - for (ptr = loaders; ptr->next != place; ptr = ptr->next) - { - /*NOWORK*/; - } - - if (ptr->next != place) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); - ++errors; - } - else - { - /* Insert NODE between PTR and PLACE. */ - node->next = place; - ptr->next = node; - } + LT__SETERROR (INVALID_HANDLE); + return 0; } - LT_DLMUTEX_UNLOCK (); - - return errors; + return &(handle->info); } -int -lt_dlloader_remove (loader_name) - const char *loader_name; -{ - lt_dlloader *place = lt_dlloader_find (loader_name); - lt_dlhandle handle; - int errors = 0; - - if (!place) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); - return 1; - } - LT_DLMUTEX_LOCK (); +lt_dlhandle +lt_dlhandle_iterate (lt_dlinterface_id iface, lt_dlhandle place) +{ + lt_dlhandle handle = place; + lt__interface_id *iterator = (lt__interface_id *) iface; - /* Fail if there are any open modules which use this loader. */ - for (handle = handles; handle; handle = handle->next) - { - if (handle->loader == place) - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (REMOVE_LOADER)); - ++errors; - goto done; - } - } + assert (iface); /* iface is a required argument */ - if (place == loaders) - { - /* PLACE is the first loader in the list. */ - loaders = loaders->next; - } + if (!handle) + handle = handles; else - { - /* Find the loader before the one being removed. */ - lt_dlloader *prev; - for (prev = loaders; prev->next; prev = prev->next) - { - if (!strcmp (prev->next->loader_name, loader_name)) - { - break; - } - } + handle = handle->next; - place = prev->next; - prev->next = prev->next->next; - } - - if (place->dlloader_exit) + /* advance while the interface check fails */ + while (handle && iterator->iface + && ((*iterator->iface) (handle, iterator->id_string) != 0)) { - errors = place->dlloader_exit (place->dlloader_data); + handle = handle->next; } - LT_DLFREE (place); - - done: - LT_DLMUTEX_UNLOCK (); - - return errors; + return handle; } -lt_dlloader * -lt_dlloader_next (place) - lt_dlloader *place; -{ - lt_dlloader *next; - - LT_DLMUTEX_LOCK (); - next = place ? place->next : loaders; - LT_DLMUTEX_UNLOCK (); - - return next; -} -const char * -lt_dlloader_name (place) - lt_dlloader *place; +lt_dlhandle +lt_dlhandle_fetch (lt_dlinterface_id iface, const char *module_name) { - const char *name = 0; + lt_dlhandle handle = 0; - if (place) - { - LT_DLMUTEX_LOCK (); - name = place ? place->loader_name : 0; - LT_DLMUTEX_UNLOCK (); - } - else + assert (iface); /* iface is a required argument */ + + while ((handle = lt_dlhandle_iterate (iface, handle))) { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); + lt_dlhandle cur = handle; + if (cur && cur->info.name && streq (cur->info.name, module_name)) + break; } - return name; + return handle; } -lt_user_data * -lt_dlloader_data (place) - lt_dlloader *place; + +int +lt_dlhandle_map (lt_dlinterface_id iface, + int (*func) (lt_dlhandle handle, void *data), void *data) { - lt_user_data *data = 0; + lt__interface_id *iterator = (lt__interface_id *) iface; + lt_dlhandle cur = handles; - if (place) - { - LT_DLMUTEX_LOCK (); - data = place ? &(place->dlloader_data) : 0; - LT_DLMUTEX_UNLOCK (); - } - else - { - LT_DLMUTEX_SETERROR (LT_DLSTRERROR (INVALID_LOADER)); - } + assert (iface); /* iface is a required argument */ - return data; -} + while (cur) + { + int errorcode = 0; -lt_dlloader * -lt_dlloader_find (loader_name) - const char *loader_name; -{ - lt_dlloader *place = 0; + /* advance while the interface check fails */ + while (cur && iterator->iface + && ((*iterator->iface) (cur, iterator->id_string) != 0)) + { + cur = cur->next; + } - LT_DLMUTEX_LOCK (); - for (place = loaders; place; place = place->next) - { - if (strcmp (place->loader_name, loader_name) == 0) - { - break; - } + if ((errorcode = (*func) (cur, data)) != 0) + return errorcode; } - LT_DLMUTEX_UNLOCK (); - return place; + return 0; } debian/patches/series0000644000000000000000000000010011773153613012030 0ustar 01_fix_getline 02_result_type_gptr 03_fix_cmdlex 04_libtool_fix debian/patches/03_fix_cmdlex0000644000000000000000000000033411773153613013173 0ustar --- a/sim/ucsim/cmd.src/cmdlex.cc +++ b/sim/ucsim/cmd.src/cmdlex.cc @@ -85,6 +85,7 @@ #include #include #include +#include /* end standard C++ headers. */ #ifdef __cplusplus debian/changelog0000644000000000000000000000131711773153613011051 0ustar cc1111 (2.9.0-2) unstable; urgency=low * fix details identified by ftp-master during initial NEW processing - debian/copyright updated to attribute package construction correctly - debian/copyright updated to mention LGPL and BSD licensed source files - debian/README.source removed as the package now uses normal processes -- Bdale Garbee Thu, 28 Jun 2012 16:13:43 -0600 cc1111 (2.9.0-1) unstable; urgency=low * fork SDCC since 3.X break the build of AltOS, and upstream remains uninterested in our TI/Chipcon SOC-specific source-level debugging support .. started with Debian 2.9.0-5 SDCC package source -- Bdale Garbee Fri, 08 Jun 2012 17:38:37 +0900 debian/compat0000644000000000000000000000000211773153613010373 0ustar 5