2003-05-28 Jeff Johnston <jjohnstn@redhat.com>
Tom Fitzsimmons <fitzsim@redhat.com> * configure.in: Add iconvdata support for x86 linux. * configure: Regenerated. * libc/sys/linux/Makefile.am: Add EL/IX level 3 network, dynamic library, iconv, and linuxthreads support. * libc/sys/linux/configure.in: Ditto. * libc/sys/linux/Makefile.in: Regenerated. * libc/sys/linux/configure: Ditto. * iconvdata/EUC-JP.irreversible: New file. * iconvdata/Makefile.am: Ditto. * iconvdata/Makefile.in: Ditto. * iconvdata/SJIS.irreversible: Ditto. * iconvdata/aclocal.m4: Ditto. * iconvdata/configure: Ditto. * iconvdata/configure.in: Ditto. * iconvdata/dummy.c: Ditto. * iconvdata/euc-jp.c: Ditto. * iconvdata/gconv-modules: Ditto. * iconvdata/jis0201.c: Ditto. * iconvdata/jis0201.h: Ditto. * iconvdata/jis0208.c: Ditto. * iconvdata/jis0208.h: Ditto. * iconvdata/jis0212.c: Ditto. * iconvdata/jis0212.h: Ditto. * iconvdata/sjis.c: Ditto. * libc/include/errno.h: Protect definition of error_t. * libc/sys/linux/gethostid.c: New file. * libc/sys/linux/sethostid.c: Ditto. * libc/sys/linux/dl/Makefile.am: Ditto. * libc/sys/linux/dl/Makefile.in: Ditto. * libc/sys/linux/dl/abi-tag.h: Ditto. * libc/sys/linux/dl/atomicity.h: Ditto. * libc/sys/linux/dl/dl-addr.c: Ditto. * libc/sys/linux/dl/dl-cache.c: Ditto. * libc/sys/linux/dl/dl-cache.h: Ditto. * libc/sys/linux/dl/dl-close.c: Ditto. * libc/sys/linux/dl/dl-debug.c: Ditto. * libc/sys/linux/dl/dl-deps.c: Ditto. * libc/sys/linux/dl/dl-dst.h: Ditto. * libc/sys/linux/dl/dl-error.c: Ditto. * libc/sys/linux/dl/dl-fini.c: Ditto. * libc/sys/linux/dl/dl-init.c: Ditto. * libc/sys/linux/dl/dl-iteratephdr.c: Ditto. * libc/sys/linux/dl/dl-libc.c: Ditto. * libc/sys/linux/dl/dl-librecon.h: Ditto. * libc/sys/linux/dl/dl-load.c: Ditto. * libc/sys/linux/dl/dl-lookup.c: Ditto. * libc/sys/linux/dl/dl-lookupcfg.h: Ditto. * libc/sys/linux/dl/dl-minimal.c: Ditto. * libc/sys/linux/dl/dl-misc.c: Ditto. * libc/sys/linux/dl/dl-object.c: Ditto. * libc/sys/linux/dl/dl-open.c: Ditto. * libc/sys/linux/dl/dl-osinfo.h: Ditto. * libc/sys/linux/dl/dl-profile.c: Ditto. * libc/sys/linux/dl/dl-profstub.c: Ditto. * libc/sys/linux/dl/dl-reloc.c: Ditto. * libc/sys/linux/dl/dl-runtime.c: Ditto. * libc/sys/linux/dl/dl-support.c: Ditto. * libc/sys/linux/dl/dl-sym.c: Ditto. * libc/sys/linux/dl/dl-version.c: Ditto. * libc/sys/linux/dl/dlfcn.h: Ditto. * libc/sys/linux/dl/do-lookup.h: Ditto. * libc/sys/linux/dl/do-rel.h: Ditto. * libc/sys/linux/dl/dynamic-link.h: Ditto. * libc/sys/linux/dl/kernel-features.h: Ditto. * libc/sys/linux/dl/ldsodefs.h: Ditto. * libc/sys/linux/dl/libintl.h: Ditto. * libc/sys/linux/dl/trusted-dirs.h: Ditto. * libc/sys/linux/dl/unsecvars.h: Ditto. * libc/sys/linux/iconv/Makefile.am: Ditto. * libc/sys/linux/iconv/Makefile.in: Ditto. * libc/sys/linux/iconv/categories.def: Ditto. * libc/sys/linux/iconv/dummy-repertoire.c: Ditto. * libc/sys/linux/iconv/gconv.c: Ditto. * libc/sys/linux/iconv/gconv_builtin.c: Ditto. * libc/sys/linux/iconv/gconv_builtin.h: Ditto. * libc/sys/linux/iconv/gconv_cache.c: Ditto. * libc/sys/linux/iconv/gconv_charset.h: Ditto. * libc/sys/linux/iconv/gconv_close.c: Ditto. * libc/sys/linux/iconv/gconv_conf.c: Ditto. * libc/sys/linux/iconv/gconv_db.c: Ditto. * libc/sys/linux/iconv/gconv_dl.c: Ditto. * libc/sys/linux/iconv/gconv_int.h: Ditto. * libc/sys/linux/iconv/gconv_open.c: Ditto. * libc/sys/linux/iconv/gconv_simple.c: Ditto. * libc/sys/linux/iconv/gconv_trans.c: Ditto. * libc/sys/linux/iconv/hash-string.h: Ditto. * libc/sys/linux/iconv/iconv.c: Ditto. * libc/sys/linux/iconv/iconv.h: Ditto. * libc/sys/linux/iconv/iconv_charmap.c: Ditto. * libc/sys/linux/iconv/iconv_close.c: Ditto. * libc/sys/linux/iconv/iconv_open.c: Ditto. * libc/sys/linux/iconv/iconvconfig.c: Ditto. * libc/sys/linux/iconv/iconvconfig.h: Ditto. * libc/sys/linux/iconv/loadinfo.h: Ditto. * libc/sys/linux/iconv/localeinfo.h: Ditto. * libc/sys/linux/iconv/loop.c: Ditto. * libc/sys/linux/iconv/skeleton.c: Ditto. * libc/sys/linux/iconv/strtab.c: Ditto. * libc/sys/linux/include/dl-hash.h: Ditto. * libc/sys/linux/include/dlfcn.h: Ditto. * libc/sys/linux/include/fnmatch.h: Ditto. * libc/sys/linux/include/gconv.h: Ditto. * libc/sys/linux/include/glob.h: Ditto. * libc/sys/linux/include/hesiod.h: Ditto. * libc/sys/linux/include/ifaddrs.h: Ditto. * libc/sys/linux/include/libc_private.h: Ditto. * libc/sys/linux/include/link.h: Ditto. * libc/sys/linux/include/namespace.h: Ditto. * libc/sys/linux/include/netconfig.h: Ditto. * libc/sys/linux/include/netdb.h: Ditto. * libc/sys/linux/include/nsswitch.h: Ditto. * libc/sys/linux/include/regex.h: Ditto. * libc/sys/linux/include/resolv.h: Ditto. * libc/sys/linux/include/rune.h: Ditto. * libc/sys/linux/include/runetype.h: Ditto. * libc/sys/linux/include/semaphore.h: Ditto. * libc/sys/linux/include/setlocale.h: Ditto. * libc/sys/linux/include/un-namespace.h: Ditto. * libc/sys/linux/include/wordexp.h: Ditto. * libc/sys/linux/include/arpa/ftp.h: Ditto. * libc/sys/linux/include/arpa/inet.h: Ditto. * libc/sys/linux/include/arpa/nameser.h: Ditto. * libc/sys/linux/include/arpa/nameser_compat.h: Ditto. * libc/sys/linux/include/arpa/telnet.h: Ditto. * libc/sys/linux/include/arpa/tftp.h: Ditto. * libc/sys/linux/include/net/bpf.h: Ditto. * libc/sys/linux/include/net/bpf_compat.h: Ditto. * libc/sys/linux/include/net/bpfdesc.h: Ditto. * libc/sys/linux/include/net/bridge.h: Ditto. * libc/sys/linux/include/net/ethernet.h: Ditto. * libc/sys/linux/include/net/fddi.h: Ditto. * libc/sys/linux/include/net/if.h: Ditto. * libc/sys/linux/include/net/if_arc.h: Ditto. * libc/sys/linux/include/net/if_arp.h: Ditto. * libc/sys/linux/include/net/if_atm.h: Ditto. * libc/sys/linux/include/net/if_dl.h: Ditto. * libc/sys/linux/include/net/if_gif.h: Ditto. * libc/sys/linux/include/net/if_ieee80211.h: Ditto. * libc/sys/linux/include/net/if_llc.h: Ditto. * libc/sys/linux/include/net/if_media.h: Ditto. * libc/sys/linux/include/net/if_mib.h: Ditto. * libc/sys/linux/include/net/if_ppp.h: Ditto. * libc/sys/linux/include/net/if_pppvar.h: Ditto. * libc/sys/linux/include/net/if_slvar.h: Ditto. * libc/sys/linux/include/net/if_sppp.h: Ditto. * libc/sys/linux/include/net/if_stf.h: Ditto. * libc/sys/linux/include/net/if_tap.h: Ditto. * libc/sys/linux/include/net/if_tapvar.h: Ditto. * libc/sys/linux/include/net/if_tun.h: Ditto. * libc/sys/linux/include/net/if_tunvar.h: Ditto. * libc/sys/linux/include/net/if_types.h: Ditto. * libc/sys/linux/include/net/if_var.h: Ditto. * libc/sys/linux/include/net/if_vlan_var.h: Ditto. * libc/sys/linux/include/net/intrq.h: Ditto. * libc/sys/linux/include/net/iso88025.h: Ditto. * libc/sys/linux/include/net/net_osdep.h: Ditto. * libc/sys/linux/include/net/netisr.h: Ditto. * libc/sys/linux/include/net/pfil.h: Ditto. * libc/sys/linux/include/net/pfkeyv2.h: Ditto. * libc/sys/linux/include/net/ppp_comp.h: Ditto. * libc/sys/linux/include/net/ppp_defs.h: Ditto. * libc/sys/linux/include/net/radix.h: Ditto. * libc/sys/linux/include/net/raw_cb.h: Ditto. * libc/sys/linux/include/net/route.h: Ditto. * libc/sys/linux/include/net/slcompress.h: Ditto. * libc/sys/linux/include/net/slip.h: Ditto. * libc/sys/linux/include/net/zlib.h: Ditto. * libc/sys/linux/include/netinet/icmp6.h: Ditto. * libc/sys/linux/include/netinet/icmp_var.h: Ditto. * libc/sys/linux/include/netinet/if_atm.h: Ditto. * libc/sys/linux/include/netinet/if_ether.h: Ditto. * libc/sys/linux/include/netinet/igmp.h: Ditto. * libc/sys/linux/include/netinet/igmp_var.h: Ditto. * libc/sys/linux/include/netinet/in.h: Ditto. * libc/sys/linux/include/netinet/in_gif.h: Ditto. * libc/sys/linux/include/netinet/in_pcb.h: Ditto. * libc/sys/linux/include/netinet/in_systm.h: Ditto. * libc/sys/linux/include/netinet/in_var.h: Ditto. * libc/sys/linux/include/netinet/ip.h: Ditto. * libc/sys/linux/include/netinet/ip6.h: Ditto. * libc/sys/linux/include/netinet/ip_dummynet.h: Ditto. * libc/sys/linux/include/netinet/ip_ecn.h: Ditto. * libc/sys/linux/include/netinet/ip_encap.h: Ditto. * libc/sys/linux/include/netinet/ip_flow.h: Ditto. * libc/sys/linux/include/netinet/ip_fw.h: Ditto. * libc/sys/linux/include/netinet/ip_icmp.h: Ditto. * libc/sys/linux/include/netinet/ip_mroute.h: Ditto. * libc/sys/linux/include/netinet/ip_var.h: Ditto. * libc/sys/linux/include/netinet/ipprotosw.h: Ditto. * libc/sys/linux/include/netinet/tcp.h: Ditto. * libc/sys/linux/include/netinet/tcp_debug.h: Ditto. * libc/sys/linux/include/netinet/tcp_fsm.h: Ditto. * libc/sys/linux/include/netinet/tcp_seq.h: Ditto. * libc/sys/linux/include/netinet/tcp_timer.h: Ditto. * libc/sys/linux/include/netinet/tcp_var.h: Ditto. * libc/sys/linux/include/netinet/tcpip.h: Ditto. * libc/sys/linux/include/netinet/udp.h: Ditto. * libc/sys/linux/include/netinet/udp_var.h: Ditto. * libc/sys/linux/include/netinet6/ah.h: Ditto. * libc/sys/linux/include/netinet6/ah6.h: Ditto. * libc/sys/linux/include/netinet6/esp.h: Ditto. * libc/sys/linux/include/netinet6/esp6.h: Ditto. * libc/sys/linux/include/netinet6/esp_rijndael.h: Ditto. * libc/sys/linux/include/netinet6/icmp6.h: Ditto. * libc/sys/linux/include/netinet6/in6.h: Ditto. * libc/sys/linux/include/netinet6/in6_gif.h: Ditto. * libc/sys/linux/include/netinet6/in6_ifattach.h: Ditto. * libc/sys/linux/include/netinet6/in6_pcb.h: Ditto. * libc/sys/linux/include/netinet6/in6_prefix.h: Ditto. * libc/sys/linux/include/netinet6/in6_var.h: Ditto. * libc/sys/linux/include/netinet6/ip6.h: Ditto. * libc/sys/linux/include/netinet6/ip6_ecn.h: Ditto. * libc/sys/linux/include/netinet6/ip6_fw.h: Ditto. * libc/sys/linux/include/netinet6/ip6_mroute.h: Ditto. * libc/sys/linux/include/netinet6/ip6_var.h: Ditto. * libc/sys/linux/include/netinet6/ip6protosw.h: Ditto. * libc/sys/linux/include/netinet6/ipcomp.h: Ditto. * libc/sys/linux/include/netinet6/ipcomp6.h: Ditto. * libc/sys/linux/include/netinet6/ipsec.h: Ditto. * libc/sys/linux/include/netinet6/ipsec6.h: Ditto. * libc/sys/linux/include/netinet6/mld6_var.h: Ditto. * libc/sys/linux/include/netinet6/nd6.h: Ditto. * libc/sys/linux/include/netinet6/pim6.h: Ditto. * libc/sys/linux/include/netinet6/pim6_var.h: Ditto. * libc/sys/linux/include/netinet6/raw_ip6.h: Ditto. * libc/sys/linux/include/netinet6/scope6_var.h: Ditto. * libc/sys/linux/include/netinet6/tcp6_var.h: Ditto. * libc/sys/linux/include/netinet6/udp6_var.h: Ditto. * libc/sys/linux/include/netns/idp.h: Ditto. * libc/sys/linux/include/netns/idp_var.h: Ditto. * libc/sys/linux/include/netns/ns.h: Ditto. * libc/sys/linux/include/netns/ns_error.h: Ditto. * libc/sys/linux/include/netns/ns_if.h: Ditto. * libc/sys/linux/include/netns/ns_pcb.h: Ditto. * libc/sys/linux/include/netns/sp.h: Ditto. * libc/sys/linux/include/netns/spidp.h: Ditto. * libc/sys/linux/include/netns/spp_debug.h: Ditto. * libc/sys/linux/include/netns/spp_timer.h: Ditto. * libc/sys/linux/include/netns/spp_var.h: Ditto. * libc/sys/linux/include/rpc/Makefile: Ditto. * libc/sys/linux/include/rpc/auth.h: Ditto. * libc/sys/linux/include/rpc/auth_des.h: Ditto. * libc/sys/linux/include/rpc/auth_kerb.h: Ditto. * libc/sys/linux/include/rpc/auth_unix.h: Ditto. * libc/sys/linux/include/rpc/clnt.h: Ditto. * libc/sys/linux/include/rpc/clnt_soc.h: Ditto. * libc/sys/linux/include/rpc/clnt_stat.h: Ditto. * libc/sys/linux/include/rpc/des.h: Ditto. * libc/sys/linux/include/rpc/des_crypt.h: Ditto. * libc/sys/linux/include/rpc/nettype.h: Ditto. * libc/sys/linux/include/rpc/pmap_clnt.h: Ditto. * libc/sys/linux/include/rpc/pmap_prot.h: Ditto. * libc/sys/linux/include/rpc/pmap_rmt.h: Ditto. * libc/sys/linux/include/rpc/raw.h: Ditto. * libc/sys/linux/include/rpc/rpc.h: Ditto. * libc/sys/linux/include/rpc/rpc_com.h: Ditto. * libc/sys/linux/include/rpc/rpc_msg.h: Ditto. * libc/sys/linux/include/rpc/rpcb_clnt.h: Ditto. * libc/sys/linux/include/rpc/rpcb_prot.h: Ditto. * libc/sys/linux/include/rpc/rpcb_prot.x: Ditto. * libc/sys/linux/include/rpc/rpcent.h: Ditto. * libc/sys/linux/include/rpc/svc.h: Ditto. * libc/sys/linux/include/rpc/svc_auth.h: Ditto. * libc/sys/linux/include/rpc/svc_dg.h: Ditto. * libc/sys/linux/include/rpc/svc_soc.h: Ditto. * libc/sys/linux/include/rpc/types.h: Ditto. * libc/sys/linux/include/rpc/xdr.h: Ditto. * libc/sys/linux/intl/Makefile.am: Ditto. * libc/sys/linux/intl/Makefile.in: Ditto. * libc/sys/linux/intl/bindtextdom.c: Ditto. * libc/sys/linux/intl/catgets.c: Ditto. * libc/sys/linux/intl/catgetsinfo.h: Ditto. * libc/sys/linux/intl/config.h: Ditto. * libc/sys/linux/intl/dcgettext.c: Ditto. * libc/sys/linux/intl/dcigettext.c: Ditto. * libc/sys/linux/intl/dcngettext.c: Ditto. * libc/sys/linux/intl/dgettext.c: Ditto. * libc/sys/linux/intl/dngettext.c: Ditto. * libc/sys/linux/intl/explodename.c: Ditto. * libc/sys/linux/intl/finddomain.c: Ditto. * libc/sys/linux/intl/gettext.c: Ditto. * libc/sys/linux/intl/gettext.h: Ditto. * libc/sys/linux/intl/gettextP.h: Ditto. * libc/sys/linux/intl/hash-string.h: Ditto. * libc/sys/linux/intl/l10nflist.c: Ditto. * libc/sys/linux/intl/loadinfo.h: Ditto. * libc/sys/linux/intl/loadmsgcat.c: Ditto. * libc/sys/linux/intl/locale.alias: Ditto. * libc/sys/linux/intl/localealias.c: Ditto. * libc/sys/linux/intl/ngettext.c: Ditto. * libc/sys/linux/intl/open_catalog.c: Ditto. * libc/sys/linux/intl/plural.c: Ditto. * libc/sys/linux/intl/plural.y: Ditto. * libc/sys/linux/intl/stpcpy.c: Ditto. * libc/sys/linux/intl/textdomain.c: Ditto. * libc/sys/linux/linuxthreads/LICENSE: Ditto. * libc/sys/linux/linuxthreads/Makefile.am: Ditto. * libc/sys/linux/linuxthreads/Makefile.in: Ditto. * libc/sys/linux/linuxthreads/aclocal.m4: Ditto. * libc/sys/linux/linuxthreads/attr.c: Ditto. * libc/sys/linux/linuxthreads/barrier.c: Ditto. * libc/sys/linux/linuxthreads/bp-sym.h: Ditto. * libc/sys/linux/linuxthreads/cancel.c: Ditto. * libc/sys/linux/linuxthreads/condvar.c: Ditto. * libc/sys/linux/linuxthreads/config.h: Ditto. * libc/sys/linux/linuxthreads/configure: Ditto. * libc/sys/linux/linuxthreads/configure.in: Ditto. * libc/sys/linux/linuxthreads/defs.awk: Ditto. * libc/sys/linux/linuxthreads/ecmutex.c: Ditto. * libc/sys/linux/linuxthreads/events.c: Ditto. * libc/sys/linux/linuxthreads/getcpuclockid.c: Ditto. * libc/sys/linux/linuxthreads/getreent.c: Ditto. * libc/sys/linux/linuxthreads/internals.h: Ditto. * libc/sys/linux/linuxthreads/join.c: Ditto. * libc/sys/linux/linuxthreads/joinrace.c: Ditto. * libc/sys/linux/linuxthreads/kernel-features.h: Ditto. * libc/sys/linux/linuxthreads/libc-internal.h: Ditto. * libc/sys/linux/linuxthreads/libc-symbols.h: Ditto. * libc/sys/linux/linuxthreads/linuxthreads.texi: Ditto. * libc/sys/linux/linuxthreads/lockfile.c: Ditto. * libc/sys/linux/linuxthreads/manager.c: Ditto. * libc/sys/linux/linuxthreads/mq_notify.c: Ditto. * libc/sys/linux/linuxthreads/mutex.c: Ditto. * libc/sys/linux/linuxthreads/no-tsd.c: Ditto. * libc/sys/linux/linuxthreads/oldsemaphore.c: Ditto. * libc/sys/linux/linuxthreads/posix-timer.h: Ditto. * libc/sys/linux/linuxthreads/prio.c: Ditto. * libc/sys/linux/linuxthreads/proc_service.h: Ditto. * libc/sys/linux/linuxthreads/pt-machine.c: Ditto. * libc/sys/linux/linuxthreads/ptclock_gettime.c: Ditto. * libc/sys/linux/linuxthreads/ptclock_settime.c: Ditto. * libc/sys/linux/linuxthreads/ptfork.c: Ditto. * libc/sys/linux/linuxthreads/pthread.c: Ditto. * libc/sys/linux/linuxthreads/ptlongjmp.c: Ditto. * libc/sys/linux/linuxthreads/queue.h: Ditto. * libc/sys/linux/linuxthreads/reent.c: Ditto. * libc/sys/linux/linuxthreads/reqsyscalls.c: Ditto. * libc/sys/linux/linuxthreads/restart.h: Ditto. * libc/sys/linux/linuxthreads/rwlock.c: Ditto. * libc/sys/linux/linuxthreads/semaphore.c: Ditto. * libc/sys/linux/linuxthreads/semaphore.h: Ditto. * libc/sys/linux/linuxthreads/shlib-compat.h: Ditto. * libc/sys/linux/linuxthreads/signals.c: Ditto. * libc/sys/linux/linuxthreads/specific.c: Ditto. * libc/sys/linux/linuxthreads/spinlock.c: Ditto. * libc/sys/linux/linuxthreads/spinlock.h: Ditto. * libc/sys/linux/linuxthreads/sysctl.c: Ditto. * libc/sys/linux/linuxthreads/td_init.c: Ditto. * libc/sys/linux/linuxthreads/td_log.c: Ditto. * libc/sys/linux/linuxthreads/td_symbol_list.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_clear_event.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_delete.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_enable_stats.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_event_addr.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_event_getmsg.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_get_nthreads.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_get_ph.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_get_stats.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_map_id2thr.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_map_lwp2thr.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_new.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_reset_stats.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_set_event.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_setconcurrency.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_thr_iter.c: Ditto. * libc/sys/linux/linuxthreads/td_ta_tsd_iter.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_clear_event.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_dbresume.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_dbsuspend.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_event_enable.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_event_getmsg.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_get_info.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_getfpregs.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_getgregs.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_getxregs.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_getxregsize.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_set_event.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_setfpregs.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_setgregs.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_setprio.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_setsigpending.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_setxregs.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_sigsetmask.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_tsd.c: Ditto. * libc/sys/linux/linuxthreads/td_thr_validate.c: Ditto. * libc/sys/linux/linuxthreads/testrtsig.h: Ditto. * libc/sys/linux/linuxthreads/thread_db.h: Ditto. * libc/sys/linux/linuxthreads/thread_dbP.h: Ditto. * libc/sys/linux/linuxthreads/timer_create.c: Ditto. * libc/sys/linux/linuxthreads/timer_delete.c: Ditto. * libc/sys/linux/linuxthreads/timer_getoverr.c: Ditto. * libc/sys/linux/linuxthreads/timer_gettime.c: Ditto. * libc/sys/linux/linuxthreads/timer_routines.c: Ditto. * libc/sys/linux/linuxthreads/timer_settime.c: Ditto. * libc/sys/linux/linuxthreads/tst-cancel.c: Ditto. * libc/sys/linux/linuxthreads/tst-context.c: Ditto. * libc/sys/linux/linuxthreads/tststack.c: Ditto. * libc/sys/linux/linuxthreads/unload.c: Ditto. * libc/sys/linux/linuxthreads/weaks.c: Ditto. * libc/sys/linux/linuxthreads/wrapsyscall.c: Ditto. * libc/sys/linux/linuxthreads/bits/initspin.h: Ditto. * libc/sys/linux/linuxthreads/bits/libc-lock.h: Ditto. * libc/sys/linux/linuxthreads/bits/libc-tsd.h: Ditto. * libc/sys/linux/linuxthreads/bits/local_lim.h: Ditto. * libc/sys/linux/linuxthreads/bits/posix_opt.h: Ditto. * libc/sys/linux/linuxthreads/bits/pthreadtypes.h: Ditto. * libc/sys/linux/linuxthreads/bits/sigthread.h: Ditto. * libc/sys/linux/linuxthreads/machine/Makefile.am: Ditto. * libc/sys/linux/linuxthreads/machine/Makefile.in: Ditto. * libc/sys/linux/linuxthreads/machine/aclocal.m4: Ditto. * libc/sys/linux/linuxthreads/machine/configure: Ditto. * libc/sys/linux/linuxthreads/machine/configure.in: Ditto. * libc/sys/linux/linuxthreads/machine/generic/generic-sysd: Ditto.ep.h * libc/sys/linux/linuxthreads/machine/i386/Makefile.am: Ditto. * libc/sys/linux/linuxthreads/machine/i386/Makefile.in: Ditto. * libc/sys/linux/linuxthreads/machine/i386/aclocal.m4: Ditto. * libc/sys/linux/linuxthreads/machine/i386/bp-asm.h: Ditto. * libc/sys/linux/linuxthreads/machine/i386/clone.S: Ditto. * libc/sys/linux/linuxthreads/machine/i386/configure: Ditto. * libc/sys/linux/linuxthreads/machine/i386/configure.in: Ditto. * libc/sys/linux/linuxthreads/machine/i386/i386-sysdep.S: Ditto. * libc/sys/linux/linuxthreads/machine/i386/i386-sysdep.h: Ditto. * libc/sys/linux/linuxthreads/machine/i386/pspinlock.c: Ditto. * libc/sys/linux/linuxthreads/machine/i386/pt-machine.h: Ditto. * libc/sys/linux/linuxthreads/machine/i386/sigcontextinfo.h: Ditto. * libc/sys/linux/linuxthreads/machine/i386/stackinfo.h: Ditto. * libc/sys/linux/linuxthreads/machine/i386/sysdep.S: Ditto. * libc/sys/linux/linuxthreads/machine/i386/sysdep.h: Ditto. * libc/sys/linux/linuxthreads/machine/i386/useldt.h: Ditto. * libc/sys/linux/machine/i386/dl-machine.h: Ditto. * libc/sys/linux/net/Makefile.am: Ditto. * libc/sys/linux/net/Makefile.in: Ditto. * libc/sys/linux/net/addr2ascii.3: Ditto. * libc/sys/linux/net/addr2ascii.c: Ditto. * libc/sys/linux/net/ascii2addr.c: Ditto. * libc/sys/linux/net/base64.c: Ditto. * libc/sys/linux/net/bindresvport.c: Ditto. * libc/sys/linux/net/byteorder.3: Ditto. * libc/sys/linux/net/ether_addr.c: Ditto. * libc/sys/linux/net/ethers.3: Ditto. * libc/sys/linux/net/getaddrinfo.3: Ditto. * libc/sys/linux/net/getaddrinfo.c: Ditto. * libc/sys/linux/net/gethostbydns.c: Ditto. * libc/sys/linux/net/gethostbyht.c: Ditto. * libc/sys/linux/net/gethostbyname.3: Ditto. * libc/sys/linux/net/gethostbynis.c: Ditto. * libc/sys/linux/net/gethostnamadr.c: Ditto. * libc/sys/linux/net/getifaddrs.3: Ditto. * libc/sys/linux/net/getifaddrs.c: Ditto. * libc/sys/linux/net/getipnodebyname.3: Ditto. * libc/sys/linux/net/getnameinfo.3: Ditto. * libc/sys/linux/net/getnameinfo.c: Ditto. * libc/sys/linux/net/getnetbydns.c: Ditto. * libc/sys/linux/net/getnetbyht.c: Ditto. * libc/sys/linux/net/getnetbynis.c: Ditto. * libc/sys/linux/net/getnetent.3: Ditto. * libc/sys/linux/net/getnetnamadr.c: Ditto. * libc/sys/linux/net/getproto.c: Ditto. * libc/sys/linux/net/getprotoent.3: Ditto. * libc/sys/linux/net/getprotoent.c: Ditto. * libc/sys/linux/net/getprotoname.c: Ditto. * libc/sys/linux/net/getservbyname.c: Ditto. * libc/sys/linux/net/getservbyport.c: Ditto. * libc/sys/linux/net/getservent.3: Ditto. * libc/sys/linux/net/getservent.c: Ditto. * libc/sys/linux/net/herror.c: Ditto. * libc/sys/linux/net/hesiod.3: Ditto. * libc/sys/linux/net/hesiod.c: Ditto. * libc/sys/linux/net/if_indextoname.3: Ditto. * libc/sys/linux/net/ifname.c: Ditto. * libc/sys/linux/net/inet.3: Ditto. * libc/sys/linux/net/inet6_option_s: Ditto.pace.3 * libc/sys/linux/net/inet6_rthdr_space.3: Ditto. * libc/sys/linux/net/inet_addr.c: Ditto. * libc/sys/linux/net/inet_lnaof.c: Ditto. * libc/sys/linux/net/inet_makeaddr.c: Ditto. * libc/sys/linux/net/inet_net.3: Ditto. * libc/sys/linux/net/inet_net_ntop.c: Ditto. * libc/sys/linux/net/inet_net_pton.c: Ditto. * libc/sys/linux/net/inet_neta.c: Ditto. * libc/sys/linux/net/inet_netof.c: Ditto. * libc/sys/linux/net/inet_network.c: Ditto. * libc/sys/linux/net/inet_ntoa.c: Ditto. * libc/sys/linux/net/inet_ntop.c: Ditto. * libc/sys/linux/net/inet_pton.c: Ditto. * libc/sys/linux/net/innetgr-stub.c: Ditto. * libc/sys/linux/net/ip6opt.c: Ditto. * libc/sys/linux/net/iso_addr.3: Ditto. * libc/sys/linux/net/iso_addr.c: Ditto. * libc/sys/linux/net/issetugid-stub.c: Ditto. * libc/sys/linux/net/linkaddr.3: Ditto. * libc/sys/linux/net/linkaddr.c: Ditto. * libc/sys/linux/net/map_v4v6.c: Ditto. * libc/sys/linux/net/name6.c: Ditto. * libc/sys/linux/net/namespace.h: Ditto. * libc/sys/linux/net/ns.3: Ditto. * libc/sys/linux/net/ns_addr.c: Ditto. * libc/sys/linux/net/ns_name.c: Ditto. * libc/sys/linux/net/ns_netint.c: Ditto. * libc/sys/linux/net/ns_ntoa.c: Ditto. * libc/sys/linux/net/ns_parse.c: Ditto. * libc/sys/linux/net/ns_print.c: Ditto. * libc/sys/linux/net/ns_ttl.c: Ditto. * libc/sys/linux/net/nsap_addr.c: Ditto. * libc/sys/linux/net/nsdispatch.3: Ditto. * libc/sys/linux/net/nsdispatch.c: Ditto. * libc/sys/linux/net/nslexer.c: Ditto. * libc/sys/linux/net/nslexer.l: Ditto. * libc/sys/linux/net/nsparser.c: Ditto. * libc/sys/linux/net/nsparser.h: Ditto. * libc/sys/linux/net/nsparser.y: Ditto. * libc/sys/linux/net/rcmd.3: Ditto. * libc/sys/linux/net/rcmd.c: Ditto. * libc/sys/linux/net/rcmdsh.3: Ditto. * libc/sys/linux/net/rcmdsh.c: Ditto. * libc/sys/linux/net/recv.c: Ditto. * libc/sys/linux/net/res_comp.c: Ditto. * libc/sys/linux/net/res_config.h: Ditto. * libc/sys/linux/net/res_data.c: Ditto. * libc/sys/linux/net/res_debug.c: Ditto. * libc/sys/linux/net/res_init.c: Ditto. * libc/sys/linux/net/res_mkquery.c: Ditto. * libc/sys/linux/net/res_mkupdate.c: Ditto. * libc/sys/linux/net/res_query.c: Ditto. * libc/sys/linux/net/res_send.c: Ditto. * libc/sys/linux/net/res_update.c: Ditto. * libc/sys/linux/net/resolver.3: Ditto. * libc/sys/linux/net/rthdr.c: Ditto. * libc/sys/linux/net/send.c: Ditto. * libc/sys/linux/net/un-namespace.h: Ditto. * libc/sys/linux/net/vars.c: Ditto. * libc/sys/linux/stdlib/COPYRIGHT: Ditto. * libc/sys/linux/stdlib/Makefile.am: Ditto. * libc/sys/linux/stdlib/Makefile.in: Ditto. * libc/sys/linux/stdlib/cclass.h: Ditto. * libc/sys/linux/stdlib/cname.h: Ditto. * libc/sys/linux/stdlib/collate.c: Ditto. * libc/sys/linux/stdlib/collate.h: Ditto. * libc/sys/linux/stdlib/collcmp.c: Ditto. * libc/sys/linux/stdlib/engine.c: Ditto. * libc/sys/linux/stdlib/fnmatch.3: Ditto. * libc/sys/linux/stdlib/fnmatch.c: Ditto. * libc/sys/linux/stdlib/glob.3: Ditto. * libc/sys/linux/stdlib/glob.c: Ditto. * libc/sys/linux/stdlib/reallocf.c: Ditto. * libc/sys/linux/stdlib/regcomp.c: Ditto. * libc/sys/linux/stdlib/regerror.c: Ditto. * libc/sys/linux/stdlib/regex.3: Ditto. * libc/sys/linux/stdlib/regex2.h: Ditto. * libc/sys/linux/stdlib/regexec.c: Ditto. * libc/sys/linux/stdlib/regfree.c: Ditto. * libc/sys/linux/stdlib/utils.h: Ditto. * libc/sys/linux/stdlib/wordexp.c: Ditto. * libc/sys/linux/stdlib/wordfree.c: Ditto. * libc/sys/linux/sys/dlfcn.h: Ditto. * libc/sys/linux/sys/elfclass.h: Ditto. * libc/sys/linux/sys/event.h: Ditto. * libc/sys/linux/sys/ioccom.h: Ditto. * libc/sys/linux/sys/libc-tsd.h: Ditto. * libc/sys/linux/sys/link.h: Ditto. * libc/sys/linux/sys/lock.h: Ditto. * libc/sys/linux/sys/param.h: Ditto. * libc/sys/linux/sys/socket.h: Ditto. * libc/sys/linux/sys/sockio.h: Ditto.
This commit is contained in:
		
							
								
								
									
										568
									
								
								newlib/ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										568
									
								
								newlib/ChangeLog
									
									
									
									
									
								
							| @@ -1,3 +1,571 @@ | ||||
| 2003-05-28  Jeff Johnston  <jjohnstn@redhat.com> | ||||
| 	    Tom Fitzsimmons  <fitzsim@redhat.com> | ||||
|  | ||||
| 	* configure.in: Add iconvdata support for x86 linux. | ||||
| 	* configure: Regenerated. | ||||
| 	* libc/sys/linux/Makefile.am: Add EL/IX level 3 network, dynamic  | ||||
| 	library, iconv, and linuxthreads support. | ||||
| 	* libc/sys/linux/configure.in: Ditto. | ||||
| 	* libc/sys/linux/Makefile.in: Regenerated. | ||||
| 	* libc/sys/linux/configure: Ditto. | ||||
| 	* iconvdata/EUC-JP.irreversible: New file. | ||||
| 	* iconvdata/Makefile.am: Ditto. | ||||
| 	* iconvdata/Makefile.in: Ditto. | ||||
| 	* iconvdata/SJIS.irreversible: Ditto. | ||||
| 	* iconvdata/aclocal.m4: Ditto. | ||||
| 	* iconvdata/configure: Ditto. | ||||
| 	* iconvdata/configure.in: Ditto. | ||||
| 	* iconvdata/dummy.c: Ditto. | ||||
| 	* iconvdata/euc-jp.c: Ditto. | ||||
| 	* iconvdata/gconv-modules: Ditto. | ||||
| 	* iconvdata/jis0201.c: Ditto. | ||||
| 	* iconvdata/jis0201.h: Ditto. | ||||
| 	* iconvdata/jis0208.c: Ditto. | ||||
| 	* iconvdata/jis0208.h: Ditto. | ||||
| 	* iconvdata/jis0212.c: Ditto. | ||||
| 	* iconvdata/jis0212.h: Ditto. | ||||
| 	* iconvdata/sjis.c: Ditto. | ||||
| 	* libc/include/errno.h: Protect definition of error_t. | ||||
| 	* libc/sys/linux/gethostid.c: New file. | ||||
| 	* libc/sys/linux/sethostid.c: Ditto. | ||||
| 	* libc/sys/linux/dl/Makefile.am: Ditto. | ||||
| 	* libc/sys/linux/dl/Makefile.in: Ditto. | ||||
| 	* libc/sys/linux/dl/abi-tag.h: Ditto. | ||||
| 	* libc/sys/linux/dl/atomicity.h: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-addr.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-cache.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-cache.h: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-close.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-debug.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-deps.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-dst.h: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-error.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-fini.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-init.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-iteratephdr.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-libc.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-librecon.h: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-load.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-lookup.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-lookupcfg.h: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-minimal.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-misc.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-object.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-open.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-osinfo.h: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-profile.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-profstub.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-reloc.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-runtime.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-support.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-sym.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dl-version.c: Ditto. | ||||
| 	* libc/sys/linux/dl/dlfcn.h: Ditto. | ||||
| 	* libc/sys/linux/dl/do-lookup.h: Ditto. | ||||
| 	* libc/sys/linux/dl/do-rel.h: Ditto. | ||||
| 	* libc/sys/linux/dl/dynamic-link.h: Ditto. | ||||
| 	* libc/sys/linux/dl/kernel-features.h: Ditto. | ||||
| 	* libc/sys/linux/dl/ldsodefs.h: Ditto. | ||||
| 	* libc/sys/linux/dl/libintl.h: Ditto. | ||||
| 	* libc/sys/linux/dl/trusted-dirs.h: Ditto. | ||||
| 	* libc/sys/linux/dl/unsecvars.h: Ditto. | ||||
| 	* libc/sys/linux/iconv/Makefile.am: Ditto. | ||||
| 	* libc/sys/linux/iconv/Makefile.in: Ditto. | ||||
| 	* libc/sys/linux/iconv/categories.def: Ditto. | ||||
| 	* libc/sys/linux/iconv/dummy-repertoire.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/gconv.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/gconv_builtin.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/gconv_builtin.h: Ditto. | ||||
| 	* libc/sys/linux/iconv/gconv_cache.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/gconv_charset.h: Ditto. | ||||
| 	* libc/sys/linux/iconv/gconv_close.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/gconv_conf.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/gconv_db.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/gconv_dl.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/gconv_int.h: Ditto. | ||||
| 	* libc/sys/linux/iconv/gconv_open.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/gconv_simple.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/gconv_trans.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/hash-string.h: Ditto. | ||||
| 	* libc/sys/linux/iconv/iconv.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/iconv.h: Ditto. | ||||
| 	* libc/sys/linux/iconv/iconv_charmap.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/iconv_close.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/iconv_open.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/iconvconfig.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/iconvconfig.h: Ditto. | ||||
| 	* libc/sys/linux/iconv/loadinfo.h: Ditto. | ||||
| 	* libc/sys/linux/iconv/localeinfo.h: Ditto. | ||||
| 	* libc/sys/linux/iconv/loop.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/skeleton.c: Ditto. | ||||
| 	* libc/sys/linux/iconv/strtab.c: Ditto. | ||||
| 	* libc/sys/linux/include/dl-hash.h: Ditto. | ||||
| 	* libc/sys/linux/include/dlfcn.h: Ditto. | ||||
| 	* libc/sys/linux/include/fnmatch.h: Ditto. | ||||
| 	* libc/sys/linux/include/gconv.h: Ditto. | ||||
| 	* libc/sys/linux/include/glob.h: Ditto. | ||||
| 	* libc/sys/linux/include/hesiod.h: Ditto. | ||||
| 	* libc/sys/linux/include/ifaddrs.h: Ditto. | ||||
| 	* libc/sys/linux/include/libc_private.h: Ditto. | ||||
| 	* libc/sys/linux/include/link.h: Ditto. | ||||
| 	* libc/sys/linux/include/namespace.h: Ditto. | ||||
| 	* libc/sys/linux/include/netconfig.h: Ditto. | ||||
| 	* libc/sys/linux/include/netdb.h: Ditto. | ||||
| 	* libc/sys/linux/include/nsswitch.h: Ditto. | ||||
| 	* libc/sys/linux/include/regex.h: Ditto. | ||||
| 	* libc/sys/linux/include/resolv.h: Ditto. | ||||
| 	* libc/sys/linux/include/rune.h: Ditto. | ||||
| 	* libc/sys/linux/include/runetype.h: Ditto. | ||||
| 	* libc/sys/linux/include/semaphore.h: Ditto. | ||||
| 	* libc/sys/linux/include/setlocale.h: Ditto. | ||||
| 	* libc/sys/linux/include/un-namespace.h: Ditto. | ||||
| 	* libc/sys/linux/include/wordexp.h: Ditto. | ||||
| 	* libc/sys/linux/include/arpa/ftp.h: Ditto. | ||||
| 	* libc/sys/linux/include/arpa/inet.h: Ditto. | ||||
| 	* libc/sys/linux/include/arpa/nameser.h: Ditto. | ||||
| 	* libc/sys/linux/include/arpa/nameser_compat.h: Ditto. | ||||
| 	* libc/sys/linux/include/arpa/telnet.h: Ditto. | ||||
| 	* libc/sys/linux/include/arpa/tftp.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/bpf.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/bpf_compat.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/bpfdesc.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/bridge.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/ethernet.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/fddi.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_arc.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_arp.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_atm.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_dl.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_gif.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_ieee80211.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_llc.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_media.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_mib.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_ppp.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_pppvar.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_slvar.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_sppp.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_stf.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_tap.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_tapvar.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_tun.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_tunvar.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_types.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/if_vlan_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/intrq.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/iso88025.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/net_osdep.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/netisr.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/pfil.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/pfkeyv2.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/ppp_comp.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/ppp_defs.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/radix.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/raw_cb.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/route.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/slcompress.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/slip.h: Ditto. | ||||
| 	* libc/sys/linux/include/net/zlib.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/icmp6.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/icmp_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/if_atm.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/if_ether.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/igmp.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/igmp_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/in.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/in_gif.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/in_pcb.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/in_systm.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/in_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/ip.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/ip6.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/ip_dummynet.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/ip_ecn.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/ip_encap.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/ip_flow.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/ip_fw.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/ip_icmp.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/ip_mroute.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/ip_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/ipprotosw.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/tcp.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/tcp_debug.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/tcp_fsm.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/tcp_seq.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/tcp_timer.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/tcp_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/tcpip.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/udp.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet/udp_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/ah.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/ah6.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/esp.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/esp6.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/esp_rijndael.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/icmp6.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/in6.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/in6_gif.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/in6_ifattach.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/in6_pcb.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/in6_prefix.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/in6_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/ip6.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/ip6_ecn.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/ip6_fw.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/ip6_mroute.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/ip6_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/ip6protosw.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/ipcomp.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/ipcomp6.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/ipsec.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/ipsec6.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/mld6_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/nd6.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/pim6.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/pim6_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/raw_ip6.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/scope6_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/tcp6_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/netinet6/udp6_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/netns/idp.h: Ditto. | ||||
| 	* libc/sys/linux/include/netns/idp_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/netns/ns.h: Ditto. | ||||
| 	* libc/sys/linux/include/netns/ns_error.h: Ditto. | ||||
| 	* libc/sys/linux/include/netns/ns_if.h: Ditto. | ||||
| 	* libc/sys/linux/include/netns/ns_pcb.h: Ditto. | ||||
| 	* libc/sys/linux/include/netns/sp.h: Ditto. | ||||
| 	* libc/sys/linux/include/netns/spidp.h: Ditto. | ||||
| 	* libc/sys/linux/include/netns/spp_debug.h: Ditto. | ||||
| 	* libc/sys/linux/include/netns/spp_timer.h: Ditto. | ||||
| 	* libc/sys/linux/include/netns/spp_var.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/Makefile: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/auth.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/auth_des.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/auth_kerb.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/auth_unix.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/clnt.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/clnt_soc.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/clnt_stat.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/des.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/des_crypt.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/nettype.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/pmap_clnt.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/pmap_prot.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/pmap_rmt.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/raw.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/rpc.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/rpc_com.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/rpc_msg.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/rpcb_clnt.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/rpcb_prot.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/rpcb_prot.x: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/rpcent.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/svc.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/svc_auth.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/svc_dg.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/svc_soc.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/types.h: Ditto. | ||||
| 	* libc/sys/linux/include/rpc/xdr.h: Ditto. | ||||
| 	* libc/sys/linux/intl/Makefile.am: Ditto. | ||||
| 	* libc/sys/linux/intl/Makefile.in: Ditto. | ||||
| 	* libc/sys/linux/intl/bindtextdom.c: Ditto. | ||||
| 	* libc/sys/linux/intl/catgets.c: Ditto. | ||||
| 	* libc/sys/linux/intl/catgetsinfo.h: Ditto. | ||||
| 	* libc/sys/linux/intl/config.h: Ditto. | ||||
| 	* libc/sys/linux/intl/dcgettext.c: Ditto. | ||||
| 	* libc/sys/linux/intl/dcigettext.c: Ditto. | ||||
| 	* libc/sys/linux/intl/dcngettext.c: Ditto. | ||||
| 	* libc/sys/linux/intl/dgettext.c: Ditto. | ||||
| 	* libc/sys/linux/intl/dngettext.c: Ditto. | ||||
| 	* libc/sys/linux/intl/explodename.c: Ditto. | ||||
| 	* libc/sys/linux/intl/finddomain.c: Ditto. | ||||
| 	* libc/sys/linux/intl/gettext.c: Ditto. | ||||
| 	* libc/sys/linux/intl/gettext.h: Ditto. | ||||
| 	* libc/sys/linux/intl/gettextP.h: Ditto. | ||||
| 	* libc/sys/linux/intl/hash-string.h: Ditto. | ||||
| 	* libc/sys/linux/intl/l10nflist.c: Ditto. | ||||
| 	* libc/sys/linux/intl/loadinfo.h: Ditto. | ||||
| 	* libc/sys/linux/intl/loadmsgcat.c: Ditto. | ||||
| 	* libc/sys/linux/intl/locale.alias: Ditto. | ||||
| 	* libc/sys/linux/intl/localealias.c: Ditto. | ||||
| 	* libc/sys/linux/intl/ngettext.c: Ditto. | ||||
| 	* libc/sys/linux/intl/open_catalog.c: Ditto. | ||||
| 	* libc/sys/linux/intl/plural.c: Ditto. | ||||
| 	* libc/sys/linux/intl/plural.y: Ditto. | ||||
| 	* libc/sys/linux/intl/stpcpy.c: Ditto. | ||||
| 	* libc/sys/linux/intl/textdomain.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/LICENSE: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/Makefile.am: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/Makefile.in: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/aclocal.m4: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/attr.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/barrier.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/bp-sym.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/cancel.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/condvar.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/config.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/configure: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/configure.in: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/defs.awk: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/ecmutex.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/events.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/getcpuclockid.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/getreent.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/internals.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/join.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/joinrace.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/kernel-features.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/libc-internal.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/libc-symbols.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/linuxthreads.texi: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/lockfile.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/manager.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/mq_notify.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/mutex.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/no-tsd.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/oldsemaphore.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/posix-timer.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/prio.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/proc_service.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/pt-machine.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/ptclock_gettime.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/ptclock_settime.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/ptfork.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/pthread.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/ptlongjmp.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/queue.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/reent.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/reqsyscalls.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/restart.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/rwlock.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/semaphore.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/semaphore.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/shlib-compat.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/signals.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/specific.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/spinlock.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/spinlock.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/sysctl.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_init.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_log.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_symbol_list.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_clear_event.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_delete.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_enable_stats.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_event_addr.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_event_getmsg.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_get_nthreads.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_get_ph.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_get_stats.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_map_id2thr.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_map_lwp2thr.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_new.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_reset_stats.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_set_event.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_setconcurrency.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_thr_iter.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_ta_tsd_iter.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_clear_event.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_dbresume.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_dbsuspend.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_event_enable.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_event_getmsg.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_get_info.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_getfpregs.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_getgregs.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_getxregs.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_getxregsize.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_set_event.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_setfpregs.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_setgregs.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_setprio.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_setsigpending.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_setxregs.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_sigsetmask.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_tsd.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/td_thr_validate.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/testrtsig.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/thread_db.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/thread_dbP.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/timer_create.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/timer_delete.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/timer_getoverr.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/timer_gettime.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/timer_routines.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/timer_settime.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/tst-cancel.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/tst-context.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/tststack.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/unload.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/weaks.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/wrapsyscall.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/bits/initspin.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/bits/libc-lock.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/bits/libc-tsd.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/bits/local_lim.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/bits/posix_opt.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/bits/pthreadtypes.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/bits/sigthread.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/Makefile.am: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/Makefile.in: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/aclocal.m4: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/configure: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/configure.in: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/generic/generic-sysd: Ditto.ep.h | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/Makefile.am: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/Makefile.in: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/aclocal.m4: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/bp-asm.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/clone.S: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/configure: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/configure.in: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/i386-sysdep.S: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/i386-sysdep.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/pspinlock.c: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/pt-machine.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/sigcontextinfo.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/stackinfo.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/sysdep.S: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/sysdep.h: Ditto. | ||||
| 	* libc/sys/linux/linuxthreads/machine/i386/useldt.h: Ditto. | ||||
| 	* libc/sys/linux/machine/i386/dl-machine.h: Ditto. | ||||
| 	* libc/sys/linux/net/Makefile.am: Ditto. | ||||
| 	* libc/sys/linux/net/Makefile.in: Ditto. | ||||
| 	* libc/sys/linux/net/addr2ascii.3: Ditto. | ||||
| 	* libc/sys/linux/net/addr2ascii.c: Ditto. | ||||
| 	* libc/sys/linux/net/ascii2addr.c: Ditto. | ||||
| 	* libc/sys/linux/net/base64.c: Ditto. | ||||
| 	* libc/sys/linux/net/bindresvport.c: Ditto. | ||||
| 	* libc/sys/linux/net/byteorder.3: Ditto. | ||||
| 	* libc/sys/linux/net/ether_addr.c: Ditto. | ||||
| 	* libc/sys/linux/net/ethers.3: Ditto. | ||||
| 	* libc/sys/linux/net/getaddrinfo.3: Ditto. | ||||
| 	* libc/sys/linux/net/getaddrinfo.c: Ditto. | ||||
| 	* libc/sys/linux/net/gethostbydns.c: Ditto. | ||||
| 	* libc/sys/linux/net/gethostbyht.c: Ditto. | ||||
| 	* libc/sys/linux/net/gethostbyname.3: Ditto. | ||||
| 	* libc/sys/linux/net/gethostbynis.c: Ditto. | ||||
| 	* libc/sys/linux/net/gethostnamadr.c: Ditto. | ||||
| 	* libc/sys/linux/net/getifaddrs.3: Ditto. | ||||
| 	* libc/sys/linux/net/getifaddrs.c: Ditto. | ||||
| 	* libc/sys/linux/net/getipnodebyname.3: Ditto. | ||||
| 	* libc/sys/linux/net/getnameinfo.3: Ditto. | ||||
| 	* libc/sys/linux/net/getnameinfo.c: Ditto. | ||||
| 	* libc/sys/linux/net/getnetbydns.c: Ditto. | ||||
| 	* libc/sys/linux/net/getnetbyht.c: Ditto. | ||||
| 	* libc/sys/linux/net/getnetbynis.c: Ditto. | ||||
| 	* libc/sys/linux/net/getnetent.3: Ditto. | ||||
| 	* libc/sys/linux/net/getnetnamadr.c: Ditto. | ||||
| 	* libc/sys/linux/net/getproto.c: Ditto. | ||||
| 	* libc/sys/linux/net/getprotoent.3: Ditto. | ||||
| 	* libc/sys/linux/net/getprotoent.c: Ditto. | ||||
| 	* libc/sys/linux/net/getprotoname.c: Ditto. | ||||
| 	* libc/sys/linux/net/getservbyname.c: Ditto. | ||||
| 	* libc/sys/linux/net/getservbyport.c: Ditto. | ||||
| 	* libc/sys/linux/net/getservent.3: Ditto. | ||||
| 	* libc/sys/linux/net/getservent.c: Ditto. | ||||
| 	* libc/sys/linux/net/herror.c: Ditto. | ||||
| 	* libc/sys/linux/net/hesiod.3: Ditto. | ||||
| 	* libc/sys/linux/net/hesiod.c: Ditto. | ||||
| 	* libc/sys/linux/net/if_indextoname.3: Ditto. | ||||
| 	* libc/sys/linux/net/ifname.c: Ditto. | ||||
| 	* libc/sys/linux/net/inet.3: Ditto. | ||||
| 	* libc/sys/linux/net/inet6_option_s: Ditto.pace.3 | ||||
| 	* libc/sys/linux/net/inet6_rthdr_space.3: Ditto. | ||||
| 	* libc/sys/linux/net/inet_addr.c: Ditto. | ||||
| 	* libc/sys/linux/net/inet_lnaof.c: Ditto. | ||||
| 	* libc/sys/linux/net/inet_makeaddr.c: Ditto. | ||||
| 	* libc/sys/linux/net/inet_net.3: Ditto. | ||||
| 	* libc/sys/linux/net/inet_net_ntop.c: Ditto. | ||||
| 	* libc/sys/linux/net/inet_net_pton.c: Ditto. | ||||
| 	* libc/sys/linux/net/inet_neta.c: Ditto. | ||||
| 	* libc/sys/linux/net/inet_netof.c: Ditto. | ||||
| 	* libc/sys/linux/net/inet_network.c: Ditto. | ||||
| 	* libc/sys/linux/net/inet_ntoa.c: Ditto. | ||||
| 	* libc/sys/linux/net/inet_ntop.c: Ditto. | ||||
| 	* libc/sys/linux/net/inet_pton.c: Ditto. | ||||
| 	* libc/sys/linux/net/innetgr-stub.c: Ditto. | ||||
| 	* libc/sys/linux/net/ip6opt.c: Ditto. | ||||
| 	* libc/sys/linux/net/iso_addr.3: Ditto. | ||||
| 	* libc/sys/linux/net/iso_addr.c: Ditto. | ||||
| 	* libc/sys/linux/net/issetugid-stub.c: Ditto. | ||||
| 	* libc/sys/linux/net/linkaddr.3: Ditto. | ||||
| 	* libc/sys/linux/net/linkaddr.c: Ditto. | ||||
| 	* libc/sys/linux/net/map_v4v6.c: Ditto. | ||||
| 	* libc/sys/linux/net/name6.c: Ditto. | ||||
| 	* libc/sys/linux/net/namespace.h: Ditto. | ||||
| 	* libc/sys/linux/net/ns.3: Ditto. | ||||
| 	* libc/sys/linux/net/ns_addr.c: Ditto. | ||||
| 	* libc/sys/linux/net/ns_name.c: Ditto. | ||||
| 	* libc/sys/linux/net/ns_netint.c: Ditto. | ||||
| 	* libc/sys/linux/net/ns_ntoa.c: Ditto. | ||||
| 	* libc/sys/linux/net/ns_parse.c: Ditto. | ||||
| 	* libc/sys/linux/net/ns_print.c: Ditto. | ||||
| 	* libc/sys/linux/net/ns_ttl.c: Ditto. | ||||
| 	* libc/sys/linux/net/nsap_addr.c: Ditto. | ||||
| 	* libc/sys/linux/net/nsdispatch.3: Ditto. | ||||
| 	* libc/sys/linux/net/nsdispatch.c: Ditto. | ||||
| 	* libc/sys/linux/net/nslexer.c: Ditto. | ||||
| 	* libc/sys/linux/net/nslexer.l: Ditto. | ||||
| 	* libc/sys/linux/net/nsparser.c: Ditto. | ||||
| 	* libc/sys/linux/net/nsparser.h: Ditto. | ||||
| 	* libc/sys/linux/net/nsparser.y: Ditto. | ||||
| 	* libc/sys/linux/net/rcmd.3: Ditto. | ||||
| 	* libc/sys/linux/net/rcmd.c: Ditto. | ||||
| 	* libc/sys/linux/net/rcmdsh.3: Ditto. | ||||
| 	* libc/sys/linux/net/rcmdsh.c: Ditto. | ||||
| 	* libc/sys/linux/net/recv.c: Ditto. | ||||
| 	* libc/sys/linux/net/res_comp.c: Ditto. | ||||
| 	* libc/sys/linux/net/res_config.h: Ditto. | ||||
| 	* libc/sys/linux/net/res_data.c: Ditto. | ||||
| 	* libc/sys/linux/net/res_debug.c: Ditto. | ||||
| 	* libc/sys/linux/net/res_init.c: Ditto. | ||||
| 	* libc/sys/linux/net/res_mkquery.c: Ditto. | ||||
| 	* libc/sys/linux/net/res_mkupdate.c: Ditto. | ||||
| 	* libc/sys/linux/net/res_query.c: Ditto. | ||||
| 	* libc/sys/linux/net/res_send.c: Ditto. | ||||
| 	* libc/sys/linux/net/res_update.c: Ditto. | ||||
| 	* libc/sys/linux/net/resolver.3: Ditto. | ||||
| 	* libc/sys/linux/net/rthdr.c: Ditto. | ||||
| 	* libc/sys/linux/net/send.c: Ditto. | ||||
| 	* libc/sys/linux/net/un-namespace.h: Ditto. | ||||
| 	* libc/sys/linux/net/vars.c: Ditto. | ||||
| 	* libc/sys/linux/stdlib/COPYRIGHT: Ditto. | ||||
| 	* libc/sys/linux/stdlib/Makefile.am: Ditto. | ||||
| 	* libc/sys/linux/stdlib/Makefile.in: Ditto. | ||||
| 	* libc/sys/linux/stdlib/cclass.h: Ditto. | ||||
| 	* libc/sys/linux/stdlib/cname.h: Ditto. | ||||
| 	* libc/sys/linux/stdlib/collate.c: Ditto. | ||||
| 	* libc/sys/linux/stdlib/collate.h: Ditto. | ||||
| 	* libc/sys/linux/stdlib/collcmp.c: Ditto. | ||||
| 	* libc/sys/linux/stdlib/engine.c: Ditto. | ||||
| 	* libc/sys/linux/stdlib/fnmatch.3: Ditto. | ||||
| 	* libc/sys/linux/stdlib/fnmatch.c: Ditto. | ||||
| 	* libc/sys/linux/stdlib/glob.3: Ditto. | ||||
| 	* libc/sys/linux/stdlib/glob.c: Ditto. | ||||
| 	* libc/sys/linux/stdlib/reallocf.c: Ditto. | ||||
| 	* libc/sys/linux/stdlib/regcomp.c: Ditto. | ||||
| 	* libc/sys/linux/stdlib/regerror.c: Ditto. | ||||
| 	* libc/sys/linux/stdlib/regex.3: Ditto. | ||||
| 	* libc/sys/linux/stdlib/regex2.h: Ditto. | ||||
| 	* libc/sys/linux/stdlib/regexec.c: Ditto. | ||||
| 	* libc/sys/linux/stdlib/regfree.c: Ditto. | ||||
| 	* libc/sys/linux/stdlib/utils.h: Ditto. | ||||
| 	* libc/sys/linux/stdlib/wordexp.c: Ditto. | ||||
| 	* libc/sys/linux/stdlib/wordfree.c: Ditto. | ||||
| 	* libc/sys/linux/sys/dlfcn.h: Ditto. | ||||
| 	* libc/sys/linux/sys/elfclass.h: Ditto. | ||||
| 	* libc/sys/linux/sys/event.h: Ditto. | ||||
| 	* libc/sys/linux/sys/ioccom.h: Ditto. | ||||
| 	* libc/sys/linux/sys/libc-tsd.h: Ditto. | ||||
| 	* libc/sys/linux/sys/link.h: Ditto. | ||||
| 	* libc/sys/linux/sys/lock.h: Ditto. | ||||
| 	* libc/sys/linux/sys/param.h: Ditto. | ||||
| 	* libc/sys/linux/sys/socket.h: Ditto. | ||||
| 	* libc/sys/linux/sys/sockio.h: Ditto. | ||||
|  | ||||
| 2003-05-28  Dhananjay Deshpande  <dhananjayd@kpitcummins.com>  | ||||
|  | ||||
| 	* newlib/libc/machine/h8300/memcpy.S: Use .h8300hn and .h8300sn for  | ||||
|   | ||||
							
								
								
									
										6
									
								
								newlib/configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								newlib/configure
									
									
									
									
										vendored
									
									
								
							| @@ -3090,6 +3090,12 @@ else | ||||
| fi | ||||
|  | ||||
| EXTRA_DIRS= | ||||
| case $host in | ||||
|   i345686-pc-linux-*) | ||||
| 	configdirs="${configdirs} iconvdata" | ||||
| 	EXTRA_DIRS=iconvdata | ||||
| 	;; | ||||
| esac | ||||
|  | ||||
|  | ||||
| # These get added in the top-level configure.in, except in the case where | ||||
|   | ||||
| @@ -51,6 +51,12 @@ fi | ||||
| AM_CONDITIONAL(HAVE_DOC, test x$have_doc = xyes) | ||||
|  | ||||
| EXTRA_DIRS= | ||||
| case $host in | ||||
|   i[3456]86-pc-linux-*) | ||||
| 	configdirs="${configdirs} iconvdata" | ||||
| 	EXTRA_DIRS=iconvdata | ||||
| 	;; | ||||
| esac | ||||
| AC_SUBST(EXTRA_DIRS) | ||||
|  | ||||
| # These get added in the top-level configure.in, except in the case where | ||||
|   | ||||
							
								
								
									
										2
									
								
								newlib/iconvdata/EUC-JP.irreversible
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								newlib/iconvdata/EUC-JP.irreversible
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| 0x5C	0x00A5 | ||||
| 0x7E	0x203E | ||||
							
								
								
									
										25
									
								
								newlib/iconvdata/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								newlib/iconvdata/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| ## Process this file with automake to generate Makefile.in | ||||
|  | ||||
| AUTOMAKE_OPTIONS = cygnus | ||||
|  | ||||
| INCLUDES = -I$(srcdir) -I$(srcdir)/../libc/sys/linux $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) | ||||
|  | ||||
| if ELIX_LEVEL_1 | ||||
| LIB_OBJS =  | ||||
| else | ||||
| LIB_OBJS = euc-jp.$(oext) jis0201.$(oext) jis0208.$(oext) jis0212.$(oext) | ||||
| endif | ||||
|  | ||||
| AM_CFLAGS = -DNDEBUG | ||||
|  | ||||
| all: Makefile | ||||
|  | ||||
| pkglib_LTLIBRARIES = EUC-JP.la | ||||
| EUC_JP_la_SOURCES = dummy.c | ||||
| EUC_JP_la_LIBADD = $(LIB_OBJS) | ||||
| EUC_JP_la_DEPENDENCIES = $(LIB_OBJS) | ||||
| EUC_JP_la_LDFLAGS = -module -no-undefined -Xcompiler -Wl,-rpath-link=.. -Xcompiler -nostdlib -L.. -lc | ||||
|  | ||||
| install-data-local: install-pkglibLTLIBRARIES $(srcdir)/gconv-modules | ||||
| 	$(INSTALL_DATA) $(srcdir)/gconv-modules $(DESTDIR)$(pkglibdir)/gconv-modules | ||||
|  | ||||
							
								
								
									
										389
									
								
								newlib/iconvdata/Makefile.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										389
									
								
								newlib/iconvdata/Makefile.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,389 @@ | ||||
| # Makefile.in generated automatically by automake 1.4 from Makefile.am | ||||
|  | ||||
| # Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. | ||||
| # This Makefile.in is free software; the Free Software Foundation | ||||
| # gives unlimited permission to copy and/or distribute it, | ||||
| # with or without modifications, as long as this notice is preserved. | ||||
|  | ||||
| # This program is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY, to the extent permitted by law; without | ||||
| # even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||||
| # PARTICULAR PURPOSE. | ||||
|  | ||||
|  | ||||
| SHELL = @SHELL@ | ||||
|  | ||||
| srcdir = @srcdir@ | ||||
| top_srcdir = @top_srcdir@ | ||||
| VPATH = @srcdir@ | ||||
| prefix = @prefix@ | ||||
| exec_prefix = @exec_prefix@ | ||||
|  | ||||
| bindir = @bindir@ | ||||
| sbindir = @sbindir@ | ||||
| libexecdir = @libexecdir@ | ||||
| datadir = @datadir@ | ||||
| sysconfdir = @sysconfdir@ | ||||
| sharedstatedir = @sharedstatedir@ | ||||
| localstatedir = @localstatedir@ | ||||
| libdir = @libdir@ | ||||
| infodir = @infodir@ | ||||
| mandir = @mandir@ | ||||
| includedir = @includedir@ | ||||
| oldincludedir = /usr/include | ||||
|  | ||||
| DESTDIR = | ||||
|  | ||||
| pkgdatadir = $(datadir)/@PACKAGE@ | ||||
| pkglibdir = $(libdir)/@PACKAGE@ | ||||
| pkgincludedir = $(includedir)/@PACKAGE@ | ||||
|  | ||||
| top_builddir = . | ||||
|  | ||||
| ACLOCAL = @ACLOCAL@ | ||||
| AUTOCONF = @AUTOCONF@ | ||||
| AUTOMAKE = @AUTOMAKE@ | ||||
| AUTOHEADER = @AUTOHEADER@ | ||||
|  | ||||
| INSTALL = @INSTALL@ | ||||
| INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) | ||||
| INSTALL_DATA = @INSTALL_DATA@ | ||||
| INSTALL_SCRIPT = @INSTALL_SCRIPT@ | ||||
| transform = @program_transform_name@ | ||||
|  | ||||
| NORMAL_INSTALL = : | ||||
| PRE_INSTALL = : | ||||
| POST_INSTALL = : | ||||
| NORMAL_UNINSTALL = : | ||||
| PRE_UNINSTALL = : | ||||
| POST_UNINSTALL = : | ||||
| build_alias = @build_alias@ | ||||
| build_triplet = @build@ | ||||
| host_alias = @host_alias@ | ||||
| host_triplet = @host@ | ||||
| target_alias = @target_alias@ | ||||
| target_triplet = @target@ | ||||
| AR = @AR@ | ||||
| AS = @AS@ | ||||
| CC = @CC@ | ||||
| CPP = @CPP@ | ||||
| CXX = @CXX@ | ||||
| CXXCPP = @CXXCPP@ | ||||
| DLLTOOL = @DLLTOOL@ | ||||
| EXEEXT = @EXEEXT@ | ||||
| GCJ = @GCJ@ | ||||
| GCJFLAGS = @GCJFLAGS@ | ||||
| LDFLAGS = @LDFLAGS@ | ||||
| LIBTOOL = @LIBTOOL@ | ||||
| LN_S = @LN_S@ | ||||
| MAINT = @MAINT@ | ||||
| MAKEINFO = @MAKEINFO@ | ||||
| NEWLIB_CFLAGS = @NEWLIB_CFLAGS@ | ||||
| OBJDUMP = @OBJDUMP@ | ||||
| OBJEXT = @OBJEXT@ | ||||
| PACKAGE = @PACKAGE@ | ||||
| RANLIB = @RANLIB@ | ||||
| STRIP = @STRIP@ | ||||
| VERSION = @VERSION@ | ||||
| aext = @aext@ | ||||
| libm_machine_dir = @libm_machine_dir@ | ||||
| machine_dir = @machine_dir@ | ||||
| newlib_basedir = @newlib_basedir@ | ||||
| oext = @oext@ | ||||
| sys_dir = @sys_dir@ | ||||
|  | ||||
| AUTOMAKE_OPTIONS = cygnus | ||||
|  | ||||
| INCLUDES = -I$(srcdir) -I$(srcdir)/../libc/sys/linux $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) | ||||
| @ELIX_LEVEL_1_TRUE@LIB_OBJS =  | ||||
| @ELIX_LEVEL_1_FALSE@LIB_OBJS = @ELIX_LEVEL_1_FALSE@euc-jp.$(oext) jis0201.$(oext) jis0208.$(oext) jis0212.$(oext) | ||||
|  | ||||
| AM_CFLAGS = -DNDEBUG | ||||
|  | ||||
| pkglib_LTLIBRARIES = EUC-JP.la | ||||
| EUC_JP_la_SOURCES = dummy.c | ||||
| EUC_JP_la_LIBADD = $(LIB_OBJS) | ||||
| EUC_JP_la_DEPENDENCIES = $(LIB_OBJS) | ||||
| EUC_JP_la_LDFLAGS = -module -no-undefined -Xcompiler -Wl,-rpath-link=.. -Xcompiler -nostdlib -L.. -lc | ||||
| ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 | ||||
| mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs | ||||
| CONFIG_CLEAN_FILES =  | ||||
| LTLIBRARIES =  $(pkglib_LTLIBRARIES) | ||||
|  | ||||
|  | ||||
| DEFS = @DEFS@ -I. -I$(srcdir)  | ||||
| CPPFLAGS = @CPPFLAGS@ | ||||
| LIBS = @LIBS@ | ||||
| EUC_JP_la_OBJECTS =  dummy.lo | ||||
| CFLAGS = @CFLAGS@ | ||||
| COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) | ||||
| LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) | ||||
| CCLD = $(CC) | ||||
| LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ | ||||
| DIST_COMMON =  Makefile.am Makefile.in aclocal.m4 configure configure.in | ||||
|  | ||||
|  | ||||
| DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) | ||||
|  | ||||
| TAR = gtar | ||||
| GZIP_ENV = --best | ||||
| SOURCES = $(EUC_JP_la_SOURCES) | ||||
| OBJECTS = $(EUC_JP_la_OBJECTS) | ||||
|  | ||||
| all: all-redirect | ||||
| .SUFFIXES: | ||||
| .SUFFIXES: .S .c .lo .o .obj .s | ||||
| $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)  | ||||
| 	cd $(top_srcdir) && $(AUTOMAKE) --cygnus Makefile | ||||
|  | ||||
| Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status | ||||
| 	cd $(top_builddir) \ | ||||
| 	  && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status | ||||
|  | ||||
| $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in  | ||||
| 	cd $(srcdir) && $(ACLOCAL) | ||||
|  | ||||
| config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) | ||||
| 	$(SHELL) ./config.status --recheck | ||||
| $(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) | ||||
| 	cd $(srcdir) && $(AUTOCONF) | ||||
|  | ||||
| mostlyclean-pkglibLTLIBRARIES: | ||||
|  | ||||
| clean-pkglibLTLIBRARIES: | ||||
| 	-test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) | ||||
|  | ||||
| distclean-pkglibLTLIBRARIES: | ||||
|  | ||||
| maintainer-clean-pkglibLTLIBRARIES: | ||||
|  | ||||
| install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) | ||||
| 	@$(NORMAL_INSTALL) | ||||
| 	$(mkinstalldirs) $(DESTDIR)$(pkglibdir) | ||||
| 	@list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ | ||||
| 	  if test -f $$p; then \ | ||||
| 	    echo "$(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(pkglibdir)/$$p"; \ | ||||
| 	    $(LIBTOOL)  --mode=install $(INSTALL) $$p $(DESTDIR)$(pkglibdir)/$$p; \ | ||||
| 	  else :; fi; \ | ||||
| 	done | ||||
|  | ||||
| uninstall-pkglibLTLIBRARIES: | ||||
| 	@$(NORMAL_UNINSTALL) | ||||
| 	list='$(pkglib_LTLIBRARIES)'; for p in $$list; do \ | ||||
| 	  $(LIBTOOL)  --mode=uninstall rm -f $(DESTDIR)$(pkglibdir)/$$p; \ | ||||
| 	done | ||||
|  | ||||
| .c.o: | ||||
| 	$(COMPILE) -c $< | ||||
|  | ||||
| # FIXME: We should only use cygpath when building on Windows, | ||||
| # and only if it is available. | ||||
| .c.obj: | ||||
| 	$(COMPILE) -c `cygpath -w $<` | ||||
|  | ||||
| .s.o: | ||||
| 	$(COMPILE) -c $< | ||||
|  | ||||
| .S.o: | ||||
| 	$(COMPILE) -c $< | ||||
|  | ||||
| mostlyclean-compile: | ||||
| 	-rm -f *.o core *.core | ||||
| 	-rm -f *.$(OBJEXT) | ||||
|  | ||||
| clean-compile: | ||||
|  | ||||
| distclean-compile: | ||||
| 	-rm -f *.tab.c | ||||
|  | ||||
| maintainer-clean-compile: | ||||
|  | ||||
| .c.lo: | ||||
| 	$(LIBTOOL) --mode=compile $(COMPILE) -c $< | ||||
|  | ||||
| .s.lo: | ||||
| 	$(LIBTOOL) --mode=compile $(COMPILE) -c $< | ||||
|  | ||||
| .S.lo: | ||||
| 	$(LIBTOOL) --mode=compile $(COMPILE) -c $< | ||||
|  | ||||
| mostlyclean-libtool: | ||||
| 	-rm -f *.lo | ||||
|  | ||||
| clean-libtool: | ||||
| 	-rm -rf .libs _libs | ||||
|  | ||||
| distclean-libtool: | ||||
|  | ||||
| maintainer-clean-libtool: | ||||
|  | ||||
| EUC-JP.la: $(EUC_JP_la_OBJECTS) $(EUC_JP_la_DEPENDENCIES) | ||||
| 	$(LINK) -rpath $(pkglibdir) $(EUC_JP_la_LDFLAGS) $(EUC_JP_la_OBJECTS) $(EUC_JP_la_LIBADD) $(LIBS) | ||||
|  | ||||
| tags: TAGS | ||||
|  | ||||
| ID: $(HEADERS) $(SOURCES) $(LISP) | ||||
| 	list='$(SOURCES) $(HEADERS)'; \ | ||||
| 	unique=`for i in $$list; do echo $$i; done | \ | ||||
| 	  awk '    { files[$$0] = 1; } \ | ||||
| 	       END { for (i in files) print i; }'`; \ | ||||
| 	here=`pwd` && cd $(srcdir) \ | ||||
| 	  && mkid -f$$here/ID $$unique $(LISP) | ||||
|  | ||||
| TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP) | ||||
| 	tags=; \ | ||||
| 	here=`pwd`; \ | ||||
| 	list='$(SOURCES) $(HEADERS)'; \ | ||||
| 	unique=`for i in $$list; do echo $$i; done | \ | ||||
| 	  awk '    { files[$$0] = 1; } \ | ||||
| 	       END { for (i in files) print i; }'`; \ | ||||
| 	test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ | ||||
| 	  || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS) | ||||
|  | ||||
| mostlyclean-tags: | ||||
|  | ||||
| clean-tags: | ||||
|  | ||||
| distclean-tags: | ||||
| 	-rm -f TAGS ID | ||||
|  | ||||
| maintainer-clean-tags: | ||||
|  | ||||
| distdir = $(PACKAGE)-$(VERSION) | ||||
| top_distdir = $(distdir) | ||||
|  | ||||
| # This target untars the dist file and tries a VPATH configuration.  Then | ||||
| # it guarantees that the distribution is self-contained by making another | ||||
| # tarfile. | ||||
| distcheck: dist | ||||
| 	-rm -rf $(distdir) | ||||
| 	GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz | ||||
| 	mkdir $(distdir)/=build | ||||
| 	mkdir $(distdir)/=inst | ||||
| 	dc_install_base=`cd $(distdir)/=inst && pwd`; \ | ||||
| 	cd $(distdir)/=build \ | ||||
| 	  && ../configure --srcdir=.. --prefix=$$dc_install_base \ | ||||
| 	  && $(MAKE) $(AM_MAKEFLAGS) \ | ||||
| 	  && $(MAKE) $(AM_MAKEFLAGS) dvi \ | ||||
| 	  && $(MAKE) $(AM_MAKEFLAGS) check \ | ||||
| 	  && $(MAKE) $(AM_MAKEFLAGS) install \ | ||||
| 	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \ | ||||
| 	  && $(MAKE) $(AM_MAKEFLAGS) dist | ||||
| 	-rm -rf $(distdir) | ||||
| 	@banner="$(distdir).tar.gz is ready for distribution"; \ | ||||
| 	dashes=`echo "$$banner" | sed s/./=/g`; \ | ||||
| 	echo "$$dashes"; \ | ||||
| 	echo "$$banner"; \ | ||||
| 	echo "$$dashes" | ||||
| dist: distdir | ||||
| 	-chmod -R a+r $(distdir) | ||||
| 	GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) | ||||
| 	-rm -rf $(distdir) | ||||
| dist-all: distdir | ||||
| 	-chmod -R a+r $(distdir) | ||||
| 	GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) | ||||
| 	-rm -rf $(distdir) | ||||
| distdir: $(DISTFILES) | ||||
| 	-rm -rf $(distdir) | ||||
| 	mkdir $(distdir) | ||||
| 	-chmod 777 $(distdir) | ||||
| 	@for file in $(DISTFILES); do \ | ||||
| 	  if test -f $$file; then d=.; else d=$(srcdir); fi; \ | ||||
| 	  if test -d $$d/$$file; then \ | ||||
| 	    cp -pr $$d/$$file $(distdir)/$$file; \ | ||||
| 	  else \ | ||||
| 	    test -f $(distdir)/$$file \ | ||||
| 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ | ||||
| 	    || cp -p $$d/$$file $(distdir)/$$file || :; \ | ||||
| 	  fi; \ | ||||
| 	done | ||||
| info-am: | ||||
| info: info-am | ||||
| dvi-am: | ||||
| dvi: dvi-am | ||||
| check-am: | ||||
| check: check-am | ||||
| installcheck-am: | ||||
| installcheck: installcheck-am | ||||
| install-info-am:  | ||||
| install-info: install-info-am | ||||
| install-exec-am: install-pkglibLTLIBRARIES | ||||
| install-exec: install-exec-am | ||||
|  | ||||
| install-data-am: install-data-local | ||||
| install-data: install-data-am | ||||
|  | ||||
| install-am: all-am | ||||
| 	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am | ||||
| install: install-am | ||||
| uninstall-am: uninstall-pkglibLTLIBRARIES | ||||
| uninstall: uninstall-am | ||||
| all-am: Makefile $(LTLIBRARIES) | ||||
| all-redirect: all-am | ||||
| install-strip: | ||||
| 	$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install | ||||
| installdirs: | ||||
| 	$(mkinstalldirs)  $(DESTDIR)$(pkglibdir) | ||||
|  | ||||
|  | ||||
| mostlyclean-generic: | ||||
|  | ||||
| clean-generic: | ||||
|  | ||||
| distclean-generic: | ||||
| 	-rm -f Makefile $(CONFIG_CLEAN_FILES) | ||||
| 	-rm -f config.cache config.log stamp-h stamp-h[0-9]* | ||||
|  | ||||
| maintainer-clean-generic: | ||||
| mostlyclean-am:  mostlyclean-pkglibLTLIBRARIES mostlyclean-compile \ | ||||
| 		mostlyclean-libtool mostlyclean-tags \ | ||||
| 		mostlyclean-generic | ||||
|  | ||||
| mostlyclean: mostlyclean-am | ||||
|  | ||||
| clean-am:  clean-pkglibLTLIBRARIES clean-compile clean-libtool \ | ||||
| 		clean-tags clean-generic mostlyclean-am | ||||
|  | ||||
| clean: clean-am | ||||
|  | ||||
| distclean-am:  distclean-pkglibLTLIBRARIES distclean-compile \ | ||||
| 		distclean-libtool distclean-tags distclean-generic \ | ||||
| 		clean-am | ||||
| 	-rm -f libtool | ||||
|  | ||||
| distclean: distclean-am | ||||
| 	-rm -f config.status | ||||
|  | ||||
| maintainer-clean-am:  maintainer-clean-pkglibLTLIBRARIES \ | ||||
| 		maintainer-clean-compile maintainer-clean-libtool \ | ||||
| 		maintainer-clean-tags maintainer-clean-generic \ | ||||
| 		distclean-am | ||||
| 	@echo "This command is intended for maintainers to use;" | ||||
| 	@echo "it deletes files that may require special tools to rebuild." | ||||
|  | ||||
| maintainer-clean: maintainer-clean-am | ||||
| 	-rm -f config.status | ||||
|  | ||||
| .PHONY: mostlyclean-pkglibLTLIBRARIES distclean-pkglibLTLIBRARIES \ | ||||
| clean-pkglibLTLIBRARIES maintainer-clean-pkglibLTLIBRARIES \ | ||||
| uninstall-pkglibLTLIBRARIES install-pkglibLTLIBRARIES \ | ||||
| mostlyclean-compile distclean-compile clean-compile \ | ||||
| maintainer-clean-compile mostlyclean-libtool distclean-libtool \ | ||||
| clean-libtool maintainer-clean-libtool tags mostlyclean-tags \ | ||||
| distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ | ||||
| dvi-am dvi check check-am installcheck-am installcheck install-info-am \ | ||||
| install-info install-exec-am install-exec install-data-local \ | ||||
| install-data-am install-data install-am install uninstall-am uninstall \ | ||||
| all-redirect all-am all installdirs mostlyclean-generic \ | ||||
| distclean-generic clean-generic maintainer-clean-generic clean \ | ||||
| mostlyclean distclean maintainer-clean | ||||
|  | ||||
|  | ||||
| all: Makefile | ||||
|  | ||||
| install-data-local: install-pkglibLTLIBRARIES $(srcdir)/gconv-modules | ||||
| 	$(INSTALL_DATA) $(srcdir)/gconv-modules $(DESTDIR)$(pkglibdir)/gconv-modules | ||||
|  | ||||
| # Tell versions [3.59,3.63) of GNU make to not export all variables. | ||||
| # Otherwise a system limit (for SysV at least) may be exceeded. | ||||
| .NOEXPORT: | ||||
							
								
								
									
										5
									
								
								newlib/iconvdata/SJIS.irreversible
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								newlib/iconvdata/SJIS.irreversible
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| 0x5C	0x005C | ||||
| 0x7E	0x007E | ||||
| 0x8191	0xFFE0 | ||||
| 0x8192	0xFFE1 | ||||
| 0x81CA	0xFFE2 | ||||
							
								
								
									
										1181
									
								
								newlib/iconvdata/aclocal.m4
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1181
									
								
								newlib/iconvdata/aclocal.m4
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										3291
									
								
								newlib/iconvdata/configure
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										3291
									
								
								newlib/iconvdata/configure
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										21
									
								
								newlib/iconvdata/configure.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								newlib/iconvdata/configure.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| dnl This is the newlib/iconvdata configure.in file. | ||||
| dnl Process this file with autoconf to produce a configure script. | ||||
|  | ||||
| AC_PREREQ(2.5) | ||||
| AC_INIT(jis0201.c) | ||||
|  | ||||
| dnl Can't be done in NEWLIB_CONFIGURE because that confuses automake.  | ||||
| AC_CONFIG_AUX_DIR(../..) | ||||
|  | ||||
| NEWLIB_CONFIGURE(..) | ||||
|  | ||||
| dnl We have to enable libtool after NEWLIB_CONFIGURE because if we try and | ||||
| dnl add it into NEWLIB_CONFIGURE, executable tests are made before the first | ||||
| dnl line of the macro which fail because appropriate LDFLAGS are not set. | ||||
|  | ||||
| if test "${use_libtool}" = "yes"; then | ||||
| AC_LIBTOOL_WIN32_DLL | ||||
| AM_PROG_LIBTOOL | ||||
| fi | ||||
|  | ||||
| AC_OUTPUT(Makefile) | ||||
							
								
								
									
										1
									
								
								newlib/iconvdata/dummy.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								newlib/iconvdata/dummy.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| /* empty file to force proper Makefile creation */ | ||||
							
								
								
									
										246
									
								
								newlib/iconvdata/euc-jp.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										246
									
								
								newlib/iconvdata/euc-jp.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,246 @@ | ||||
| /* Mapping tables for EUC-JP handling. | ||||
|    Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <dlfcn.h> | ||||
| #include <stdint.h> | ||||
| #include <gconv.h> | ||||
| #include <jis0201.h> | ||||
| #include <jis0208.h> | ||||
| #include <jis0212.h> | ||||
|  | ||||
| /* Definitions used in the body of the `gconv' function.  */ | ||||
| #define CHARSET_NAME		"EUC-JP//" | ||||
| #define FROM_LOOP		from_euc_jp | ||||
| #define TO_LOOP			to_euc_jp | ||||
| #define DEFINE_INIT		1 | ||||
| #define DEFINE_FINI		1 | ||||
| #define MIN_NEEDED_FROM		1 | ||||
| #define MAX_NEEDED_FROM		3 | ||||
| #define MIN_NEEDED_TO		4 | ||||
|  | ||||
|  | ||||
| /* First define the conversion function from EUC-JP to UCS4.  */ | ||||
| #define MIN_NEEDED_INPUT	MIN_NEEDED_FROM | ||||
| #define MAX_NEEDED_INPUT	MAX_NEEDED_FROM | ||||
| #define MIN_NEEDED_OUTPUT	MIN_NEEDED_TO | ||||
| #define LOOPFCT			FROM_LOOP | ||||
| #define BODY \ | ||||
|   {									      \ | ||||
|     uint32_t ch = *inptr;						      \ | ||||
| 									      \ | ||||
|     if (ch < 0x8e || (ch >= 0x90 && ch <= 0x9f))			      \ | ||||
|       ++inptr;								      \ | ||||
|     else if (ch == 0xff)						      \ | ||||
|       {									      \ | ||||
| 	/* This is illegal.  */						      \ | ||||
| 	if (! ignore_errors_p ())					      \ | ||||
| 	  {								      \ | ||||
| 	    result = __GCONV_ILLEGAL_INPUT;				      \ | ||||
| 	    break;							      \ | ||||
| 	  }								      \ | ||||
| 									      \ | ||||
| 	++inptr;							      \ | ||||
| 	++*irreversible;						      \ | ||||
| 	continue;							      \ | ||||
|       }									      \ | ||||
|     else								      \ | ||||
|       {									      \ | ||||
| 	/* Two or more byte character.  First test whether the next	      \ | ||||
| 	   character is also available.  */				      \ | ||||
| 	int ch2;							      \ | ||||
| 									      \ | ||||
| 	if (__builtin_expect (inptr + 1 >= inend, 0))			      \ | ||||
| 	  {								      \ | ||||
| 	    /* The second character is not available.  Store the	      \ | ||||
| 	       intermediate result.  */					      \ | ||||
| 	    result = __GCONV_INCOMPLETE_INPUT;				      \ | ||||
| 	    break;							      \ | ||||
| 	  }								      \ | ||||
| 									      \ | ||||
| 	ch2 = inptr[1];							      \ | ||||
| 									      \ | ||||
| 	/* All second bytes of a multibyte character must be >= 0xa1. */      \ | ||||
| 	if (__builtin_expect (ch2 < 0xa1, 0))				      \ | ||||
| 	  {								      \ | ||||
| 	    /* This is an illegal character.  */			      \ | ||||
| 	    if (! ignore_errors_p ())					      \ | ||||
| 	      {								      \ | ||||
| 		result = __GCONV_ILLEGAL_INPUT;				      \ | ||||
| 		break;							      \ | ||||
| 	      }								      \ | ||||
| 									      \ | ||||
| 	    ++inptr;							      \ | ||||
| 	    ++*irreversible;						      \ | ||||
| 	    continue;							      \ | ||||
| 	  }								      \ | ||||
| 									      \ | ||||
| 	if (ch == 0x8e)							      \ | ||||
| 	  {								      \ | ||||
| 	    /* This is code set 2: half-width katakana.  */		      \ | ||||
| 	    ch = jisx0201_to_ucs4 (ch2);				      \ | ||||
| 	    if (__builtin_expect (ch, 0) == __UNKNOWN_10646_CHAR)	      \ | ||||
| 	      {								      \ | ||||
| 		/* Illegal character.  */				      \ | ||||
| 		if (! ignore_errors_p ())				      \ | ||||
| 		  {							      \ | ||||
| 		    /* This is an illegal character.  */		      \ | ||||
| 		    result = __GCONV_ILLEGAL_INPUT;			      \ | ||||
| 		    break;						      \ | ||||
| 		  }							      \ | ||||
| 	      }								      \ | ||||
| 									      \ | ||||
| 	    inptr += 2;							      \ | ||||
| 	  }								      \ | ||||
| 	else								      \ | ||||
| 	  {								      \ | ||||
| 	    const unsigned char *endp;					      \ | ||||
| 									      \ | ||||
| 	    if (ch == 0x8f)						      \ | ||||
| 	      {								      \ | ||||
| 		/* This is code set 3: JIS X 0212-1990.  */		      \ | ||||
| 		endp = inptr + 1;					      \ | ||||
| 									      \ | ||||
| 		ch = jisx0212_to_ucs4 (&endp, inend - endp, 0x80);	      \ | ||||
| 	      }								      \ | ||||
| 	    else							      \ | ||||
| 	      {								      \ | ||||
| 		/* This is code set 1: JIS X 0208.  */			      \ | ||||
| 		endp = inptr;						      \ | ||||
| 									      \ | ||||
| 		ch = jisx0208_to_ucs4 (&endp, inend - inptr, 0x80);	      \ | ||||
| 	      }								      \ | ||||
| 									      \ | ||||
| 	    if (__builtin_expect (ch, 1) == 0)				      \ | ||||
| 	      {								      \ | ||||
| 		/* Not enough input available.  */			      \ | ||||
| 		result = __GCONV_INCOMPLETE_INPUT;			      \ | ||||
| 		break;							      \ | ||||
| 	      }								      \ | ||||
| 	    if (__builtin_expect (ch, 0) == __UNKNOWN_10646_CHAR)	      \ | ||||
| 	      {								      \ | ||||
| 		/* Illegal character.  */				      \ | ||||
| 		if (! ignore_errors_p ())				      \ | ||||
| 		  {							      \ | ||||
| 		    /* This is an illegal character.  */		      \ | ||||
| 		    result = __GCONV_ILLEGAL_INPUT;			      \ | ||||
| 		    break;						      \ | ||||
| 		  }							      \ | ||||
| 									      \ | ||||
| 		inptr += 2;						      \ | ||||
| 		++*irreversible;					      \ | ||||
| 		continue;						      \ | ||||
| 	      }								      \ | ||||
| 	    inptr = endp;						      \ | ||||
| 	  }								      \ | ||||
|       }									      \ | ||||
| 									      \ | ||||
|     put32 (outptr, ch);							      \ | ||||
|     outptr += 4;							      \ | ||||
|   } | ||||
| #define LOOP_NEED_FLAGS | ||||
| #include <iconv/loop.c> | ||||
|  | ||||
|  | ||||
| /* Next, define the other direction.  */ | ||||
| #define MIN_NEEDED_INPUT	MIN_NEEDED_TO | ||||
| #define MIN_NEEDED_OUTPUT	MIN_NEEDED_FROM | ||||
| #define MAX_NEEDED_OUTPUT	MAX_NEEDED_FROM | ||||
| #define LOOPFCT			TO_LOOP | ||||
| #define BODY \ | ||||
|   {									      \ | ||||
|     uint32_t ch = get32 (inptr);					      \ | ||||
| 									      \ | ||||
|     if (ch < 0x8e || (ch >= 0x90 && ch <= 0x9f))			      \ | ||||
|       /* It's plain ASCII or C1.  */					      \ | ||||
|       *outptr++ = ch;							      \ | ||||
|     else if (ch == 0xa5)						      \ | ||||
|       /* YEN sign => backslash  */					      \ | ||||
|       *outptr++ = 0x5c;							      \ | ||||
|     else if (ch == 0x203e)						      \ | ||||
|       /* overscore => asciitilde */					      \ | ||||
|       *outptr++ = 0x7e;							      \ | ||||
|     else								      \ | ||||
|       {									      \ | ||||
| 	/* Try the JIS character sets.  */				      \ | ||||
| 	size_t found;							      \ | ||||
| 									      \ | ||||
| 	/* See whether we have room for at least two characters.  */	      \ | ||||
| 	if (__builtin_expect (outptr + 1 >= outend, 0))			      \ | ||||
| 	  {								      \ | ||||
| 	    result = __GCONV_FULL_OUTPUT;				      \ | ||||
| 	    break;							      \ | ||||
| 	  }								      \ | ||||
| 									      \ | ||||
| 	found = ucs4_to_jisx0201 (ch, outptr + 1);			      \ | ||||
| 	if (found != __UNKNOWN_10646_CHAR)				      \ | ||||
| 	  {								      \ | ||||
| 	    /* Yes, it's a JIS 0201 character.  Store the shift byte.  */     \ | ||||
| 	    *outptr = 0x8e;						      \ | ||||
| 	    outptr += 2;						      \ | ||||
| 	  }								      \ | ||||
| 	else								      \ | ||||
| 	  {								      \ | ||||
| 	    /* No JIS 0201 character.  */				      \ | ||||
| 	    found = ucs4_to_jisx0208 (ch, outptr, 2);			      \ | ||||
| 	    /* Please note that we always have enough room for the output. */ \ | ||||
| 	    if (found != __UNKNOWN_10646_CHAR)				      \ | ||||
| 	      {								      \ | ||||
| 		/* It's a JIS 0208 character, adjust it for EUC-JP.  */	      \ | ||||
| 		*outptr++ += 0x80;					      \ | ||||
| 		*outptr++ += 0x80;					      \ | ||||
| 	      }								      \ | ||||
| 	    else							      \ | ||||
| 	      {								      \ | ||||
| 		/* No JIS 0208 character.  */				      \ | ||||
| 		found = ucs4_to_jisx0212 (ch, outptr + 1,		      \ | ||||
| 					  outend - outptr - 1);		      \ | ||||
| 		  							      \ | ||||
| 		if (__builtin_expect (found, 1) == 0)			      \ | ||||
| 		  {							      \ | ||||
| 		    /* We ran out of space.  */				      \ | ||||
| 		    result = __GCONV_FULL_OUTPUT;			      \ | ||||
| 		    break;						      \ | ||||
| 		  }							      \ | ||||
| 		else if (__builtin_expect (found, 0) != __UNKNOWN_10646_CHAR) \ | ||||
| 		  {							      \ | ||||
| 		    /* It's a JIS 0212 character, adjust it for EUC-JP.  */   \ | ||||
| 		    *outptr++ = 0x8f;					      \ | ||||
| 		    *outptr++ += 0x80;					      \ | ||||
| 		    *outptr++ += 0x80;					      \ | ||||
| 		  }							      \ | ||||
| 		else							      \ | ||||
| 		  {							      \ | ||||
| 		    UNICODE_TAG_HANDLER (ch, 4);			      \ | ||||
| 									      \ | ||||
| 		    /* Illegal character.  */				      \ | ||||
| 		    STANDARD_ERR_HANDLER (4);				      \ | ||||
| 		  }							      \ | ||||
| 	      }								      \ | ||||
| 	  }								      \ | ||||
|       }									      \ | ||||
| 									      \ | ||||
|     inptr += 4;								      \ | ||||
|   } | ||||
| #define LOOP_NEED_FLAGS | ||||
| #include <iconv/loop.c> | ||||
|  | ||||
|  | ||||
| /* Now define the toplevel functions.  */ | ||||
| #include <iconv/skeleton.c> | ||||
							
								
								
									
										1511
									
								
								newlib/iconvdata/gconv-modules
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1511
									
								
								newlib/iconvdata/gconv-modules
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										58
									
								
								newlib/iconvdata/jis0201.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								newlib/iconvdata/jis0201.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| /* Mapping tables for JIS0201 handling. | ||||
|    Copyright (C) 1997, 1998 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
|  | ||||
| const uint32_t __jisx0201_to_ucs4[256] = | ||||
| { | ||||
|   0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, | ||||
|   0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, | ||||
|   0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, | ||||
|   0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, | ||||
|   0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, | ||||
|   0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, | ||||
|   0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, | ||||
|   0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, | ||||
|   0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, | ||||
|   0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, | ||||
|   0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, | ||||
|   0x0058, 0x0059, 0x005a, 0x005b, 0x00a5, 0x005d, 0x005e, 0x005f, | ||||
|   0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, | ||||
|   0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, | ||||
|   0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, | ||||
|   0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x203e, 0x0000, | ||||
|   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||||
|   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||||
|   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||||
|   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||||
|   0x0000, 0xff61, 0xff62, 0xff63, 0xff64, 0xff65, 0xff66, 0xff67, | ||||
|   0xff68, 0xff69, 0xff6a, 0xff6b, 0xff6c, 0xff6d, 0xff6e, 0xff6f, | ||||
|   0xff70, 0xff71, 0xff72, 0xff73, 0xff74, 0xff75, 0xff76, 0xff77, | ||||
|   0xff78, 0xff79, 0xff7a, 0xff7b, 0xff7c, 0xff7d, 0xff7e, 0xff7f, | ||||
|   0xff80, 0xff81, 0xff82, 0xff83, 0xff84, 0xff85, 0xff86, 0xff87, | ||||
|   0xff88, 0xff89, 0xff8a, 0xff8b, 0xff8c, 0xff8d, 0xff8e, 0xff8f, | ||||
|   0xff90, 0xff91, 0xff92, 0xff93, 0xff94, 0xff95, 0xff96, 0xff97, | ||||
|   0xff98, 0xff99, 0xff9a, 0xff9b, 0xff9c, 0xff9d, 0xff9e, 0xff9f, | ||||
|   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||||
|   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||||
|   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, | ||||
|   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 | ||||
| }; | ||||
							
								
								
									
										60
									
								
								newlib/iconvdata/jis0201.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								newlib/iconvdata/jis0201.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| /* Access functions for JISX0201 conversion. | ||||
|    Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #ifndef _JIS0201_H | ||||
| #define _JIS0201_H	1 | ||||
|  | ||||
| /* Conversion table.  */ | ||||
| extern const uint32_t __jisx0201_to_ucs4[]; | ||||
|  | ||||
|  | ||||
| static inline uint32_t | ||||
| jisx0201_to_ucs4 (char ch) | ||||
| { | ||||
|   uint32_t val = __jisx0201_to_ucs4[(unsigned char) ch]; | ||||
|  | ||||
|   if (val == 0 && ch != '\0') | ||||
|     val = __UNKNOWN_10646_CHAR; | ||||
|  | ||||
|   return val; | ||||
| } | ||||
|  | ||||
|  | ||||
| static inline size_t | ||||
| ucs4_to_jisx0201 (uint32_t wch, char *s) | ||||
| { | ||||
|   char ch; | ||||
|  | ||||
|   if (wch == 0xa5) | ||||
|     ch = '\x5c'; | ||||
|   else if (wch == 0x203e) | ||||
|     ch = '\x7e'; | ||||
|   else if (wch < 0x7e && wch != 0x5c) | ||||
|     ch = wch; | ||||
|   else if (wch >= 0xff61 && wch <= 0xff9f) | ||||
|     ch = wch - 0xfec0; | ||||
|   else | ||||
|     return __UNKNOWN_10646_CHAR; | ||||
|  | ||||
|   s[0] = ch; | ||||
|   return 1; | ||||
| } | ||||
|  | ||||
| #endif /* jis0201.h */ | ||||
							
								
								
									
										5012
									
								
								newlib/iconvdata/jis0208.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5012
									
								
								newlib/iconvdata/jis0208.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										108
									
								
								newlib/iconvdata/jis0208.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								newlib/iconvdata/jis0208.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| /* Access functions for JISX0208 conversion. | ||||
|    Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #ifndef _JIS0208_H | ||||
| #define _JIS0208_H	1 | ||||
|  | ||||
| #include <gconv.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| /* Conversion table.  */ | ||||
| extern const uint16_t __jis0208_to_ucs[]; | ||||
|  | ||||
| extern const char __jisx0208_from_ucs4_lat1[256][2]; | ||||
| extern const char __jisx0208_from_ucs4_greek[0xc1][2]; | ||||
| extern const struct jisx0208_ucs_idx __jisx0208_from_ucs_idx[]; | ||||
| extern const char __jisx0208_from_ucs_tab[][2]; | ||||
|  | ||||
|  | ||||
| /* Struct for table with indeces in UCS mapping table.  */ | ||||
| struct jisx0208_ucs_idx | ||||
| { | ||||
|   uint16_t start; | ||||
|   uint16_t end; | ||||
|   uint16_t idx; | ||||
| }; | ||||
|  | ||||
|  | ||||
| static inline uint32_t | ||||
| jisx0208_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset) | ||||
| { | ||||
|   unsigned char ch = *(*s); | ||||
|   unsigned char ch2; | ||||
|   int idx; | ||||
|  | ||||
|   if (ch < offset || (ch - offset) <= 0x20) | ||||
|     return __UNKNOWN_10646_CHAR; | ||||
|  | ||||
|   if (avail < 2) | ||||
|     return 0; | ||||
|  | ||||
|   ch2 = (*s)[1]; | ||||
|   if (ch2 < offset || (ch2 - offset) <= 0x20 || (ch2 - offset) >= 0x7f) | ||||
|     return __UNKNOWN_10646_CHAR; | ||||
|  | ||||
|   idx = (ch - 0x21 - offset) * 94 + (ch2 - 0x21 - offset); | ||||
|   if (idx >= 0x1e80) | ||||
|     return __UNKNOWN_10646_CHAR; | ||||
|  | ||||
|   (*s) += 2; | ||||
|  | ||||
|   return __jis0208_to_ucs[idx] ?: ((*s) -= 2, __UNKNOWN_10646_CHAR); | ||||
| } | ||||
|  | ||||
|  | ||||
| static inline size_t | ||||
| ucs4_to_jisx0208 (uint32_t wch, char *s, size_t avail) | ||||
| { | ||||
|   unsigned int ch = (unsigned int) wch; | ||||
|   const char *cp; | ||||
|  | ||||
|   if (avail < 2) | ||||
|     return 0; | ||||
|  | ||||
|   if (ch < 0x100) | ||||
|     cp = __jisx0208_from_ucs4_lat1[ch]; | ||||
|   else if (ch >= 0x391 && ch <= 0x451) | ||||
|     cp = __jisx0208_from_ucs4_greek[ch - 0x391]; | ||||
|   else | ||||
|     { | ||||
|       const struct jisx0208_ucs_idx *rp = __jisx0208_from_ucs_idx; | ||||
|  | ||||
|       if (ch >= 0xffff) | ||||
| 	return __UNKNOWN_10646_CHAR; | ||||
|       while (ch > rp->end) | ||||
| 	++rp; | ||||
|       if (ch >= rp->start) | ||||
| 	cp = __jisx0208_from_ucs_tab[rp->idx + ch - rp->start]; | ||||
|       else | ||||
| 	return __UNKNOWN_10646_CHAR; | ||||
|     } | ||||
|  | ||||
|   if (cp[0] == '\0') | ||||
|     return __UNKNOWN_10646_CHAR; | ||||
|  | ||||
|   s[0] = cp[0]; | ||||
|   s[1] = cp[1]; | ||||
|  | ||||
|   return 2; | ||||
| } | ||||
|  | ||||
| #endif /* jis0208.h */ | ||||
							
								
								
									
										3940
									
								
								newlib/iconvdata/jis0212.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3940
									
								
								newlib/iconvdata/jis0212.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										110
									
								
								newlib/iconvdata/jis0212.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								newlib/iconvdata/jis0212.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | ||||
| /* Access functions for JISX0212 conversion. | ||||
|    Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #ifndef _JIS0212_H | ||||
| #define _JIS0212_H	1 | ||||
|  | ||||
| #include <gconv.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
|  | ||||
| /* Struct for table with indeces in mapping table.  */ | ||||
| struct jisx0212_idx | ||||
| { | ||||
|   uint16_t start; | ||||
|   uint16_t end; | ||||
|   uint16_t idx; | ||||
| }; | ||||
|  | ||||
| /* Conversion table.  */ | ||||
| extern const struct jisx0212_idx __jisx0212_to_ucs_idx[]; | ||||
| extern const uint16_t __jisx0212_to_ucs[]; | ||||
|  | ||||
| extern const struct jisx0212_idx __jisx0212_from_ucs_idx[]; | ||||
| extern const char __jisx0212_from_ucs[][2]; | ||||
|  | ||||
|  | ||||
| static inline uint32_t | ||||
| jisx0212_to_ucs4 (const unsigned char **s, size_t avail, unsigned char offset) | ||||
| { | ||||
|   const struct jisx0212_idx *rp = __jisx0212_to_ucs_idx; | ||||
|   unsigned char ch = *(*s); | ||||
|   unsigned char ch2; | ||||
|   uint32_t wch = 0; | ||||
|   int idx; | ||||
|  | ||||
|   if (ch < offset || (ch - offset) < 0x22 || (ch - offset) > 0x6d) | ||||
|     return __UNKNOWN_10646_CHAR; | ||||
|  | ||||
|   if (avail < 2) | ||||
|     return 0; | ||||
|  | ||||
|   ch2 = (*s)[1]; | ||||
|   if (ch2 < offset || (ch2 - offset) <= 0x20 || (ch2 - offset) >= 0x7f) | ||||
|     return __UNKNOWN_10646_CHAR; | ||||
|  | ||||
|   idx = (ch - offset - 0x21) * 94 + (ch2 - offset - 0x21); | ||||
|  | ||||
|   while (idx > rp->end) | ||||
|     ++rp; | ||||
|   if (idx >= rp->start) | ||||
|     wch = __jisx0212_to_ucs[rp->idx + idx - rp->start]; | ||||
|  | ||||
|   if (wch != L'\0') | ||||
|     (*s) += 2; | ||||
|   else | ||||
|     wch = __UNKNOWN_10646_CHAR; | ||||
|  | ||||
|   return wch; | ||||
| } | ||||
|  | ||||
|  | ||||
| static inline size_t | ||||
| ucs4_to_jisx0212 (uint32_t wch, char *s, size_t avail) | ||||
| { | ||||
|   const struct jisx0212_idx *rp = __jisx0212_from_ucs_idx; | ||||
|   unsigned int ch = (unsigned int) wch; | ||||
|   const char *cp; | ||||
|  | ||||
|   if (ch >= 0xffff) | ||||
|     return __UNKNOWN_10646_CHAR; | ||||
|   while (ch > rp->end) | ||||
|     ++rp; | ||||
|   if (ch >= rp->start) | ||||
|     cp = __jisx0212_from_ucs[rp->idx + ch - rp->start]; | ||||
|   else | ||||
|     return __UNKNOWN_10646_CHAR; | ||||
|  | ||||
|   if (cp[0] == '\0') | ||||
|     return __UNKNOWN_10646_CHAR; | ||||
|  | ||||
|   s[0] = cp[0]; | ||||
|   if (cp[1] != '\0') | ||||
|     { | ||||
|       if (avail < 2) | ||||
| 	return 0; | ||||
|  | ||||
|       s[1] = cp[1]; | ||||
|     } | ||||
|  | ||||
|   return 2; | ||||
| } | ||||
|  | ||||
| #endif /* jis0212.h */ | ||||
							
								
								
									
										4512
									
								
								newlib/iconvdata/sjis.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4512
									
								
								newlib/iconvdata/sjis.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,7 +1,10 @@ | ||||
| #ifndef __ERRNO_H__ | ||||
| #define __ERRNO_H__ | ||||
|  | ||||
| #ifndef __error_t_defined | ||||
| typedef int error_t; | ||||
| #define __error_t_defined 1 | ||||
| #endif | ||||
|  | ||||
| #include <sys/errno.h> | ||||
|  | ||||
|   | ||||
| @@ -169,6 +169,8 @@ liblinux_la_LDFLAGS = -Xcompiler -nostdlib | ||||
|  | ||||
| ADD_OBJS = \ | ||||
| 	malloc.$(oext) \ | ||||
| 	gethostid.$(oext) \ | ||||
| 	sethostid.$(oext) \ | ||||
| 	$(LINUX_MACH_LIB) | ||||
|  | ||||
| if USE_LIBTOOL | ||||
|   | ||||
| @@ -257,6 +257,8 @@ liblinux_la_LDFLAGS = -Xcompiler -nostdlib | ||||
|  | ||||
| ADD_OBJS = \ | ||||
| 	malloc.$(oext) \ | ||||
| 	gethostid.$(oext) \ | ||||
| 	sethostid.$(oext) \ | ||||
| 	$(LINUX_MACH_LIB) | ||||
|  | ||||
|  | ||||
|   | ||||
							
								
								
									
										15
									
								
								newlib/libc/sys/linux/configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								newlib/libc/sys/linux/configure
									
									
									
									
										vendored
									
									
								
							| @@ -3043,6 +3043,17 @@ fi | ||||
| EXTRA_SUBDIRS= | ||||
| EXTRA_SUBLIBS= | ||||
|  | ||||
| if test "${newlib_multithread}" = "yes"; then | ||||
| EXTRA_CONFIG_DIRS=linuxthreads | ||||
| fi | ||||
| if test "x${newlib_elix_level}" = "x1"; then | ||||
| EXTRA_SUBDIRS=linuxthreads net | ||||
| else  | ||||
| EXTRA_SUBDIRS="linuxthreads net intl stdlib iconv dl" | ||||
| EXTRA_SUBLIBS="net/libnet.la intl/libintl.la stdlib/libstdlib.la iconv/libiconv.la dl/libdl.la" | ||||
| fi | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| subdirs="machine $EXTRA_CONFIG_DIRS" | ||||
| @@ -3161,7 +3172,7 @@ done | ||||
| ac_given_srcdir=$srcdir | ||||
| ac_given_INSTALL="$INSTALL" | ||||
|  | ||||
| trap 'rm -fr `echo "Makefile cmath/Makefile argp/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 | ||||
| trap 'rm -fr `echo "Makefile intl/Makefile net/Makefile stdlib/Makefile iconv/Makefile dl/Makefile cmath/Makefile argp/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 | ||||
| EOF | ||||
| cat >> $CONFIG_STATUS <<EOF | ||||
|  | ||||
| @@ -3300,7 +3311,7 @@ EOF | ||||
|  | ||||
| cat >> $CONFIG_STATUS <<EOF | ||||
|  | ||||
| CONFIG_FILES=\${CONFIG_FILES-"Makefile cmath/Makefile argp/Makefile"} | ||||
| CONFIG_FILES=\${CONFIG_FILES-"Makefile intl/Makefile net/Makefile stdlib/Makefile iconv/Makefile dl/Makefile cmath/Makefile argp/Makefile"} | ||||
| EOF | ||||
| cat >> $CONFIG_STATUS <<\EOF | ||||
| for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then | ||||
|   | ||||
| @@ -31,9 +31,20 @@ AC_SUBST(LINUX_MACH_LIB) | ||||
|  | ||||
| EXTRA_SUBDIRS= | ||||
| EXTRA_SUBLIBS= | ||||
|  | ||||
| if test "${newlib_multithread}" = "yes"; then | ||||
| EXTRA_CONFIG_DIRS=linuxthreads | ||||
| fi | ||||
| if test "x${newlib_elix_level}" = "x1"; then | ||||
| EXTRA_SUBDIRS=linuxthreads net | ||||
| else  | ||||
| EXTRA_SUBDIRS="linuxthreads net intl stdlib iconv dl" | ||||
| EXTRA_SUBLIBS="net/libnet.la intl/libintl.la stdlib/libstdlib.la iconv/libiconv.la dl/libdl.la" | ||||
| fi | ||||
|  | ||||
| AC_SUBST(EXTRA_SUBDIRS) | ||||
| AC_SUBST(EXTRA_SUBLIBS) | ||||
|  | ||||
| AC_CONFIG_SUBDIRS(machine $EXTRA_CONFIG_DIRS) | ||||
|  | ||||
| AC_OUTPUT(Makefile cmath/Makefile argp/Makefile) | ||||
| AC_OUTPUT(Makefile intl/Makefile net/Makefile stdlib/Makefile iconv/Makefile dl/Makefile cmath/Makefile argp/Makefile) | ||||
|   | ||||
							
								
								
									
										25
									
								
								newlib/libc/sys/linux/dl/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								newlib/libc/sys/linux/dl/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| ## Process this file with automake to generate Makefile.in | ||||
|  | ||||
| AUTOMAKE_OPTIONS = cygnus | ||||
|  | ||||
| INCLUDES = -DSHARED -D_GNU_SOURCE $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) -I$(srcdir)/.. | ||||
|  | ||||
| LIB_SOURCES = \ | ||||
| 	dl-addr.c   dl-deps.c   dl-init.c         dl-load.c     dl-misc.c    dl-profile.c   dl-runtime.c  dl-version.c \ | ||||
| 	dl-close.c  dl-error.c  dl-iteratephdr.c  dl-lookup.c   dl-object.c  dl-profstub.c  dl-support.c \ | ||||
| 	dl-debug.c  dl-fini.c   dl-libc.c         dl-open.c    dl-reloc.c     dl-sym.c   dl-cache.c | ||||
|  | ||||
| AM_CFLAGS = -D_GNU_SOURCE -D__strerror_r=strerror_r | ||||
| libdl_la_LDFLAGS = -Xcompiler -nostdlib | ||||
|  | ||||
| if USE_LIBTOOL | ||||
| noinst_LTLIBRARIES = libdl.la | ||||
| libdl_la_SOURCES = $(LIB_SOURCES) | ||||
| noinst_DATA = objectlist.awk.in | ||||
| else | ||||
| noinst_LIBRARIES = lib.a | ||||
| lib_a_SOURCES = $(LIB_SOURCES) | ||||
| noinst_DATA = | ||||
| endif # USE_LIBTOOL | ||||
|  | ||||
| include $(srcdir)/../../../../Makefile.shared | ||||
							
								
								
									
										379
									
								
								newlib/libc/sys/linux/dl/Makefile.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										379
									
								
								newlib/libc/sys/linux/dl/Makefile.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,379 @@ | ||||
| # Makefile.in generated automatically by automake 1.4 from Makefile.am | ||||
|  | ||||
| # Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. | ||||
| # This Makefile.in is free software; the Free Software Foundation | ||||
| # gives unlimited permission to copy and/or distribute it, | ||||
| # with or without modifications, as long as this notice is preserved. | ||||
|  | ||||
| # This program is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY, to the extent permitted by law; without | ||||
| # even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||||
| # PARTICULAR PURPOSE. | ||||
|  | ||||
|  | ||||
|  | ||||
| SHELL = @SHELL@ | ||||
|  | ||||
| srcdir = @srcdir@ | ||||
| top_srcdir = @top_srcdir@ | ||||
| VPATH = @srcdir@ | ||||
| prefix = @prefix@ | ||||
| exec_prefix = @exec_prefix@ | ||||
|  | ||||
| bindir = @bindir@ | ||||
| sbindir = @sbindir@ | ||||
| libexecdir = @libexecdir@ | ||||
| datadir = @datadir@ | ||||
| sysconfdir = @sysconfdir@ | ||||
| sharedstatedir = @sharedstatedir@ | ||||
| localstatedir = @localstatedir@ | ||||
| libdir = @libdir@ | ||||
| infodir = @infodir@ | ||||
| mandir = @mandir@ | ||||
| includedir = @includedir@ | ||||
| oldincludedir = /usr/include | ||||
|  | ||||
| DESTDIR = | ||||
|  | ||||
| pkgdatadir = $(datadir)/@PACKAGE@ | ||||
| pkglibdir = $(libdir)/@PACKAGE@ | ||||
| pkgincludedir = $(includedir)/@PACKAGE@ | ||||
|  | ||||
| top_builddir = .. | ||||
|  | ||||
| ACLOCAL = @ACLOCAL@ | ||||
| AUTOCONF = @AUTOCONF@ | ||||
| AUTOMAKE = @AUTOMAKE@ | ||||
| AUTOHEADER = @AUTOHEADER@ | ||||
|  | ||||
| INSTALL = @INSTALL@ | ||||
| INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) | ||||
| INSTALL_DATA = @INSTALL_DATA@ | ||||
| INSTALL_SCRIPT = @INSTALL_SCRIPT@ | ||||
| transform = @program_transform_name@ | ||||
|  | ||||
| NORMAL_INSTALL = : | ||||
| PRE_INSTALL = : | ||||
| POST_INSTALL = : | ||||
| NORMAL_UNINSTALL = : | ||||
| PRE_UNINSTALL = : | ||||
| POST_UNINSTALL = : | ||||
| build_alias = @build_alias@ | ||||
| build_triplet = @build@ | ||||
| host_alias = @host_alias@ | ||||
| host_triplet = @host@ | ||||
| target_alias = @target_alias@ | ||||
| target_triplet = @target@ | ||||
| AR = @AR@ | ||||
| AS = @AS@ | ||||
| AWK = @AWK@ | ||||
| CC = @CC@ | ||||
| CPP = @CPP@ | ||||
| CXX = @CXX@ | ||||
| CXXCPP = @CXXCPP@ | ||||
| DLLTOOL = @DLLTOOL@ | ||||
| EXEEXT = @EXEEXT@ | ||||
| GCJ = @GCJ@ | ||||
| GCJFLAGS = @GCJFLAGS@ | ||||
| LDFLAGS = @LDFLAGS@ | ||||
| LIBTOOL = @LIBTOOL@ | ||||
| LINUX_MACH_LIB = @LINUX_MACH_LIB@ | ||||
| LN_S = @LN_S@ | ||||
| MAINT = @MAINT@ | ||||
| MAKEINFO = @MAKEINFO@ | ||||
| NEWLIB_CFLAGS = @NEWLIB_CFLAGS@ | ||||
| OBJDUMP = @OBJDUMP@ | ||||
| OBJEXT = @OBJEXT@ | ||||
| PACKAGE = @PACKAGE@ | ||||
| RANLIB = @RANLIB@ | ||||
| STRIP = @STRIP@ | ||||
| VERSION = @VERSION@ | ||||
| aext = @aext@ | ||||
| libm_machine_dir = @libm_machine_dir@ | ||||
| machine_dir = @machine_dir@ | ||||
| newlib_basedir = @newlib_basedir@ | ||||
| oext = @oext@ | ||||
| sys_dir = @sys_dir@ | ||||
|  | ||||
| AUTOMAKE_OPTIONS = cygnus | ||||
|  | ||||
| INCLUDES = -DSHARED -D_GNU_SOURCE $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) -I$(srcdir)/.. | ||||
|  | ||||
| LIB_SOURCES = \ | ||||
| 	dl-addr.c   dl-deps.c   dl-init.c         dl-load.c     dl-misc.c    dl-profile.c   dl-runtime.c  dl-version.c \ | ||||
| 	dl-close.c  dl-error.c  dl-iteratephdr.c  dl-lookup.c   dl-object.c  dl-profstub.c  dl-support.c \ | ||||
| 	dl-debug.c  dl-fini.c   dl-libc.c         dl-open.c    dl-reloc.c     dl-sym.c   dl-cache.c | ||||
|  | ||||
|  | ||||
| AM_CFLAGS = -D_GNU_SOURCE -D__strerror_r=strerror_r | ||||
| libdl_la_LDFLAGS = -Xcompiler -nostdlib | ||||
|  | ||||
| @USE_LIBTOOL_TRUE@noinst_LTLIBRARIES = @USE_LIBTOOL_TRUE@libdl.la | ||||
| @USE_LIBTOOL_TRUE@libdl_la_SOURCES = @USE_LIBTOOL_TRUE@$(LIB_SOURCES) | ||||
| @USE_LIBTOOL_TRUE@noinst_DATA = @USE_LIBTOOL_TRUE@objectlist.awk.in | ||||
| @USE_LIBTOOL_FALSE@noinst_DATA =  | ||||
| @USE_LIBTOOL_FALSE@noinst_LIBRARIES = @USE_LIBTOOL_FALSE@lib.a | ||||
| @USE_LIBTOOL_FALSE@lib_a_SOURCES = @USE_LIBTOOL_FALSE@$(LIB_SOURCES) | ||||
| mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs | ||||
| CONFIG_CLEAN_FILES =  | ||||
| LIBRARIES =  $(noinst_LIBRARIES) | ||||
|  | ||||
|  | ||||
| DEFS = @DEFS@ -I. -I$(srcdir)  | ||||
| CPPFLAGS = @CPPFLAGS@ | ||||
| LIBS = @LIBS@ | ||||
| lib_a_LIBADD =  | ||||
| @USE_LIBTOOL_FALSE@lib_a_OBJECTS =  dl-addr.$(OBJEXT) dl-deps.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@dl-init.$(OBJEXT) dl-load.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@dl-misc.$(OBJEXT) dl-profile.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@dl-runtime.$(OBJEXT) dl-version.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@dl-close.$(OBJEXT) dl-error.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@dl-iteratephdr.$(OBJEXT) dl-lookup.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@dl-object.$(OBJEXT) dl-profstub.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@dl-support.$(OBJEXT) dl-debug.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@dl-fini.$(OBJEXT) dl-libc.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@dl-open.$(OBJEXT) dl-reloc.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@dl-sym.$(OBJEXT) dl-cache.$(OBJEXT) | ||||
| LTLIBRARIES =  $(noinst_LTLIBRARIES) | ||||
|  | ||||
| libdl_la_LIBADD =  | ||||
| @USE_LIBTOOL_TRUE@libdl_la_OBJECTS =  dl-addr.lo dl-deps.lo dl-init.lo \ | ||||
| @USE_LIBTOOL_TRUE@dl-load.lo dl-misc.lo dl-profile.lo dl-runtime.lo \ | ||||
| @USE_LIBTOOL_TRUE@dl-version.lo dl-close.lo dl-error.lo \ | ||||
| @USE_LIBTOOL_TRUE@dl-iteratephdr.lo dl-lookup.lo dl-object.lo \ | ||||
| @USE_LIBTOOL_TRUE@dl-profstub.lo dl-support.lo dl-debug.lo dl-fini.lo \ | ||||
| @USE_LIBTOOL_TRUE@dl-libc.lo dl-open.lo dl-reloc.lo dl-sym.lo \ | ||||
| @USE_LIBTOOL_TRUE@dl-cache.lo | ||||
| CFLAGS = @CFLAGS@ | ||||
| COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) | ||||
| LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) | ||||
| CCLD = $(CC) | ||||
| LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ | ||||
| DATA =  $(noinst_DATA) | ||||
|  | ||||
| DIST_COMMON =  Makefile.am Makefile.in | ||||
|  | ||||
|  | ||||
| DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) | ||||
|  | ||||
| TAR = gtar | ||||
| GZIP_ENV = --best | ||||
| SOURCES = $(lib_a_SOURCES) $(libdl_la_SOURCES) | ||||
| OBJECTS = $(lib_a_OBJECTS) $(libdl_la_OBJECTS) | ||||
|  | ||||
| all: all-redirect | ||||
| .SUFFIXES: | ||||
| .SUFFIXES: .S .c .lo .o .obj .s | ||||
| $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../../../Makefile.shared | ||||
| 	cd $(top_srcdir) && $(AUTOMAKE) --cygnus dl/Makefile | ||||
|  | ||||
| Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status | ||||
| 	cd $(top_builddir) \ | ||||
| 	  && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status | ||||
|  | ||||
|  | ||||
| mostlyclean-noinstLIBRARIES: | ||||
|  | ||||
| clean-noinstLIBRARIES: | ||||
| 	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) | ||||
|  | ||||
| distclean-noinstLIBRARIES: | ||||
|  | ||||
| maintainer-clean-noinstLIBRARIES: | ||||
|  | ||||
| .c.o: | ||||
| 	$(COMPILE) -c $< | ||||
|  | ||||
| # FIXME: We should only use cygpath when building on Windows, | ||||
| # and only if it is available. | ||||
| .c.obj: | ||||
| 	$(COMPILE) -c `cygpath -w $<` | ||||
|  | ||||
| .s.o: | ||||
| 	$(COMPILE) -c $< | ||||
|  | ||||
| .S.o: | ||||
| 	$(COMPILE) -c $< | ||||
|  | ||||
| mostlyclean-compile: | ||||
| 	-rm -f *.o core *.core | ||||
| 	-rm -f *.$(OBJEXT) | ||||
|  | ||||
| clean-compile: | ||||
|  | ||||
| distclean-compile: | ||||
| 	-rm -f *.tab.c | ||||
|  | ||||
| maintainer-clean-compile: | ||||
|  | ||||
| .c.lo: | ||||
| 	$(LIBTOOL) --mode=compile $(COMPILE) -c $< | ||||
|  | ||||
| .s.lo: | ||||
| 	$(LIBTOOL) --mode=compile $(COMPILE) -c $< | ||||
|  | ||||
| .S.lo: | ||||
| 	$(LIBTOOL) --mode=compile $(COMPILE) -c $< | ||||
|  | ||||
| mostlyclean-libtool: | ||||
| 	-rm -f *.lo | ||||
|  | ||||
| clean-libtool: | ||||
| 	-rm -rf .libs _libs | ||||
|  | ||||
| distclean-libtool: | ||||
|  | ||||
| maintainer-clean-libtool: | ||||
|  | ||||
| lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES) | ||||
| 	-rm -f lib.a | ||||
| 	$(AR) cru lib.a $(lib_a_OBJECTS) $(lib_a_LIBADD) | ||||
| 	$(RANLIB) lib.a | ||||
|  | ||||
| mostlyclean-noinstLTLIBRARIES: | ||||
|  | ||||
| clean-noinstLTLIBRARIES: | ||||
| 	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) | ||||
|  | ||||
| distclean-noinstLTLIBRARIES: | ||||
|  | ||||
| maintainer-clean-noinstLTLIBRARIES: | ||||
|  | ||||
| libdl.la: $(libdl_la_OBJECTS) $(libdl_la_DEPENDENCIES) | ||||
| 	$(LINK)  $(libdl_la_LDFLAGS) $(libdl_la_OBJECTS) $(libdl_la_LIBADD) $(LIBS) | ||||
|  | ||||
| tags: TAGS | ||||
|  | ||||
| ID: $(HEADERS) $(SOURCES) $(LISP) | ||||
| 	list='$(SOURCES) $(HEADERS)'; \ | ||||
| 	unique=`for i in $$list; do echo $$i; done | \ | ||||
| 	  awk '    { files[$$0] = 1; } \ | ||||
| 	       END { for (i in files) print i; }'`; \ | ||||
| 	here=`pwd` && cd $(srcdir) \ | ||||
| 	  && mkid -f$$here/ID $$unique $(LISP) | ||||
|  | ||||
| TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP) | ||||
| 	tags=; \ | ||||
| 	here=`pwd`; \ | ||||
| 	list='$(SOURCES) $(HEADERS)'; \ | ||||
| 	unique=`for i in $$list; do echo $$i; done | \ | ||||
| 	  awk '    { files[$$0] = 1; } \ | ||||
| 	       END { for (i in files) print i; }'`; \ | ||||
| 	test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ | ||||
| 	  || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS) | ||||
|  | ||||
| mostlyclean-tags: | ||||
|  | ||||
| clean-tags: | ||||
|  | ||||
| distclean-tags: | ||||
| 	-rm -f TAGS ID | ||||
|  | ||||
| maintainer-clean-tags: | ||||
|  | ||||
| distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) | ||||
|  | ||||
| subdir = dl | ||||
|  | ||||
| distdir: $(DISTFILES) | ||||
| 	@for file in $(DISTFILES); do \ | ||||
| 	  if test -f $$file; then d=.; else d=$(srcdir); fi; \ | ||||
| 	  if test -d $$d/$$file; then \ | ||||
| 	    cp -pr $$d/$$file $(distdir)/$$file; \ | ||||
| 	  else \ | ||||
| 	    test -f $(distdir)/$$file \ | ||||
| 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ | ||||
| 	    || cp -p $$d/$$file $(distdir)/$$file || :; \ | ||||
| 	  fi; \ | ||||
| 	done | ||||
| info-am: | ||||
| info: info-am | ||||
| dvi-am: | ||||
| dvi: dvi-am | ||||
| check-am: | ||||
| check: check-am | ||||
| installcheck-am: | ||||
| installcheck: installcheck-am | ||||
| install-info-am:  | ||||
| install-info: install-info-am | ||||
| install-exec-am: | ||||
| install-exec: install-exec-am | ||||
|  | ||||
| install-data-am: | ||||
| install-data: install-data-am | ||||
|  | ||||
| install-am: all-am | ||||
| 	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am | ||||
| install: install-am | ||||
| uninstall-am: | ||||
| uninstall: uninstall-am | ||||
| all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(DATA) | ||||
| all-redirect: all-am | ||||
| install-strip: | ||||
| 	$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install | ||||
| installdirs: | ||||
|  | ||||
|  | ||||
| mostlyclean-generic: | ||||
|  | ||||
| clean-generic: | ||||
|  | ||||
| distclean-generic: | ||||
| 	-rm -f Makefile $(CONFIG_CLEAN_FILES) | ||||
| 	-rm -f config.cache config.log stamp-h stamp-h[0-9]* | ||||
|  | ||||
| maintainer-clean-generic: | ||||
| mostlyclean-am:  mostlyclean-noinstLIBRARIES mostlyclean-compile \ | ||||
| 		mostlyclean-libtool mostlyclean-noinstLTLIBRARIES \ | ||||
| 		mostlyclean-tags mostlyclean-generic | ||||
|  | ||||
| mostlyclean: mostlyclean-am | ||||
|  | ||||
| clean-am:  clean-noinstLIBRARIES clean-compile clean-libtool \ | ||||
| 		clean-noinstLTLIBRARIES clean-tags clean-generic \ | ||||
| 		mostlyclean-am | ||||
|  | ||||
| clean: clean-am | ||||
|  | ||||
| distclean-am:  distclean-noinstLIBRARIES distclean-compile \ | ||||
| 		distclean-libtool distclean-noinstLTLIBRARIES \ | ||||
| 		distclean-tags distclean-generic clean-am | ||||
| 	-rm -f libtool | ||||
|  | ||||
| distclean: distclean-am | ||||
|  | ||||
| maintainer-clean-am:  maintainer-clean-noinstLIBRARIES \ | ||||
| 		maintainer-clean-compile maintainer-clean-libtool \ | ||||
| 		maintainer-clean-noinstLTLIBRARIES \ | ||||
| 		maintainer-clean-tags maintainer-clean-generic \ | ||||
| 		distclean-am | ||||
| 	@echo "This command is intended for maintainers to use;" | ||||
| 	@echo "it deletes files that may require special tools to rebuild." | ||||
|  | ||||
| maintainer-clean: maintainer-clean-am | ||||
|  | ||||
| .PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ | ||||
| clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ | ||||
| mostlyclean-compile distclean-compile clean-compile \ | ||||
| maintainer-clean-compile mostlyclean-libtool distclean-libtool \ | ||||
| clean-libtool maintainer-clean-libtool mostlyclean-noinstLTLIBRARIES \ | ||||
| distclean-noinstLTLIBRARIES clean-noinstLTLIBRARIES \ | ||||
| maintainer-clean-noinstLTLIBRARIES tags mostlyclean-tags distclean-tags \ | ||||
| clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ | ||||
| check-am installcheck-am installcheck install-info-am install-info \ | ||||
| install-exec-am install-exec install-data-am install-data install-am \ | ||||
| install uninstall-am uninstall all-redirect all-am all installdirs \ | ||||
| mostlyclean-generic distclean-generic clean-generic \ | ||||
| maintainer-clean-generic clean mostlyclean distclean maintainer-clean | ||||
|  | ||||
|  | ||||
| objectlist.awk.in: $(noinst_LTLIBRARIES) | ||||
| 	-rm -f objectlist.awk.in | ||||
| 	for i in `ls *.lo` ; \ | ||||
| 	do \ | ||||
| 	  echo $$i `pwd`/$$i >> objectlist.awk.in ; \ | ||||
| 	done | ||||
|  | ||||
| # Tell versions [3.59,3.63) of GNU make to not export all variables. | ||||
| # Otherwise a system limit (for SysV at least) may be exceeded. | ||||
| .NOEXPORT: | ||||
							
								
								
									
										4
									
								
								newlib/libc/sys/linux/dl/abi-tag.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								newlib/libc/sys/linux/dl/abi-tag.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| #define __ABI_TAG_OS 0 | ||||
| #ifndef __ABI_TAG_VERSION | ||||
| # define __ABI_TAG_VERSION 2,0,0 | ||||
| #endif | ||||
							
								
								
									
										56
									
								
								newlib/libc/sys/linux/dl/atomicity.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								newlib/libc/sys/linux/dl/atomicity.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| /* Low-level functions for atomic operations.  ix86 version, x >= 4. | ||||
|    Copyright (C) 1997, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #ifndef _ATOMICITY_H | ||||
| #define _ATOMICITY_H	1 | ||||
|  | ||||
|  | ||||
|  | ||||
| static inline uint32_t | ||||
| __attribute__ ((unused)) | ||||
| exchange_and_add (volatile uint32_t *mem, uint32_t val) | ||||
| { | ||||
|   register uint32_t result; | ||||
|   __asm__ __volatile__ ("lock; xaddl %0,%1" | ||||
| 			: "=r" (result), "=m" (*mem) : "0" (val), "1" (*mem)); | ||||
|   return result; | ||||
| } | ||||
|  | ||||
| static inline void | ||||
| __attribute__ ((unused)) | ||||
| atomic_add (volatile uint32_t *mem, int val) | ||||
| { | ||||
|   __asm__ __volatile__ ("lock; addl %1,%0" | ||||
| 			: "=m" (*mem) : "ir" (val), "0" (*mem)); | ||||
| } | ||||
|  | ||||
| static inline char | ||||
| __attribute__ ((unused)) | ||||
| compare_and_swap (volatile long int *p, long int oldval, long int newval) | ||||
| { | ||||
|   char ret; | ||||
|   long int readval; | ||||
|  | ||||
|   __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0" | ||||
|                         : "=q" (ret), "=m" (*p), "=a" (readval) | ||||
|                         : "r" (newval), "1" (*p), "a" (oldval)); | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| #endif /* atomicity.h */ | ||||
							
								
								
									
										101
									
								
								newlib/libc/sys/linux/dl/dl-addr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								newlib/libc/sys/linux/dl/dl-addr.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| /* Locate the shared object symbol nearest a given address. | ||||
|    Copyright (C) 1996-2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <dlfcn.h> | ||||
| #include <stddef.h> | ||||
| #include <ldsodefs.h> | ||||
|  | ||||
| int | ||||
| internal_function | ||||
| _dl_addr (const void *address, Dl_info *info) | ||||
| { | ||||
|   const ElfW(Addr) addr = DL_LOOKUP_ADDRESS (address); | ||||
|   struct link_map *l, *match; | ||||
|   const ElfW(Sym) *symtab, *matchsym; | ||||
|   const char *strtab; | ||||
|   ElfW(Word) strtabsize; | ||||
|  | ||||
|   /* Find the highest-addressed object that ADDRESS is not below.  */ | ||||
|   match = NULL; | ||||
|   for (l = _dl_loaded; l; l = l->l_next) | ||||
|     if (addr >= l->l_map_start && addr < l->l_map_end) | ||||
|       { | ||||
| 	/* We know ADDRESS lies within L if in any shared object. | ||||
| 	   Make sure it isn't past the end of L's segments.  */ | ||||
| 	size_t n = l->l_phnum; | ||||
| 	if (n > 0) | ||||
| 	  { | ||||
| 	    do | ||||
| 	      --n; | ||||
| 	    while (l->l_phdr[n].p_type != PT_LOAD); | ||||
| 	    if (addr >= (l->l_addr + | ||||
| 			 l->l_phdr[n].p_vaddr + l->l_phdr[n].p_memsz)) | ||||
| 	      /* Off the end of the highest-addressed shared object.  */ | ||||
| 	      continue; | ||||
| 	  } | ||||
|  | ||||
| 	match = l; | ||||
| 	break; | ||||
|       } | ||||
|  | ||||
|   if (match == NULL) | ||||
|     return 0; | ||||
|  | ||||
|   /* Now we know what object the address lies in.  */ | ||||
|   info->dli_fname = match->l_name; | ||||
|   info->dli_fbase = (void *) match->l_addr; | ||||
|  | ||||
|   /* If this is the main program the information is incomplete.  */ | ||||
|   if (__builtin_expect (info->dli_fbase == NULL, 0)) | ||||
|     { | ||||
|       info->dli_fname = _dl_argv[0]; | ||||
|       info->dli_fbase = (void *) match->l_map_start; | ||||
|     } | ||||
|  | ||||
|   symtab = (const void *) D_PTR (match, l_info[DT_SYMTAB]); | ||||
|   strtab = (const void *) D_PTR (match, l_info[DT_STRTAB]); | ||||
|   strtabsize = match->l_info[DT_STRSZ]->d_un.d_val; | ||||
|  | ||||
|   /* We assume that the string table follows the symbol table, because | ||||
|      there is no way in ELF to know the size of the dynamic symbol table!!  */ | ||||
|   for (matchsym = NULL; (void *) symtab < (void *) strtab; ++symtab) | ||||
|     if (addr >= match->l_addr + symtab->st_value | ||||
| 	&& ((symtab->st_size == 0 && addr == match->l_addr + symtab->st_value) | ||||
| 	    || addr < match->l_addr + symtab->st_value + symtab->st_size) | ||||
| 	&& symtab->st_name < strtabsize | ||||
| 	&& (matchsym == NULL || matchsym->st_value < symtab->st_value) | ||||
| 	&& (ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL | ||||
| 	    || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)) | ||||
|       matchsym = symtab; | ||||
|  | ||||
|   if (matchsym) | ||||
|     { | ||||
|       /* We found a symbol close by.  Fill in its name and exact address.  */ | ||||
|       info->dli_sname = strtab + matchsym->st_name; | ||||
|       info->dli_saddr = (void *) (match->l_addr + matchsym->st_value); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* No symbol matches.  We return only the containing object.  */ | ||||
|       info->dli_sname = NULL; | ||||
|       info->dli_saddr = NULL; | ||||
|     } | ||||
|  | ||||
|   return 1; | ||||
| } | ||||
							
								
								
									
										271
									
								
								newlib/libc/sys/linux/dl/dl-cache.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										271
									
								
								newlib/libc/sys/linux/dl/dl-cache.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,271 @@ | ||||
| /* Support for reading /etc/ld.so.cache files written by Linux ldconfig. | ||||
|    Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <unistd.h> | ||||
| #include <ldsodefs.h> | ||||
| #include <sys/mman.h> | ||||
| #include <dl-cache.h> | ||||
| #include <machine/dl-procinfo.h> | ||||
| #include <machine/weakalias.h> | ||||
|  | ||||
| extern const char *_dl_platform; | ||||
|  | ||||
| #ifndef _DL_PLATFORMS_COUNT | ||||
| # define _DL_PLATFORMS_COUNT 0 | ||||
| #endif | ||||
|  | ||||
| /* This is the starting address and the size of the mmap()ed file.  */ | ||||
| static struct cache_file *cache; | ||||
| static struct cache_file_new *cache_new; | ||||
| static size_t cachesize; | ||||
|  | ||||
| /* 1 if cache_data + PTR points into the cache.  */ | ||||
| #define _dl_cache_verify_ptr(ptr) (ptr < cache_data_size) | ||||
|  | ||||
| /* This is the cache ID we expect.  Normally it is 3 for glibc linked | ||||
|    binaries.  */ | ||||
| int _dl_correct_cache_id = _DL_CACHE_DEFAULT_ID; | ||||
|  | ||||
| #define SEARCH_CACHE(cache) \ | ||||
| /* We use binary search since the table is sorted in the cache file.	      \ | ||||
|    The first matching entry in the table is returned.			      \ | ||||
|    It is important to use the same algorithm as used while generating	      \ | ||||
|    the cache file.  */							      \ | ||||
| do									      \ | ||||
|   {									      \ | ||||
|     left = 0;								      \ | ||||
|     right = cache->nlibs - 1;						      \ | ||||
| 									      \ | ||||
|     while (left <= right)						      \ | ||||
|       {									      \ | ||||
| 	__typeof__ (cache->libs[0].key) key;				      \ | ||||
| 									      \ | ||||
| 	middle = (left + right) / 2;					      \ | ||||
| 									      \ | ||||
| 	key = cache->libs[middle].key;					      \ | ||||
| 									      \ | ||||
| 	/* Make sure string table indices are not bogus before using	      \ | ||||
| 	   them.  */							      \ | ||||
| 	if (! _dl_cache_verify_ptr (key))				      \ | ||||
| 	  {								      \ | ||||
| 	    cmpres = 1;							      \ | ||||
| 	    break;							      \ | ||||
| 	  }								      \ | ||||
| 									      \ | ||||
| 	/* Actually compare the entry with the key.  */			      \ | ||||
| 	cmpres = _dl_cache_libcmp (name, cache_data + key);		      \ | ||||
| 	if (__builtin_expect (cmpres == 0, 0))				      \ | ||||
| 	  {								      \ | ||||
| 	    /* Found it.  LEFT now marks the last entry for which we	      \ | ||||
| 	       know the name is correct.  */				      \ | ||||
| 	    left = middle;						      \ | ||||
| 									      \ | ||||
| 	    /* There might be entries with this name before the one we	      \ | ||||
| 	       found.  So we have to find the beginning.  */		      \ | ||||
| 	    while (middle > 0)						      \ | ||||
| 	      {								      \ | ||||
| 		__typeof__ (cache->libs[0].key) key;			      \ | ||||
| 									      \ | ||||
| 		key = cache->libs[middle - 1].key;			      \ | ||||
| 		/* Make sure string table indices are not bogus before	      \ | ||||
| 		   using them.  */					      \ | ||||
| 		if (! _dl_cache_verify_ptr (key)			      \ | ||||
| 		    /* Actually compare the entry.  */			      \ | ||||
| 		    || _dl_cache_libcmp (name, cache_data + key) != 0)	      \ | ||||
| 		  break;						      \ | ||||
| 		--middle;						      \ | ||||
| 	      }								      \ | ||||
| 									      \ | ||||
| 	    do								      \ | ||||
| 	      {								      \ | ||||
| 		int flags;						      \ | ||||
| 		__typeof__ (cache->libs[0]) *lib = &cache->libs[middle];      \ | ||||
| 									      \ | ||||
| 		/* Only perform the name test if necessary.  */		      \ | ||||
| 		if (middle > left					      \ | ||||
| 		    /* We haven't seen this string so far.  Test whether the  \ | ||||
| 		       index is ok and whether the name matches.  Otherwise   \ | ||||
| 		       we are done.  */					      \ | ||||
| 		    && (! _dl_cache_verify_ptr (lib->key)		      \ | ||||
| 			|| (_dl_cache_libcmp (name, cache_data + lib->key)    \ | ||||
| 			    != 0)))					      \ | ||||
| 		  break;						      \ | ||||
| 									      \ | ||||
| 		flags = lib->flags;					      \ | ||||
| 		if (_dl_cache_check_flags (flags)			      \ | ||||
| 		    && _dl_cache_verify_ptr (lib->value))		      \ | ||||
| 		  {							      \ | ||||
| 		    if (best == NULL || flags == _dl_correct_cache_id)	      \ | ||||
| 		      {							      \ | ||||
| 			HWCAP_CHECK;					      \ | ||||
| 			best = cache_data + lib->value;			      \ | ||||
| 									      \ | ||||
| 			if (flags == _dl_correct_cache_id)		      \ | ||||
| 			  /* We've found an exact match for the shared	      \ | ||||
| 			     object and no general `ELF' release.  Stop	      \ | ||||
| 			     searching.  */				      \ | ||||
| 			  break;					      \ | ||||
| 		      }							      \ | ||||
| 		  }							      \ | ||||
| 	      }								      \ | ||||
| 	    while (++middle <= right);					      \ | ||||
| 	    break;							      \ | ||||
| 	}								      \ | ||||
| 									      \ | ||||
| 	if (cmpres < 0)							      \ | ||||
| 	  left = middle + 1;						      \ | ||||
| 	else								      \ | ||||
| 	  right = middle - 1;						      \ | ||||
|       }									      \ | ||||
|   }									      \ | ||||
| while (0) | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Look up NAME in ld.so.cache and return the file name stored there, | ||||
|    or null if none is found.  */ | ||||
|  | ||||
| const char * | ||||
| internal_function | ||||
| _dl_load_cache_lookup (const char *name) | ||||
| { | ||||
|   int left, right, middle; | ||||
|   int cmpres; | ||||
|   const char *cache_data; | ||||
|   uint32_t cache_data_size; | ||||
|   const char *best; | ||||
|  | ||||
|   if (cache == NULL) | ||||
|     { | ||||
|       /* Read the contents of the file.  */ | ||||
|       void *file = _dl_sysdep_read_whole_file (LD_SO_CACHE, &cachesize, | ||||
| 					       PROT_READ); | ||||
|  | ||||
|       /* We can handle three different cache file formats here: | ||||
| 	 - the old libc5/glibc2.0/2.1 format | ||||
| 	 - the old format with the new format in it | ||||
| 	 - only the new format | ||||
| 	 The following checks if the cache contains any of these formats.  */ | ||||
|       if (file != MAP_FAILED && cachesize > sizeof *cache | ||||
| 	  && memcmp (file, CACHEMAGIC, sizeof CACHEMAGIC - 1) == 0) | ||||
| 	{ | ||||
| 	  size_t offset; | ||||
| 	  /* Looks ok.  */ | ||||
| 	  cache = file; | ||||
|  | ||||
| 	  /* Check for new version.  */ | ||||
| 	  offset = ALIGN_CACHE (sizeof (struct cache_file) | ||||
| 				+ cache->nlibs * sizeof (struct file_entry)); | ||||
|  | ||||
| 	  cache_new = (struct cache_file_new *) ((void *) cache + offset); | ||||
| 	  if (cachesize < (offset + sizeof (struct cache_file_new)) | ||||
| 	      || memcmp (cache_new->magic, CACHEMAGIC_VERSION_NEW, | ||||
| 			 sizeof CACHEMAGIC_VERSION_NEW - 1) != 0) | ||||
| 	    cache_new = (void *) -1; | ||||
| 	} | ||||
|       else if (file != MAP_FAILED && cachesize > sizeof *cache_new | ||||
| 	       && memcmp (file, CACHEMAGIC_VERSION_NEW, | ||||
| 			  sizeof CACHEMAGIC_VERSION_NEW - 1) == 0) | ||||
| 	{ | ||||
| 	  cache_new = file; | ||||
| 	  cache = file; | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  if (file != MAP_FAILED) | ||||
| 	    munmap (file, cachesize); | ||||
| 	  cache = (void *) -1; | ||||
| 	} | ||||
|  | ||||
|       assert (cache != NULL); | ||||
|     } | ||||
|  | ||||
|   if (cache == (void *) -1) | ||||
|     /* Previously looked for the cache file and didn't find it.  */ | ||||
|     return NULL; | ||||
|  | ||||
|   best = NULL; | ||||
|  | ||||
|   if (cache_new != (void *) -1) | ||||
|     { | ||||
|       /* This file ends in static libraries where we don't have a hwcap.  */ | ||||
|       unsigned long int *hwcap; | ||||
|       uint64_t platform; | ||||
|       weak_extern (_dl_hwcap); | ||||
|  | ||||
|       /* This is where the strings start.  */ | ||||
|       cache_data = (const char *) cache_new; | ||||
|  | ||||
|       /* Now we can compute how large the string table is.  */ | ||||
|       cache_data_size = (const char *) cache + cachesize - cache_data; | ||||
|  | ||||
|       hwcap = &_dl_hwcap; | ||||
|       platform = _dl_string_platform (_dl_platform); | ||||
|       if (platform != -1) | ||||
| 	platform = 1ULL << platform; | ||||
|  | ||||
|       /* Only accept hwcap if it's for the right platform.  */ | ||||
| #define HWCAP_CHECK \ | ||||
|       if (_dl_osversion	&& cache_new->libs[middle].osversion > _dl_osversion) \ | ||||
| 	continue;							      \ | ||||
|       if (_DL_PLATFORMS_COUNT && platform != -1				      \ | ||||
| 	  && (lib->hwcap & _DL_HWCAP_PLATFORM) != 0			      \ | ||||
| 	  && (lib->hwcap & _DL_HWCAP_PLATFORM) != platform)		      \ | ||||
| 	continue;							      \ | ||||
|       if (hwcap								      \ | ||||
| 	  && ((lib->hwcap & *hwcap & ~_DL_HWCAP_PLATFORM) > *hwcap))	      \ | ||||
| 	continue | ||||
|       SEARCH_CACHE (cache_new); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* This is where the strings start.  */ | ||||
|       cache_data = (const char *) &cache->libs[cache->nlibs]; | ||||
|  | ||||
|       /* Now we can compute how large the string table is.  */ | ||||
|       cache_data_size = (const char *) cache + cachesize - cache_data; | ||||
|  | ||||
| #undef HWCAP_CHECK | ||||
| #define HWCAP_CHECK do {} while (0) | ||||
|       SEARCH_CACHE (cache); | ||||
|     } | ||||
|  | ||||
|   /* Print our result if wanted.  */ | ||||
|   if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0) && best != NULL) | ||||
|     _dl_debug_printf ("  trying file=%s\n", best); | ||||
|  | ||||
|   return best; | ||||
| } | ||||
|  | ||||
| #ifndef MAP_COPY | ||||
| /* If the system does not support MAP_COPY we cannot leave the file open | ||||
|    all the time since this would create problems when the file is replaced. | ||||
|    Therefore we provide this function to close the file and open it again | ||||
|    once needed.  */ | ||||
| void | ||||
| _dl_unload_cache (void) | ||||
| { | ||||
|   if (cache != NULL && cache != (struct cache_file *) -1) | ||||
|     { | ||||
|       munmap (cache, cachesize); | ||||
|       cache = NULL; | ||||
|     } | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										140
									
								
								newlib/libc/sys/linux/dl/dl-cache.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								newlib/libc/sys/linux/dl/dl-cache.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,140 @@ | ||||
| /* Support for reading /etc/ld.so.cache files written by Linux ldconfig. | ||||
|    Copyright (C) 1999, 2000 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #ifndef _DL_CACHE_DEFAULT_ID | ||||
| # define _DL_CACHE_DEFAULT_ID	3 | ||||
| #endif | ||||
|  | ||||
| #ifndef _dl_cache_check_flags | ||||
| # define _dl_cache_check_flags(flags)			\ | ||||
|   ((flags) == 1 || (flags) == _DL_CACHE_DEFAULT_ID) | ||||
| #endif | ||||
|  | ||||
| #ifndef SYSCONFDIR | ||||
| # define SYSCONFDIR "/etc" | ||||
| #endif | ||||
|  | ||||
| #ifndef LD_SO_CACHE | ||||
| # define LD_SO_CACHE SYSCONFDIR "/ld.so.cache" | ||||
| #endif | ||||
|  | ||||
| #define CACHEMAGIC "ld.so-1.7.0" | ||||
|  | ||||
| /* libc5 and glibc 2.0/2.1 use the same format.  For glibc 2.2 another | ||||
|    format has been added in a compatible way: | ||||
|    The beginning of the string table is used for the new table: | ||||
| 	old_magic | ||||
| 	nlibs | ||||
| 	libs[0] | ||||
| 	... | ||||
| 	libs[nlibs-1] | ||||
| 	pad, new magic needs to be aligned | ||||
| 	     - this is string[0] for the old format | ||||
| 	new magic - this is string[0] for the new format | ||||
| 	newnlibs | ||||
| 	... | ||||
| 	newlibs[0] | ||||
| 	... | ||||
| 	newlibs[newnlibs-1] | ||||
| 	string 1 | ||||
| 	string 2 | ||||
| 	... | ||||
| */ | ||||
| struct file_entry | ||||
| { | ||||
|   int flags;		/* This is 1 for an ELF library.  */ | ||||
|   unsigned int key, value; /* String table indices.  */ | ||||
| }; | ||||
|  | ||||
| struct cache_file | ||||
| { | ||||
|   char magic[sizeof CACHEMAGIC - 1]; | ||||
|   unsigned int nlibs; | ||||
|   struct file_entry libs[0]; | ||||
| }; | ||||
|  | ||||
| #define CACHEMAGIC_NEW "glibc-ld.so.cache" | ||||
| #define CACHE_VERSION "1.1" | ||||
| #define CACHEMAGIC_VERSION_NEW CACHEMAGIC_NEW CACHE_VERSION | ||||
|  | ||||
|  | ||||
| struct file_entry_new | ||||
| { | ||||
|   int32_t flags;		/* This is 1 for an ELF library.  */ | ||||
|   uint32_t key, value;		/* String table indices.  */ | ||||
|   uint32_t osversion;		/* Required OS version.	 */ | ||||
|   uint64_t hwcap;		/* Hwcap entry.	 */ | ||||
| }; | ||||
|  | ||||
| struct cache_file_new | ||||
| { | ||||
|   char magic[sizeof CACHEMAGIC_NEW - 1]; | ||||
|   char version[sizeof CACHE_VERSION - 1]; | ||||
|   uint32_t nlibs;		/* Number of entries.  */ | ||||
|   uint32_t len_strings;		/* Size of string table. */ | ||||
|   uint32_t unused[5];		/* Leave space for future extensions | ||||
| 				   and align to 8 byte boundary.  */ | ||||
|   struct file_entry_new libs[0]; /* Entries describing libraries.  */ | ||||
|   /* After this the string table of size len_strings is found.	*/ | ||||
| }; | ||||
|  | ||||
| /* Used to align cache_file_new.  */ | ||||
| #define ALIGN_CACHE(addr)				\ | ||||
| (((addr) + __alignof__ (struct cache_file_new) -1)	\ | ||||
|  & (~(__alignof__ (struct cache_file_new) - 1))) | ||||
|  | ||||
| static int | ||||
| _dl_cache_libcmp (const char *p1, const char *p2) | ||||
| { | ||||
|   while (*p1 != '\0') | ||||
|     { | ||||
|       if (*p1 >= '0' && *p1 <= '9') | ||||
|         { | ||||
|           if (*p2 >= '0' && *p2 <= '9') | ||||
|             { | ||||
| 	      /* Must compare this numerically.  */ | ||||
| 	      int val1; | ||||
| 	      int val2; | ||||
|  | ||||
| 	      val1 = *p1++ - '0'; | ||||
| 	      val2 = *p2++ - '0'; | ||||
| 	      while (*p1 >= '0' && *p1 <= '9') | ||||
| 	        val1 = val1 * 10 + *p1++ - '0'; | ||||
| 	      while (*p2 >= '0' && *p2 <= '9') | ||||
| 	        val2 = val2 * 10 + *p2++ - '0'; | ||||
| 	      if (val1 != val2) | ||||
| 		return val1 - val2; | ||||
| 	    } | ||||
| 	  else | ||||
|             return 1; | ||||
|         } | ||||
|       else if (*p2 >= '0' && *p2 <= '9') | ||||
|         return -1; | ||||
|       else if (*p1 != *p2) | ||||
|         return *p1 - *p2; | ||||
|       else | ||||
| 	{ | ||||
| 	  ++p1; | ||||
| 	  ++p2; | ||||
| 	} | ||||
|     } | ||||
|   return *p1 - *p2; | ||||
| } | ||||
							
								
								
									
										334
									
								
								newlib/libc/sys/linux/dl/dl-close.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										334
									
								
								newlib/libc/sys/linux/dl/dl-close.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,334 @@ | ||||
| /* Close a shared object opened by `_dl_open'. | ||||
|    Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <dlfcn.h> | ||||
| #include <libintl.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <bits/libc-lock.h> | ||||
| #include <ldsodefs.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/mman.h> | ||||
|  | ||||
|  | ||||
| /* Type of the constructor functions.  */ | ||||
| typedef void (*fini_t) (void); | ||||
|  | ||||
|  | ||||
| void | ||||
| internal_function | ||||
| _dl_close (void *_map) | ||||
| { | ||||
|   struct reldep_list | ||||
|   { | ||||
|     struct link_map **rellist; | ||||
|     unsigned int nrellist; | ||||
|     struct reldep_list *next; | ||||
|   } *reldeps = NULL; | ||||
|   struct link_map **list; | ||||
|   struct link_map *map = _map; | ||||
|   unsigned int i; | ||||
|   unsigned int *new_opencount; | ||||
|  | ||||
|   /* First see whether we can remove the object at all.  */ | ||||
|   if (__builtin_expect (map->l_flags_1 & DF_1_NODELETE, 0) | ||||
|       && map->l_init_called) | ||||
|     /* Nope.  Do nothing.  */ | ||||
|     return; | ||||
|  | ||||
|   if (__builtin_expect (map->l_opencount, 1) == 0) | ||||
|     _dl_signal_error (0, map->l_name, NULL, N_("shared object not open")); | ||||
|  | ||||
|   /* Acquire the lock.  */ | ||||
| #ifdef HAVE_DD_LOCK | ||||
|     __lock_acquire(_dl_load_lock); | ||||
| #endif | ||||
|  | ||||
|  | ||||
|   /* Decrement the reference count.  */ | ||||
|   if (map->l_opencount > 1 || map->l_type != lt_loaded) | ||||
|     { | ||||
|       /* There are still references to this object.  Do nothing more.  */ | ||||
|       if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) | ||||
| 	_dl_debug_printf ("\nclosing file=%s; opencount == %u\n", | ||||
| 			  map->l_name, map->l_opencount); | ||||
|  | ||||
|       /* One decrement the object itself, not the dependencies.  */ | ||||
|       --map->l_opencount; | ||||
|  | ||||
| #ifdef HAVE_DD_LOCK | ||||
|         __lock_release(_dl_load_lock); | ||||
| #endif | ||||
|  | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   list = map->l_initfini; | ||||
|  | ||||
|   /* Compute the new l_opencount values.  */ | ||||
|   i = map->l_searchlist.r_nlist; | ||||
|   if (__builtin_expect (i == 0, 0)) | ||||
|     /* This can happen if we handle relocation dependencies for an | ||||
|        object which wasn't loaded directly.  */ | ||||
|     for (i = 1; list[i] != NULL; ++i) | ||||
|       ; | ||||
|  | ||||
|   new_opencount = (unsigned int *) alloca (i * sizeof (unsigned int)); | ||||
|  | ||||
|   for (i = 0; list[i] != NULL; ++i) | ||||
|     { | ||||
|       list[i]->l_idx = i; | ||||
|       new_opencount[i] = list[i]->l_opencount; | ||||
|     } | ||||
|   --new_opencount[0]; | ||||
|   for (i = 1; list[i] != NULL; ++i) | ||||
|     if ((! (list[i]->l_flags_1 & DF_1_NODELETE) || ! list[i]->l_init_called) | ||||
| 	/* Decrement counter.  */ | ||||
| 	&& --new_opencount[i] == 0 | ||||
| 	/* Test whether this object was also loaded directly.  */ | ||||
| 	&& list[i]->l_searchlist.r_list != NULL) | ||||
|       { | ||||
| 	/* In this case we have the decrement all the dependencies of | ||||
|            this object.  They are all in MAP's dependency list.  */ | ||||
| 	unsigned int j; | ||||
| 	struct link_map **dep_list = list[i]->l_searchlist.r_list; | ||||
|  | ||||
| 	for (j = 1; j < list[i]->l_searchlist.r_nlist; ++j) | ||||
| 	  if (! (dep_list[j]->l_flags_1 & DF_1_NODELETE) | ||||
| 	      || ! dep_list[j]->l_init_called) | ||||
| 	    { | ||||
| 	      assert (dep_list[j]->l_idx < map->l_searchlist.r_nlist); | ||||
| 	      --new_opencount[dep_list[j]->l_idx]; | ||||
| 	    } | ||||
|       } | ||||
|   assert (new_opencount[0] == 0); | ||||
|  | ||||
|   /* Call all termination functions at once.  */ | ||||
|   for (i = 0; list[i] != NULL; ++i) | ||||
|     { | ||||
|       struct link_map *imap = list[i]; | ||||
|       if (new_opencount[i] == 0 && imap->l_type == lt_loaded | ||||
| 	  && (imap->l_info[DT_FINI] || imap->l_info[DT_FINI_ARRAY]) | ||||
| 	  && (! (imap->l_flags_1 & DF_1_NODELETE) || ! imap->l_init_called) | ||||
| 	  /* Skip any half-cooked objects that were never initialized.  */ | ||||
| 	  && imap->l_init_called) | ||||
| 	{ | ||||
| 	  /* When debugging print a message first.  */ | ||||
| 	  if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) | ||||
| 	    _dl_debug_printf ("\ncalling fini: %s\n\n", imap->l_name); | ||||
|  | ||||
| 	  /* Call its termination function.  */ | ||||
| 	  if (imap->l_info[DT_FINI_ARRAY] != NULL) | ||||
| 	    { | ||||
| 	      ElfW(Addr) *array = | ||||
| 		(ElfW(Addr) *) (imap->l_addr | ||||
| 				+ imap->l_info[DT_FINI_ARRAY]->d_un.d_ptr); | ||||
| 	      unsigned int sz = (imap->l_info[DT_FINI_ARRAYSZ]->d_un.d_val | ||||
| 				 / sizeof (ElfW(Addr))); | ||||
| 	      unsigned int cnt; | ||||
|  | ||||
| 	      for (cnt = 0; cnt < sz; ++cnt) | ||||
| 		((fini_t) (imap->l_addr + array[cnt])) (); | ||||
| 	    } | ||||
|  | ||||
| 	  /* Next try the old-style destructor.  */ | ||||
| 	  if (imap->l_info[DT_FINI] != NULL) | ||||
| 	    (*(void (*) (void)) DL_DT_FINI_ADDRESS | ||||
| 	      (imap, (void *) imap->l_addr | ||||
| 		     + imap->l_info[DT_FINI]->d_un.d_ptr)) (); | ||||
| 	} | ||||
|       else if (new_opencount[i] != 0 && imap->l_type == lt_loaded) | ||||
| 	{ | ||||
| 	  /* The object is still used.  But the object we are unloading | ||||
| 	     right now is responsible for loading it and therefore we | ||||
| 	     have the search list of the current object in its scope. | ||||
| 	     Remove it.  */ | ||||
| 	  struct r_scope_elem **runp = imap->l_scope; | ||||
|  | ||||
| 	  while (*runp != NULL) | ||||
| 	    if (*runp == &map->l_searchlist) | ||||
| 	      { | ||||
| 		/* Copy all later elements.  */ | ||||
| 		while ((runp[0] = runp[1]) != NULL) | ||||
| 		  ++runp; | ||||
| 		break; | ||||
| 	      } | ||||
| 	  else | ||||
| 	    ++runp; | ||||
| 	} | ||||
|  | ||||
|       /* Store the new l_opencount value.  */ | ||||
|       imap->l_opencount = new_opencount[i]; | ||||
|       /* Just a sanity check.  */ | ||||
|       assert (imap->l_type == lt_loaded || imap->l_opencount > 0); | ||||
|     } | ||||
|  | ||||
|   /* Notify the debugger we are about to remove some loaded objects.  */ | ||||
|   _r_debug.r_state = RT_DELETE; | ||||
|   _dl_debug_state (); | ||||
|  | ||||
|   /* Check each element of the search list to see if all references to | ||||
|      it are gone.  */ | ||||
|   for (i = 0; list[i] != NULL; ++i) | ||||
|     { | ||||
|       struct link_map *imap = list[i]; | ||||
|       if (imap->l_opencount == 0 && imap->l_type == lt_loaded) | ||||
| 	{ | ||||
| 	  struct libname_list *lnp; | ||||
|  | ||||
| 	  /* That was the last reference, and this was a dlopen-loaded | ||||
| 	     object.  We can unmap it.  */ | ||||
| 	  if (__builtin_expect (imap->l_global, 0)) | ||||
| 	    { | ||||
| 	      /* This object is in the global scope list.  Remove it.  */ | ||||
| 	      unsigned int cnt = _dl_main_searchlist->r_nlist; | ||||
|  | ||||
| 	      do | ||||
| 		--cnt; | ||||
| 	      while (_dl_main_searchlist->r_list[cnt] != imap); | ||||
|  | ||||
| 	      /* The object was already correctly registered.  */ | ||||
| 	      while (++cnt < _dl_main_searchlist->r_nlist) | ||||
| 		_dl_main_searchlist->r_list[cnt - 1] | ||||
| 		  = _dl_main_searchlist->r_list[cnt]; | ||||
|  | ||||
| 	      --_dl_main_searchlist->r_nlist; | ||||
| 	    } | ||||
|  | ||||
| 	  /* We can unmap all the maps at once.  We determined the | ||||
| 	     start address and length when we loaded the object and | ||||
| 	     the `munmap' call does the rest.  */ | ||||
| 	  DL_UNMAP (imap); | ||||
|  | ||||
| 	  /* Finally, unlink the data structure and free it.  */ | ||||
| #ifdef SHARED | ||||
| 	  /* We will unlink the first object only if this is a statically | ||||
| 	     linked program.  */ | ||||
| 	  assert (imap->l_prev != NULL); | ||||
| 	  imap->l_prev->l_next = imap->l_next; | ||||
| #else | ||||
| 	  if (imap->l_prev != NULL) | ||||
| 	    imap->l_prev->l_next = imap->l_next; | ||||
| 	  else | ||||
| 	    _dl_loaded = imap->l_next; | ||||
| #endif | ||||
| 	  --_dl_nloaded; | ||||
| 	  if (imap->l_next) | ||||
| 	    imap->l_next->l_prev = imap->l_prev; | ||||
|  | ||||
| 	  if (imap->l_versions != NULL) | ||||
| 	    free (imap->l_versions); | ||||
| 	  if (imap->l_origin != NULL && imap->l_origin != (char *) -1) | ||||
| 	    free ((char *) imap->l_origin); | ||||
|  | ||||
| 	  /* If the object has relocation dependencies save this | ||||
|              information for latter.  */ | ||||
| 	  if (__builtin_expect (imap->l_reldeps != NULL, 0)) | ||||
| 	    { | ||||
| 	      struct reldep_list *newrel; | ||||
|  | ||||
| 	      newrel = (struct reldep_list *) alloca (sizeof (*reldeps)); | ||||
| 	      newrel->rellist = imap->l_reldeps; | ||||
| 	      newrel->nrellist = imap->l_reldepsact; | ||||
| 	      newrel->next = reldeps; | ||||
|  | ||||
| 	      reldeps = newrel; | ||||
| 	    } | ||||
|  | ||||
| 	  /* This name always is allocated.  */ | ||||
| 	  free (imap->l_name); | ||||
| 	  /* Remove the list with all the names of the shared object.  */ | ||||
| 	  lnp = imap->l_libname; | ||||
| 	  do | ||||
| 	    { | ||||
| 	      struct libname_list *this = lnp; | ||||
| 	      lnp = lnp->next; | ||||
| 	      if (!this->dont_free) | ||||
| 		free (this); | ||||
| 	    } | ||||
| 	  while (lnp != NULL); | ||||
|  | ||||
| 	  /* Remove the searchlists.  */ | ||||
| 	  if (imap != map) | ||||
| 	      free (imap->l_initfini); | ||||
|  | ||||
| 	  /* Remove the scope array if we allocated it.  */ | ||||
| 	  if (imap->l_scope != imap->l_scope_mem) | ||||
| 	    free (imap->l_scope); | ||||
|  | ||||
| 	  if (imap->l_phdr_allocated) | ||||
| 	    free ((void *) imap->l_phdr); | ||||
|  | ||||
| 	  if (imap->l_rpath_dirs.dirs != (void *) -1) | ||||
| 	    free (imap->l_rpath_dirs.dirs); | ||||
| 	  if (imap->l_runpath_dirs.dirs != (void *) -1) | ||||
| 	    free (imap->l_runpath_dirs.dirs); | ||||
|  | ||||
| 	  free (imap); | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   /* Notify the debugger those objects are finalized and gone.  */ | ||||
|   _r_debug.r_state = RT_CONSISTENT; | ||||
|   _dl_debug_state (); | ||||
|  | ||||
|   /* Now we can perhaps also remove the modules for which we had | ||||
|      dependencies because of symbol lookup.  */ | ||||
|   while (__builtin_expect (reldeps != NULL, 0)) | ||||
|     { | ||||
|       while (reldeps->nrellist-- > 0) | ||||
| 	_dl_close (reldeps->rellist[reldeps->nrellist]); | ||||
|  | ||||
|       free (reldeps->rellist); | ||||
|  | ||||
|       reldeps = reldeps->next; | ||||
|     } | ||||
|  | ||||
|   free (list); | ||||
|  | ||||
|   /* Release the lock.  */ | ||||
| #ifdef HAVE_DD_LOCK | ||||
|     __lock_release(_dl_load_lock); | ||||
| #endif | ||||
|  | ||||
|    | ||||
| } | ||||
|  | ||||
|  | ||||
| static void | ||||
| free_mem (void) | ||||
| { | ||||
|   if (__builtin_expect (_dl_global_scope_alloc, 0) != 0 | ||||
|       && _dl_main_searchlist->r_nlist == _dl_initial_searchlist.r_nlist) | ||||
|     { | ||||
|       /* All object dynamically loaded by the program are unloaded.  Free | ||||
| 	 the memory allocated for the global scope variable.  */ | ||||
|       struct link_map **old = _dl_main_searchlist->r_list; | ||||
|  | ||||
|       /* Put the old map in.  */ | ||||
|       _dl_main_searchlist->r_list = _dl_initial_searchlist.r_list; | ||||
|       /* Signal that the original map is used.  */ | ||||
|       _dl_global_scope_alloc = 0; | ||||
|  | ||||
|       /* Now free the old map.  */ | ||||
|       free (old); | ||||
|     } | ||||
| } | ||||
| text_set_element (__libc_subfreeres, free_mem); | ||||
							
								
								
									
										57
									
								
								newlib/libc/sys/linux/dl/dl-debug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								newlib/libc/sys/linux/dl/dl-debug.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| /* Communicate dynamic linker state to the debugger at runtime. | ||||
|    Copyright (C) 1996, 1998, 2000 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <ldsodefs.h> | ||||
|  | ||||
| /* This structure communicates dl state to the debugger.  The debugger | ||||
|    normally finds it via the DT_DEBUG entry in the dynamic section, but in | ||||
|    a statically-linked program there is no dynamic section for the debugger | ||||
|    to examine and it looks for this particular symbol name.  */ | ||||
| struct r_debug _r_debug; | ||||
|  | ||||
|  | ||||
| /* Initialize _r_debug if it has not already been done.  The argument is | ||||
|    the run-time load address of the dynamic linker, to be put in | ||||
|    _r_debug.r_ldbase.  Returns the address of _r_debug.  */ | ||||
|  | ||||
| struct r_debug * | ||||
| internal_function | ||||
| _dl_debug_initialize (ElfW(Addr) ldbase) | ||||
| { | ||||
|   if (_r_debug.r_brk == 0) | ||||
|     { | ||||
|       /* Tell the debugger where to find the map of loaded objects.  */ | ||||
|       _r_debug.r_version = 1	/* R_DEBUG_VERSION XXX */; | ||||
|       _r_debug.r_ldbase = ldbase; | ||||
|       _r_debug.r_map = _dl_loaded; | ||||
|       _r_debug.r_brk = (ElfW(Addr)) &_dl_debug_state; | ||||
|     } | ||||
|  | ||||
|   return &_r_debug; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* This function exists solely to have a breakpoint set on it by the | ||||
|    debugger.  The debugger is supposed to find this function's address by | ||||
|    examining the r_brk member of struct r_debug, but GDB 4.15 in fact looks | ||||
|    for this particular symbol name in the PT_INTERP file.  */ | ||||
| void | ||||
| _dl_debug_state (void) | ||||
| { | ||||
| } | ||||
							
								
								
									
										561
									
								
								newlib/libc/sys/linux/dl/dl-deps.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										561
									
								
								newlib/libc/sys/linux/dl/dl-deps.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,561 @@ | ||||
| /* Load the dependencies of a mapped object. | ||||
|    Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <dlfcn.h> | ||||
| #include <errno.h> | ||||
| #include <libintl.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/param.h> | ||||
| #include <ldsodefs.h> | ||||
|  | ||||
| #include <dl-dst.h> | ||||
|  | ||||
| /* Whether an shared object references one or more auxiliary objects | ||||
|    is signaled by the AUXTAG entry in l_info.  */ | ||||
| #define AUXTAG	(DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ | ||||
| 		 + DT_EXTRATAGIDX (DT_AUXILIARY)) | ||||
| /* Whether an shared object references one or more auxiliary objects | ||||
|    is signaled by the AUXTAG entry in l_info.  */ | ||||
| #define FILTERTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \ | ||||
| 		   + DT_EXTRATAGIDX (DT_FILTER)) | ||||
|  | ||||
| /* This is zero at program start to signal that the global scope map is | ||||
|    allocated by rtld.  Later it keeps the size of the map.  It might be | ||||
|    reset if in _dl_close if the last global object is removed.  */ | ||||
| size_t _dl_global_scope_alloc; | ||||
|  | ||||
| extern size_t _dl_platformlen; | ||||
|  | ||||
| /* When loading auxiliary objects we must ignore errors.  It's ok if | ||||
|    an object is missing.  */ | ||||
| struct openaux_args | ||||
|   { | ||||
|     /* The arguments to openaux.  */ | ||||
|     struct link_map *map; | ||||
|     int trace_mode; | ||||
|     const char *strtab; | ||||
|     const char *name; | ||||
|  | ||||
|     /* The return value of openaux.  */ | ||||
|     struct link_map *aux; | ||||
|   }; | ||||
|  | ||||
| static void | ||||
| openaux (void *a) | ||||
| { | ||||
|   struct openaux_args *args = (struct openaux_args *) a; | ||||
|  | ||||
|   args->aux = _dl_map_object (args->map, args->name, 0, | ||||
| 			      (args->map->l_type == lt_executable | ||||
| 			       ? lt_library : args->map->l_type), | ||||
| 			      args->trace_mode, 0); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* We use a very special kind of list to track the path | ||||
|    through the list of loaded shared objects.  We have to | ||||
|    produce a flat list with unique members of all involved objects. | ||||
| */ | ||||
| struct list | ||||
|   { | ||||
|     int done;			/* Nonzero if this map was processed.  */ | ||||
|     struct link_map *map;	/* The data.  */ | ||||
|     struct list *next;	/* Elements for normal list.  */ | ||||
|   }; | ||||
|  | ||||
|  | ||||
| /* Macro to expand DST.  It is an macro since we use `alloca'.  */ | ||||
| #define expand_dst(l, str, fatal) \ | ||||
|   ({									      \ | ||||
|     const char *__str = (str);						      \ | ||||
|     const char *__result = __str;					      \ | ||||
|     size_t __cnt = DL_DST_COUNT(__str, 0);				      \ | ||||
| 									      \ | ||||
|     if (__cnt != 0)							      \ | ||||
|       {									      \ | ||||
| 	char *__newp;							      \ | ||||
| 									      \ | ||||
| 	__newp = (char *) alloca (DL_DST_REQUIRED (l, __str, strlen (__str),  \ | ||||
| 						   __cnt));		      \ | ||||
| 									      \ | ||||
| 	__result = DL_DST_SUBSTITUTE (l, __str, __newp, 0);		      \ | ||||
| 									      \ | ||||
| 	if (*__result == '\0')						      \ | ||||
| 	  {								      \ | ||||
| 	    /* The replacement for the DST is not known.  We can't	      \ | ||||
| 	       processed.  */						      \ | ||||
| 	    if (fatal)							      \ | ||||
| 	      _dl_signal_error (0, __str, NULL, N_("\ | ||||
| empty dynamics string token substitution"));				      \ | ||||
| 	    else							      \ | ||||
| 	      {								      \ | ||||
| 		/* This is for DT_AUXILIARY.  */			      \ | ||||
| 		if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0))     \ | ||||
| 		  _dl_debug_printf ("cannot load auxiliary `%s' because of"   \ | ||||
| 				    "empty dynamic string token "	      \ | ||||
| 				    "substitution\n", __str);		      \ | ||||
| 		continue;						      \ | ||||
| 	      }								      \ | ||||
| 	  }								      \ | ||||
|       }									      \ | ||||
| 									      \ | ||||
|     __result; }) | ||||
|  | ||||
|  | ||||
| void | ||||
| internal_function | ||||
| _dl_map_object_deps (struct link_map *map, | ||||
| 		     struct link_map **preloads, unsigned int npreloads, | ||||
| 		     int trace_mode) | ||||
| { | ||||
|   struct list known[1 + npreloads + 1]; | ||||
|   struct list *runp, *tail; | ||||
|   unsigned int nlist, i; | ||||
|   /* Object name.  */ | ||||
|   const char *name; | ||||
|   int errno_saved; | ||||
|   int errno_reason; | ||||
|   const char *errstring; | ||||
|   const char *objname; | ||||
|  | ||||
|   auto inline void preload (struct link_map *map); | ||||
|  | ||||
|   inline void preload (struct link_map *map) | ||||
|     { | ||||
|       known[nlist].done = 0; | ||||
|       known[nlist].map = map; | ||||
|       known[nlist].next = &known[nlist + 1]; | ||||
|  | ||||
|       ++nlist; | ||||
|       /* We use `l_reserved' as a mark bit to detect objects we have | ||||
| 	 already put in the search list and avoid adding duplicate | ||||
| 	 elements later in the list.  */ | ||||
|       map->l_reserved = 1; | ||||
|     } | ||||
|  | ||||
|   /* No loaded object so far.  */ | ||||
|   nlist = 0; | ||||
|  | ||||
|   /* First load MAP itself.  */ | ||||
|   preload (map); | ||||
|  | ||||
|   /* Add the preloaded items after MAP but before any of its dependencies.  */ | ||||
|   for (i = 0; i < npreloads; ++i) | ||||
|     preload (preloads[i]); | ||||
|  | ||||
|   /* Terminate the lists.  */ | ||||
|   known[nlist - 1].next = NULL; | ||||
|  | ||||
|   /* Pointer to last unique object.  */ | ||||
|   tail = &known[nlist - 1]; | ||||
|  | ||||
|   /* Process each element of the search list, loading each of its | ||||
|      auxiliary objects and immediate dependencies.  Auxiliary objects | ||||
|      will be added in the list before the object itself and | ||||
|      dependencies will be appended to the list as we step through it. | ||||
|      This produces a flat, ordered list that represents a | ||||
|      breadth-first search of the dependency tree. | ||||
|  | ||||
|      The whole process is complicated by the fact that we better | ||||
|      should use alloca for the temporary list elements.  But using | ||||
|      alloca means we cannot use recursive function calls.  */ | ||||
|   errno_saved = errno; | ||||
|   errno_reason = 0; | ||||
|   errstring = NULL; | ||||
|   errno = 0; | ||||
|   name = NULL; | ||||
|   for (runp = known; runp; ) | ||||
|     { | ||||
|       struct link_map *l = runp->map; | ||||
|       struct link_map **needed = NULL; | ||||
|       unsigned int nneeded = 0; | ||||
|  | ||||
|       /* Unless otherwise stated, this object is handled.  */ | ||||
|       runp->done = 1; | ||||
|  | ||||
|       /* Allocate a temporary record to contain the references to the | ||||
| 	 dependencies of this object.  */ | ||||
|       if (l->l_searchlist.r_list == NULL && l->l_initfini == NULL | ||||
| 	  && l != map && l->l_ldnum > 0) | ||||
| 	needed = (struct link_map **) alloca (l->l_ldnum | ||||
| 					      * sizeof (struct link_map *)); | ||||
|  | ||||
|       if (l->l_info[DT_NEEDED] || l->l_info[AUXTAG] || l->l_info[FILTERTAG]) | ||||
| 	{ | ||||
| 	  const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); | ||||
| 	  struct openaux_args args; | ||||
| 	  struct list *orig; | ||||
| 	  const ElfW(Dyn) *d; | ||||
|  | ||||
| 	  args.strtab = strtab; | ||||
| 	  args.map = l; | ||||
| 	  args.trace_mode = trace_mode; | ||||
| 	  orig = runp; | ||||
|  | ||||
| 	  for (d = l->l_ld; d->d_tag != DT_NULL; ++d) | ||||
| 	    if (__builtin_expect (d->d_tag, DT_NEEDED) == DT_NEEDED) | ||||
| 	      { | ||||
| 		/* Map in the needed object.  */ | ||||
| 		struct link_map *dep; | ||||
| 		int err; | ||||
|  | ||||
| 		/* Recognize DSTs.  */ | ||||
| 		name = expand_dst (l, strtab + d->d_un.d_val, 0); | ||||
| 		/* Store the tag in the argument structure.  */ | ||||
| 		args.name = name; | ||||
|  | ||||
| 		err = _dl_catch_error (&objname, &errstring, openaux, &args); | ||||
| 		if (__builtin_expect (errstring != NULL, 0)) | ||||
| 		  { | ||||
| 		    if (err) | ||||
| 		      errno_reason = err; | ||||
| 		    else | ||||
| 		      errno_reason = -1; | ||||
| 		    goto out; | ||||
| 		  } | ||||
| 		else | ||||
| 		  dep = args.aux; | ||||
|  | ||||
| 		if (! dep->l_reserved) | ||||
| 		  { | ||||
| 		    /* Allocate new entry.  */ | ||||
| 		    struct list *newp; | ||||
|  | ||||
| 		    newp = alloca (sizeof (struct list)); | ||||
|  | ||||
| 		    /* Append DEP to the list.  */ | ||||
| 		    newp->map = dep; | ||||
| 		    newp->done = 0; | ||||
| 		    newp->next = NULL; | ||||
| 		    tail->next = newp; | ||||
| 		    tail = newp; | ||||
| 		    ++nlist; | ||||
| 		    /* Set the mark bit that says it's already in the list.  */ | ||||
| 		    dep->l_reserved = 1; | ||||
| 		  } | ||||
|  | ||||
| 		/* Remember this dependency.  */ | ||||
| 		if (needed != NULL) | ||||
| 		  needed[nneeded++] = dep; | ||||
| 	      } | ||||
| 	    else if (d->d_tag == DT_AUXILIARY || d->d_tag == DT_FILTER) | ||||
| 	      { | ||||
| 		struct list *newp; | ||||
|  | ||||
| 		/* Recognize DSTs.  */ | ||||
| 		name = expand_dst (l, strtab + d->d_un.d_val, | ||||
| 				   d->d_tag == DT_AUXILIARY); | ||||
| 		/* Store the tag in the argument structure.  */ | ||||
| 		args.name = name; | ||||
|  | ||||
| 		if (d->d_tag == DT_AUXILIARY) | ||||
| 		  { | ||||
| 		    int err; | ||||
|  | ||||
| 		    /* Say that we are about to load an auxiliary library.  */ | ||||
| 		    if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) | ||||
| 		      _dl_debug_printf ("load auxiliary object=%s" | ||||
| 					" requested by file=%s\n", name, | ||||
| 					l->l_name[0] | ||||
| 					? l->l_name : _dl_argv[0]); | ||||
|  | ||||
| 		    /* We must be prepared that the addressed shared | ||||
| 		       object is not available.  */ | ||||
| 		    err = _dl_catch_error (&objname, &errstring, openaux, | ||||
| 					   &args); | ||||
| 		    if (__builtin_expect (errstring != NULL, 0)) | ||||
| 		      { | ||||
| 			/* We are not interested in the error message.  */ | ||||
| 			assert (errstring != NULL); | ||||
| 			if (errstring != _dl_out_of_memory) | ||||
| 			  free ((char *) errstring); | ||||
|  | ||||
| 			/* Simply ignore this error and continue the work.  */ | ||||
| 			continue; | ||||
| 		      } | ||||
| 		  } | ||||
| 		else | ||||
| 		  { | ||||
| 		    int err; | ||||
|  | ||||
| 		    /* Say that we are about to load an auxiliary library.  */ | ||||
| 		    if (__builtin_expect (_dl_debug_mask & DL_DEBUG_LIBS, 0)) | ||||
| 		      _dl_debug_printf ("load filtered object=%s" | ||||
| 					" requested by file=%s\n", name, | ||||
| 					l->l_name[0] | ||||
| 					? l->l_name : _dl_argv[0]); | ||||
|  | ||||
| 		    /* For filter objects the dependency must be available.  */ | ||||
| 		    err = _dl_catch_error (&objname, &errstring, openaux, | ||||
| 					   &args); | ||||
| 		    if (__builtin_expect (errstring != NULL, 0)) | ||||
| 		      { | ||||
| 			if (err) | ||||
| 			  errno_reason = err; | ||||
| 			else | ||||
| 			  errno_reason = -1; | ||||
| 			goto out; | ||||
| 		      } | ||||
| 		  } | ||||
|  | ||||
| 		/* The auxiliary object is actually available. | ||||
| 		   Incorporate the map in all the lists.  */ | ||||
|  | ||||
| 		/* Allocate new entry.  This always has to be done.  */ | ||||
| 		newp = alloca (sizeof (struct list)); | ||||
|  | ||||
| 		/* We want to insert the new map before the current one, | ||||
| 		   but we have no back links.  So we copy the contents of | ||||
| 		   the current entry over.  Note that ORIG and NEWP now | ||||
| 		   have switched their meanings.  */ | ||||
| 		memcpy (newp, orig, sizeof (*newp)); | ||||
|  | ||||
| 		/* Initialize new entry.  */ | ||||
| 		orig->done = 0; | ||||
| 		orig->map = args.aux; | ||||
|  | ||||
| 		/* Remember this dependency.  */ | ||||
| 		if (needed != NULL) | ||||
| 		  needed[nneeded++] = args.aux; | ||||
|  | ||||
| 		/* We must handle two situations here: the map is new, | ||||
| 		   so we must add it in all three lists.  If the map | ||||
| 		   is already known, we have two further possibilities: | ||||
| 		   - if the object is before the current map in the | ||||
| 		   search list, we do nothing.  It is already found | ||||
| 		   early | ||||
| 		   - if the object is after the current one, we must | ||||
| 		   move it just before the current map to make sure | ||||
| 		   the symbols are found early enough | ||||
| 		*/ | ||||
| 		if (args.aux->l_reserved) | ||||
| 		  { | ||||
| 		    /* The object is already somewhere in the list. | ||||
| 		       Locate it first.  */ | ||||
| 		    struct list *late; | ||||
|  | ||||
| 		    /* This object is already in the search list we | ||||
| 		       are building.  Don't add a duplicate pointer. | ||||
| 		       Just added by _dl_map_object.  */ | ||||
| 		    for (late = newp; late->next != NULL; late = late->next) | ||||
| 		      if (late->next->map == args.aux) | ||||
| 			break; | ||||
|  | ||||
| 		    if (late->next != NULL) | ||||
| 		      { | ||||
| 			/* The object is somewhere behind the current | ||||
| 			   position in the search path.  We have to | ||||
| 			   move it to this earlier position.  */ | ||||
| 			orig->next = newp; | ||||
|  | ||||
| 			/* Now remove the later entry from the list | ||||
| 			   and adjust the tail pointer.  */ | ||||
| 			if (tail == late->next) | ||||
| 			  tail = late; | ||||
| 			late->next = late->next->next; | ||||
|  | ||||
| 			/* We must move the object earlier in the chain.  */ | ||||
| 			if (args.aux->l_prev != NULL) | ||||
| 			  args.aux->l_prev->l_next = args.aux->l_next; | ||||
| 			if (args.aux->l_next != NULL) | ||||
| 			  args.aux->l_next->l_prev = args.aux->l_prev; | ||||
|  | ||||
| 			args.aux->l_prev = newp->map->l_prev; | ||||
| 			newp->map->l_prev = args.aux; | ||||
| 			if (args.aux->l_prev != NULL) | ||||
| 			  args.aux->l_prev->l_next = args.aux; | ||||
| 			args.aux->l_next = newp->map; | ||||
| 		      } | ||||
| 		    else | ||||
| 		      { | ||||
| 			/* The object must be somewhere earlier in the | ||||
| 			   list.  Undo to the current list element what | ||||
| 			   we did above.  */ | ||||
| 			memcpy (orig, newp, sizeof (*newp)); | ||||
| 			continue; | ||||
| 		      } | ||||
| 		  } | ||||
| 		else | ||||
| 		  { | ||||
| 		    /* This is easy.  We just add the symbol right here.  */ | ||||
| 		    orig->next = newp; | ||||
| 		    ++nlist; | ||||
| 		    /* Set the mark bit that says it's already in the list.  */ | ||||
| 		    args.aux->l_reserved = 1; | ||||
|  | ||||
| 		    /* The only problem is that in the double linked | ||||
| 		       list of all objects we don't have this new | ||||
| 		       object at the correct place.  Correct this here.  */ | ||||
| 		    if (args.aux->l_prev) | ||||
| 		      args.aux->l_prev->l_next = args.aux->l_next; | ||||
| 		    if (args.aux->l_next) | ||||
| 		      args.aux->l_next->l_prev = args.aux->l_prev; | ||||
|  | ||||
| 		    args.aux->l_prev = newp->map->l_prev; | ||||
| 		    newp->map->l_prev = args.aux; | ||||
| 		    if (args.aux->l_prev != NULL) | ||||
| 		      args.aux->l_prev->l_next = args.aux; | ||||
| 		    args.aux->l_next = newp->map; | ||||
| 		  } | ||||
|  | ||||
| 		/* Move the tail pointer if necessary.  */ | ||||
| 		if (orig == tail) | ||||
| 		  tail = newp; | ||||
|  | ||||
| 		/* Move on the insert point.  */ | ||||
| 		orig = newp; | ||||
| 	      } | ||||
| 	} | ||||
|  | ||||
|       /* Terminate the list of dependencies and store the array address.  */ | ||||
|       if (needed != NULL) | ||||
| 	{ | ||||
| 	  needed[nneeded++] = NULL; | ||||
|  | ||||
| 	  l->l_initfini = (struct link_map **) | ||||
| 	    malloc ((nneeded + 1) * sizeof needed[0]); | ||||
| 	  if (l->l_initfini == NULL) | ||||
| 	    _dl_signal_error (ENOMEM, map->l_name, NULL, | ||||
| 			      N_("cannot allocate dependency list")); | ||||
| 	  l->l_initfini[0] = l; | ||||
| 	  memcpy (&l->l_initfini[1], needed, nneeded * sizeof needed[0]); | ||||
| 	} | ||||
|  | ||||
|       /* If we have no auxiliary objects just go on to the next map.  */ | ||||
|       if (runp->done) | ||||
| 	do | ||||
| 	  runp = runp->next; | ||||
| 	while (runp != NULL && runp->done); | ||||
|     } | ||||
|  | ||||
|  out: | ||||
|   if (errno == 0 && errno_saved != 0) | ||||
|     __set_errno (errno_saved); | ||||
|  | ||||
|   if (map->l_initfini != NULL && map->l_type == lt_loaded) | ||||
|     { | ||||
|       /* This object was previously loaded as a dependency and we have | ||||
| 	 a separate l_initfini list.  We don't need it anymore.  */ | ||||
|       assert (map->l_searchlist.r_list == NULL); | ||||
|       free (map->l_initfini); | ||||
|     } | ||||
|  | ||||
|   /* Store the search list we built in the object.  It will be used for | ||||
|      searches in the scope of this object.  */ | ||||
|   map->l_initfini = | ||||
|     (struct link_map **) malloc ((2 * nlist + 1) | ||||
| 				 * sizeof (struct link_map *)); | ||||
|   if (map->l_initfini == NULL) | ||||
|     _dl_signal_error (ENOMEM, map->l_name, NULL, | ||||
| 		      N_("cannot allocate symbol search list")); | ||||
|  | ||||
|  | ||||
|   map->l_searchlist.r_list = &map->l_initfini[nlist + 1]; | ||||
|   map->l_searchlist.r_nlist = nlist; | ||||
|  | ||||
|   for (nlist = 0, runp = known; runp; runp = runp->next) | ||||
|     { | ||||
|       if (__builtin_expect (trace_mode, 0) && runp->map->l_faked) | ||||
| 	/* This can happen when we trace the loading.  */ | ||||
| 	--map->l_searchlist.r_nlist; | ||||
|       else | ||||
| 	map->l_searchlist.r_list[nlist++] = runp->map; | ||||
|  | ||||
|       /* Now clear all the mark bits we set in the objects on the search list | ||||
| 	 to avoid duplicates, so the next call starts fresh.  */ | ||||
|       runp->map->l_reserved = 0; | ||||
|     } | ||||
|  | ||||
|   /* Maybe we can remove some relocation dependencies now.  */ | ||||
|   assert (map->l_searchlist.r_list[0] == map); | ||||
|   for (i = 0; i < map->l_reldepsact; ++i) | ||||
|     { | ||||
|       unsigned int j; | ||||
|  | ||||
|       for (j = 1; j < nlist; ++j) | ||||
| 	if (map->l_searchlist.r_list[j] == map->l_reldeps[i]) | ||||
| 	  { | ||||
| 	    /* A direct or transitive dependency is also on the list | ||||
| 	       of relocation dependencies.  Remove the latter.  */ | ||||
| 	    --map->l_reldeps[i]->l_opencount; | ||||
|  | ||||
| 	    for (j = i + 1; j < map->l_reldepsact; ++j) | ||||
| 	      map->l_reldeps[j - 1] = map->l_reldeps[j]; | ||||
|  | ||||
| 	    --map->l_reldepsact; | ||||
|  | ||||
| 	    /* Account for the '++i' performed by the 'for'.  */ | ||||
| 	    --i; | ||||
| 	    break; | ||||
| 	  } | ||||
|     } | ||||
|  | ||||
|   /* Now determine the order in which the initialization has to happen.  */ | ||||
|   memcpy (map->l_initfini, map->l_searchlist.r_list, | ||||
| 	  nlist * sizeof (struct link_map *)); | ||||
|   /* We can skip looking for the binary itself which is at the front | ||||
|      of the search list.  Look through the list backward so that circular | ||||
|      dependencies are not changing the order.  */ | ||||
|   for (i = 1; i < nlist; ++i) | ||||
|     { | ||||
|       struct link_map *l = map->l_searchlist.r_list[i]; | ||||
|       unsigned int j; | ||||
|       unsigned int k; | ||||
|  | ||||
|       /* Find the place in the initfini list where the map is currently | ||||
| 	 located.  */ | ||||
|       for (j = 1; map->l_initfini[j] != l; ++j) | ||||
| 	; | ||||
|  | ||||
|       /* Find all object for which the current one is a dependency and | ||||
| 	 move the found object (if necessary) in front.  */ | ||||
|       for (k = j + 1; k < nlist; ++k) | ||||
| 	{ | ||||
| 	  struct link_map **runp; | ||||
|  | ||||
| 	  runp = map->l_initfini[k]->l_initfini; | ||||
| 	  if (runp != NULL) | ||||
| 	    { | ||||
| 	      while (*runp != NULL) | ||||
| 		if (__builtin_expect (*runp++ == l, 0)) | ||||
| 		  { | ||||
| 		    struct link_map *here = map->l_initfini[k]; | ||||
|  | ||||
| 		    /* Move it now.  */ | ||||
| 		    memmove (&map->l_initfini[j] + 1, | ||||
| 			     &map->l_initfini[j], | ||||
| 			     (k - j) * sizeof (struct link_map *)); | ||||
| 		    map->l_initfini[j] = here; | ||||
|  | ||||
| 		    break; | ||||
| 		  } | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|   /* Terminate the list of dependencies.  */ | ||||
|   map->l_initfini[nlist] = NULL; | ||||
|  | ||||
|   if (errno_reason) | ||||
|     _dl_signal_error (errno_reason == -1 ? 0 : errno_reason, | ||||
| 		      objname, NULL, errstring); | ||||
| } | ||||
							
								
								
									
										45
									
								
								newlib/libc/sys/linux/dl/dl-dst.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								newlib/libc/sys/linux/dl/dl-dst.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| /* Handling of dynamic sring tokens. | ||||
|    Copyright (C) 1999, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| /* Determine the number of DST elements in the name.  Only if IS_PATH is | ||||
|    nonzero paths are recognized (i.e., multiple, ':' separated filenames).  */ | ||||
| #define DL_DST_COUNT(name, is_path) \ | ||||
|   ({									      \ | ||||
|     size_t __cnt = 0;							      \ | ||||
|     const char *__sf = strchr (name, '$');				      \ | ||||
| 									      \ | ||||
|     if (__builtin_expect (__sf != NULL, 0))				      \ | ||||
|       __cnt = _dl_dst_count (__sf, is_path);				      \ | ||||
| 									      \ | ||||
|     __cnt; }) | ||||
|  | ||||
| /* Prototype for used function.  */ | ||||
| extern size_t _dl_dst_count (const char *name, int is_path); | ||||
|  | ||||
|  | ||||
| /* Guess from the number of DSTs the length of the result string.  */ | ||||
| #define DL_DST_REQUIRED(l, name, len, cnt) 1024 | ||||
|  | ||||
| /* Perform the DST substitution.  */ | ||||
| #define DL_DST_SUBSTITUTE(l, name, res, is_path) \ | ||||
|   _dl_dst_substitute (l, name, res, is_path) | ||||
|  | ||||
| /* Prototype for used function.  */ | ||||
| extern char *_dl_dst_substitute (struct link_map *l, const char *name, | ||||
| 				 char *result, int is_path); | ||||
							
								
								
									
										189
									
								
								newlib/libc/sys/linux/dl/dl-error.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								newlib/libc/sys/linux/dl/dl-error.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,189 @@ | ||||
| /* Error handling for runtime dynamic linker. | ||||
|    Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <libintl.h> | ||||
| #include <setjmp.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <ldsodefs.h> | ||||
| #include <sys/libc-tsd.h> | ||||
|  | ||||
| /* This structure communicates state between _dl_catch_error and | ||||
|    _dl_signal_error.  */ | ||||
| struct catch | ||||
|   { | ||||
|     const char *objname;	/* Object/File name.  */ | ||||
|     const char *errstring;	/* Error detail filled in here.  */ | ||||
|     jmp_buf env;		/* longjmp here on error.  */ | ||||
|   }; | ||||
|  | ||||
| /* Multiple threads at once can use the `_dl_catch_error' function.  The | ||||
|    calls can come from `_dl_map_object_deps', `_dlerror_run', or from | ||||
|    any of the libc functionality which loads dynamic objects (NSS, iconv). | ||||
|    Therefore we have to be prepared to save the state in thread-local | ||||
|    memory.  */ | ||||
|  | ||||
| __libc_tsd_define (static, DL_ERROR) | ||||
| #define tsd_getspecific()	__libc_tsd_get (DL_ERROR) | ||||
| #define tsd_setspecific(data)	__libc_tsd_set (DL_ERROR, (data)) | ||||
|  | ||||
|  | ||||
| /* This message we return as a last resort.  We define the string in a | ||||
|    variable since we have to avoid freeing it and so have to enable | ||||
|    a pointer comparison.  See below and in dlfcn/dlerror.c.  */ | ||||
| const char _dl_out_of_memory[] = "out of memory"; | ||||
|  | ||||
|  | ||||
| /* This points to a function which is called when an continuable error is | ||||
|    received.  Unlike the handling of `catch' this function may return. | ||||
|    The arguments will be the `errstring' and `objname'. | ||||
|  | ||||
|    Since this functionality is not used in normal programs (only in ld.so) | ||||
|    we do not care about multi-threaded programs here.  We keep this as a | ||||
|    global variable.  */ | ||||
| static receiver_fct receiver; | ||||
|  | ||||
|  | ||||
| void | ||||
| internal_function | ||||
| _dl_signal_error (int errcode, const char *objname, const char *occation, | ||||
| 		  const char *errstring) | ||||
| { | ||||
|   struct catch *lcatch; | ||||
|  | ||||
|   if (! errstring) | ||||
|     errstring = N_("DYNAMIC LINKER BUG!!!"); | ||||
|  | ||||
|   lcatch = tsd_getspecific (); | ||||
|   if (objname == NULL) | ||||
|     objname = ""; | ||||
|   if (lcatch != NULL) | ||||
|     { | ||||
|       /* We are inside _dl_catch_error.  Return to it.  We have to | ||||
| 	 duplicate the error string since it might be allocated on the | ||||
| 	 stack.  The object name is always a string constant.  */ | ||||
|       size_t len_objname = strlen (objname) + 1; | ||||
|       size_t len_errstring = strlen (errstring) + 1; | ||||
|  | ||||
|       lcatch->errstring = (char *) malloc (len_objname + len_errstring); | ||||
|       if (lcatch->errstring != NULL) | ||||
|         { | ||||
|           char *tmp; | ||||
|           /* Make a copy of the object file name and the error string.  */ | ||||
|           tmp = memcpy ((char *) lcatch->errstring, | ||||
|                            errstring, len_errstring); | ||||
|           tmp += len_errstring; | ||||
|           lcatch->objname = memcpy (tmp, | ||||
| 				  objname, len_objname); | ||||
|         } | ||||
|       else | ||||
| 	{ | ||||
| 	  /* This is better than nothing.  */ | ||||
| 	  lcatch->objname = ""; | ||||
| 	  lcatch->errstring = _dl_out_of_memory; | ||||
| 	} | ||||
|       longjmp (lcatch->env, errcode ?: -1); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* Lossage while resolving the program's own symbols is always fatal.  */ | ||||
|       char buffer[1024]; | ||||
|       _dl_fatal_printf ("%s: %s: %s%s%s%s%s\n", | ||||
| 			_dl_argv[0] ?: "<program name unknown>", | ||||
| 			occation ?: N_("error while loading shared libraries"), | ||||
| 			objname, *objname ? ": " : "", | ||||
| 			errstring, errcode ? ": " : "", | ||||
| 			(errcode | ||||
| 			 ? __strerror_r (errcode, buffer, sizeof buffer) | ||||
| 			 : "")); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| void | ||||
| internal_function | ||||
| _dl_signal_cerror (int errcode, const char *objname, const char *occation, | ||||
| 		   const char *errstring) | ||||
| { | ||||
|   if (receiver) | ||||
|     { | ||||
|       /* We are inside _dl_receive_error.  Call the user supplied | ||||
| 	 handler and resume the work.  The receiver will still be | ||||
| 	 installed.  */ | ||||
|       (*receiver) (errcode, objname, errstring); | ||||
|     } | ||||
|   else | ||||
|     _dl_signal_error (errcode, objname, occation, errstring); | ||||
| } | ||||
|  | ||||
|  | ||||
| int | ||||
| internal_function | ||||
| _dl_catch_error (const char **objname, const char **errstring, | ||||
| 		 void (*operate) (void *), void *args) | ||||
| { | ||||
|   int errcode; | ||||
|   struct catch *volatile old; | ||||
|   struct catch c; | ||||
|   /* We need not handle `receiver' since setting a `catch' is handled | ||||
|      before it.  */ | ||||
|  | ||||
|   /* Some systems (e.g., SPARC) handle constructors to local variables | ||||
|      inefficient.  So we initialize `c' by hand.  */ | ||||
|   c.errstring = NULL; | ||||
|  | ||||
|   old = tsd_getspecific (); | ||||
|   errcode = setjmp (c.env); | ||||
|   if (__builtin_expect (errcode, 0) == 0) | ||||
|     { | ||||
|       tsd_setspecific (&c); | ||||
|       (*operate) (args); | ||||
|       tsd_setspecific (old); | ||||
|       *objname = NULL; | ||||
|       *errstring = NULL; | ||||
|       return 0; | ||||
|     } | ||||
|  | ||||
|   /* We get here only if we longjmp'd out of OPERATE.  */ | ||||
|   tsd_setspecific (old); | ||||
|   *objname = c.objname; | ||||
|   *errstring = c.errstring; | ||||
|   return errcode == -1 ? 0 : errcode; | ||||
| } | ||||
|  | ||||
| void | ||||
| internal_function | ||||
| _dl_receive_error (receiver_fct fct, void (*operate) (void *), void *args) | ||||
| { | ||||
|   struct catch *old_catch; | ||||
|   receiver_fct old_receiver; | ||||
|  | ||||
|   old_catch = tsd_getspecific (); | ||||
|   old_receiver = receiver; | ||||
|  | ||||
|   /* Set the new values.  */ | ||||
|   tsd_setspecific (NULL); | ||||
|   receiver = fct; | ||||
|  | ||||
|   (*operate) (args); | ||||
|  | ||||
|   tsd_setspecific (old_catch); | ||||
|   receiver = old_receiver; | ||||
| } | ||||
							
								
								
									
										172
									
								
								newlib/libc/sys/linux/dl/dl-fini.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								newlib/libc/sys/linux/dl/dl-fini.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,172 @@ | ||||
| /* Call the termination functions of loaded shared objects. | ||||
|    Copyright (C) 1995,96,98,99,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <alloca.h> | ||||
| #include <assert.h> | ||||
| #include <string.h> | ||||
| #include <ldsodefs.h> | ||||
|  | ||||
|  | ||||
| /* Type of the constructor functions.  */ | ||||
| typedef void (*fini_t) (void); | ||||
|  | ||||
|  | ||||
| void | ||||
| internal_function | ||||
| _dl_fini (void) | ||||
| { | ||||
|   /* Lots of fun ahead.  We have to call the destructors for all still | ||||
|      loaded objects.  The problem is that the ELF specification now | ||||
|      demands that dependencies between the modules are taken into account. | ||||
|      I.e., the destructor for a module is called before the ones for any | ||||
|      of its dependencies. | ||||
|  | ||||
|      To make things more complicated, we cannot simply use the reverse | ||||
|      order of the constructors.  Since the user might have loaded objects | ||||
|      using `dlopen' there are possibly several other modules with its | ||||
|      dependencies to be taken into account.  Therefore we have to start | ||||
|      determining the order of the modules once again from the beginning.  */ | ||||
|   unsigned int i; | ||||
|   struct link_map *l; | ||||
|   struct link_map **maps; | ||||
|  | ||||
|   /* XXX Could it be (in static binaries) that there is no object loaded?  */ | ||||
|   assert (_dl_nloaded > 0); | ||||
|  | ||||
|   /* Now we can allocate an array to hold all the pointers and copy | ||||
|      the pointers in.  */ | ||||
|   maps = (struct link_map **) alloca (_dl_nloaded | ||||
| 				      * sizeof (struct link_map *)); | ||||
|   for (l = _dl_loaded, i = 0; l != NULL; l = l->l_next) | ||||
|     { | ||||
|       assert (i < _dl_nloaded); | ||||
|  | ||||
|       maps[i++] = l; | ||||
|  | ||||
|       /* Bump l_opencount of all objects so that they are not dlclose()ed | ||||
| 	 from underneath us.  */ | ||||
|       ++l->l_opencount; | ||||
|     } | ||||
|   assert (i == _dl_nloaded); | ||||
|  | ||||
|   /* Now we have to do the sorting.  */ | ||||
|   for (l = _dl_loaded->l_next; l != NULL; l = l->l_next) | ||||
|     { | ||||
|       unsigned int j; | ||||
|       unsigned int k; | ||||
|  | ||||
|       /* Find the place in the `maps' array.  */ | ||||
|       for (j = 1; maps[j] != l; ++j) | ||||
| 	; | ||||
|  | ||||
|       /* Find all object for which the current one is a dependency and | ||||
| 	 move the found object (if necessary) in front.  */ | ||||
|       for (k = j + 1; k < _dl_nloaded; ++k) | ||||
| 	{ | ||||
| 	  struct link_map **runp; | ||||
|  | ||||
| 	  runp = maps[k]->l_initfini; | ||||
| 	  if (runp != NULL) | ||||
| 	    { | ||||
| 	      while (*runp != NULL) | ||||
| 		if (*runp == l) | ||||
| 		  { | ||||
| 		    struct link_map *here = maps[k]; | ||||
|  | ||||
| 		    /* Move it now.  */ | ||||
| 		    memmove (&maps[j] + 1, | ||||
| 			     &maps[j], | ||||
| 			     (k - j) * sizeof (struct link_map *)); | ||||
| 		    maps[j++] = here; | ||||
|  | ||||
| 		    break; | ||||
| 		  } | ||||
| 		else | ||||
| 		  ++runp; | ||||
| 	    } | ||||
|  | ||||
| 	  if (__builtin_expect (maps[k]->l_reldeps != NULL, 0)) | ||||
| 	    { | ||||
| 	      unsigned int m = maps[k]->l_reldepsact; | ||||
| 	      struct link_map **relmaps = maps[k]->l_reldeps; | ||||
|  | ||||
| 	      while (m-- > 0) | ||||
| 		{ | ||||
| 		  if (relmaps[m] == l) | ||||
| 		    { | ||||
| 		      struct link_map *here = maps[k]; | ||||
|  | ||||
| 		      /* Move it now.  */ | ||||
| 		      memmove (&maps[j] + 1, | ||||
| 			       &maps[j], | ||||
| 			       (k - j) * sizeof (struct link_map *)); | ||||
| 		      maps[j] = here; | ||||
|  | ||||
| 		      break; | ||||
| 		    } | ||||
|  | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   /* `maps' now contains the objects in the right order.  Now call the | ||||
|      destructors.  We have to process this array from the front.  */ | ||||
|   for (i = 0; i < _dl_nloaded; ++i) | ||||
|     { | ||||
|       l = maps[i]; | ||||
|  | ||||
|       if (l->l_init_called) | ||||
| 	{ | ||||
| 	  /* Make sure nothing happens if we are called twice.  */ | ||||
| 	  l->l_init_called = 0; | ||||
|  | ||||
| 	  /* Don't call the destructors for objects we are not supposed to.  */ | ||||
| 	  if (l->l_name[0] == '\0' && l->l_type == lt_executable) | ||||
| 	    continue; | ||||
|  | ||||
| 	  /* Is there a destructor function?  */ | ||||
| 	  if (l->l_info[DT_FINI_ARRAY] == NULL && l->l_info[DT_FINI] == NULL) | ||||
| 	    continue; | ||||
|  | ||||
| 	  /* When debugging print a message first.  */ | ||||
| 	  if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) | ||||
| 	    _dl_debug_printf ("\ncalling fini: %s\n\n", | ||||
| 			      l->l_name[0] ? l->l_name : _dl_argv[0]); | ||||
|  | ||||
| 	  /* First see whether an array is given.  */ | ||||
| 	  if (l->l_info[DT_FINI_ARRAY] != NULL) | ||||
| 	    { | ||||
| 	      ElfW(Addr) *array = | ||||
| 		(ElfW(Addr) *) (l->l_addr | ||||
| 				+ l->l_info[DT_FINI_ARRAY]->d_un.d_ptr); | ||||
| 	      unsigned int sz = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val | ||||
| 				 / sizeof (ElfW(Addr))); | ||||
| 	      unsigned int cnt; | ||||
|  | ||||
| 	      for (cnt = 0; cnt < sz; ++cnt) | ||||
| 		((fini_t) (l->l_addr + array[cnt])) (); | ||||
| 	    } | ||||
|  | ||||
| 	  /* Next try the old-style destructor.  */ | ||||
| 	  if (l->l_info[DT_FINI] != NULL) | ||||
| 	    ((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) (); | ||||
| 	} | ||||
|     } | ||||
| } | ||||
							
								
								
									
										149
									
								
								newlib/libc/sys/linux/dl/dl-init.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								newlib/libc/sys/linux/dl/dl-init.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,149 @@ | ||||
| /* Return the next shared object initializer function not yet run. | ||||
|    Copyright (C) 1995,1996,1998,1999,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <ldsodefs.h> | ||||
|  | ||||
|  | ||||
| /* Type of the initializer.  */ | ||||
| typedef void (*init_t) (int, char **, char **); | ||||
|  | ||||
| /* Flag, nonzero during startup phase.  */ | ||||
| extern int _dl_starting_up; | ||||
|  | ||||
| /* The object to be initialized first.  */ | ||||
| extern struct link_map *_dl_initfirst; | ||||
|  | ||||
|  | ||||
| static void | ||||
| call_init (struct link_map *l, int argc, char **argv, char **env) | ||||
| { | ||||
|   if (l->l_init_called) | ||||
|     /* This object is all done.  */ | ||||
|     return; | ||||
|  | ||||
|   /* Avoid handling this constructor again in case we have a circular | ||||
|      dependency.  */ | ||||
|   l->l_init_called = 1; | ||||
|  | ||||
|   /* Check for object which constructors we do not run here.  */ | ||||
|   if (__builtin_expect (l->l_name[0], 'a') == '\0' | ||||
|       && l->l_type == lt_executable) | ||||
|     return; | ||||
|  | ||||
|   /* Are there any constructors?  */ | ||||
|   if (l->l_info[DT_INIT] == NULL | ||||
|       && __builtin_expect (l->l_info[DT_INIT_ARRAY] == NULL, 1)) | ||||
|     return; | ||||
|  | ||||
|   /* Print a debug message if wanted.  */ | ||||
|   if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) | ||||
|     _dl_debug_printf ("\ncalling init: %s\n\n", | ||||
| 		      l->l_name[0] ? l->l_name : _dl_argv[0]); | ||||
|  | ||||
|   /* Now run the local constructors.  There are two forms of them: | ||||
|      - the one named by DT_INIT | ||||
|      - the others in the DT_INIT_ARRAY. | ||||
|   */ | ||||
|   if (l->l_info[DT_INIT] != NULL) | ||||
|     { | ||||
|       init_t init = (init_t) DL_DT_INIT_ADDRESS | ||||
| 	(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr); | ||||
|  | ||||
|       /* Call the function.  */ | ||||
|       init (argc, argv, env); | ||||
|     } | ||||
|  | ||||
|   /* Next see whether there is an array with initialization functions.  */ | ||||
|   if (l->l_info[DT_INIT_ARRAY] != NULL) | ||||
|     { | ||||
|       unsigned int j; | ||||
|       unsigned int jm; | ||||
|       ElfW(Addr) *addrs; | ||||
|  | ||||
|       jm = l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr)); | ||||
|  | ||||
|       addrs = (ElfW(Addr) *) (l->l_info[DT_INIT_ARRAY]->d_un.d_ptr | ||||
| 			      + l->l_addr); | ||||
|       for (j = 0; j < jm; ++j) | ||||
| 	((init_t) addrs[j]) (argc, argv, env); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| void | ||||
| internal_function | ||||
| _dl_init (struct link_map *main_map, int argc, char **argv, char **env) | ||||
| { | ||||
|   ElfW(Dyn) *preinit_array = main_map->l_info[DT_PREINIT_ARRAY]; | ||||
|   struct r_debug *r; | ||||
|   unsigned int i; | ||||
|  | ||||
|   if (__builtin_expect (_dl_initfirst != NULL, 0)) | ||||
|     { | ||||
|       call_init (_dl_initfirst, argc, argv, env); | ||||
|       _dl_initfirst = NULL; | ||||
|     } | ||||
|  | ||||
|   /* Don't do anything if there is no preinit array.  */ | ||||
|   if (__builtin_expect (preinit_array != NULL, 0) | ||||
|       && (i = preinit_array->d_un.d_val / sizeof (ElfW(Addr))) > 0) | ||||
|     { | ||||
|       ElfW(Addr) *addrs; | ||||
|       unsigned int cnt; | ||||
|  | ||||
|       if (__builtin_expect (_dl_debug_mask & DL_DEBUG_IMPCALLS, 0)) | ||||
| 	_dl_debug_printf ("\ncalling preinit: %s\n\n", | ||||
| 			  main_map->l_name[0] | ||||
| 			  ? main_map->l_name : _dl_argv[0]); | ||||
|  | ||||
|       addrs = (ElfW(Addr) *) (main_map->l_info[DT_PREINIT_ARRAY]->d_un.d_ptr | ||||
| 			      + main_map->l_addr); | ||||
|       for (cnt = 0; cnt < i; ++cnt) | ||||
| 	((init_t) addrs[cnt]) (argc, argv, env); | ||||
|     } | ||||
|  | ||||
|   /* Notify the debugger we have added some objects.  We need to call | ||||
|      _dl_debug_initialize in a static program in case dynamic linking has | ||||
|      not been used before.  */ | ||||
|   r = _dl_debug_initialize (0); | ||||
|   r->r_state = RT_ADD; | ||||
|   _dl_debug_state (); | ||||
|  | ||||
|   /* Stupid users forced the ELF specification to be changed.  It now | ||||
|      says that the dynamic loader is responsible for determining the | ||||
|      order in which the constructors have to run.  The constructors | ||||
|      for all dependencies of an object must run before the constructor | ||||
|      for the object itself.  Circular dependencies are left unspecified. | ||||
|  | ||||
|      This is highly questionable since it puts the burden on the dynamic | ||||
|      loader which has to find the dependencies at runtime instead of | ||||
|      letting the user do it right.  Stupidity rules!  */ | ||||
|  | ||||
|   i = main_map->l_searchlist.r_nlist; | ||||
|   while (i-- > 0) | ||||
|     call_init (main_map->l_initfini[i], argc, argv, env); | ||||
|  | ||||
|   /* Notify the debugger all new objects are now ready to go.  */ | ||||
|   r->r_state = RT_CONSISTENT; | ||||
|   _dl_debug_state (); | ||||
|  | ||||
|   /* Finished starting up.  */ | ||||
|   _dl_starting_up = 0; | ||||
| } | ||||
							
								
								
									
										65
									
								
								newlib/libc/sys/linux/dl/dl-iteratephdr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								newlib/libc/sys/linux/dl/dl-iteratephdr.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| /* Get loaded objects program headers. | ||||
|    Copyright (C) 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Jakub Jelinek <jakub@redhat.com>, 2001. | ||||
|  | ||||
|    The GNU C Library is free software; you can redistribute it and/or | ||||
|    modify it under the terms of the GNU Library General Public License as | ||||
|    published by the Free Software Foundation; either version 2 of the | ||||
|    License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 | ||||
|    Library General Public License for more details. | ||||
|  | ||||
|    You should have received a copy of the GNU Library General Public | ||||
|    License along with the GNU C Library; see the file COPYING.LIB.  If not, | ||||
|    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||||
|    Boston, MA 02111-1307, USA.  */ | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <ldsodefs.h> | ||||
| #include <stddef.h> | ||||
| #include <bits/libc-lock.h> | ||||
|  | ||||
| int | ||||
| __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info, | ||||
| 				    size_t size, void *data), void *data) | ||||
| { | ||||
|   struct link_map *l; | ||||
|   struct dl_phdr_info info; | ||||
|   int ret = 0; | ||||
|  | ||||
|   /* Make sure we are alone.  */ | ||||
| #ifdef HAVE_DD_LOCK | ||||
|     __lock_acquire(_dl_load_lock); | ||||
| #endif | ||||
|  | ||||
|  | ||||
|   for (l = _dl_loaded; l != NULL; l = l->l_next) | ||||
|     { | ||||
|       /* Skip the dynamic linker.  */ | ||||
|       if (l->l_phdr == NULL) | ||||
| 	continue; | ||||
|       info.dlpi_addr = l->l_addr; | ||||
|       info.dlpi_name = l->l_name; | ||||
|       info.dlpi_phdr = l->l_phdr; | ||||
|       info.dlpi_phnum = l->l_phnum; | ||||
|       ret = callback (&info, sizeof (struct dl_phdr_info), data); | ||||
|       if (ret) | ||||
| 	break; | ||||
|     } | ||||
|  | ||||
|   /* Release the lock.  */ | ||||
| #ifdef HAVE_DD_LOCK | ||||
|     __lock_release(_dl_load_lock); | ||||
| #endif | ||||
|  | ||||
|  | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| #ifdef SHARED | ||||
| weak_alias (__dl_iterate_phdr, dl_iterate_phdr); | ||||
| #endif | ||||
							
								
								
									
										156
									
								
								newlib/libc/sys/linux/dl/dl-libc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								newlib/libc/sys/linux/dl/dl-libc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,156 @@ | ||||
| /* Handle loading and unloading shared objects for internal libc purposes. | ||||
|    Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Zack Weinberg <zack@rabi.columbia.edu>, 1999. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <dlfcn.h> | ||||
| #include <stdlib.h> | ||||
| #include <ldsodefs.h> | ||||
|  | ||||
| /* The purpose of this file is to provide wrappers around the dynamic | ||||
|    linker error mechanism (similar to dlopen() et al in libdl) which | ||||
|    are usable from within libc.  Generally we want to throw away the | ||||
|    string that dlerror() would return and just pass back a null pointer | ||||
|    for errors.  This also lets the rest of libc not know about the error | ||||
|    handling mechanism. | ||||
|  | ||||
|    Much of this code came from gconv_dl.c with slight modifications. */ | ||||
|  | ||||
| static int | ||||
| internal_function | ||||
| dlerror_run (void (*operate) (void *), void *args) | ||||
| { | ||||
|   const char *objname; | ||||
|   const char *last_errstring = NULL; | ||||
|   int result; | ||||
|  | ||||
|   (void) _dl_catch_error (&objname, &last_errstring, operate, args); | ||||
|  | ||||
|   result = last_errstring != NULL; | ||||
|   if (result && last_errstring != _dl_out_of_memory) | ||||
|     free ((char *) last_errstring); | ||||
|  | ||||
|   return result; | ||||
| } | ||||
|  | ||||
| /* These functions are called by dlerror_run... */ | ||||
|  | ||||
| struct do_dlopen_args | ||||
| { | ||||
|   /* Argument to do_dlopen.  */ | ||||
|   const char *name; | ||||
|  | ||||
|   /* Return from do_dlopen.  */ | ||||
|   struct link_map *map; | ||||
| }; | ||||
|  | ||||
| struct do_dlsym_args | ||||
| { | ||||
|   /* Arguments to do_dlsym.  */ | ||||
|   struct link_map *map; | ||||
|   const char *name; | ||||
|  | ||||
|   /* Return values of do_dlsym.  */ | ||||
|   lookup_t loadbase; | ||||
|   const ElfW(Sym) *ref; | ||||
| }; | ||||
|  | ||||
| static void | ||||
| do_dlopen (void *ptr) | ||||
| { | ||||
|   struct do_dlopen_args *args = (struct do_dlopen_args *) ptr; | ||||
|   /* Open and relocate the shared object.  */ | ||||
|   args->map = _dl_open (args->name, RTLD_LAZY, NULL); | ||||
| } | ||||
|  | ||||
| static void | ||||
| do_dlsym (void *ptr) | ||||
| { | ||||
|   struct do_dlsym_args *args = (struct do_dlsym_args *) ptr; | ||||
|   args->ref = NULL; | ||||
|   args->loadbase = _dl_lookup_symbol (args->name, args->map, &args->ref, | ||||
| 				      args->map->l_local_scope, 0, 1); | ||||
| } | ||||
|  | ||||
| static void | ||||
| do_dlclose (void *ptr) | ||||
| { | ||||
|   _dl_close ((struct link_map *) ptr); | ||||
| } | ||||
|  | ||||
| /* ... and these functions call dlerror_run. */ | ||||
|  | ||||
| void * | ||||
| __libc_dlopen (const char *__name) | ||||
| { | ||||
|   struct do_dlopen_args args; | ||||
|   args.name = __name; | ||||
|  | ||||
|   return (dlerror_run (do_dlopen, &args) ? NULL : (void *) args.map); | ||||
| } | ||||
|  | ||||
| void * | ||||
| __libc_dlsym (void *__map, const char *__name) | ||||
| { | ||||
|   struct do_dlsym_args args; | ||||
|   args.map = __map; | ||||
|   args.name = __name; | ||||
|  | ||||
|   return (dlerror_run (do_dlsym, &args) ? NULL | ||||
| 	  : (void *) (DL_SYMBOL_ADDRESS (args.loadbase, args.ref))); | ||||
| } | ||||
|  | ||||
| int | ||||
| __libc_dlclose (void *__map) | ||||
| { | ||||
|   return dlerror_run (do_dlclose, __map); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void | ||||
| free_mem (void) | ||||
| { | ||||
|   struct link_map *l; | ||||
|   struct r_search_path_elem *d; | ||||
|  | ||||
|   /* Remove all search directories.  */ | ||||
|   d = _dl_all_dirs; | ||||
|   while (d != _dl_init_all_dirs) | ||||
|     { | ||||
|       struct r_search_path_elem *old = d; | ||||
|       d = d->next; | ||||
|       free (old); | ||||
|     } | ||||
|  | ||||
|   /* Remove all additional names added to the objects.  */ | ||||
|   for (l = _dl_loaded; l != NULL; l = l->l_next) | ||||
|     { | ||||
|       struct libname_list *lnp = l->l_libname->next; | ||||
|  | ||||
|       l->l_libname->next = NULL; | ||||
|  | ||||
|       while (lnp != NULL) | ||||
| 	{ | ||||
| 	  struct libname_list *old = lnp; | ||||
| 	  lnp = lnp->next; | ||||
| 	  if (! old->dont_free) | ||||
| 	    free (old); | ||||
| 	} | ||||
|     } | ||||
| } | ||||
| text_set_element (__libc_subfreeres, free_mem); | ||||
							
								
								
									
										87
									
								
								newlib/libc/sys/linux/dl/dl-librecon.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								newlib/libc/sys/linux/dl/dl-librecon.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| /* Optional code to distinguish library flavours. | ||||
|    Copyright (C) 1998, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #ifndef _DL_LIBRECON_H | ||||
| #define _DL_LIBRECON_H	1 | ||||
|  | ||||
| #define DISTINGUISH_LIB_VERSIONS \ | ||||
|   do									      \ | ||||
|     {									      \ | ||||
|       /* We have to find out whether the binary is linked against	      \ | ||||
| 	 libc 5 or glibc.  We do this by looking at all the DT_NEEDED	      \ | ||||
| 	 entries.  If one is libc.so.5 this is a libc 5 linked binary.  */    \ | ||||
|       if (_dl_loaded->l_info[DT_NEEDED])				      \ | ||||
| 	{								      \ | ||||
| 	  /* We have dependencies.  */					      \ | ||||
| 	  const ElfW(Dyn) *d;						      \ | ||||
| 	  const char *strtab;						      \ | ||||
| 									      \ | ||||
| 	  strtab = (const char *) D_PTR (_dl_loaded, l_info[DT_STRTAB]);      \ | ||||
| 									      \ | ||||
| 	  for (d = _dl_loaded->l_ld; d->d_tag != DT_NULL; ++d)		      \ | ||||
| 	    if (d->d_tag == DT_NEEDED					      \ | ||||
| 		&& strcmp (strtab + d->d_un.d_val, "libc.so.5") == 0)	      \ | ||||
| 	      break;							      \ | ||||
| 									      \ | ||||
| 	  /* We print a `5' or `6' depending on the outcome.  */	      \ | ||||
| 	  _dl_printf (d->d_tag != DT_NULL ? "5\n" : "6\n");		      \ | ||||
| 	}								      \ | ||||
|     }									      \ | ||||
|   while (0) | ||||
|  | ||||
| /* Recognizing extra environment variables.  */ | ||||
| #define EXTRA_LD_ENVVARS \ | ||||
|   case 13:								      \ | ||||
|     if (memcmp (envline, "ASSUME_KERNEL", 13) == 0)			      \ | ||||
|       {									      \ | ||||
| 	unsigned long int i, j, osversion = 0;				      \ | ||||
| 	char *p = &envline[14], *q;					      \ | ||||
| 									      \ | ||||
| 	for (i = 0; i < 3; i++, p = q + 1)				      \ | ||||
| 	  {								      \ | ||||
| 	    j = __strtoul_internal (p, &q, 0, 0);			      \ | ||||
| 	    if (j >= 255 || p == q || (i < 2 && *q && *q != '.'))	      \ | ||||
| 	      {								      \ | ||||
| 		osversion = 0;						      \ | ||||
| 		break;							      \ | ||||
| 	      }								      \ | ||||
| 	    osversion |= j << (16 - 8 * i);				      \ | ||||
| 	    if (!*q)							      \ | ||||
| 	      break;							      \ | ||||
| 	  }								      \ | ||||
| 	if (osversion)							      \ | ||||
| 	  _dl_osversion = osversion;					      \ | ||||
| 	break;								      \ | ||||
|       }									      \ | ||||
| 									      \ | ||||
|   case 15:								      \ | ||||
|     if (memcmp (envline, "LIBRARY_VERSION", 15) == 0)			      \ | ||||
|       {									      \ | ||||
| 	_dl_correct_cache_id = envline[16] == '5' ? 2 : 3;		      \ | ||||
| 	break;								      \ | ||||
|       } | ||||
|  | ||||
| /* Extra unsecure variables.  The names are all stuffed in a single | ||||
|    string which means they have to be terminated with a '\0' explicitly.  */ | ||||
| #define EXTRA_UNSECURE_ENVVARS \ | ||||
|   "LD_AOUT_LIBRARY_PATH\0"						      \ | ||||
|   "LD_AOUT_PRELOAD\0" | ||||
|  | ||||
| #endif /* dl-librecon.h */ | ||||
							
								
								
									
										1830
									
								
								newlib/libc/sys/linux/dl/dl-load.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1830
									
								
								newlib/libc/sys/linux/dl/dl-load.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										654
									
								
								newlib/libc/sys/linux/dl/dl-lookup.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										654
									
								
								newlib/libc/sys/linux/dl/dl-lookup.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,654 @@ | ||||
| /* Look up a symbol in the loaded objects. | ||||
|    Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <alloca.h> | ||||
| #include <libintl.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <ldsodefs.h> | ||||
| #include "dl-hash.h" | ||||
| #include <machine/dl-machine.h> | ||||
| #include <bits/libc-lock.h> | ||||
|  | ||||
| #include <assert.h> | ||||
|  | ||||
| #define VERSTAG(tag)	(DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag)) | ||||
|  | ||||
| /* We need this string more than once.  */ | ||||
| static const char undefined_msg[] = "undefined symbol: "; | ||||
|  | ||||
|  | ||||
| struct sym_val | ||||
|   { | ||||
|     const ElfW(Sym) *s; | ||||
|     struct link_map *m; | ||||
|   }; | ||||
|  | ||||
|  | ||||
| #define make_string(string, rest...) \ | ||||
|   ({									      \ | ||||
|     const char *all[] = { string, ## rest };				      \ | ||||
|     size_t len, cnt;							      \ | ||||
|     char *result, *cp;							      \ | ||||
| 									      \ | ||||
|     len = 1;								      \ | ||||
|     for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt)		      \ | ||||
|       len += strlen (all[cnt]);						      \ | ||||
| 									      \ | ||||
|     cp = result = alloca (len);						      \ | ||||
|     for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt)		      \ | ||||
|     {                                                                         \ | ||||
|       cp = strcpy (cp, all[cnt]);					      \ | ||||
|       cp += strlen(all[cnt]);                                                 \ | ||||
|     }                                                                         \ | ||||
| 									      \ | ||||
|     result;								      \ | ||||
|   }) | ||||
|  | ||||
| /* Statistics function.  */ | ||||
| unsigned long int _dl_num_relocations; | ||||
|  | ||||
|  | ||||
| /* We have two different situations when looking up a simple: with or | ||||
|    without versioning.  gcc is not able to optimize a single function | ||||
|    definition serving for both purposes so we define two functions.  */ | ||||
| #define VERSIONED	0 | ||||
| #include "do-lookup.h" | ||||
|  | ||||
| #define VERSIONED	1 | ||||
| #include "do-lookup.h" | ||||
|  | ||||
|  | ||||
| /* Add extra dependency on MAP to UNDEF_MAP.  */ | ||||
| static int | ||||
| internal_function | ||||
| add_dependency (struct link_map *undef_map, struct link_map *map) | ||||
| { | ||||
|   struct link_map **list; | ||||
|   struct link_map *runp; | ||||
|   unsigned int act; | ||||
|   unsigned int i; | ||||
|   int result = 0; | ||||
|  | ||||
|   /* Avoid self-references.  */ | ||||
|   if (undef_map == map) | ||||
|     return 0; | ||||
|  | ||||
|   /* Make sure nobody can unload the object while we are at it.  */ | ||||
| #ifdef HAVE_DD_LOCK | ||||
|     __lock_acquire(_dl_load_lock); | ||||
| #endif | ||||
|  | ||||
|  | ||||
|   /* Determine whether UNDEF_MAP already has a reference to MAP.  First | ||||
|      look in the normal dependencies.  */ | ||||
|   if (undef_map->l_searchlist.r_list != NULL) | ||||
|     { | ||||
|       list = undef_map->l_initfini; | ||||
|  | ||||
|       for (i = 0; list[i] != NULL; ++i) | ||||
| 	if (list[i] == map) | ||||
| 	  goto out; | ||||
|     } | ||||
|  | ||||
|   /* No normal dependency.  See whether we already had to add it | ||||
|      to the special list of dynamic dependencies.  */ | ||||
|   list = undef_map->l_reldeps; | ||||
|   act = undef_map->l_reldepsact; | ||||
|  | ||||
|   for (i = 0; i < act; ++i) | ||||
|     if (list[i] == map) | ||||
|       goto out; | ||||
|  | ||||
|   /* The object is not yet in the dependency list.  Before we add | ||||
|      it make sure just one more time the object we are about to | ||||
|      reference is still available.  There is a brief period in | ||||
|      which the object could have been removed since we found the | ||||
|      definition.  */ | ||||
|   runp = _dl_loaded; | ||||
|   while (runp != NULL && runp != map) | ||||
|     runp = runp->l_next; | ||||
|  | ||||
|   if (runp != NULL) | ||||
|     { | ||||
|       /* The object is still available.  Add the reference now.  */ | ||||
|       if (__builtin_expect (act >= undef_map->l_reldepsmax, 0)) | ||||
| 	{ | ||||
| 	  /* Allocate more memory for the dependency list.  Since this | ||||
| 	     can never happen during the startup phase we can use | ||||
| 	     `realloc'.  */ | ||||
| 	  void *newp; | ||||
|  | ||||
| 	  undef_map->l_reldepsmax += 5; | ||||
| 	  newp = realloc (undef_map->l_reldeps, | ||||
| 			  undef_map->l_reldepsmax | ||||
| 			  * sizeof (struct link_map *)); | ||||
|  | ||||
| 	  if (__builtin_expect (newp != NULL, 1)) | ||||
| 	    undef_map->l_reldeps = (struct link_map **) newp; | ||||
| 	  else | ||||
| 	    /* Correct the addition.  */ | ||||
| 	    undef_map->l_reldepsmax -= 5; | ||||
| 	} | ||||
|  | ||||
|       /* If we didn't manage to allocate memory for the list this is | ||||
| 	 no fatal mistake.  We simply increment the use counter of the | ||||
| 	 referenced object and don't record the dependencies.  This | ||||
| 	 means this increment can never be reverted and the object | ||||
| 	 will never be unloaded.  This is semantically the correct | ||||
| 	 behaviour.  */ | ||||
|       if (__builtin_expect (act < undef_map->l_reldepsmax, 1)) | ||||
| 	undef_map->l_reldeps[undef_map->l_reldepsact++] = map; | ||||
|  | ||||
|       if (map->l_searchlist.r_list != NULL) | ||||
| 	/* And increment the counter in the referenced object.  */ | ||||
| 	++map->l_opencount; | ||||
|       else | ||||
| 	/* We have to bump the counts for all dependencies since so far | ||||
| 	   this object was only a normal or transitive dependency. | ||||
| 	   Now it might be closed with _dl_close() directly.  */ | ||||
| 	for (list = map->l_initfini; *list != NULL; ++list) | ||||
| 	  ++(*list)->l_opencount; | ||||
|  | ||||
|       /* Display information if we are debugging.  */ | ||||
|       if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) | ||||
| 	_dl_debug_printf ("\ | ||||
| \nfile=%s;  needed by %s (relocation dependency)\n\n", | ||||
| 			  map->l_name[0] ? map->l_name : _dl_argv[0], | ||||
| 			  undef_map->l_name[0] | ||||
| 			  ? undef_map->l_name : _dl_argv[0]); | ||||
|     } | ||||
|   else | ||||
|     /* Whoa, that was bad luck.  We have to search again.  */ | ||||
|     result = -1; | ||||
|  | ||||
|  out: | ||||
|   /* Release the lock.  */ | ||||
| #ifdef HAVE_DD_LOCK | ||||
|     __lock_release(_dl_load_lock); | ||||
| #endif | ||||
|  | ||||
|  | ||||
|   return result; | ||||
| } | ||||
|  | ||||
| static int | ||||
| internal_function | ||||
| _dl_do_lookup (const char *undef_name, unsigned long int hash, | ||||
| 	       const ElfW(Sym) *ref, struct sym_val *result, | ||||
| 	       struct r_scope_elem *scope, size_t i, | ||||
| 	       struct link_map *skip, int type_class); | ||||
| static int | ||||
| internal_function | ||||
| _dl_do_lookup_versioned (const char *undef_name, unsigned long int hash, | ||||
| 			 const ElfW(Sym) *ref, struct sym_val *result, | ||||
| 			 struct r_scope_elem *scope, size_t i, | ||||
| 			 const struct r_found_version *const version, | ||||
| 			 struct link_map *skip, int type_class); | ||||
|  | ||||
|  | ||||
| /* Search loaded objects' symbol tables for a definition of the symbol | ||||
|    UNDEF_NAME.  */ | ||||
|  | ||||
| lookup_t | ||||
| internal_function | ||||
| _dl_lookup_symbol (const char *undef_name, struct link_map *undef_map, | ||||
| 		   const ElfW(Sym) **ref, struct r_scope_elem *symbol_scope[], | ||||
| 		   int type_class, int explicit) | ||||
| { | ||||
|   unsigned long int hash = _dl_elf_hash (undef_name); | ||||
|   struct sym_val current_value = { NULL, NULL }; | ||||
|   struct r_scope_elem **scope; | ||||
|   int protected; | ||||
|  | ||||
|   ++_dl_num_relocations; | ||||
|  | ||||
|   /* Search the relevant loaded objects for a definition.  */ | ||||
|   for (scope = symbol_scope; *scope; ++scope) | ||||
|     if (do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0, NULL, | ||||
| 		   type_class)) | ||||
|       { | ||||
| 	/* We have to check whether this would bind UNDEF_MAP to an object | ||||
| 	   in the global scope which was dynamically loaded.  In this case | ||||
| 	   we have to prevent the latter from being unloaded unless the | ||||
| 	   UNDEF_MAP object is also unloaded.  */ | ||||
| 	if (__builtin_expect (current_value.m->l_type == lt_loaded, 0) | ||||
| 	    /* Don't do this for explicit lookups as opposed to implicit | ||||
| 	       runtime lookups.  */ | ||||
| 	    && ! explicit | ||||
| 	    /* Add UNDEF_MAP to the dependencies.  */ | ||||
| 	    && add_dependency (undef_map, current_value.m) < 0) | ||||
| 	  /* Something went wrong.  Perhaps the object we tried to reference | ||||
| 	     was just removed.  Try finding another definition.  */ | ||||
| 	  return _dl_lookup_symbol (undef_name, undef_map, ref, symbol_scope, | ||||
| 				    type_class, 0); | ||||
|  | ||||
| 	break; | ||||
|       } | ||||
|  | ||||
|   if (__builtin_expect (current_value.s == NULL, 0)) | ||||
|     { | ||||
|       const char *reference_name = undef_map ? undef_map->l_name : NULL; | ||||
|  | ||||
|       if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) | ||||
| 	/* We could find no value for a strong reference.  */ | ||||
| 	/* XXX We cannot translate the messages.  */ | ||||
| 	_dl_signal_cerror (0, (reference_name && reference_name[0] | ||||
| 			       ? reference_name | ||||
| 			       : (_dl_argv[0] ?: "<main program>")), | ||||
| 			   N_("relocation error"), | ||||
| 			   make_string (undefined_msg, undef_name)); | ||||
|       *ref = NULL; | ||||
|       return 0; | ||||
|     } | ||||
|  | ||||
|   protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED; | ||||
|  | ||||
|   if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0)) | ||||
|     { | ||||
|       const char *reference_name = undef_map ? undef_map->l_name : NULL; | ||||
|  | ||||
|       _dl_debug_printf ("binding file %s to %s: %s symbol `%s'\n", | ||||
| 			(reference_name && reference_name[0] | ||||
| 			 ? reference_name : (_dl_argv[0] ?: "<main program>")), | ||||
| 			current_value.m->l_name[0] | ||||
| 			? current_value.m->l_name : _dl_argv[0], | ||||
| 			protected ? "protected" : "normal", undef_name); | ||||
|     } | ||||
|  | ||||
|   if (__builtin_expect (protected == 0, 1)) | ||||
|     { | ||||
|       *ref = current_value.s; | ||||
|       return LOOKUP_VALUE (current_value.m); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* It is very tricky. We need to figure out what value to | ||||
|          return for the protected symbol */ | ||||
|       struct sym_val protected_value = { NULL, NULL }; | ||||
|  | ||||
|       for (scope = symbol_scope; *scope; ++scope) | ||||
| 	if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope, | ||||
| 			   0, NULL, ELF_RTYPE_CLASS_PLT)) | ||||
| 	  break; | ||||
|  | ||||
|       if (protected_value.s == NULL || protected_value.m == undef_map) | ||||
| 	{ | ||||
| 	  *ref = current_value.s; | ||||
| 	  return LOOKUP_VALUE (current_value.m); | ||||
| 	} | ||||
|  | ||||
|       return LOOKUP_VALUE (undef_map); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| /* This function is nearly the same as `_dl_lookup_symbol' but it | ||||
|    skips in the first list all objects until SKIP_MAP is found.  I.e., | ||||
|    it only considers objects which were loaded after the described | ||||
|    object.  If there are more search lists the object described by | ||||
|    SKIP_MAP is only skipped.  */ | ||||
| lookup_t | ||||
| internal_function | ||||
| _dl_lookup_symbol_skip (const char *undef_name, | ||||
| 			struct link_map *undef_map, const ElfW(Sym) **ref, | ||||
| 			struct r_scope_elem *symbol_scope[], | ||||
| 			struct link_map *skip_map) | ||||
| { | ||||
|   const char *reference_name = undef_map ? undef_map->l_name : NULL; | ||||
|   const unsigned long int hash = _dl_elf_hash (undef_name); | ||||
|   struct sym_val current_value = { NULL, NULL }; | ||||
|   struct r_scope_elem **scope; | ||||
|   size_t i; | ||||
|   int protected; | ||||
|  | ||||
|   ++_dl_num_relocations; | ||||
|  | ||||
|   /* Search the relevant loaded objects for a definition.  */ | ||||
|   scope = symbol_scope; | ||||
|   for (i = 0; (*scope)->r_list[i] != skip_map; ++i) | ||||
|     assert (i < (*scope)->r_nlist); | ||||
|  | ||||
|   if (! _dl_do_lookup (undef_name, hash, *ref, ¤t_value, *scope, i, | ||||
| 		       skip_map, 0)) | ||||
|     while (*++scope) | ||||
|       if (_dl_do_lookup (undef_name, hash, *ref, ¤t_value, *scope, 0, | ||||
| 			 skip_map, 0)) | ||||
| 	break; | ||||
|  | ||||
|   if (__builtin_expect (current_value.s == NULL, 0)) | ||||
|     { | ||||
|       *ref = NULL; | ||||
|       return 0; | ||||
|     } | ||||
|  | ||||
|   protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED; | ||||
|  | ||||
|   if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0)) | ||||
|     _dl_debug_printf ("binding file %s to %s: %s symbol `%s'\n", | ||||
| 		       (reference_name && reference_name[0] | ||||
| 			? reference_name : (_dl_argv[0] ?: "<main program>")), | ||||
| 		       current_value.m->l_name[0] | ||||
| 		       ? current_value.m->l_name : _dl_argv[0], | ||||
| 		       protected ? "protected" : "normal", undef_name); | ||||
|  | ||||
|   if (__builtin_expect (protected == 0, 1)) | ||||
|     { | ||||
|       *ref = current_value.s; | ||||
|       return LOOKUP_VALUE (current_value.m); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* It is very tricky.  We need to figure out what value to | ||||
|          return for the protected symbol.  */ | ||||
|       struct sym_val protected_value = { NULL, NULL }; | ||||
|  | ||||
|       if (i >= (*scope)->r_nlist | ||||
| 	  || !_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope, | ||||
| 			     i, skip_map, ELF_RTYPE_CLASS_PLT)) | ||||
| 	while (*++scope) | ||||
| 	  if (_dl_do_lookup (undef_name, hash, *ref, &protected_value, *scope, | ||||
| 			     0, skip_map, ELF_RTYPE_CLASS_PLT)) | ||||
| 	    break; | ||||
|  | ||||
|       if (protected_value.s == NULL || protected_value.m == undef_map) | ||||
| 	{ | ||||
| 	  *ref = current_value.s; | ||||
| 	  return LOOKUP_VALUE (current_value.m); | ||||
| 	} | ||||
|  | ||||
|       return LOOKUP_VALUE (undef_map); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| /* This function works like _dl_lookup_symbol but it takes an | ||||
|    additional arguement with the version number of the requested | ||||
|    symbol. | ||||
|  | ||||
|    XXX We'll see whether we need this separate function.  */ | ||||
| lookup_t | ||||
| internal_function | ||||
| _dl_lookup_versioned_symbol (const char *undef_name, | ||||
| 			     struct link_map *undef_map, const ElfW(Sym) **ref, | ||||
| 			     struct r_scope_elem *symbol_scope[], | ||||
| 			     const struct r_found_version *version, | ||||
| 			     int type_class, int explicit) | ||||
| { | ||||
|   unsigned long int hash = _dl_elf_hash (undef_name); | ||||
|   struct sym_val current_value = { NULL, NULL }; | ||||
|   struct r_scope_elem **scope; | ||||
|   int protected; | ||||
|  | ||||
|   ++_dl_num_relocations; | ||||
|  | ||||
|   /* Search the relevant loaded objects for a definition.  */ | ||||
|   for (scope = symbol_scope; *scope; ++scope) | ||||
|     { | ||||
|       int res = do_lookup_versioned (undef_name, hash, *ref, ¤t_value, | ||||
| 				     *scope, 0, version, NULL, type_class); | ||||
|       if (res > 0) | ||||
| 	{ | ||||
| 	  /* We have to check whether this would bind UNDEF_MAP to an object | ||||
| 	     in the global scope which was dynamically loaded.  In this case | ||||
| 	     we have to prevent the latter from being unloaded unless the | ||||
| 	     UNDEF_MAP object is also unloaded.  */ | ||||
| 	  if (__builtin_expect (current_value.m->l_type == lt_loaded, 0) | ||||
| 	      /* Don't do this for explicit lookups as opposed to implicit | ||||
| 		 runtime lookups.  */ | ||||
| 	      && ! explicit | ||||
| 	      /* Add UNDEF_MAP to the dependencies.  */ | ||||
| 	      && add_dependency (undef_map, current_value.m) < 0) | ||||
| 	    /* Something went wrong.  Perhaps the object we tried to reference | ||||
| 	       was just removed.  Try finding another definition.  */ | ||||
| 	    return _dl_lookup_versioned_symbol (undef_name, undef_map, ref, | ||||
| 						symbol_scope, version, | ||||
| 						type_class, 0); | ||||
|  | ||||
| 	  break; | ||||
| 	} | ||||
|  | ||||
|       if (__builtin_expect (res, 0) < 0) | ||||
| 	{ | ||||
| 	  /* Oh, oh.  The file named in the relocation entry does not | ||||
| 	     contain the needed symbol.  */ | ||||
| 	  const char *reference_name = undef_map ? undef_map->l_name : NULL; | ||||
|  | ||||
| 	  /* XXX We cannot translate the message.  */ | ||||
| 	  _dl_signal_cerror (0, (reference_name && reference_name[0] | ||||
| 				 ? reference_name | ||||
| 				 : (_dl_argv[0] ?: "<main program>")), | ||||
| 			     N_("relocation error"), | ||||
| 			     make_string ("symbol ", undef_name, ", version ", | ||||
| 					  version->name, | ||||
| 					  " not defined in file ", | ||||
| 					  version->filename, | ||||
| 					  " with link time reference", | ||||
| 					  res == -2 | ||||
| 					  ? " (no version symbols)" : "")); | ||||
| 	  *ref = NULL; | ||||
| 	  return 0; | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   if (__builtin_expect (current_value.s == NULL, 0)) | ||||
|     { | ||||
|       if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) | ||||
| 	{ | ||||
| 	  /* We could find no value for a strong reference.  */ | ||||
| 	  const char *reference_name = undef_map ? undef_map->l_name : NULL; | ||||
|  | ||||
| 	  /* XXX We cannot translate the message.  */ | ||||
| 	  _dl_signal_cerror (0, (reference_name && reference_name[0] | ||||
| 				 ? reference_name | ||||
| 				 : (_dl_argv[0] ?: "<main program>")), NULL, | ||||
| 			     make_string (undefined_msg, undef_name, | ||||
| 					  ", version ", | ||||
| 					  version->name ?: NULL)); | ||||
| 	} | ||||
|       *ref = NULL; | ||||
|       return 0; | ||||
|     } | ||||
|  | ||||
|   protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED; | ||||
|  | ||||
|   if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0)) | ||||
|     { | ||||
|       const char *reference_name = undef_map ? undef_map->l_name : NULL; | ||||
|  | ||||
|       _dl_debug_printf ("binding file %s to %s: %s symbol `%s' [%s]\n", | ||||
| 			(reference_name && reference_name[0] | ||||
| 			 ? reference_name : (_dl_argv[0] ?: "<main program>")), | ||||
| 			current_value.m->l_name[0] | ||||
| 			? current_value.m->l_name : _dl_argv[0], | ||||
| 			protected ? "protected" : "normal", | ||||
| 			undef_name, version->name); | ||||
|     } | ||||
|  | ||||
|   if (__builtin_expect (protected == 0, 1)) | ||||
|     { | ||||
|       *ref = current_value.s; | ||||
|       return LOOKUP_VALUE (current_value.m); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* It is very tricky. We need to figure out what value to | ||||
|          return for the protected symbol */ | ||||
|       struct sym_val protected_value = { NULL, NULL }; | ||||
|  | ||||
|       for (scope = symbol_scope; *scope; ++scope) | ||||
| 	if (_dl_do_lookup_versioned (undef_name, hash, *ref, &protected_value, | ||||
| 				     *scope, 0, version, NULL, | ||||
| 				     ELF_RTYPE_CLASS_PLT)) | ||||
| 	  break; | ||||
|  | ||||
|       if (protected_value.s == NULL || protected_value.m == undef_map) | ||||
| 	{ | ||||
| 	  *ref = current_value.s; | ||||
| 	  return LOOKUP_VALUE (current_value.m); | ||||
| 	} | ||||
|  | ||||
|       return LOOKUP_VALUE (undef_map); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Similar to _dl_lookup_symbol_skip but takes an additional argument | ||||
|    with the version we are looking for.  */ | ||||
| lookup_t | ||||
| internal_function | ||||
| _dl_lookup_versioned_symbol_skip (const char *undef_name, | ||||
| 				  struct link_map *undef_map, | ||||
| 				  const ElfW(Sym) **ref, | ||||
| 				  struct r_scope_elem *symbol_scope[], | ||||
| 				  const struct r_found_version *version, | ||||
| 				  struct link_map *skip_map) | ||||
| { | ||||
|   const char *reference_name = undef_map ? undef_map->l_name : NULL; | ||||
|   const unsigned long int hash = _dl_elf_hash (undef_name); | ||||
|   struct sym_val current_value = { NULL, NULL }; | ||||
|   struct r_scope_elem **scope; | ||||
|   size_t i; | ||||
|   int protected; | ||||
|  | ||||
|   ++_dl_num_relocations; | ||||
|  | ||||
|   /* Search the relevant loaded objects for a definition.  */ | ||||
|   scope = symbol_scope; | ||||
|   for (i = 0; (*scope)->r_list[i] != skip_map; ++i) | ||||
|     assert (i < (*scope)->r_nlist); | ||||
|  | ||||
|   if (! _dl_do_lookup_versioned (undef_name, hash, *ref, ¤t_value, | ||||
| 				 *scope, i, version, skip_map, 0)) | ||||
|     while (*++scope) | ||||
|       if (_dl_do_lookup_versioned (undef_name, hash, *ref, ¤t_value, | ||||
| 				   *scope, 0, version, skip_map, 0)) | ||||
| 	break; | ||||
|  | ||||
|   if (__builtin_expect (current_value.s == NULL, 0)) | ||||
|     { | ||||
|       if (*ref == NULL || ELFW(ST_BIND) ((*ref)->st_info) != STB_WEAK) | ||||
| 	{ | ||||
| 	  /* We could find no value for a strong reference.  */ | ||||
| 	  const size_t len = strlen (undef_name); | ||||
| 	  char buf[sizeof undefined_msg + len]; | ||||
|           char *tmp; | ||||
|           tmp = memcpy (buf, undefined_msg, sizeof undefined_msg - 1); | ||||
|           tmp += (sizeof undefined_msg - 1); | ||||
|  | ||||
| 	  memcpy (tmp, undef_name, len + 1); | ||||
|  | ||||
| 	  /* XXX We cannot translate the messages.  */ | ||||
| 	  _dl_signal_cerror (0, (reference_name && reference_name[0] | ||||
| 				 ? reference_name | ||||
| 				 : (_dl_argv[0] ?: "<main program>")), | ||||
| 			     NULL, buf); | ||||
| 	} | ||||
|       *ref = NULL; | ||||
|       return 0; | ||||
|     } | ||||
|  | ||||
|   protected = *ref && ELFW(ST_VISIBILITY) ((*ref)->st_other) == STV_PROTECTED; | ||||
|  | ||||
|   if (__builtin_expect (_dl_debug_mask & DL_DEBUG_BINDINGS, 0)) | ||||
|     _dl_debug_printf ("binding file %s to %s: %s symbol `%s' [%s]\n", | ||||
| 		      (reference_name && reference_name[0] | ||||
| 		       ? reference_name : (_dl_argv[0] ?: "<main program>")), | ||||
| 		      current_value.m->l_name[0] | ||||
| 		      ? current_value.m->l_name : _dl_argv[0], | ||||
| 		      protected ? "protected" : "normal", | ||||
| 		      undef_name, version->name); | ||||
|  | ||||
|   if (__builtin_expect (protected == 0, 1)) | ||||
|     { | ||||
|       *ref = current_value.s; | ||||
|       return LOOKUP_VALUE (current_value.m); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* It is very tricky. We need to figure out what value to | ||||
|          return for the protected symbol */ | ||||
|       struct sym_val protected_value = { NULL, NULL }; | ||||
|  | ||||
|       if (i >= (*scope)->r_nlist | ||||
| 	  || !_dl_do_lookup_versioned (undef_name, hash, *ref, | ||||
| 				       &protected_value, *scope, i, version, | ||||
| 				       skip_map, ELF_RTYPE_CLASS_PLT)) | ||||
| 	while (*++scope) | ||||
| 	  if (_dl_do_lookup_versioned (undef_name, hash, *ref, | ||||
| 				       &protected_value, *scope, 0, version, | ||||
| 				       skip_map, ELF_RTYPE_CLASS_PLT)) | ||||
| 	    break; | ||||
|  | ||||
|       if (protected_value.s == NULL || protected_value.m == undef_map) | ||||
| 	{ | ||||
| 	  *ref = current_value.s; | ||||
| 	  return LOOKUP_VALUE (current_value.m); | ||||
| 	} | ||||
|  | ||||
|       return LOOKUP_VALUE (undef_map); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Cache the location of MAP's hash table.  */ | ||||
|  | ||||
| void | ||||
| internal_function | ||||
| _dl_setup_hash (struct link_map *map) | ||||
| { | ||||
|   Elf_Symndx *hash; | ||||
|   Elf_Symndx nchain; | ||||
|  | ||||
|   if (!map->l_info[DT_HASH]) | ||||
|     return; | ||||
|   hash = (void *)(map->l_addr + map->l_info[DT_HASH]->d_un.d_ptr); | ||||
|  | ||||
|   map->l_nbuckets = *hash++; | ||||
|   nchain = *hash++; | ||||
|   map->l_buckets = hash; | ||||
|   hash += map->l_nbuckets; | ||||
|   map->l_chain = hash; | ||||
| } | ||||
|  | ||||
| /* These are here so that we only inline do_lookup{,_versioned} in the common | ||||
|    case, not everywhere.  */ | ||||
| static int | ||||
| internal_function | ||||
| _dl_do_lookup (const char *undef_name, unsigned long int hash, | ||||
| 	       const ElfW(Sym) *ref, struct sym_val *result, | ||||
| 	       struct r_scope_elem *scope, size_t i, | ||||
| 	       struct link_map *skip, int type_class) | ||||
| { | ||||
|   return do_lookup (undef_name, hash, ref, result, scope, i, skip, | ||||
| 		    type_class); | ||||
| } | ||||
|  | ||||
| static int | ||||
| internal_function | ||||
| _dl_do_lookup_versioned (const char *undef_name, unsigned long int hash, | ||||
| 			 const ElfW(Sym) *ref, struct sym_val *result, | ||||
| 			 struct r_scope_elem *scope, size_t i, | ||||
| 			 const struct r_found_version *const version, | ||||
| 			 struct link_map *skip, int type_class) | ||||
| { | ||||
|   return do_lookup_versioned (undef_name, hash, ref, result, scope, i, | ||||
| 			      version, skip, type_class); | ||||
| } | ||||
							
								
								
									
										22
									
								
								newlib/libc/sys/linux/dl/dl-lookupcfg.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								newlib/libc/sys/linux/dl/dl-lookupcfg.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| /* Configuration of lookup functions. | ||||
|    Copyright (C) 2000 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| /* Some platforms need more information from the symbol lookup function | ||||
|    than just the address.  But this is not generally the case.  */ | ||||
| #undef DL_LOOKUP_RETURNS_MAP | ||||
							
								
								
									
										250
									
								
								newlib/libc/sys/linux/dl/dl-minimal.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										250
									
								
								newlib/libc/sys/linux/dl/dl-minimal.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,250 @@ | ||||
| /* Minimal replacements for basic facilities used in the dynamic linker. | ||||
|    Copyright (C) 1995,96,97,98,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <limits.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/mman.h> | ||||
| #include <ldsodefs.h> | ||||
| #include <machine/weakalias.h> | ||||
|  | ||||
| #include <assert.h> | ||||
|  | ||||
| /* Minimal `malloc' allocator for use while loading shared libraries. | ||||
|    No block is ever freed.  */ | ||||
|  | ||||
| static void *alloc_ptr, *alloc_end, *alloc_last_block; | ||||
|  | ||||
| /* Declarations of global functions.  */ | ||||
| extern void weak_function free (void *ptr); | ||||
| extern void * weak_function realloc (void *ptr, size_t n); | ||||
| extern unsigned long int weak_function __strtoul_internal | ||||
| (const char *nptr, char **endptr, int base, int group); | ||||
| extern unsigned long int weak_function strtoul (const char *nptr, | ||||
| 						char **endptr, int base); | ||||
|  | ||||
|  | ||||
| void * weak_function | ||||
| malloc (size_t n) | ||||
| { | ||||
| #ifdef MAP_ANON | ||||
| #define	_dl_zerofd (-1) | ||||
| #else | ||||
|   extern int _dl_zerofd; | ||||
|  | ||||
|   if (_dl_zerofd == -1) | ||||
|     _dl_zerofd = _dl_sysdep_open_zero_fill (); | ||||
| #define MAP_ANON 0 | ||||
| #endif | ||||
|  | ||||
|   if (alloc_end == 0) | ||||
|     { | ||||
|       /* Consume any unused space in the last page of our data segment.  */ | ||||
|       extern int _end; | ||||
|       alloc_ptr = &_end; | ||||
|       alloc_end = (void *) 0 + (((alloc_ptr - (void *) 0) + _dl_pagesize - 1) | ||||
| 				& ~(_dl_pagesize - 1)); | ||||
|     } | ||||
|  | ||||
|   /* Make sure the allocation pointer is ideally aligned.  */ | ||||
|   alloc_ptr = (void *) 0 + (((alloc_ptr - (void *) 0) + sizeof (double) - 1) | ||||
| 			    & ~(sizeof (double) - 1)); | ||||
|  | ||||
|   if (alloc_ptr + n >= alloc_end) | ||||
|     { | ||||
|       /* Insufficient space left; allocate another page.  */ | ||||
|       caddr_t page; | ||||
|       size_t nup = (n + _dl_pagesize - 1) & ~(_dl_pagesize - 1); | ||||
|       page = __mmap (0, nup, PROT_READ|PROT_WRITE, | ||||
| 		     MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0); | ||||
|       assert (page != MAP_FAILED); | ||||
|       if (page != alloc_end) | ||||
| 	alloc_ptr = page; | ||||
|       alloc_end = page + nup; | ||||
|     } | ||||
|  | ||||
|   alloc_last_block = (void *) alloc_ptr; | ||||
|   alloc_ptr += n; | ||||
|   return alloc_last_block; | ||||
| } | ||||
|  | ||||
| /* We use this function occasionally since the real implementation may | ||||
|    be optimized when it can assume the memory it returns already is | ||||
|    set to NUL.  */ | ||||
| void * weak_function | ||||
| calloc (size_t nmemb, size_t size) | ||||
| { | ||||
|   size_t total = nmemb * size; | ||||
|   void *result = malloc (total); | ||||
|   return memset (result, '\0', total); | ||||
| } | ||||
|  | ||||
| /* This will rarely be called.  */ | ||||
| void weak_function | ||||
| free (void *ptr) | ||||
| { | ||||
|   /* We can free only the last block allocated.  */ | ||||
|   if (ptr == alloc_last_block) | ||||
|     alloc_ptr = alloc_last_block; | ||||
| } | ||||
|  | ||||
| /* This is only called with the most recent block returned by malloc.  */ | ||||
| void * weak_function | ||||
| realloc (void *ptr, size_t n) | ||||
| { | ||||
|   void *new; | ||||
|   if (ptr == NULL) | ||||
|     return malloc (n); | ||||
|   assert (ptr == alloc_last_block); | ||||
|   alloc_ptr = alloc_last_block; | ||||
|   new = malloc (n); | ||||
|   assert (new == ptr); | ||||
|   return new; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Define our own version of the internal function used by strerror.  We | ||||
|    only provide the messages for some common errors.  This avoids pulling | ||||
|    in the whole error list.  */ | ||||
|  | ||||
| char * weak_function | ||||
| __strerror_r (int errnum, char *buf, size_t buflen) | ||||
| { | ||||
|   char *msg; | ||||
|  | ||||
|   switch (errnum) | ||||
|     { | ||||
|     case ENOMEM: | ||||
|       msg = (char *) "Cannot allocate memory"; | ||||
|       break; | ||||
|     case EINVAL: | ||||
|       msg = (char *) "Invalid argument"; | ||||
|       break; | ||||
|     case ENOENT: | ||||
|       msg = (char *) "No such file or directory"; | ||||
|       break; | ||||
|     case EPERM: | ||||
|       msg = (char *) "Operation not permitted"; | ||||
|       break; | ||||
|     case EIO: | ||||
|       msg = (char *) "Input/output error"; | ||||
|       break; | ||||
|     case EACCES: | ||||
|       msg = (char *) "Permission denied"; | ||||
|       break; | ||||
|     default: | ||||
|       /* No need to check buffer size, all calls in the dynamic linker | ||||
| 	 provide enough space.  */ | ||||
|       msg = (char *) "Error"; | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|   return msg; | ||||
| } | ||||
|  | ||||
| #ifndef NDEBUG | ||||
|  | ||||
| /* Define (weakly) our own assert failure function which doesn't use stdio. | ||||
|    If we are linked into the user program (-ldl), the normal __assert_fail | ||||
|    defn can override this one.  */ | ||||
|  | ||||
| void weak_function | ||||
| __assert_fail (const char *assertion, | ||||
| 	       const char *file, unsigned int line, const char *function) | ||||
| { | ||||
|   _dl_fatal_printf ("\ | ||||
| Inconsistency detected by ld.so: %s: %u: %s%sAssertion `%s' failed!\n", | ||||
| 		    file, line, function ?: "", function ? ": " : "", | ||||
| 		    assertion); | ||||
|  | ||||
| } | ||||
|  | ||||
| void weak_function | ||||
| __assert_perror_fail (int errnum, | ||||
| 		      const char *file, unsigned int line, | ||||
| 		      const char *function) | ||||
| { | ||||
|   char errbuf[64]; | ||||
|   _dl_fatal_printf ("\ | ||||
| Inconsistency detected by ld.so: %s: %u: %s%sUnexpected error: %s\n", | ||||
| 		    file, line, function ?: "", function ? ": " : "", | ||||
| 		    __strerror_r (errnum, errbuf, sizeof (errbuf))); | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| unsigned long int weak_function | ||||
| __strtoul_internal (const char *nptr, char **endptr, int base, int group) | ||||
| { | ||||
|   unsigned long int result = 0; | ||||
|   long int sign = 1; | ||||
|  | ||||
|   while (*nptr == ' ' || *nptr == '\t') | ||||
|     ++nptr; | ||||
|  | ||||
|   if (*nptr == '-') | ||||
|     { | ||||
|       sign = -1; | ||||
|       ++nptr; | ||||
|     } | ||||
|   else if (*nptr == '+') | ||||
|     ++nptr; | ||||
|  | ||||
|   if (*nptr < '0' || *nptr > '9') | ||||
|     { | ||||
|       if (endptr != NULL) | ||||
| 	*endptr = (char *) nptr; | ||||
|       return 0UL; | ||||
|     } | ||||
|  | ||||
|   assert (base == 0); | ||||
|   base = 10; | ||||
|   if (*nptr == '0') | ||||
|     { | ||||
|       if (nptr[1] == 'x' || nptr[1] == 'X') | ||||
| 	{ | ||||
| 	  base = 16; | ||||
| 	  nptr += 2; | ||||
| 	} | ||||
|       else | ||||
| 	base = 8; | ||||
|     } | ||||
|  | ||||
|   while (*nptr >= '0' && *nptr <= '9') | ||||
|     { | ||||
|       unsigned long int digval = *nptr - '0'; | ||||
|       if (result > LONG_MAX / 10 | ||||
| 	  || (result == ULONG_MAX / 10 && digval > ULONG_MAX % 10)) | ||||
| 	{ | ||||
| 	  errno = ERANGE; | ||||
| 	  if (endptr != NULL) | ||||
| 	    *endptr = (char *) nptr; | ||||
| 	  return ULONG_MAX; | ||||
| 	} | ||||
|       result *= base; | ||||
|       result += digval; | ||||
|       ++nptr; | ||||
|     } | ||||
|  | ||||
|   if (endptr != NULL) | ||||
|     *endptr = (char *) nptr; | ||||
|   return result * sign; | ||||
| } | ||||
							
								
								
									
										277
									
								
								newlib/libc/sys/linux/dl/dl-misc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										277
									
								
								newlib/libc/sys/linux/dl/dl-misc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,277 @@ | ||||
| /* Miscellaneous support functions for dynamic linker | ||||
|    Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <fcntl.h> | ||||
| #include <ldsodefs.h> | ||||
| #include <limits.h> | ||||
| #include <link.h> | ||||
| #include <stdarg.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/mman.h> | ||||
| #include <sys/param.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/uio.h> | ||||
|  | ||||
| #ifndef MAP_ANON | ||||
| /* This is the only dl-sysdep.c function that is actually needed at run-time | ||||
|    by _dl_map_object.  */ | ||||
|  | ||||
| int | ||||
| _dl_sysdep_open_zero_fill (void) | ||||
| { | ||||
|   return __open ("/dev/zero", O_RDONLY); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /* Read the whole contents of FILE into new mmap'd space with given | ||||
|    protections.  *SIZEP gets the size of the file.  On error MAP_FAILED | ||||
|    is returned.  */ | ||||
|  | ||||
| void * | ||||
| internal_function | ||||
| _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot) | ||||
| { | ||||
|   void *result = MAP_FAILED; | ||||
|   struct stat64 st; | ||||
|   int fd = __open (file, O_RDONLY); | ||||
|   if (fd >= 0) | ||||
|     { | ||||
|       if (fstat64 (fd, &st) >= 0) | ||||
| 	{ | ||||
| 	  *sizep = st.st_size; | ||||
|  | ||||
| 	  /* No need to map the file if it is empty.  */ | ||||
| 	  if (*sizep != 0) | ||||
| 	    /* Map a copy of the file contents.  */ | ||||
| 	    result = mmap (NULL, *sizep, prot, | ||||
| #ifdef MAP_COPY | ||||
| 			     MAP_COPY | ||||
| #else | ||||
| 			     MAP_PRIVATE | ||||
| #endif | ||||
| #ifdef MAP_FILE | ||||
| 			     | MAP_FILE | ||||
| #endif | ||||
| 			     , fd, 0); | ||||
| 	} | ||||
|       close (fd); | ||||
|     } | ||||
|   return result; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Descriptor to write debug messages to.  */ | ||||
| int _dl_debug_fd = 2; | ||||
|  | ||||
|  | ||||
| /* Bare-bone printf implementation.  This function only knows about | ||||
|    the formats and flags needed and can handle only up to 64 stripes in | ||||
|    the output.  */ | ||||
| static void | ||||
| _dl_debug_vdprintf (int fd, int tag_p, const char *fmt, va_list arg) | ||||
| { | ||||
|   const int niovmax = 64; | ||||
|   struct iovec iov[niovmax]; | ||||
|   int niov = 0; | ||||
|   pid_t pid = 0; | ||||
|   char pidbuf[7]; | ||||
|  | ||||
|   while (*fmt != '\0') | ||||
|     { | ||||
|       const char *startp = fmt; | ||||
|  | ||||
|       if (tag_p > 0) | ||||
| 	{ | ||||
| 	  /* Generate the tag line once.  It consists of the PID and a | ||||
| 	     colon followed by a tab.  */ | ||||
| 	  if (pid == 0) | ||||
| 	    { | ||||
| 	      char *p = "0"; | ||||
| 	      pid = __getpid (); | ||||
| 	      assert (pid >= 0 && pid < 100000); | ||||
| 	      while (p > pidbuf) | ||||
| 		*--p = '0'; | ||||
| 	      pidbuf[5] = ':'; | ||||
| 	      pidbuf[6] = '\t'; | ||||
| 	    } | ||||
|  | ||||
| 	  /* Append to the output.  */ | ||||
| 	  assert (niov < niovmax); | ||||
| 	  iov[niov].iov_len = 7; | ||||
| 	  iov[niov++].iov_base = pidbuf; | ||||
|  | ||||
| 	  /* No more tags until we see the next newline.  */ | ||||
| 	  tag_p = -1; | ||||
| 	} | ||||
|  | ||||
|       /* Skip everything except % and \n (if tags are needed).  */ | ||||
|       while (*fmt != '\0' && *fmt != '%' && (! tag_p || *fmt != '\n')) | ||||
| 	++fmt; | ||||
|  | ||||
|       /* Append constant string.  */ | ||||
|       assert (niov < niovmax); | ||||
|       if ((iov[niov].iov_len = fmt - startp) != 0) | ||||
| 	iov[niov++].iov_base = (char *) startp; | ||||
|  | ||||
|       if (*fmt == '%') | ||||
| 	{ | ||||
| 	  /* It is a format specifier.  */ | ||||
| 	  char fill = ' '; | ||||
| 	  int width = -1; | ||||
| #if LONG_MAX != INT_MAX | ||||
| 	  int long_mod = 0; | ||||
| #endif | ||||
|  | ||||
| 	  /* Recognize zero-digit fill flag.  */ | ||||
| 	  if (*++fmt == '0') | ||||
| 	    { | ||||
| 	      fill = '0'; | ||||
| 	      ++fmt; | ||||
| 	    } | ||||
|  | ||||
| 	  /* See whether with comes from a parameter.  Note that no other | ||||
| 	     way to specify the width is implemented.  */ | ||||
| 	  if (*fmt == '*') | ||||
| 	    { | ||||
| 	      width = va_arg (arg, int); | ||||
| 	      ++fmt; | ||||
| 	    } | ||||
|  | ||||
| 	  /* Recognize the l modifier.  It is only important on some | ||||
| 	     platforms where long and int have a different size.  We | ||||
| 	     can use the same code for size_t.  */ | ||||
| 	  if (*fmt == 'l' || *fmt == 'Z') | ||||
| 	    { | ||||
| #if LONG_MAX != INT_MAX | ||||
| 	      long_mod = 1; | ||||
| #endif | ||||
| 	      ++fmt; | ||||
| 	    } | ||||
|  | ||||
| 	  switch (*fmt) | ||||
| 	    { | ||||
| 	      /* Integer formatting.  */ | ||||
| 	    case 'u': | ||||
| 	    case 'x': | ||||
| 	      { | ||||
| 		/* We have to make a difference if long and int have a | ||||
| 		   different size.  */ | ||||
| #if LONG_MAX != INT_MAX | ||||
| 		unsigned long int num = (long_mod | ||||
| 					 ? va_arg (arg, unsigned long int) | ||||
| 					 : va_arg (arg, unsigned int)); | ||||
| #else | ||||
| 		unsigned long int num = va_arg (arg, unsigned int); | ||||
| #endif | ||||
| 		/* We use alloca() to allocate the buffer with the most | ||||
| 		   pessimistic guess for the size.  Using alloca() allows | ||||
| 		   having more than one integer formatting in a call.  */ | ||||
| 		char *buf = (char *) alloca (3 * sizeof (unsigned long int)); | ||||
| 		char *endp = &buf[3 * sizeof (unsigned long int)]; | ||||
| 		char *cp = "0";  | ||||
|  | ||||
| 		/* Pad to the width the user specified.  */ | ||||
| 		if (width != -1) | ||||
| 		  while (endp - cp < width) | ||||
| 		    *--cp = fill; | ||||
|  | ||||
| 		iov[niov].iov_base = cp; | ||||
| 		iov[niov].iov_len = endp - cp; | ||||
| 		++niov; | ||||
| 	      } | ||||
| 	      break; | ||||
|  | ||||
| 	    case 's': | ||||
| 	      /* Get the string argument.  */ | ||||
| 	      iov[niov].iov_base = va_arg (arg, char *); | ||||
| 	      iov[niov].iov_len = strlen (iov[niov].iov_base); | ||||
| 	      ++niov; | ||||
| 	      break; | ||||
|  | ||||
| 	    case '%': | ||||
| 	      iov[niov].iov_base = (void *) fmt; | ||||
| 	      iov[niov].iov_len = 1; | ||||
| 	      ++niov; | ||||
| 	      break; | ||||
|  | ||||
| 	    default: | ||||
| 	      assert (! "invalid format specifier"); | ||||
| 	    } | ||||
| 	  ++fmt; | ||||
| 	} | ||||
|       else if (*fmt == '\n') | ||||
| 	{ | ||||
| 	  /* See whether we have to print a single newline character.  */ | ||||
| 	  if (fmt == startp) | ||||
| 	    { | ||||
| 	      iov[niov].iov_base = (char *) startp; | ||||
| 	      iov[niov++].iov_len = 1; | ||||
| 	    } | ||||
| 	  else | ||||
| 	    /* No, just add it to the rest of the string.  */ | ||||
| 	    ++iov[niov - 1].iov_len; | ||||
|  | ||||
| 	  /* Next line, print a tag again.  */ | ||||
| 	  tag_p = 1; | ||||
| 	  ++fmt; | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   /* Finally write the result.  */ | ||||
|   writev (fd, iov, niov); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Write to debug file.  */ | ||||
| void | ||||
| _dl_debug_printf (const char *fmt, ...) | ||||
| { | ||||
|   va_list arg; | ||||
|  | ||||
|   va_start (arg, fmt); | ||||
|   _dl_debug_vdprintf (_dl_debug_fd, 1, fmt, arg); | ||||
|   va_end (arg); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Write to debug file but don't start with a tag.  */ | ||||
| void | ||||
| _dl_debug_printf_c (const char *fmt, ...) | ||||
| { | ||||
|   va_list arg; | ||||
|  | ||||
|   va_start (arg, fmt); | ||||
|   _dl_debug_vdprintf (_dl_debug_fd, -1, fmt, arg); | ||||
|   va_end (arg); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Write the given file descriptor.  */ | ||||
| void | ||||
| _dl_dprintf (int fd, const char *fmt, ...) | ||||
| { | ||||
|   va_list arg; | ||||
|  | ||||
|   va_start (arg, fmt); | ||||
|   _dl_debug_vdprintf (fd, 0, fmt, arg); | ||||
|   va_end (arg); | ||||
| } | ||||
							
								
								
									
										163
									
								
								newlib/libc/sys/linux/dl/dl-object.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								newlib/libc/sys/linux/dl/dl-object.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,163 @@ | ||||
| /* Storage management for the chain of loaded shared objects. | ||||
|    Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| #include <ldsodefs.h> | ||||
|  | ||||
| #include <assert.h> | ||||
|  | ||||
|  | ||||
| /* Allocate a `struct link_map' for a new object being loaded, | ||||
|    and enter it into the _dl_loaded list.  */ | ||||
|  | ||||
| struct link_map * | ||||
| internal_function | ||||
| _dl_new_object (char *realname, const char *libname, int type, | ||||
| 		struct link_map *loader) | ||||
| { | ||||
|   struct link_map *l; | ||||
|   int idx; | ||||
|   size_t libname_len = strlen (libname) + 1; | ||||
|   struct link_map *new; | ||||
|   struct libname_list *newname; | ||||
|  | ||||
|   new = (struct link_map *) calloc (sizeof (*new) + sizeof (*newname) | ||||
| 				    + libname_len, 1); | ||||
|   if (new == NULL) | ||||
|     return NULL; | ||||
|  | ||||
|   new->l_libname = newname = (struct libname_list *) (new + 1); | ||||
|   newname->name = (char *) memcpy (newname + 1, libname, libname_len); | ||||
|   /* newname->next = NULL;	We use calloc therefore not necessary.  */ | ||||
|   newname->dont_free = 1; | ||||
|  | ||||
|   new->l_name = realname; | ||||
|   new->l_type = type; | ||||
|   new->l_loader = loader; | ||||
|   /* new->l_global = 0;	We use calloc therefore not necessary.  */ | ||||
|  | ||||
|   /* Use the 'l_scope_mem' array by default for the the 'l_scope' | ||||
|      information.  If we need more entries we will allocate a large | ||||
|      array dynamically.  */ | ||||
|   new->l_scope = new->l_scope_mem; | ||||
|   new->l_scope_max = sizeof (new->l_scope_mem) / sizeof (new->l_scope_mem[0]); | ||||
|  | ||||
|   /* Counter for the scopes we have to handle.  */ | ||||
|   idx = 0; | ||||
|  | ||||
|   if (_dl_loaded != NULL) | ||||
|     { | ||||
|       l = _dl_loaded; | ||||
|       while (l->l_next != NULL) | ||||
| 	l = l->l_next; | ||||
|       new->l_prev = l; | ||||
|       /* new->l_next = NULL;	Would be necessary but we use calloc.  */ | ||||
|       l->l_next = new; | ||||
|  | ||||
|       /* Add the global scope.  */ | ||||
|       new->l_scope[idx++] = &_dl_loaded->l_searchlist; | ||||
|     } | ||||
|   else | ||||
|     _dl_loaded = new; | ||||
|   ++_dl_nloaded; | ||||
|  | ||||
|   /* If we have no loader the new object acts as it.  */ | ||||
|   if (loader == NULL) | ||||
|     loader = new; | ||||
|   else | ||||
|     /* Determine the local scope.  */ | ||||
|     while (loader->l_loader != NULL) | ||||
|       loader = loader->l_loader; | ||||
|  | ||||
|   /* Insert the scope if it isn't the global scope we already added.  */ | ||||
|   if (idx == 0 || &loader->l_searchlist != new->l_scope[0]) | ||||
|     new->l_scope[idx] = &loader->l_searchlist; | ||||
|  | ||||
|   new->l_local_scope[0] = &new->l_searchlist; | ||||
|  | ||||
|   /* Don't try to find the origin for the main map which has the name "".  */ | ||||
|   if (realname[0] != '\0') | ||||
|     { | ||||
|       size_t realname_len = strlen (realname) + 1; | ||||
|       char *origin; | ||||
|       char *cp; | ||||
|  | ||||
|       if (realname[0] == '/') | ||||
| 	{ | ||||
| 	  /* It is an absolute path.  Use it.  But we have to make a | ||||
| 	     copy since we strip out the trailing slash.  */ | ||||
| 	  cp = origin = (char *) malloc (realname_len); | ||||
| 	  if (origin == NULL) | ||||
| 	    { | ||||
| 	      origin = (char *) -1; | ||||
| 	      goto out; | ||||
| 	    } | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  size_t len = realname_len; | ||||
| 	  char *result = NULL; | ||||
|  | ||||
| 	  /* Get the current directory name.  */ | ||||
| 	  origin = NULL; | ||||
| 	  do | ||||
| 	    { | ||||
| 	      len += 128; | ||||
| 	      origin = (char *) realloc (origin, len); | ||||
| 	    } | ||||
| 	  while (origin != NULL | ||||
| 		 && (result = getcwd (origin, len - realname_len)) == NULL | ||||
| 		 && errno == ERANGE); | ||||
|  | ||||
| 	  if (result == NULL) | ||||
| 	    { | ||||
| 	      /* We were not able to determine the current directory. | ||||
| 	         Note that free(origin) is OK if origin == NULL.  */ | ||||
| 	      free (origin); | ||||
| 	      origin = (char *) -1; | ||||
| 	      goto out; | ||||
| 	    } | ||||
|  | ||||
| 	  /* Find the end of the path and see whether we have to add | ||||
| 	     a slash.  */ | ||||
| 	  cp = memchr (origin, '\0', strlen(origin)); | ||||
| 	  if (cp[-1] != '/') | ||||
| 	    *cp++ = '/'; | ||||
| 	} | ||||
|  | ||||
|       /* Add the real file name.  */ | ||||
|       memcpy (cp, realname, realname_len); | ||||
|  | ||||
|       /* Now remove the filename and the slash.  Leave the slash if it | ||||
| 	 the name is something like "/foo".  */ | ||||
|       cp = strrchr (origin, '/'); | ||||
|       if (cp == origin) | ||||
| 	origin[1] = '\0'; | ||||
|       else | ||||
| 	*cp = '\0'; | ||||
|  | ||||
|     out: | ||||
|       new->l_origin = origin; | ||||
|     } | ||||
|  | ||||
|   return new; | ||||
| } | ||||
							
								
								
									
										487
									
								
								newlib/libc/sys/linux/dl/dl-open.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										487
									
								
								newlib/libc/sys/linux/dl/dl-open.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,487 @@ | ||||
| /* Load a shared object at runtime, relocate it, and run its initializer. | ||||
|    Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <dlfcn.h> | ||||
| #include <errno.h> | ||||
| #include <libintl.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/mman.h>		/* Check whether MAP_COPY is defined.  */ | ||||
| #include <sys/param.h> | ||||
| #include <ldsodefs.h> | ||||
| #include <bp-sym.h> | ||||
|  | ||||
| #include <dl-dst.h> | ||||
| #include <machine/weakalias.h> | ||||
|  | ||||
|  | ||||
| extern ElfW(Addr) _dl_sysdep_start (void **start_argptr, | ||||
| 				    void (*dl_main) (const ElfW(Phdr) *phdr, | ||||
| 						     ElfW(Word) phnum, | ||||
| 						     ElfW(Addr) *user_entry)); | ||||
| weak_extern (BP_SYM (_dl_sysdep_start)) | ||||
|  | ||||
| /* This function is used to unload the cache file if necessary.  */ | ||||
| extern void _dl_unload_cache (void); | ||||
|  | ||||
| int __libc_argc = 0; | ||||
| char **__libc_argv = NULL; | ||||
|  | ||||
| extern char **environ; | ||||
|  | ||||
| extern int _dl_lazy;			/* Do we do lazy relocations?  */ | ||||
|  | ||||
| /* Undefine the following for debugging.  */ | ||||
| /* #define SCOPE_DEBUG 1 */ | ||||
| #ifdef SCOPE_DEBUG | ||||
| static void show_scope (struct link_map *new); | ||||
| #endif | ||||
|  | ||||
| extern size_t _dl_platformlen; | ||||
|  | ||||
| /* We must be carefull not to leave us in an inconsistent state.  Thus we | ||||
|    catch any error and re-raise it after cleaning up.  */ | ||||
|  | ||||
| struct dl_open_args | ||||
| { | ||||
|   const char *file; | ||||
|   int mode; | ||||
|   const void *caller; | ||||
|   struct link_map *map; | ||||
| }; | ||||
|  | ||||
|  | ||||
| static int | ||||
| add_to_global (struct link_map *new) | ||||
| { | ||||
|   struct link_map **new_global; | ||||
|   unsigned int to_add = 0; | ||||
|   unsigned int cnt; | ||||
|  | ||||
|   /* Count the objects we have to put in the global scope.  */ | ||||
|   for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt) | ||||
|     if (new->l_searchlist.r_list[cnt]->l_global == 0) | ||||
|       ++to_add; | ||||
|  | ||||
|   /* The symbols of the new objects and its dependencies are to be | ||||
|      introduced into the global scope that will be used to resolve | ||||
|      references from other dynamically-loaded objects. | ||||
|  | ||||
|      The global scope is the searchlist in the main link map.  We | ||||
|      extend this list if necessary.  There is one problem though: | ||||
|      since this structure was allocated very early (before the libc | ||||
|      is loaded) the memory it uses is allocated by the malloc()-stub | ||||
|      in the ld.so.  When we come here these functions are not used | ||||
|      anymore.  Instead the malloc() implementation of the libc is | ||||
|      used.  But this means the block from the main map cannot be used | ||||
|      in an realloc() call.  Therefore we allocate a completely new | ||||
|      array the first time we have to add something to the locale scope.  */ | ||||
|  | ||||
|   if (_dl_global_scope_alloc == 0) | ||||
|     { | ||||
|       /* This is the first dynamic object given global scope.  */ | ||||
|       _dl_global_scope_alloc = _dl_main_searchlist->r_nlist + to_add + 8; | ||||
|       new_global = (struct link_map **) | ||||
| 	malloc (_dl_global_scope_alloc * sizeof (struct link_map *)); | ||||
|       if (new_global == NULL) | ||||
| 	{ | ||||
| 	  _dl_global_scope_alloc = 0; | ||||
| 	nomem: | ||||
| 	  _dl_signal_error (ENOMEM, new->l_libname->name, NULL, | ||||
| 			    N_("cannot extend global scope")); | ||||
| 	  return 1; | ||||
| 	} | ||||
|  | ||||
|       /* Copy over the old entries.  */ | ||||
|       memcpy (new_global, _dl_main_searchlist->r_list, | ||||
| 	      (_dl_main_searchlist->r_nlist * sizeof (struct link_map *))); | ||||
|  | ||||
|       _dl_main_searchlist->r_list = new_global; | ||||
|     } | ||||
|   else if (_dl_main_searchlist->r_nlist + to_add > _dl_global_scope_alloc) | ||||
|     { | ||||
|       /* We have to extend the existing array of link maps in the | ||||
| 	 main map.  */ | ||||
|       new_global = (struct link_map **) | ||||
| 	realloc (_dl_main_searchlist->r_list, | ||||
| 		 ((_dl_global_scope_alloc + to_add + 8) | ||||
| 		  * sizeof (struct link_map *))); | ||||
|       if (new_global == NULL) | ||||
| 	goto nomem; | ||||
|  | ||||
|       _dl_global_scope_alloc += to_add + 8; | ||||
|       _dl_main_searchlist->r_list = new_global; | ||||
|     } | ||||
|  | ||||
|   /* Now add the new entries.  */ | ||||
|   for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt) | ||||
|     { | ||||
|       struct link_map *map = new->l_searchlist.r_list[cnt]; | ||||
|  | ||||
|       if (map->l_global == 0) | ||||
| 	{ | ||||
| 	  map->l_global = 1; | ||||
| 	  _dl_main_searchlist->r_list[_dl_main_searchlist->r_nlist] = map; | ||||
| 	  ++_dl_main_searchlist->r_nlist; | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void | ||||
| dl_open_worker (void *a) | ||||
| { | ||||
|   struct dl_open_args *args = a; | ||||
|   const char *file = args->file; | ||||
|   int mode = args->mode; | ||||
|   struct link_map *new, *l; | ||||
|   const char *dst; | ||||
|   int lazy; | ||||
|   unsigned int i; | ||||
|  | ||||
|   /* Maybe we have to expand a DST.  */ | ||||
|   dst = strchr (file, '$'); | ||||
|   if (dst != NULL) | ||||
|     { | ||||
|       const void *caller = args->caller; | ||||
|       size_t len = strlen (file); | ||||
|       size_t required; | ||||
|       struct link_map *call_map; | ||||
|       char *new_file; | ||||
|  | ||||
|       /* We have to find out from which object the caller is calling.  */ | ||||
|       call_map = NULL; | ||||
|       for (l = _dl_loaded; l; l = l->l_next) | ||||
| 	if (caller >= (const void *) l->l_map_start | ||||
| 	    && caller < (const void *) l->l_map_end) | ||||
| 	  { | ||||
| 	    /* There must be exactly one DSO for the range of the virtual | ||||
| 	       memory.  Otherwise something is really broken.  */ | ||||
| 	    call_map = l; | ||||
| 	    break; | ||||
| 	  } | ||||
|  | ||||
|       if (call_map == NULL) | ||||
| 	/* In this case we assume this is the main application.  */ | ||||
| 	call_map = _dl_loaded; | ||||
|  | ||||
|       /* Determine how much space we need.  We have to allocate the | ||||
| 	 memory locally.  */ | ||||
|       required = DL_DST_REQUIRED (call_map, file, len, _dl_dst_count (dst, 0)); | ||||
|  | ||||
|       /* Get space for the new file name.  */ | ||||
|       new_file = (char *) alloca (required + 1); | ||||
|  | ||||
|       /* Generate the new file name.  */ | ||||
|       DL_DST_SUBSTITUTE (call_map, file, new_file, 0); | ||||
|  | ||||
|       /* If the substitution failed don't try to load.  */ | ||||
|       if (*new_file == '\0') | ||||
| 	_dl_signal_error (0, "dlopen", NULL, | ||||
| 			  N_("empty dynamic string token substitution")); | ||||
|  | ||||
|       /* Now we have a new file name.  */ | ||||
|       file = new_file; | ||||
|     } | ||||
|  | ||||
|   /* Load the named object.  */ | ||||
|   args->map = new = _dl_map_object (NULL, file, 0, lt_loaded, 0, | ||||
| 				    mode); | ||||
|  | ||||
|   /* If the pointer returned is NULL this means the RTLD_NOLOAD flag is | ||||
|      set and the object is not already loaded.  */ | ||||
|   if (new == NULL) | ||||
|     { | ||||
|       assert (mode & RTLD_NOLOAD); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   /* It was already open.  */ | ||||
|   if (new->l_searchlist.r_list != NULL) | ||||
|     { | ||||
|       /* Let the user know about the opencount.  */ | ||||
|       if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) | ||||
| 	_dl_debug_printf ("opening file=%s; opencount == %u\n\n", | ||||
| 			  new->l_name, new->l_opencount); | ||||
|  | ||||
|       /* If the user requested the object to be in the global namespace | ||||
| 	 but it is not so far, add it now.  */ | ||||
|       if ((mode & RTLD_GLOBAL) && new->l_global == 0) | ||||
| 	(void) add_to_global (new); | ||||
|  | ||||
|       /* Increment just the reference counter of the object.  */ | ||||
|       ++new->l_opencount; | ||||
|  | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   /* Load that object's dependencies.  */ | ||||
|   _dl_map_object_deps (new, NULL, 0, 0); | ||||
|  | ||||
|   /* So far, so good.  Now check the versions.  */ | ||||
|   for (i = 0; i < new->l_searchlist.r_nlist; ++i) | ||||
|     if (new->l_searchlist.r_list[i]->l_versions == NULL) | ||||
|       (void) _dl_check_map_versions (new->l_searchlist.r_list[i], 0, 0); | ||||
|  | ||||
| #ifdef SCOPE_DEBUG | ||||
|   show_scope (new); | ||||
| #endif | ||||
|  | ||||
|   /* Only do lazy relocation if `LD_BIND_NOW' is not set.  */ | ||||
|   lazy = (mode & RTLD_BINDING_MASK) == RTLD_LAZY && _dl_lazy; | ||||
|  | ||||
|   /* Relocate the objects loaded.  We do this in reverse order so that copy | ||||
|      relocs of earlier objects overwrite the data written by later objects.  */ | ||||
|  | ||||
|   l = new; | ||||
|   while (l->l_next) | ||||
|     l = l->l_next; | ||||
|   while (1) | ||||
|     { | ||||
|       if (! l->l_relocated) | ||||
| 	{ | ||||
| #if 0 | ||||
| #ifdef SHARED | ||||
| 	  if (_dl_profile != NULL) | ||||
| 	    { | ||||
| 	      /* If this here is the shared object which we want to profile | ||||
| 		 make sure the profile is started.  We can find out whether | ||||
| 	         this is necessary or not by observing the `_dl_profile_map' | ||||
| 	         variable.  If was NULL but is not NULL afterwars we must | ||||
| 		 start the profiling.  */ | ||||
| 	      struct link_map *old_profile_map = _dl_profile_map; | ||||
|  | ||||
| 	      _dl_relocate_object (l, l->l_scope, 1, 1); | ||||
|  | ||||
| 	      if (old_profile_map == NULL && _dl_profile_map != NULL) | ||||
| 		/* We must prepare the profiling.  */ | ||||
| 		_dl_start_profile (_dl_profile_map, _dl_profile_output); | ||||
| 	    } | ||||
| 	  else | ||||
| #endif | ||||
| #endif | ||||
| 	    _dl_relocate_object (l, l->l_scope, lazy, 0); | ||||
| 	} | ||||
|  | ||||
|       if (l == new) | ||||
| 	break; | ||||
|       l = l->l_prev; | ||||
|     } | ||||
|  | ||||
|   /* Increment the open count for all dependencies.  If the file is | ||||
|      not loaded as a dependency here add the search list of the newly | ||||
|      loaded object to the scope.  */ | ||||
|   for (i = 0; i < new->l_searchlist.r_nlist; ++i) | ||||
|     if (++new->l_searchlist.r_list[i]->l_opencount > 1 | ||||
| 	&& new->l_searchlist.r_list[i]->l_type == lt_loaded) | ||||
|       { | ||||
| 	struct link_map *imap = new->l_searchlist.r_list[i]; | ||||
| 	struct r_scope_elem **runp = imap->l_scope; | ||||
| 	size_t cnt = 0; | ||||
|  | ||||
| 	while (*runp != NULL) | ||||
| 	  { | ||||
| 	    /* This can happen if imap was just loaded, but during | ||||
| 	       relocation had l_opencount bumped because of relocation | ||||
| 	       dependency.  Avoid duplicates in l_scope.  */ | ||||
| 	    if (__builtin_expect (*runp == &new->l_searchlist, 0)) | ||||
| 	      break; | ||||
|  | ||||
| 	    ++cnt; | ||||
| 	    ++runp; | ||||
| 	  } | ||||
|  | ||||
| 	if (*runp != NULL) | ||||
| 	  /* Avoid duplicates.  */ | ||||
| 	  continue; | ||||
|  | ||||
| 	if (__builtin_expect (cnt + 1 >= imap->l_scope_max, 0)) | ||||
| 	  { | ||||
| 	    /* The 'r_scope' array is too small.  Allocate a new one | ||||
| 	       dynamically.  */ | ||||
| 	    struct r_scope_elem **newp; | ||||
| 	    size_t new_size = imap->l_scope_max * 2; | ||||
|  | ||||
| 	    if (imap->l_scope == imap->l_scope_mem) | ||||
| 	      { | ||||
| 		newp = (struct r_scope_elem **) | ||||
| 		  malloc (new_size * sizeof (struct r_scope_elem *)); | ||||
| 		if (newp == NULL) | ||||
| 		  _dl_signal_error (ENOMEM, "dlopen", NULL, | ||||
| 				    N_("cannot create scope list")); | ||||
| 		imap->l_scope = memcpy (newp, imap->l_scope, | ||||
| 					cnt * sizeof (imap->l_scope[0])); | ||||
| 	      } | ||||
| 	    else | ||||
| 	      { | ||||
| 		newp = (struct r_scope_elem **) | ||||
| 		  realloc (imap->l_scope, | ||||
| 			   new_size * sizeof (struct r_scope_elem *)); | ||||
| 		if (newp == NULL) | ||||
| 		  _dl_signal_error (ENOMEM, "dlopen", NULL, | ||||
| 				    N_("cannot create scope list")); | ||||
| 		imap->l_scope = newp; | ||||
| 	      } | ||||
|  | ||||
| 	    imap->l_scope_max = new_size; | ||||
| 	  } | ||||
|  | ||||
| 	imap->l_scope[cnt++] = &new->l_searchlist; | ||||
| 	imap->l_scope[cnt] = NULL; | ||||
|       } | ||||
|  | ||||
|   /* Run the initializer functions of new objects.  */ | ||||
|   _dl_init (new, __libc_argc, __libc_argv, environ); | ||||
|  | ||||
|   /* Now we can make the new map available in the global scope.  */ | ||||
|   if (mode & RTLD_GLOBAL) | ||||
|     /* Move the object in the global namespace.  */ | ||||
|     if (add_to_global (new) != 0) | ||||
|       /* It failed.  */ | ||||
|       return; | ||||
|  | ||||
|   /* Mark the object as not deletable if the RTLD_NODELETE flags was | ||||
|      passed.  */ | ||||
|   if (__builtin_expect (mode & RTLD_NODELETE, 0)) | ||||
|     new->l_flags_1 |= DF_1_NODELETE; | ||||
|  | ||||
|   /* Let the user know about the opencount.  */ | ||||
|   if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0)) | ||||
|     _dl_debug_printf ("opening file=%s; opencount == %u\n\n", | ||||
| 		      new->l_name, new->l_opencount); | ||||
| } | ||||
|  | ||||
|  | ||||
| void * | ||||
| internal_function | ||||
| _dl_open (const char *file, int mode, const void *caller) | ||||
| { | ||||
|   struct dl_open_args args; | ||||
|   const char *objname; | ||||
|   const char *errstring; | ||||
|   int errcode; | ||||
|  | ||||
|   if ((mode & RTLD_BINDING_MASK) == 0) | ||||
|     /* One of the flags must be set.  */ | ||||
|     _dl_signal_error (EINVAL, file, NULL, N_("invalid mode for dlopen()")); | ||||
|  | ||||
|   /* Make sure we are alone.  */ | ||||
| #ifdef HAVE_DD_LOCK | ||||
|     __lock_acquire_recursive(_dl_load_lock); | ||||
| #endif | ||||
|  | ||||
|   args.file = file; | ||||
|   args.mode = mode; | ||||
|   args.caller = caller; | ||||
|   args.map = NULL; | ||||
|   errcode = _dl_catch_error (&objname, &errstring, dl_open_worker, &args); | ||||
|  | ||||
| #ifndef MAP_COPY | ||||
|   /* We must munmap() the cache file.  */ | ||||
|   _dl_unload_cache (); | ||||
| #endif | ||||
|  | ||||
|   /* Release the lock.  */ | ||||
| #ifdef HAVE_DD_LOCK | ||||
|     __lock_release_recursive(_dl_load_lock); | ||||
| #endif | ||||
|  | ||||
|  | ||||
|   if (errstring) | ||||
|     { | ||||
|       /* Some error occurred during loading.  */ | ||||
|       char *local_errstring; | ||||
|       size_t len_errstring; | ||||
|  | ||||
|       /* Remove the object from memory.  It may be in an inconsistent | ||||
| 	 state if relocation failed, for example.  */ | ||||
|       if (args.map) | ||||
| 	{ | ||||
| 	  unsigned int i; | ||||
|  | ||||
| 	  /* Increment open counters for all objects since this has | ||||
| 	     not happened yet.  */ | ||||
| 	  for (i = 0; i < args.map->l_searchlist.r_nlist; ++i) | ||||
| 	    ++args.map->l_searchlist.r_list[i]->l_opencount; | ||||
|  | ||||
| 	  _dl_close (args.map); | ||||
| 	} | ||||
|  | ||||
|       /* Make a local copy of the error string so that we can release the | ||||
| 	 memory allocated for it.  */ | ||||
|       len_errstring = strlen (errstring) + 1; | ||||
|       if (objname == errstring + len_errstring) | ||||
| 	{ | ||||
| 	  size_t total_len = len_errstring + strlen (objname) + 1; | ||||
| 	  local_errstring = alloca (total_len); | ||||
| 	  memcpy (local_errstring, errstring, total_len); | ||||
| 	  objname = local_errstring + len_errstring; | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  local_errstring = alloca (len_errstring); | ||||
| 	  memcpy (local_errstring, errstring, len_errstring); | ||||
| 	} | ||||
|  | ||||
|       if (errstring != _dl_out_of_memory) | ||||
| 	free ((char *) errstring); | ||||
|  | ||||
|       /* Reraise the error.  */ | ||||
|       _dl_signal_error (errcode, objname, NULL, local_errstring); | ||||
|     } | ||||
|  | ||||
| #ifndef SHARED | ||||
|   DL_STATIC_INIT (args.map); | ||||
| #endif | ||||
|  | ||||
|   return args.map; | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifdef SCOPE_DEBUG | ||||
| #include <unistd.h> | ||||
|  | ||||
| static void | ||||
| show_scope (struct link_map *new) | ||||
| { | ||||
|   int scope_cnt; | ||||
|  | ||||
|   for (scope_cnt = 0; new->l_scope[scope_cnt] != NULL; ++scope_cnt) | ||||
|     { | ||||
|       char numbuf[2]; | ||||
|       unsigned int cnt; | ||||
|  | ||||
|       numbuf[0] = '0' + scope_cnt; | ||||
|       numbuf[1] = '\0'; | ||||
|       _dl_printf ("scope %s:", numbuf); | ||||
|  | ||||
|       for (cnt = 0; cnt < new->l_scope[scope_cnt]->r_nlist; ++cnt) | ||||
| 	if (*new->l_scope[scope_cnt]->r_list[cnt]->l_name) | ||||
| 	  _dl_printf (" %s", new->l_scope[scope_cnt]->r_list[cnt]->l_name); | ||||
| 	else | ||||
| 	  _dl_printf (" <main>"); | ||||
|  | ||||
|       _dl_printf ("\n"); | ||||
|     } | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										108
									
								
								newlib/libc/sys/linux/dl/dl-osinfo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								newlib/libc/sys/linux/dl/dl-osinfo.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,108 @@ | ||||
| /* Operating system specific code  for generic dynamic loader functions. | ||||
|    Copyright (C) 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <string.h> | ||||
| #include <sys/sysctl.h> | ||||
| #include <sys/utsname.h> | ||||
| #include "kernel-features.h" | ||||
|  | ||||
| #ifndef MIN | ||||
| # define MIN(a,b) (((a)<(b))?(a):(b)) | ||||
| #endif | ||||
|  | ||||
| #ifdef SHARED | ||||
| /* This is the function used in the dynamic linker to print the fatal error | ||||
|    message.  */ | ||||
| static inline void | ||||
| __attribute__ ((__noreturn__)) | ||||
| dl_fatal (const char *str) | ||||
| { | ||||
|   _dl_dprintf (2, str); | ||||
|   _exit (1); | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #define DL_SYSDEP_OSCHECK(FATAL) \ | ||||
|   do {									      \ | ||||
|     /* Test whether the kernel is new enough.  This test is only	      \ | ||||
|        performed if the library is not compiled to run on all		      \ | ||||
|        kernels.  */							      \ | ||||
|     if (__LINUX_KERNEL_VERSION > 0)					      \ | ||||
|       {									      \ | ||||
| 	char bufmem[64];						      \ | ||||
| 	char *buf = bufmem;						      \ | ||||
| 	unsigned int version;						      \ | ||||
| 	int parts;							      \ | ||||
| 	char *cp;							      \ | ||||
| 	struct utsname uts;						      \ | ||||
| 									      \ | ||||
| 	/* Try the uname syscall */					      \ | ||||
| 	if (__uname (&uts))					      	      \ | ||||
| 	  {							      	      \ | ||||
| 	    /* This was not successful.  Now try reading the /proc	      \ | ||||
| 	       filesystem.  */						      \ | ||||
| 	    ssize_t reslen;						      \ | ||||
| 	    int fd = __open ("/proc/sys/kernel/osrelease", O_RDONLY);	      \ | ||||
| 	    if (fd == -1						      \ | ||||
| 		|| (reslen = __read (fd, bufmem, sizeof (bufmem))) <= 0)      \ | ||||
|   	      /* This also didn't work.  We give up since we cannot	      \ | ||||
| 		 make sure the library can actually work.  */		      \ | ||||
| 	      FATAL ("FATAL: cannot determine library version\n");	      \ | ||||
| 	    __close (fd);						      \ | ||||
| 	    buf[MIN (reslen, (ssize_t) sizeof (bufmem) - 1)] = '\0';	      \ | ||||
| 	  }								      \ | ||||
| 	else								      \ | ||||
|           buf = uts.release;						      \ | ||||
| 									      \ | ||||
| 	/* Now convert it into a number.  The string consists of at most      \ | ||||
| 	   three parts.  */						      \ | ||||
| 	version = 0;							      \ | ||||
| 	parts = 0;							      \ | ||||
| 	cp = buf;							      \ | ||||
| 	while ((*cp >= '0') && (*cp <= '9'))				      \ | ||||
| 	  {								      \ | ||||
| 	    unsigned int here = *cp++ - '0';				      \ | ||||
| 									      \ | ||||
| 	    while ((*cp >= '0') && (*cp <= '9'))			      \ | ||||
| 	      {								      \ | ||||
| 		here *= 10;						      \ | ||||
| 		here += *cp++ - '0';					      \ | ||||
| 	      }								      \ | ||||
| 									      \ | ||||
| 	    ++parts;							      \ | ||||
| 	    version <<= 8;						      \ | ||||
| 	    version |= here;						      \ | ||||
| 									      \ | ||||
| 	    if (*cp++ != '.')						      \ | ||||
| 	      /* Another part following?  */				      \ | ||||
| 	      break;							      \ | ||||
| 	  }								      \ | ||||
| 									      \ | ||||
| 	if (parts < 3)							      \ | ||||
| 	  version <<= 8 * (3 - parts);					      \ | ||||
| 									      \ | ||||
| 	/* Now we can test with the required version.  */		      \ | ||||
| 	if (version < __LINUX_KERNEL_VERSION)				      \ | ||||
| 	  /* Not sufficent.  */						      \ | ||||
| 	  FATAL ("FATAL: kernel too old\n");				      \ | ||||
| 									      \ | ||||
| 	_dl_osversion = version;					      \ | ||||
|       }									      \ | ||||
|   } while (0) | ||||
							
								
								
									
										539
									
								
								newlib/libc/sys/linux/dl/dl-profile.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										539
									
								
								newlib/libc/sys/linux/dl/dl-profile.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,539 @@ | ||||
| /* Profiling of shared libraries. | ||||
|    Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|    Based on the BSD mcount implementation. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <limits.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <ldsodefs.h> | ||||
| #include <sys/gmon.h> | ||||
| #include <sys/gmon_out.h> | ||||
| #include <sys/mman.h> | ||||
| #include <sys/param.h> | ||||
| #include <sys/stat.h> | ||||
| #include <atomicity.h> | ||||
| #include <config.h> | ||||
|  | ||||
| /* The LD_PROFILE feature has to be implemented different to the | ||||
|    normal profiling using the gmon/ functions.  The problem is that an | ||||
|    arbitrary amount of processes simulataneously can be run using | ||||
|    profiling and all write the results in the same file.  To provide | ||||
|    this mechanism one could implement a complicated mechanism to merge | ||||
|    the content of two profiling runs or one could extend the file | ||||
|    format to allow more than one data set.  For the second solution we | ||||
|    would have the problem that the file can grow in size beyond any | ||||
|    limit and both solutions have the problem that the concurrency of | ||||
|    writing the results is a big problem. | ||||
|  | ||||
|    Another much simpler method is to use mmap to map the same file in | ||||
|    all using programs and modify the data in the mmap'ed area and so | ||||
|    also automatically on the disk.  Using the MAP_SHARED option of | ||||
|    mmap(2) this can be done without big problems in more than one | ||||
|    file. | ||||
|  | ||||
|    This approach is very different from the normal profiling.  We have | ||||
|    to use the profiling data in exactly the way they are expected to | ||||
|    be written to disk.  But the normal format used by gprof is not usable | ||||
|    to do this.  It is optimized for size.  It writes the tags as single | ||||
|    bytes but this means that the following 32/64 bit values are | ||||
|    unaligned. | ||||
|  | ||||
|    Therefore we use a new format.  This will look like this | ||||
|  | ||||
| 					0  1  2  3	<- byte is 32 bit word | ||||
| 	0000				g  m  o  n | ||||
| 	0004				*version*	<- GMON_SHOBJ_VERSION | ||||
| 	0008				00 00 00 00 | ||||
| 	000c				00 00 00 00 | ||||
| 	0010				00 00 00 00 | ||||
|  | ||||
| 	0014				*tag*		<- GMON_TAG_TIME_HIST | ||||
| 	0018				?? ?? ?? ?? | ||||
| 					?? ?? ?? ??	<- 32/64 bit LowPC | ||||
| 	0018+A				?? ?? ?? ?? | ||||
| 					?? ?? ?? ??	<- 32/64 bit HighPC | ||||
| 	0018+2*A			*histsize* | ||||
| 	001c+2*A			*profrate* | ||||
| 	0020+2*A			s  e  c  o | ||||
| 	0024+2*A			n  d  s  \0 | ||||
| 	0028+2*A			\0 \0 \0 \0 | ||||
| 	002c+2*A			\0 \0 \0 | ||||
| 	002f+2*A			s | ||||
|  | ||||
| 	0030+2*A			?? ?? ?? ??	<- Count data | ||||
| 	...				... | ||||
| 	0030+2*A+K			?? ?? ?? ?? | ||||
|  | ||||
| 	0030+2*A+K			*tag*		<- GMON_TAG_CG_ARC | ||||
| 	0034+2*A+K			*lastused* | ||||
| 	0038+2*A+K			?? ?? ?? ?? | ||||
| 					?? ?? ?? ??	<- FromPC#1 | ||||
| 	0038+3*A+K			?? ?? ?? ?? | ||||
| 					?? ?? ?? ??	<- ToPC#1 | ||||
| 	0038+4*A+K			?? ?? ?? ??	<- Count#1 | ||||
| 	...				...		   ... | ||||
| 	0038+(2*(CN-1)+2)*A+(CN-1)*4+K	?? ?? ?? ?? | ||||
| 					?? ?? ?? ??	<- FromPC#CGN | ||||
| 	0038+(2*(CN-1)+3)*A+(CN-1)*4+K	?? ?? ?? ?? | ||||
| 					?? ?? ?? ??	<- ToPC#CGN | ||||
| 	0038+(2*CN+2)*A+(CN-1)*4+K	?? ?? ?? ??	<- Count#CGN | ||||
|  | ||||
|    We put (for now?) no basic block information in the file since this would | ||||
|    introduce rase conditions among all the processes who want to write them. | ||||
|  | ||||
|    `K' is the number of count entries which is computed as | ||||
|  | ||||
|  		textsize / HISTFRACTION | ||||
|  | ||||
|    `CG' in the above table is the number of call graph arcs.  Normally, | ||||
|    the table is sparse and the profiling code writes out only the those | ||||
|    entries which are really used in the program run.  But since we must | ||||
|    not extend this table (the profiling file) we'll keep them all here. | ||||
|    So CN can be executed in advance as | ||||
|  | ||||
| 		MINARCS <= textsize*(ARCDENSITY/100) <= MAXARCS | ||||
|  | ||||
|    Now the remaining question is: how to build the data structures we can | ||||
|    work with from this data.  We need the from set and must associate the | ||||
|    froms with all the associated tos.  We will do this by constructing this | ||||
|    data structures at the program start.  To do this we'll simply visit all | ||||
|    entries in the call graph table and add it to the appropriate list.  */ | ||||
|  | ||||
| extern int __profile_frequency (void); | ||||
|  | ||||
| /* We define a special type to address the elements of the arc table. | ||||
|    This is basically the `gmon_cg_arc_record' format but it includes | ||||
|    the room for the tag and it uses real types.  */ | ||||
| struct here_cg_arc_record | ||||
|   { | ||||
|     uintptr_t from_pc; | ||||
|     uintptr_t self_pc; | ||||
|     uint32_t count; | ||||
|   } __attribute__ ((packed)); | ||||
|  | ||||
| static struct here_cg_arc_record *data; | ||||
|  | ||||
| /* Nonzero if profiling is under way.  */ | ||||
| static int running; | ||||
|  | ||||
| /* This is the number of entry which have been incorporated in the toset.  */ | ||||
| static uint32_t narcs; | ||||
| /* This is a pointer to the object representing the number of entries | ||||
|    currently in the mmaped file.  At no point of time this has to be the | ||||
|    same as NARCS.  If it is equal all entries from the file are in our | ||||
|    lists.  */ | ||||
| static volatile uint32_t *narcsp; | ||||
|  | ||||
| static volatile uint16_t *kcount; | ||||
| static size_t kcountsize; | ||||
|  | ||||
| struct here_fromstruct | ||||
|   { | ||||
|     struct here_cg_arc_record volatile *here; | ||||
|     uint16_t link; | ||||
|   }; | ||||
|  | ||||
| static volatile uint16_t *tos; | ||||
|  | ||||
| static struct here_fromstruct *froms; | ||||
| static uint32_t fromlimit; | ||||
| static volatile uint32_t fromidx; | ||||
|  | ||||
| static uintptr_t lowpc; | ||||
| static size_t textsize; | ||||
| static unsigned int hashfraction; | ||||
| static unsigned int log_hashfraction; | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Set up profiling data to profile object desribed by MAP.  The output | ||||
|    file is found (or created) in OUTPUT_DIR.  */ | ||||
| void | ||||
| internal_function | ||||
| _dl_start_profile (struct link_map *map, const char *output_dir) | ||||
| { | ||||
|   char *filename; | ||||
|   int fd; | ||||
|   struct stat64 st; | ||||
|   const ElfW(Phdr) *ph; | ||||
|   ElfW(Addr) mapstart = ~((ElfW(Addr)) 0); | ||||
|   ElfW(Addr) mapend = 0; | ||||
|   struct gmon_hdr gmon_hdr; | ||||
|   struct gmon_hist_hdr hist_hdr; | ||||
|   char *hist, *cp, *tmp; | ||||
|   size_t idx; | ||||
|   size_t tossize; | ||||
|   size_t fromssize; | ||||
|   uintptr_t highpc; | ||||
|   struct gmon_hdr *addr = NULL; | ||||
|   off_t expected_size; | ||||
|   /* See profil(2) where this is described.  */ | ||||
|   int s_scale; | ||||
| #define SCALE_1_TO_1	0x10000L | ||||
|  | ||||
|   /* Compute the size of the sections which contain program code.  */ | ||||
|   for (ph = map->l_phdr; ph < &map->l_phdr[map->l_phnum]; ++ph) | ||||
|     if (ph->p_type == PT_LOAD && (ph->p_flags & PF_X)) | ||||
|       { | ||||
| 	ElfW(Addr) start = (ph->p_vaddr & ~(_dl_pagesize - 1)); | ||||
| 	ElfW(Addr) end = ((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1) | ||||
| 			  & ~(_dl_pagesize - 1)); | ||||
|  | ||||
| 	if (start < mapstart) | ||||
| 	  mapstart = start; | ||||
| 	if (end > mapend) | ||||
| 	  mapend = end; | ||||
|       } | ||||
|  | ||||
|   /* Now we can compute the size of the profiling data.  This is done | ||||
|      with the same formulars as in `monstartup' (see gmon.c).  */ | ||||
|   running = 0; | ||||
|   lowpc = ROUNDDOWN (mapstart + map->l_addr, | ||||
| 		     HISTFRACTION * sizeof (HISTCOUNTER)); | ||||
|   highpc = ROUNDUP (mapend + map->l_addr, | ||||
| 		    HISTFRACTION * sizeof (HISTCOUNTER)); | ||||
|   textsize = highpc - lowpc; | ||||
|   kcountsize = textsize / HISTFRACTION; | ||||
|   hashfraction = HASHFRACTION; | ||||
|   if ((HASHFRACTION & (HASHFRACTION - 1)) == 0) | ||||
|     /* If HASHFRACTION is a power of two, mcount can use shifting | ||||
|        instead of integer division.  Precompute shift amount.  */ | ||||
|     log_hashfraction = ffs (hashfraction * sizeof (*froms)) - 1; | ||||
|   else | ||||
|     log_hashfraction = -1; | ||||
|   tossize = textsize / HASHFRACTION; | ||||
|   fromlimit = textsize * ARCDENSITY / 100; | ||||
|   if (fromlimit < MINARCS) | ||||
|     fromlimit = MINARCS; | ||||
|   if (fromlimit > MAXARCS) | ||||
|     fromlimit = MAXARCS; | ||||
|   fromssize = fromlimit * sizeof (struct here_fromstruct); | ||||
|  | ||||
|   expected_size = (sizeof (struct gmon_hdr) | ||||
| 		   + 4 + sizeof (struct gmon_hist_hdr) + kcountsize | ||||
| 		   + 4 + 4 + fromssize * sizeof (struct here_cg_arc_record)); | ||||
|  | ||||
|   /* Create the gmon_hdr we expect or write.  */ | ||||
|   memset (&gmon_hdr, '\0', sizeof (struct gmon_hdr)); | ||||
|   memcpy (&gmon_hdr.cookie[0], GMON_MAGIC, sizeof (gmon_hdr.cookie)); | ||||
|   *(int32_t *) gmon_hdr.version = GMON_SHOBJ_VERSION; | ||||
|  | ||||
|   /* Create the hist_hdr we expect or write.  */ | ||||
|   *(char **) hist_hdr.low_pc = (char *) mapstart; | ||||
|   *(char **) hist_hdr.high_pc = (char *) mapend; | ||||
|   *(int32_t *) hist_hdr.hist_size = kcountsize / sizeof (HISTCOUNTER); | ||||
|   *(int32_t *) hist_hdr.prof_rate = __profile_frequency (); | ||||
|   strncpy (hist_hdr.dimen, "seconds", sizeof (hist_hdr.dimen)); | ||||
|   hist_hdr.dimen_abbrev = 's'; | ||||
|  | ||||
|   /* First determine the output name.  We write in the directory | ||||
|      OUTPUT_DIR and the name is composed from the shared objects | ||||
|      soname (or the file name) and the ending ".profile".  */ | ||||
|   filename = (char *) alloca (strlen (output_dir) + 1 + strlen (_dl_profile) | ||||
| 			      + sizeof ".profile"); | ||||
|   cp = strcpy (filename, output_dir); | ||||
|   cp += strlen (output_dir); | ||||
|   *cp++ = '/'; | ||||
|   tmp = strcpy (cp, _dl_profile); | ||||
|   tmp += strlen (_dl_profile); | ||||
|   strcpy (tmp, ".profile"); | ||||
|  | ||||
| #ifdef O_NOFOLLOW | ||||
| # define EXTRA_FLAGS | O_NOFOLLOW | ||||
| #else | ||||
| # define EXTRA_FLAGS | ||||
| #endif | ||||
|   fd = __open (filename, O_RDWR | O_CREAT EXTRA_FLAGS); | ||||
|   if (fd == -1) | ||||
|     { | ||||
|       /* We cannot write the profiling data so don't do anything.  */ | ||||
|       char buf[400]; | ||||
|       _dl_error_printf ("%s: cannot open file: %s\n", filename, | ||||
| 			__strerror_r (errno, buf, sizeof buf)); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   if (fstat64 (fd, &st) < 0 || !S_ISREG (st.st_mode)) | ||||
|     { | ||||
|       /* Not stat'able or not a regular file => don't use it.  */ | ||||
|       char buf[400]; | ||||
|       int errnum = errno; | ||||
|       __close (fd); | ||||
|       _dl_error_printf ("%s: cannot stat file: %s\n", filename, | ||||
| 			__strerror_r (errnum, buf, sizeof buf)); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   /* Test the size.  If it does not match what we expect from the size | ||||
|      values in the map MAP we don't use it and warn the user.  */ | ||||
|   if (st.st_size == 0) | ||||
|     { | ||||
|       /* We have to create the file.  */ | ||||
|       char buf[_dl_pagesize]; | ||||
|  | ||||
|       memset (buf, '\0', _dl_pagesize); | ||||
|  | ||||
|       if (__lseek (fd, expected_size & ~(_dl_pagesize - 1), SEEK_SET) == -1) | ||||
| 	{ | ||||
| 	  char buf[400]; | ||||
| 	  int errnum; | ||||
| 	cannot_create: | ||||
| 	  errnum = errno; | ||||
| 	  __close (fd); | ||||
| 	  _dl_error_printf ("%s: cannot create file: %s\n", filename, | ||||
| 			    __strerror_r (errnum, buf, sizeof buf)); | ||||
| 	  return; | ||||
| 	} | ||||
|  | ||||
|       if (TEMP_FAILURE_RETRY (__libc_write (fd, buf, (expected_size | ||||
| 						      & (_dl_pagesize - 1)))) | ||||
| 	  < 0) | ||||
| 	goto cannot_create; | ||||
|     } | ||||
|   else if (st.st_size != expected_size) | ||||
|     { | ||||
|       __close (fd); | ||||
|     wrong_format: | ||||
|  | ||||
|       if (addr != NULL) | ||||
| 	__munmap ((void *) addr, expected_size); | ||||
|  | ||||
|       _dl_error_printf ("%s: file is no correct profile data file for `%s'\n", | ||||
| 			filename, _dl_profile); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   addr = (struct gmon_hdr *) __mmap (NULL, expected_size, PROT_READ|PROT_WRITE, | ||||
| 				     MAP_SHARED|MAP_FILE, fd, 0); | ||||
|   if (addr == (struct gmon_hdr *) MAP_FAILED) | ||||
|     { | ||||
|       char buf[400]; | ||||
|       int errnum = errno; | ||||
|       __close (fd); | ||||
|       _dl_error_printf ("%s: cannot map file: %s\n", filename, | ||||
| 			__strerror_r (errnum, buf, sizeof buf)); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   /* We don't need the file desriptor anymore.  */ | ||||
|   __close (fd); | ||||
|  | ||||
|   /* Pointer to data after the header.  */ | ||||
|   hist = (char *) (addr + 1); | ||||
|   kcount = (uint16_t *) ((char *) hist + sizeof (uint32_t) | ||||
| 			 + sizeof (struct gmon_hist_hdr)); | ||||
|  | ||||
|   /* Compute pointer to array of the arc information.  */ | ||||
|   narcsp = (uint32_t *) ((char *) kcount + kcountsize + sizeof (uint32_t)); | ||||
|   data = (struct here_cg_arc_record *) ((char *) narcsp + sizeof (uint32_t)); | ||||
|  | ||||
|   if (st.st_size == 0) | ||||
|     { | ||||
|       /* Create the signature.  */ | ||||
|       memcpy (addr, &gmon_hdr, sizeof (struct gmon_hdr)); | ||||
|  | ||||
|       *(uint32_t *) hist = GMON_TAG_TIME_HIST; | ||||
|       memcpy (hist + sizeof (uint32_t), &hist_hdr, | ||||
| 	      sizeof (struct gmon_hist_hdr)); | ||||
|  | ||||
|       narcsp[-1] = GMON_TAG_CG_ARC; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* Test the signature in the file.  */ | ||||
|       if (memcmp (addr, &gmon_hdr, sizeof (struct gmon_hdr)) != 0 | ||||
| 	  || *(uint32_t *) hist != GMON_TAG_TIME_HIST | ||||
| 	  || memcmp (hist + sizeof (uint32_t), &hist_hdr, | ||||
| 		     sizeof (struct gmon_hist_hdr)) != 0 | ||||
| 	  || narcsp[-1] != GMON_TAG_CG_ARC) | ||||
| 	goto wrong_format; | ||||
|     } | ||||
|  | ||||
|   /* Allocate memory for the froms data and the pointer to the tos records.  */ | ||||
|   tos = (uint16_t *) calloc (tossize + fromssize, 1); | ||||
|   if (tos == NULL) | ||||
|     { | ||||
|       __munmap ((void *) addr, expected_size); | ||||
|       _dl_fatal_printf ("Out of memory while initializing profiler\n"); | ||||
|       /* NOTREACHED */ | ||||
|     } | ||||
|  | ||||
|   froms = (struct here_fromstruct *) ((char *) tos + tossize); | ||||
|   fromidx = 0; | ||||
|  | ||||
|   /* Now we have to process all the arc count entries.  BTW: it is | ||||
|      not critical whether the *NARCSP value changes meanwhile.  Before | ||||
|      we enter a new entry in to toset we will check that everything is | ||||
|      available in TOS.  This happens in _dl_mcount. | ||||
|  | ||||
|      Loading the entries in reverse order should help to get the most | ||||
|      frequently used entries at the front of the list.  */ | ||||
|   for (idx = narcs = MIN (*narcsp, fromlimit); idx > 0; ) | ||||
|     { | ||||
|       size_t to_index; | ||||
|       size_t newfromidx; | ||||
|       --idx; | ||||
|       to_index = (data[idx].self_pc / (hashfraction * sizeof (*tos))); | ||||
|       newfromidx = fromidx++; | ||||
|       froms[newfromidx].here = &data[idx]; | ||||
|       froms[newfromidx].link = tos[to_index]; | ||||
|       tos[to_index] = newfromidx; | ||||
|     } | ||||
|  | ||||
|   /* Setup counting data.  */ | ||||
|   if (kcountsize < highpc - lowpc) | ||||
|     { | ||||
| #if 0 | ||||
|       s_scale = ((double) kcountsize / (highpc - lowpc)) * SCALE_1_TO_1; | ||||
| #else | ||||
|       size_t range = highpc - lowpc; | ||||
|       size_t quot = range / kcountsize; | ||||
|  | ||||
|       if (quot >= SCALE_1_TO_1) | ||||
| 	s_scale = 1; | ||||
|       else if (quot >= SCALE_1_TO_1 / 256) | ||||
| 	s_scale = SCALE_1_TO_1 / quot; | ||||
|       else if (range > ULONG_MAX / 256) | ||||
| 	s_scale = (SCALE_1_TO_1 * 256) / (range / (kcountsize / 256)); | ||||
|       else | ||||
| 	s_scale = (SCALE_1_TO_1 * 256) / ((range * 256) / kcountsize); | ||||
| #endif | ||||
|     } | ||||
|   else | ||||
|     s_scale = SCALE_1_TO_1; | ||||
|  | ||||
|   /* Start the profiler.  */ | ||||
|   profil ((void *) kcount, kcountsize, lowpc, s_scale); | ||||
|  | ||||
|   /* Turn on profiling.  */ | ||||
|   running = 1; | ||||
| } | ||||
|  | ||||
|  | ||||
| void | ||||
| _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc) | ||||
| { | ||||
|   volatile uint16_t *topcindex; | ||||
|   size_t i, fromindex; | ||||
|   struct here_fromstruct *fromp; | ||||
|  | ||||
|   if (! running) | ||||
|     return; | ||||
|  | ||||
|   /* Compute relative addresses.  The shared object can be loaded at | ||||
|      any address.  The value of frompc could be anything.  We cannot | ||||
|      restrict it in any way, just set to a fixed value (0) in case it | ||||
|      is outside the allowed range.  These calls show up as calls from | ||||
|      <external> in the gprof output.  */ | ||||
|   frompc -= lowpc; | ||||
|   if (frompc >= textsize) | ||||
|     frompc = 0; | ||||
|   selfpc -= lowpc; | ||||
|   if (selfpc >= textsize) | ||||
|     goto done; | ||||
|  | ||||
|   /* Getting here we now have to find out whether the location was | ||||
|      already used.  If yes we are lucky and only have to increment a | ||||
|      counter (this also has to be atomic).  If the entry is new things | ||||
|      are getting complicated...  */ | ||||
|  | ||||
|   /* Avoid integer divide if possible.  */ | ||||
|   if ((HASHFRACTION & (HASHFRACTION - 1)) == 0) | ||||
|     i = selfpc >> log_hashfraction; | ||||
|   else | ||||
|     i = selfpc / (hashfraction * sizeof (*tos)); | ||||
|  | ||||
|   topcindex = &tos[i]; | ||||
|   fromindex = *topcindex; | ||||
|  | ||||
|   if (fromindex == 0) | ||||
|     goto check_new_or_add; | ||||
|  | ||||
|   fromp = &froms[fromindex]; | ||||
|  | ||||
|   /* We have to look through the chain of arcs whether there is already | ||||
|      an entry for our arc.  */ | ||||
|   while (fromp->here->from_pc != frompc) | ||||
|     { | ||||
|       if (fromp->link != 0) | ||||
| 	do | ||||
| 	  fromp = &froms[fromp->link]; | ||||
| 	while (fromp->link != 0 && fromp->here->from_pc != frompc); | ||||
|  | ||||
|       if (fromp->here->from_pc != frompc) | ||||
| 	{ | ||||
| 	  topcindex = &fromp->link; | ||||
|  | ||||
| 	check_new_or_add: | ||||
| 	  /* Our entry is not among the entries we read so far from the | ||||
| 	     data file.  Now see whether we have to update the list.  */ | ||||
| 	  while (narcs != *narcsp && narcs < fromlimit) | ||||
| 	    { | ||||
| 	      size_t to_index; | ||||
| 	      size_t newfromidx; | ||||
| 	      to_index = (data[narcs].self_pc | ||||
| 			  / (hashfraction * sizeof (*tos))); | ||||
| 	      newfromidx = exchange_and_add (&fromidx, 1) + 1; | ||||
| 	      froms[newfromidx].here = &data[narcs]; | ||||
| 	      froms[newfromidx].link = tos[to_index]; | ||||
| 	      tos[to_index] = newfromidx; | ||||
| 	      atomic_add (&narcs, 1); | ||||
| 	    } | ||||
|  | ||||
| 	  /* If we still have no entry stop searching and insert.  */ | ||||
| 	  if (*topcindex == 0) | ||||
| 	    { | ||||
| 	      uint32_t newarc = exchange_and_add (narcsp, 1); | ||||
|  | ||||
| 	      /* In rare cases it could happen that all entries in FROMS are | ||||
| 		 occupied.  So we cannot count this anymore.  */ | ||||
| 	      if (newarc >= fromlimit) | ||||
| 		goto done; | ||||
|  | ||||
| 	      *topcindex = exchange_and_add (&fromidx, 1) + 1; | ||||
| 	      fromp = &froms[*topcindex]; | ||||
|  | ||||
| 	      fromp->here = &data[newarc]; | ||||
| 	      data[newarc].from_pc = frompc; | ||||
| 	      data[newarc].self_pc = selfpc; | ||||
| 	      data[newarc].count = 0; | ||||
| 	      fromp->link = 0; | ||||
| 	      atomic_add (&narcs, 1); | ||||
|  | ||||
| 	      break; | ||||
| 	    } | ||||
|  | ||||
| 	  fromp = &froms[*topcindex]; | ||||
| 	} | ||||
|       else | ||||
| 	/* Found in.  */ | ||||
| 	break; | ||||
|     } | ||||
|  | ||||
|   /* Increment the counter.  */ | ||||
|   atomic_add (&fromp->here->count, 1); | ||||
|  | ||||
|  done: | ||||
|   ; | ||||
| } | ||||
							
								
								
									
										43
									
								
								newlib/libc/sys/linux/dl/dl-profstub.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								newlib/libc/sys/linux/dl/dl-profstub.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| /* Helper definitions for profiling of shared libraries. | ||||
|    Copyright (C) 1998, 2000 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <dlfcn.h> | ||||
| #include <elf.h> | ||||
| #include <ldsodefs.h> | ||||
| #include <libc-symbols.h> | ||||
|  | ||||
| /* This is the map for the shared object we profile.  It is defined here | ||||
|    only because we test for this value being NULL or not.  */ | ||||
| extern struct link_map *_dl_profile_map; | ||||
|  | ||||
|  | ||||
| void | ||||
| _dl_mcount_wrapper (void *selfpc) | ||||
| { | ||||
|   _dl_mcount ((ElfW(Addr)) RETURN_ADDRESS (0), (ElfW(Addr)) selfpc); | ||||
| } | ||||
|  | ||||
|  | ||||
| void | ||||
| _dl_mcount_wrapper_check (void *selfpc) | ||||
| { | ||||
|   if (_dl_profile_map != NULL) | ||||
|     _dl_mcount ((ElfW(Addr)) RETURN_ADDRESS (0), (ElfW(Addr)) selfpc); | ||||
| } | ||||
							
								
								
									
										213
									
								
								newlib/libc/sys/linux/dl/dl-reloc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								newlib/libc/sys/linux/dl/dl-reloc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,213 @@ | ||||
| /* Relocate a shared object and resolve its references to other loaded objects. | ||||
|    Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <libintl.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| #include <ldsodefs.h> | ||||
| #include <sys/mman.h> | ||||
| #include <sys/param.h> | ||||
| #include <sys/types.h> | ||||
| #include "dynamic-link.h" | ||||
|  | ||||
| /* Statistics function.  */ | ||||
| unsigned long int _dl_num_cache_relocations; | ||||
|  | ||||
|  | ||||
| void | ||||
| _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], | ||||
| 		     int lazy, int consider_profiling) | ||||
| { | ||||
|   struct textrels | ||||
|   { | ||||
|     caddr_t start; | ||||
|     size_t len; | ||||
|     int prot; | ||||
|     struct textrels *next; | ||||
|   } *textrels = NULL; | ||||
|   /* Initialize it to make the compiler happy.  */ | ||||
|   const char *errstring = NULL; | ||||
|  | ||||
|   if (l->l_relocated) | ||||
|     return; | ||||
|  | ||||
|   /* If DT_BIND_NOW is set relocate all references in this object.  We | ||||
|      do not do this if we are profiling, of course.  */ | ||||
|   if (!consider_profiling | ||||
|       && __builtin_expect (l->l_info[DT_BIND_NOW] != NULL, 0)) | ||||
|     lazy = 0; | ||||
|  | ||||
|   if (__builtin_expect (_dl_debug_mask & DL_DEBUG_RELOC, 0)) | ||||
|     _dl_printf ("\nrelocation processing: %s%s\n", | ||||
| 		l->l_name[0] ? l->l_name : _dl_argv[0], lazy ? " (lazy)" : ""); | ||||
|  | ||||
|   /* DT_TEXTREL is now in level 2 and might phase out at some time. | ||||
|      But we rewrite the DT_FLAGS entry to a DT_TEXTREL entry to make | ||||
|      testing easier and therefore it will be available at all time.  */ | ||||
|   if (__builtin_expect (l->l_info[DT_TEXTREL] != NULL, 0)) | ||||
|     { | ||||
|       /* Bletch.  We must make read-only segments writable | ||||
| 	 long enough to relocate them.  */ | ||||
|       const ElfW(Phdr) *ph; | ||||
|       for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph) | ||||
| 	if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0) | ||||
| 	  { | ||||
| 	    struct textrels *newp; | ||||
|  | ||||
| 	    newp = (struct textrels *) alloca (sizeof (*newp)); | ||||
| 	    newp->len = (((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1) | ||||
| 			  & ~(_dl_pagesize - 1)) | ||||
| 			 - (ph->p_vaddr & ~(_dl_pagesize - 1))); | ||||
| 	    newp->start = ((ph->p_vaddr & ~(_dl_pagesize - 1)) | ||||
| 			   + (caddr_t) l->l_addr); | ||||
|  | ||||
| 	    if (mprotect (newp->start, newp->len, PROT_READ|PROT_WRITE) < 0) | ||||
| 	      { | ||||
| 		errstring = N_("cannot make segment writable for relocation"); | ||||
| 	      call_error: | ||||
| 		_dl_signal_error (errno, l->l_name, NULL, errstring); | ||||
| 	      } | ||||
|  | ||||
| #if (PF_R | PF_W | PF_X) == 7 && (PROT_READ | PROT_WRITE | PROT_EXEC) == 7 | ||||
| 	    newp->prot = (PF_TO_PROT | ||||
| 			  >> ((ph->p_flags & (PF_R | PF_W | PF_X)) * 4)) & 0xf; | ||||
| #else | ||||
| 	    newp->prot = 0; | ||||
| 	    if (ph->p_flags & PF_R) | ||||
| 	      newp->prot |= PROT_READ; | ||||
| 	    if (ph->p_flags & PF_W) | ||||
| 	      newp->prot |= PROT_WRITE; | ||||
| 	    if (ph->p_flags & PF_X) | ||||
| 	      newp->prot |= PROT_EXEC; | ||||
| #endif | ||||
| 	    newp->next = textrels; | ||||
| 	    textrels = newp; | ||||
| 	  } | ||||
|     } | ||||
|  | ||||
|   { | ||||
|     /* Do the actual relocation of the object's GOT and other data.  */ | ||||
|  | ||||
|     /* String table object symbols.  */ | ||||
|     const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); | ||||
|  | ||||
|     /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */ | ||||
| #define RESOLVE_MAP(ref, version, r_type) \ | ||||
|     (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL			      \ | ||||
|      ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0)		      \ | ||||
| 	 && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class)  \ | ||||
| 	? (++_dl_num_cache_relocations,					      \ | ||||
| 	   (*ref) = l->l_lookup_cache.ret,				      \ | ||||
| 	   l->l_lookup_cache.value)					      \ | ||||
| 	: ({ lookup_t _lr;						      \ | ||||
| 	     int _tc = elf_machine_type_class (r_type);			      \ | ||||
| 	     l->l_lookup_cache.type_class = _tc;			      \ | ||||
| 	     l->l_lookup_cache.sym = (*ref);				      \ | ||||
| 	     _lr = ((version) != NULL && (version)->hash != 0		      \ | ||||
| 		    ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name,  \ | ||||
| 						   l, (ref), scope,	      \ | ||||
| 						   (version), _tc, 0)	      \ | ||||
| 		    : _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref),  \ | ||||
| 					 scope, _tc, 0));		      \ | ||||
| 	     l->l_lookup_cache.ret = (*ref);				      \ | ||||
| 	     l->l_lookup_cache.value = _lr; }))				      \ | ||||
|      : l) | ||||
| #define RESOLVE(ref, version, r_type) \ | ||||
|     (ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL			      \ | ||||
|      ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0)		      \ | ||||
| 	 && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class)  \ | ||||
| 	? (++_dl_num_cache_relocations,					      \ | ||||
| 	   (*ref) = l->l_lookup_cache.ret,				      \ | ||||
| 	   l->l_lookup_cache.value)					      \ | ||||
| 	: ({ lookup_t _lr;						      \ | ||||
| 	     int _tc = elf_machine_type_class (r_type);			      \ | ||||
| 	     l->l_lookup_cache.type_class = _tc;			      \ | ||||
| 	     l->l_lookup_cache.sym = (*ref);				      \ | ||||
| 	     _lr = ((version) != NULL && (version)->hash != 0		      \ | ||||
| 		    ? _dl_lookup_versioned_symbol (strtab + (*ref)->st_name,  \ | ||||
| 						   l, (ref), scope,	      \ | ||||
| 						   (version), _tc, 0)	      \ | ||||
| 		    : _dl_lookup_symbol (strtab + (*ref)->st_name, l, (ref),  \ | ||||
| 					 scope, _tc, 0));		      \ | ||||
| 	     l->l_lookup_cache.ret = (*ref);				      \ | ||||
| 	     l->l_lookup_cache.value = _lr; }))				      \ | ||||
|      : l->l_addr) | ||||
|  | ||||
| #include "dynamic-link.h" | ||||
|  | ||||
|     ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling); | ||||
|  | ||||
|     if (__builtin_expect (consider_profiling, 0)) | ||||
|       { | ||||
| 	/* Allocate the array which will contain the already found | ||||
| 	   relocations.  If the shared object lacks a PLT (for example | ||||
| 	   if it only contains lead function) the l_info[DT_PLTRELSZ] | ||||
| 	   will be NULL.  */ | ||||
| 	if (l->l_info[DT_PLTRELSZ] == NULL) | ||||
| 	  { | ||||
| 	    errstring = N_("%s: profiler found no PLTREL in object %s\n"); | ||||
| 	  fatal: | ||||
| 	    _dl_fatal_printf (errstring, | ||||
| 			      _dl_argv[0] ?: "<program name unknown>", | ||||
| 			      l->l_name); | ||||
| 	  } | ||||
|  | ||||
| 	l->l_reloc_result = | ||||
| 	  (ElfW(Addr) *) calloc (sizeof (ElfW(Addr)), | ||||
| 				 l->l_info[DT_PLTRELSZ]->d_un.d_val); | ||||
| 	if (l->l_reloc_result == NULL) | ||||
| 	  { | ||||
| 	    errstring = N_("\ | ||||
| %s: profiler out of memory shadowing PLTREL of %s\n"); | ||||
| 	    goto fatal; | ||||
| 	  } | ||||
|       } | ||||
|   } | ||||
|  | ||||
|   /* Mark the object so we know this work has been done.  */ | ||||
|   l->l_relocated = 1; | ||||
|  | ||||
|   /* Undo the segment protection changes.  */ | ||||
|   while (__builtin_expect (textrels != NULL, 0)) | ||||
|     { | ||||
|       if (mprotect (textrels->start, textrels->len, textrels->prot) < 0) | ||||
| 	{ | ||||
| 	  errstring = N_("cannot restore segment prot after reloc"); | ||||
| 	  goto call_error; | ||||
| 	} | ||||
|  | ||||
|       textrels = textrels->next; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| void | ||||
| internal_function | ||||
| _dl_reloc_bad_type (struct link_map *map, unsigned int type, int plt) | ||||
| { | ||||
|   /* XXX We cannot translate these messages.  */ | ||||
|   static const char msg[2][32] = { "unexpected reloc type", | ||||
| 				   "unexpected PLT reloc type" }; | ||||
|   char msgbuf[sizeof (msg[0])]; | ||||
|  | ||||
|   strcpy (msgbuf, msg[plt]); | ||||
|  | ||||
|   _dl_signal_error (0, map->l_name, NULL, msgbuf); | ||||
| } | ||||
							
								
								
									
										231
									
								
								newlib/libc/sys/linux/dl/dl-runtime.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								newlib/libc/sys/linux/dl/dl-runtime.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,231 @@ | ||||
| /* On-demand PLT fixup for shared objects. | ||||
|    Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <alloca.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| #include <ldsodefs.h> | ||||
| #include "dynamic-link.h" | ||||
|  | ||||
| #define __attribute_used__ | ||||
|  | ||||
| #if !defined ELF_MACHINE_NO_RELA || ELF_MACHINE_NO_REL | ||||
| # define PLTREL  ElfW(Rela) | ||||
| #else | ||||
| # define PLTREL  ElfW(Rel) | ||||
| #endif | ||||
|  | ||||
| #ifndef VERSYMIDX | ||||
| # define VERSYMIDX(sym)	(DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* This function is called through a special trampoline from the PLT the | ||||
|    first time each PLT entry is called.  We must perform the relocation | ||||
|    specified in the PLT of the given shared object, and return the resolved | ||||
|    function address to the trampoline, which will restart the original call | ||||
|    to that address.  Future calls will bounce directly from the PLT to the | ||||
|    function.  */ | ||||
|  | ||||
| #ifndef ELF_MACHINE_NO_PLT | ||||
| static ElfW(Addr) __attribute_used__ | ||||
| fixup ( | ||||
| # ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS | ||||
|         ELF_MACHINE_RUNTIME_FIXUP_ARGS, | ||||
| # endif | ||||
| 	/* GKM FIXME: Fix trampoline to pass bounds so we can do | ||||
| 	   without the `__unbounded' qualifier.  */ | ||||
|        struct link_map *__unbounded l, ElfW(Word) reloc_offset) | ||||
| { | ||||
|   const ElfW(Sym) *const symtab | ||||
|     = (const void *) D_PTR (l, l_info[DT_SYMTAB]); | ||||
|   const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); | ||||
|  | ||||
|   const PLTREL *const reloc | ||||
|     = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset); | ||||
|   const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)]; | ||||
|   void *const rel_addr = (void *)(l->l_addr + reloc->r_offset); | ||||
|   lookup_t result; | ||||
|   ElfW(Addr) value; | ||||
|  | ||||
|   /* The use of `alloca' here looks ridiculous but it helps.  The goal is | ||||
|      to prevent the function from being inlined and thus optimized out. | ||||
|      There is no official way to do this so we use this trick.  gcc never | ||||
|      inlines functions which use `alloca'.  */ | ||||
|   alloca (sizeof (int)); | ||||
|  | ||||
|   /* Sanity check that we're really looking at a PLT relocation.  */ | ||||
|   assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT); | ||||
|  | ||||
|    /* Look up the target symbol.  If the normal lookup rules are not | ||||
|       used don't look in the global scope.  */ | ||||
|   if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0) | ||||
|     { | ||||
|       switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) | ||||
| 	{ | ||||
| 	default: | ||||
| 	  { | ||||
| 	    const ElfW(Half) *vernum = | ||||
| 	      (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]); | ||||
| 	    ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)]; | ||||
| 	    const struct r_found_version *version = &l->l_versions[ndx]; | ||||
|  | ||||
| 	    if (version->hash != 0) | ||||
| 	      { | ||||
| 		result = _dl_lookup_versioned_symbol (strtab + sym->st_name, | ||||
| 						      l, &sym, l->l_scope, | ||||
| 						      version, | ||||
| 						      ELF_RTYPE_CLASS_PLT, 0); | ||||
| 		break; | ||||
| 	      } | ||||
| 	  } | ||||
| 	case 0: | ||||
| 	  result = _dl_lookup_symbol (strtab + sym->st_name, l, &sym, | ||||
| 				      l->l_scope, ELF_RTYPE_CLASS_PLT, 0); | ||||
| 	} | ||||
|  | ||||
|       /* Currently result contains the base load address (or link map) | ||||
| 	 of the object that defines sym.  Now add in the symbol | ||||
| 	 offset.  */ | ||||
|       value = (sym ? LOOKUP_VALUE_ADDRESS (result) + sym->st_value : 0); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* We already found the symbol.  The module (and therefore its load | ||||
| 	 address) is also known.  */ | ||||
|       value = l->l_addr + sym->st_value; | ||||
| #ifdef DL_LOOKUP_RETURNS_MAP | ||||
|       result = l; | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|   /* And now perhaps the relocation addend.  */ | ||||
|   value = elf_machine_plt_value (l, reloc, value); | ||||
|  | ||||
|   /* Finally, fix up the plt itself.  */ | ||||
|   if (__builtin_expect (_dl_bind_not, 0)) | ||||
|     return value; | ||||
|  | ||||
|   return elf_machine_fixup_plt (l, result, reloc, rel_addr, value); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #if !defined PROF && !defined ELF_MACHINE_NO_PLT && !__BOUNDED_POINTERS__ | ||||
|  | ||||
| static ElfW(Addr) __attribute_used__ | ||||
| profile_fixup ( | ||||
| #ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS | ||||
|        ELF_MACHINE_RUNTIME_FIXUP_ARGS, | ||||
| #endif | ||||
|        struct link_map *l, ElfW(Word) reloc_offset, ElfW(Addr) retaddr) | ||||
| { | ||||
|   void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = _dl_mcount; | ||||
|   ElfW(Addr) *resultp; | ||||
|   lookup_t result; | ||||
|   ElfW(Addr) value; | ||||
|  | ||||
|   /* The use of `alloca' here looks ridiculous but it helps.  The goal is | ||||
|      to prevent the function from being inlined, and thus optimized out. | ||||
|      There is no official way to do this so we use this trick.  gcc never | ||||
|      inlines functions which use `alloca'.  */ | ||||
|   alloca (sizeof (int)); | ||||
|  | ||||
|   /* This is the address in the array where we store the result of previous | ||||
|      relocations.  */ | ||||
|   resultp = &l->l_reloc_result[reloc_offset / sizeof (PLTREL)]; | ||||
|  | ||||
|   value = *resultp; | ||||
|   if (value == 0) | ||||
|     { | ||||
|       /* This is the first time we have to relocate this object.  */ | ||||
|       const ElfW(Sym) *const symtab | ||||
| 	= (const void *) D_PTR (l, l_info[DT_SYMTAB]); | ||||
|       const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); | ||||
|  | ||||
|       const PLTREL *const reloc | ||||
| 	= (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset); | ||||
|       const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)]; | ||||
|  | ||||
|       /* Sanity check that we're really looking at a PLT relocation.  */ | ||||
|       assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT); | ||||
|  | ||||
|       /* Look up the target symbol.  If the symbol is marked STV_PROTECTED | ||||
| 	 don't look in the global scope.  */ | ||||
|       if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0) | ||||
| 	{ | ||||
| 	  switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL) | ||||
| 	    { | ||||
| 	    default: | ||||
| 	      { | ||||
| 		const ElfW(Half) *vernum = | ||||
| 		  (const void *) D_PTR (l,l_info[VERSYMIDX (DT_VERSYM)]); | ||||
| 		ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)]; | ||||
| 		const struct r_found_version *version = &l->l_versions[ndx]; | ||||
|  | ||||
| 		if (version->hash != 0) | ||||
| 		  { | ||||
| 		    result = _dl_lookup_versioned_symbol(strtab + sym->st_name, | ||||
| 							 l, &sym, l->l_scope, | ||||
| 							 version, | ||||
| 							 ELF_RTYPE_CLASS_PLT, | ||||
| 							 0); | ||||
| 		    break; | ||||
| 		  } | ||||
| 	      } | ||||
| 	    case 0: | ||||
| 	      result = _dl_lookup_symbol (strtab + sym->st_name, l, &sym, | ||||
| 					  l->l_scope, ELF_RTYPE_CLASS_PLT, 0); | ||||
| 	    } | ||||
|  | ||||
| 	  /* Currently result contains the base load address (or link map) | ||||
| 	     of the object that defines sym.  Now add in the symbol | ||||
| 	     offset.  */ | ||||
| 	  value = (sym ? LOOKUP_VALUE_ADDRESS (result) + sym->st_value : 0); | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  /* We already found the symbol.  The module (and therefore its load | ||||
| 	     address) is also known.  */ | ||||
| 	  value = l->l_addr + sym->st_value; | ||||
| #ifdef DL_LOOKUP_RETURNS_MAP | ||||
| 	  result = l; | ||||
| #endif | ||||
| 	} | ||||
|       /* And now perhaps the relocation addend.  */ | ||||
|       value = elf_machine_plt_value (l, reloc, value); | ||||
|  | ||||
|       /* Store the result for later runs.  */ | ||||
|       if (__builtin_expect (! _dl_bind_not, 1)) | ||||
| 	*resultp = value; | ||||
|     } | ||||
|  | ||||
|   (*mcount_fct) (retaddr, value); | ||||
|  | ||||
|   return value; | ||||
| } | ||||
|  | ||||
| #endif /* PROF && ELF_MACHINE_NO_PLT */ | ||||
|  | ||||
|  | ||||
| /* This macro is defined in dl-machine.h to define the entry point called | ||||
|    by the PLT.  The `fixup' function above does the real work, but a little | ||||
|    more twiddling is needed to get the stack right and jump to the address | ||||
|    finally resolved.  */ | ||||
|  | ||||
| ELF_MACHINE_RUNTIME_TRAMPOLINE | ||||
							
								
								
									
										184
									
								
								newlib/libc/sys/linux/dl/dl-support.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								newlib/libc/sys/linux/dl/dl-support.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,184 @@ | ||||
| /* Support for dynamic linking code in static libc. | ||||
|    Copyright (C) 1996, 97, 98, 99, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| /* This file defines some things that for the dynamic linker are defined in | ||||
|    rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking.  */ | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <libintl.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| #include <dirent.h> | ||||
| #include <pthread.h> | ||||
| #include <ldsodefs.h> | ||||
| #include <machine/dl-machine.h> | ||||
| #include <dl-librecon.h> | ||||
| #include <unsecvars.h> | ||||
| #include <machine/hp-timing.h> | ||||
|  | ||||
| char *__progname = "newlib"; | ||||
| char **_dl_argv = &__progname;	/* This is checked for some error messages.  */ | ||||
|  | ||||
| /* Name of the architecture.  */ | ||||
| const char *_dl_platform; | ||||
| size_t _dl_platformlen; | ||||
|  | ||||
| int _dl_debug_mask; | ||||
| int _dl_lazy; | ||||
| /* XXX I know about at least one case where we depend on the old weak | ||||
|    behavior (it has to do with librt).  Until we get DSO groups implemented | ||||
|    we have to make this the default.  Bummer. --drepper  */ | ||||
| #if 0 | ||||
| int _dl_dynamic_weak; | ||||
| #else | ||||
| int _dl_dynamic_weak = 1; | ||||
| #endif | ||||
|  | ||||
| /* If nonzero print warnings about problematic situations.  */ | ||||
| int _dl_verbose; | ||||
|  | ||||
| /* Structure to store information about search paths.  */ | ||||
| struct r_search_path *_dl_search_paths; | ||||
|  | ||||
| /* We never do profiling.  */ | ||||
| const char *_dl_profile; | ||||
|  | ||||
| /* Names of shared object for which the RUNPATHs and RPATHs should be | ||||
|    ignored.  */ | ||||
| const char *_dl_inhibit_rpath; | ||||
|  | ||||
| /* The map for the object we will profile.  */ | ||||
| struct link_map *_dl_profile_map; | ||||
|  | ||||
| /* This is the address of the last stack address ever used.  */ | ||||
| void *__libc_stack_end; | ||||
|  | ||||
| /* Path where the binary is found.  */ | ||||
| const char *_dl_origin_path; | ||||
|  | ||||
| /* Nonzero if runtime lookup should not update the .got/.plt.  */ | ||||
| int _dl_bind_not; | ||||
|  | ||||
| /* Initially empty list of loaded objects.  */ | ||||
| struct link_map *_dl_loaded; | ||||
| /* Number of object in the _dl_loaded list.  */ | ||||
| unsigned int _dl_nloaded; | ||||
|  | ||||
| /* Fake scope.  In dynamically linked binaries this is the scope of the | ||||
|    main application but here we don't have something like this.  So | ||||
|    create a fake scope containing nothing.  */ | ||||
| struct r_scope_elem _dl_initial_searchlist; | ||||
| /* Variable which can be used in lookup to process the global scope.  */ | ||||
| struct r_scope_elem *_dl_global_scope[2] = { &_dl_initial_searchlist, NULL }; | ||||
| /* This is a global pointer to this structure which is public.  It is | ||||
|    used by dlopen/dlclose to add and remove objects from what is regarded | ||||
|    to be the global scope.  */ | ||||
| struct r_scope_elem *_dl_main_searchlist = &_dl_initial_searchlist; | ||||
|  | ||||
| /* Nonzero during startup.  */ | ||||
| int _dl_starting_up = 1; | ||||
|  | ||||
| /* We expect less than a second for relocation.  */ | ||||
| #ifdef HP_SMALL_TIMING_AVAIL | ||||
| # undef HP_TIMING_AVAIL | ||||
| # define HP_TIMING_AVAIL HP_SMALL_TIMING_AVAIL | ||||
| #endif | ||||
|  | ||||
| /* Initial value of the CPU clock.  */ | ||||
| #ifndef HP_TIMING_NONAVAIL | ||||
| hp_timing_t _dl_cpuclock_offset; | ||||
| #endif | ||||
|  | ||||
| /* During the program run we must not modify the global data of | ||||
|    loaded shared object simultanously in two threads.  Therefore we | ||||
|    protect `_dl_open' and `_dl_close' in dl-close.c. | ||||
|  | ||||
|    This must be a recursive lock since the initializer function of | ||||
|    the loaded object might as well require a call to this function. | ||||
|    At this time it is not anymore a problem to modify the tables.  */ | ||||
| __LOCK_RECURSIVE_INIT (, _dl_load_lock) | ||||
|  | ||||
|  | ||||
| #ifdef HAVE_AUX_VECTOR | ||||
| extern int _dl_clktck; | ||||
|  | ||||
| void | ||||
| internal_function | ||||
| _dl_aux_init (ElfW(auxv_t) *av) | ||||
| { | ||||
|   for (; av->a_type != AT_NULL; ++av) | ||||
|     switch (av->a_type) | ||||
|       { | ||||
|       case AT_PAGESZ: | ||||
| 	_dl_pagesize = av->a_un.a_val; | ||||
| 	break; | ||||
|       case AT_CLKTCK: | ||||
| 	_dl_clktck = av->a_un.a_val; | ||||
| 	break; | ||||
|       } | ||||
| } | ||||
| #endif | ||||
|  | ||||
| void non_dynamic_init (void) __attribute__ ((unused)); | ||||
|  | ||||
| void | ||||
| non_dynamic_init (void) | ||||
| { | ||||
|   if (HP_TIMING_AVAIL) | ||||
|     HP_TIMING_NOW (_dl_cpuclock_offset); | ||||
|  | ||||
|   if (!_dl_pagesize) | ||||
|     _dl_pagesize = __getpagesize (); | ||||
|  | ||||
|   _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1; | ||||
|  | ||||
|   /* Initialize the data structures for the search paths for shared | ||||
|      objects.  */ | ||||
|   _dl_init_paths (getenv ("LD_LIBRARY_PATH")); | ||||
|  | ||||
|   _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0'; | ||||
|  | ||||
|   _dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0'; | ||||
|  | ||||
|   _dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0'; | ||||
|  | ||||
| #ifdef DL_PLATFORM_INIT | ||||
|   DL_PLATFORM_INIT; | ||||
| #endif | ||||
|  | ||||
|   /* Now determine the length of the platform string.  */ | ||||
|   if (_dl_platform != NULL) | ||||
|     _dl_platformlen = strlen (_dl_platform); | ||||
| } | ||||
| text_set_element (__libc_subinit, non_dynamic_init); | ||||
|  | ||||
| const struct r_strlenpair * | ||||
| internal_function | ||||
| _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz, | ||||
| 		      size_t *max_capstrlen) | ||||
| { | ||||
|   static struct r_strlenpair result; | ||||
|   static char buf[1]; | ||||
|  | ||||
|   result.str = buf;	/* Does not really matter.  */ | ||||
|   result.len = 0; | ||||
|  | ||||
|   *sz = 1; | ||||
|   return &result; | ||||
| } | ||||
							
								
								
									
										158
									
								
								newlib/libc/sys/linux/dl/dl-sym.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								newlib/libc/sys/linux/dl/dl-sym.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,158 @@ | ||||
| /* Look up a symbol in a shared object loaded by `dlopen'. | ||||
|    Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <setjmp.h> | ||||
| #include <libintl.h> | ||||
|  | ||||
| #include <dlfcn.h> | ||||
| #include <ldsodefs.h> | ||||
| #include <dl-hash.h> | ||||
|  | ||||
| void * | ||||
| internal_function | ||||
| _dl_sym (void *handle, const char *name, void *who) | ||||
| { | ||||
|   const ElfW(Sym) *ref = NULL; | ||||
|   lookup_t result; | ||||
|   ElfW(Addr) caller = (ElfW(Addr)) who; | ||||
|   struct link_map *match; | ||||
|   struct link_map *l; | ||||
|  | ||||
|   /* If the address is not recognized the call comes from the main | ||||
|      program (we hope).  */ | ||||
|   match = _dl_loaded; | ||||
|  | ||||
|   /* Find the highest-addressed object that CALLER is not below.  */ | ||||
|   for (l = _dl_loaded; l != NULL; l = l->l_next) | ||||
|     if (caller >= l->l_map_start && caller < l->l_map_end) | ||||
|       { | ||||
| 	/* There must be exactly one DSO for the range of the virtual | ||||
| 	   memory.  Otherwise something is really broken.  */ | ||||
| 	match = l; | ||||
| 	break; | ||||
|       } | ||||
|  | ||||
|   if (handle == RTLD_DEFAULT) | ||||
|     /* Search the global scope as seen in the caller object.  */ | ||||
|     result = _dl_lookup_symbol (name, match, &ref, match->l_scope, 0, 0); | ||||
|   else | ||||
|     { | ||||
|       if (handle != RTLD_NEXT) | ||||
| 	{ | ||||
| 	  /* Search the scope of the given object.  */ | ||||
| 	  struct link_map *map = handle; | ||||
|  | ||||
| 	  result = _dl_lookup_symbol (name, match, &ref, map->l_local_scope, | ||||
| 				      0, 1); | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  if (__builtin_expect (match == _dl_loaded, 0)) | ||||
| 	    { | ||||
| 	      if (! _dl_loaded | ||||
| 		  || caller < _dl_loaded->l_map_start | ||||
| 		  || caller >= _dl_loaded->l_map_end) | ||||
| 	        _dl_signal_error (0, NULL, NULL, N_("\ | ||||
| RTLD_NEXT used in code not dynamically loaded")); | ||||
| 	    } | ||||
|  | ||||
| 	  l = match; | ||||
| 	  while (l->l_loader != NULL) | ||||
| 	    l = l->l_loader; | ||||
|  | ||||
| 	  result = _dl_lookup_symbol_skip (name, l, &ref, l->l_local_scope, | ||||
| 					   match); | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   if (ref != NULL) | ||||
|     return DL_SYMBOL_ADDRESS (result, ref); | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| void * | ||||
| internal_function | ||||
| _dl_vsym (void *handle, const char *name, const char *version, void *who) | ||||
| { | ||||
|   const ElfW(Sym) *ref = NULL; | ||||
|   struct r_found_version vers; | ||||
|   lookup_t result; | ||||
|   ElfW(Addr) caller = (ElfW(Addr)) who; | ||||
|   struct link_map *match; | ||||
|   struct link_map *l; | ||||
|  | ||||
|   /* Compute hash value to the version string.  */ | ||||
|   vers.name = version; | ||||
|   vers.hidden = 1; | ||||
|   vers.hash = _dl_elf_hash (version); | ||||
|   /* We don't have a specific file where the symbol can be found.  */ | ||||
|   vers.filename = NULL; | ||||
|  | ||||
|   /* If the address is not recognized the call comes from the main | ||||
|      program (we hope).  */ | ||||
|   match = _dl_loaded; | ||||
|  | ||||
|   /* Find the highest-addressed object that CALLER is not below.  */ | ||||
|   for (l = _dl_loaded; l != NULL; l = l->l_next) | ||||
|     if (caller >= l->l_map_start && caller < l->l_map_end) | ||||
|       { | ||||
| 	/* There must be exactly one DSO for the range of the virtual | ||||
| 	   memory.  Otherwise something is really broken.  */ | ||||
| 	match = l; | ||||
| 	break; | ||||
|       } | ||||
|  | ||||
|   if (handle == RTLD_DEFAULT) | ||||
|     /* Search the global scope.  */ | ||||
|     result = _dl_lookup_versioned_symbol (name, match, &ref, match->l_scope, | ||||
| 					  &vers, 0, 0); | ||||
|   else if (handle == RTLD_NEXT) | ||||
|     { | ||||
|       if (__builtin_expect (match == _dl_loaded, 0)) | ||||
| 	{ | ||||
| 	  if (! _dl_loaded | ||||
| 	      || caller < _dl_loaded->l_map_start | ||||
| 	      || caller >= _dl_loaded->l_map_end) | ||||
| 	    _dl_signal_error (0, NULL, NULL, N_("\ | ||||
| RTLD_NEXT used in code not dynamically loaded")); | ||||
| 	} | ||||
|  | ||||
|       l = match; | ||||
|       while (l->l_loader != NULL) | ||||
| 	l = l->l_loader; | ||||
|  | ||||
|       result = _dl_lookup_versioned_symbol_skip (name, l, &ref, | ||||
| 						 l->l_local_scope, | ||||
| 						 &vers, match); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* Search the scope of the given object.  */ | ||||
|       struct link_map *map = handle; | ||||
|       result = _dl_lookup_versioned_symbol (name, map, &ref, | ||||
| 					    map->l_local_scope, &vers, 0, 1); | ||||
|     } | ||||
|  | ||||
|   if (ref != NULL) | ||||
|     return DL_SYMBOL_ADDRESS (result, ref); | ||||
|  | ||||
|   return NULL; | ||||
| } | ||||
							
								
								
									
										385
									
								
								newlib/libc/sys/linux/dl/dl-version.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										385
									
								
								newlib/libc/sys/linux/dl/dl-version.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,385 @@ | ||||
| /* Handle symbol and library versioning. | ||||
|    Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <elf.h> | ||||
| #include <errno.h> | ||||
| #include <libintl.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <ldsodefs.h> | ||||
|  | ||||
| #include <assert.h> | ||||
|  | ||||
|  | ||||
| #ifndef VERSYMIDX | ||||
| # define VERSYMIDX(tag)	(DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag)) | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #define make_string(string, rest...) \ | ||||
|   ({									      \ | ||||
|     const char *all[] = { string, ## rest };				      \ | ||||
|     size_t len, cnt;							      \ | ||||
|     char *result, *cp;							      \ | ||||
| 									      \ | ||||
|     len = 1;								      \ | ||||
|     for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt)		      \ | ||||
|       len += strlen (all[cnt]);						      \ | ||||
| 									      \ | ||||
|     cp = result = alloca (len);						      \ | ||||
|     for (cnt = 0; cnt < sizeof (all) / sizeof (all[0]); ++cnt)		      \ | ||||
|     {                    						      \ | ||||
|       cp = strcpy (cp, all[cnt]);					      \ | ||||
|       cp += strlen (all[cnt]);					              \ | ||||
|     }                    						      \ | ||||
| 									      \ | ||||
|     result;								      \ | ||||
|   }) | ||||
|  | ||||
|  | ||||
| static inline struct link_map * | ||||
| find_needed (const char *name, struct link_map *map) | ||||
| { | ||||
|   struct link_map *tmap; | ||||
|   unsigned int n; | ||||
|  | ||||
|   for (tmap = _dl_loaded; tmap != NULL; tmap = tmap->l_next) | ||||
|     if (_dl_name_match_p (name, tmap)) | ||||
|       return tmap; | ||||
|  | ||||
|   /* The required object is not in the global scope, look to see if it is | ||||
|      a dependency of the current object.  */ | ||||
|   for (n = 0; n < map->l_searchlist.r_nlist; n++) | ||||
|     if (_dl_name_match_p (name, map->l_searchlist.r_list[n])) | ||||
|       return map->l_searchlist.r_list[n]; | ||||
|  | ||||
|   /* Should never happen.  */ | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int | ||||
| internal_function | ||||
| match_symbol (const char *name, ElfW(Word) hash, const char *string, | ||||
| 	      struct link_map *map, int verbose, int weak) | ||||
| { | ||||
|   const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); | ||||
|   ElfW(Addr) def_offset; | ||||
|   ElfW(Verdef) *def; | ||||
|   /* Initialize to make the compiler happy.  */ | ||||
|   const char *errstring = NULL; | ||||
|   int result = 0; | ||||
|  | ||||
|   /* Display information about what we are doing while debugging.  */ | ||||
|   if (__builtin_expect (_dl_debug_mask & DL_DEBUG_VERSIONS, 0)) | ||||
|     _dl_debug_printf ("\ | ||||
| checking for version `%s' in file %s required by file %s\n", | ||||
| 		      string, map->l_name[0] ? map->l_name : _dl_argv[0], | ||||
| 		      name); | ||||
|  | ||||
|   if (__builtin_expect (map->l_info[VERSYMIDX (DT_VERDEF)] == NULL, 0)) | ||||
|     { | ||||
|       /* The file has no symbol versioning.  I.e., the dependent | ||||
| 	 object was linked against another version of this file.  We | ||||
| 	 only print a message if verbose output is requested.  */ | ||||
|       if (verbose) | ||||
| 	{ | ||||
| 	  /* XXX We cannot translate the messages.  */ | ||||
| 	  errstring = make_string ("\ | ||||
| no version information available (required by ", name, ")"); | ||||
| 	  goto call_cerror; | ||||
| 	} | ||||
|       return 0; | ||||
|     } | ||||
|  | ||||
|   def_offset = map->l_info[VERSYMIDX (DT_VERDEF)]->d_un.d_ptr; | ||||
|   assert (def_offset != 0); | ||||
|  | ||||
|   def = (ElfW(Verdef) *) ((char *) map->l_addr + def_offset); | ||||
|   while (1) | ||||
|     { | ||||
|       /* Currently the version number of the definition entry is 1. | ||||
| 	 Make sure all we see is this version.  */ | ||||
|       if (__builtin_expect (def->vd_version, 1) != 1) | ||||
| 	{ | ||||
| 	  char buf[20]; | ||||
| 	  buf[sizeof (buf) - 1] = '\0'; | ||||
| 	  /* XXX We cannot translate the message.  */ | ||||
| 	  errstring = make_string ("unsupported version of Verdef record"); | ||||
| 	  result = 1; | ||||
| 	  goto call_cerror; | ||||
| 	} | ||||
|  | ||||
|       /* Compare the hash values.  */ | ||||
|       if (hash == def->vd_hash) | ||||
| 	{ | ||||
| 	  ElfW(Verdaux) *aux = (ElfW(Verdaux) *) ((char *) def + def->vd_aux); | ||||
|  | ||||
| 	  /* To be safe, compare the string as well.  */ | ||||
| 	  if (__builtin_expect (strcmp (string, strtab + aux->vda_name), 0) | ||||
| 	      == 0) | ||||
| 	    /* Bingo!  */ | ||||
| 	    return 0; | ||||
| 	} | ||||
|  | ||||
|       /* If no more definitions we failed to find what we want.  */ | ||||
|       if (def->vd_next == 0) | ||||
| 	break; | ||||
|  | ||||
|       /* Next definition.  */ | ||||
|       def = (ElfW(Verdef) *) ((char *) def + def->vd_next); | ||||
|     } | ||||
|  | ||||
|   /* Symbol not found.  If it was a weak reference it is not fatal.  */ | ||||
|   if (__builtin_expect (weak, 1)) | ||||
|     { | ||||
|       if (verbose) | ||||
| 	{ | ||||
| 	  /* XXX We cannot translate the message.  */ | ||||
| 	  errstring = make_string ("weak version `", string, | ||||
| 				   "' not found (required by ", name, ")"); | ||||
| 	  goto call_cerror; | ||||
| 	} | ||||
|       return 0; | ||||
|     } | ||||
|  | ||||
|   /* XXX We cannot translate the message.  */ | ||||
|   errstring = make_string ("version `", string, "' not found (required by ", | ||||
| 			   name, ")"); | ||||
|   result = 1; | ||||
|  call_cerror: | ||||
|   _dl_signal_cerror (0, map->l_name[0] ? map->l_name : _dl_argv[0], NULL, | ||||
| 		     errstring); | ||||
|   return result; | ||||
| } | ||||
|  | ||||
|  | ||||
| int | ||||
| internal_function | ||||
| _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode) | ||||
| { | ||||
|   int result = 0; | ||||
|   const char *strtab; | ||||
|   /* Pointer to section with needed versions.  */ | ||||
|   ElfW(Dyn) *dyn; | ||||
|   /* Pointer to dynamic section with definitions.  */ | ||||
|   ElfW(Dyn) *def; | ||||
|   /* We need to find out which is the highest version index used | ||||
|     in a dependecy.  */ | ||||
|   unsigned int ndx_high = 0; | ||||
|   /* Initialize to make the compiler happy.  */ | ||||
|   const char *errstring = NULL; | ||||
|   int errval = 0; | ||||
|  | ||||
|   /* If we don't have a string table, we must be ok.  */ | ||||
|   if (map->l_info[DT_STRTAB] == NULL) | ||||
|     return 0; | ||||
|   strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); | ||||
|  | ||||
|   dyn = map->l_info[VERSYMIDX (DT_VERNEED)]; | ||||
|   def = map->l_info[VERSYMIDX (DT_VERDEF)]; | ||||
|  | ||||
|   if (dyn != NULL) | ||||
|     { | ||||
|       /* This file requires special versions from its dependencies.  */ | ||||
|       ElfW(Verneed) *ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr); | ||||
|  | ||||
|       /* Currently the version number of the needed entry is 1. | ||||
| 	 Make sure all we see is this version.  */ | ||||
|       if (__builtin_expect (ent->vn_version, 1) != 1) | ||||
| 	{ | ||||
| 	  char buf[20]; | ||||
| 	  buf[sizeof (buf) - 1] = '\0'; | ||||
| 	  /* XXX We cannot translate the message.  */ | ||||
| 	  errstring = make_string ("unsupported version of Verneed record\n"); | ||||
| 	call_error: | ||||
| 	  _dl_signal_error (errval, (*map->l_name ? map->l_name : _dl_argv[0]), | ||||
| 			    NULL, errstring); | ||||
| 	} | ||||
|  | ||||
|       while (1) | ||||
| 	{ | ||||
| 	  ElfW(Vernaux) *aux; | ||||
| 	  struct link_map *needed = find_needed (strtab + ent->vn_file, map); | ||||
|  | ||||
| 	  /* If NEEDED is NULL this means a dependency was not found | ||||
| 	     and no stub entry was created.  This should never happen.  */ | ||||
| 	  assert (needed != NULL); | ||||
|  | ||||
| 	  /* Make sure this is no stub we created because of a missing | ||||
| 	     dependency.  */ | ||||
| 	  if (__builtin_expect (! trace_mode, 1) | ||||
| 	      || ! __builtin_expect (needed->l_faked, 0)) | ||||
| 	    { | ||||
| 	      /* NEEDED is the map for the file we need.  Now look for the | ||||
| 		 dependency symbols.  */ | ||||
| 	      aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux); | ||||
| 	      while (1) | ||||
| 		{ | ||||
| 		  /* Match the symbol.  */ | ||||
| 		  result |= match_symbol ((*map->l_name | ||||
| 					   ? map->l_name : _dl_argv[0]), | ||||
| 					  aux->vna_hash, | ||||
| 					  strtab + aux->vna_name, | ||||
| 					  needed, verbose, | ||||
| 					  aux->vna_flags & VER_FLG_WEAK); | ||||
|  | ||||
| 		  /* Compare the version index.  */ | ||||
| 		  if ((unsigned int) (aux->vna_other & 0x7fff) > ndx_high) | ||||
| 		    ndx_high = aux->vna_other & 0x7fff; | ||||
|  | ||||
| 		  if (aux->vna_next == 0) | ||||
| 		    /* No more symbols.  */ | ||||
| 		    break; | ||||
|  | ||||
| 		  /* Next symbol.  */ | ||||
| 		  aux = (ElfW(Vernaux) *) ((char *) aux + aux->vna_next); | ||||
| 		} | ||||
| 	    } | ||||
|  | ||||
| 	  if (ent->vn_next == 0) | ||||
| 	    /* No more dependencies.  */ | ||||
| 	    break; | ||||
|  | ||||
| 	  /* Next dependency.  */ | ||||
| 	  ent = (ElfW(Verneed) *) ((char *) ent + ent->vn_next); | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   /* We also must store the names of the defined versions.  Determine | ||||
|      the maximum index here as well. | ||||
|  | ||||
|      XXX We could avoid the loop by just taking the number of definitions | ||||
|      as an upper bound of new indeces.  */ | ||||
|   if (def != NULL) | ||||
|     { | ||||
|       ElfW(Verdef) *ent; | ||||
|       ent = (ElfW(Verdef) *) (map->l_addr + def->d_un.d_ptr); | ||||
|       while (1) | ||||
| 	{ | ||||
| 	  if ((unsigned int) (ent->vd_ndx & 0x7fff) > ndx_high) | ||||
| 	    ndx_high = ent->vd_ndx & 0x7fff; | ||||
|  | ||||
| 	  if (ent->vd_next == 0) | ||||
| 	    /* No more definitions.  */ | ||||
| 	    break; | ||||
|  | ||||
| 	  ent = (ElfW(Verdef) *) ((char *) ent + ent->vd_next); | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   if (ndx_high > 0) | ||||
|     { | ||||
|       /* Now we are ready to build the array with the version names | ||||
| 	 which can be indexed by the version index in the VERSYM | ||||
| 	 section.  */ | ||||
|       map->l_versions = (struct r_found_version *) | ||||
| 	calloc (ndx_high + 1, sizeof (*map->l_versions)); | ||||
|       if (__builtin_expect (map->l_versions == NULL, 0)) | ||||
| 	{ | ||||
| 	  errstring = N_("cannot allocate version reference table"); | ||||
| 	  errval = ENOMEM; | ||||
| 	  goto call_error; | ||||
| 	} | ||||
|  | ||||
|       /* Store the number of available symbols.  */ | ||||
|       map->l_nversions = ndx_high + 1; | ||||
|  | ||||
|       /* Compute the pointer to the version symbols.  */ | ||||
|       map->l_versyms = (void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); | ||||
|  | ||||
|       if (dyn != NULL) | ||||
| 	{ | ||||
| 	  ElfW(Verneed) *ent; | ||||
| 	  ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr); | ||||
| 	  while (1) | ||||
| 	    { | ||||
| 	      ElfW(Vernaux) *aux; | ||||
| 	      aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux); | ||||
| 	      while (1) | ||||
| 		{ | ||||
| 		  ElfW(Half) ndx = aux->vna_other & 0x7fff; | ||||
| 		  map->l_versions[ndx].hash = aux->vna_hash; | ||||
| 		  map->l_versions[ndx].hidden = aux->vna_other & 0x8000; | ||||
| 		  map->l_versions[ndx].name = &strtab[aux->vna_name]; | ||||
| 		  map->l_versions[ndx].filename = &strtab[ent->vn_file]; | ||||
|  | ||||
| 		  if (aux->vna_next == 0) | ||||
| 		    /* No more symbols.  */ | ||||
| 		    break; | ||||
|  | ||||
| 		  /* Advance to next symbol.  */ | ||||
| 		  aux = (ElfW(Vernaux) *) ((char *) aux + aux->vna_next); | ||||
| 		} | ||||
|  | ||||
| 	      if (ent->vn_next == 0) | ||||
| 		/* No more dependencies.  */ | ||||
| 		break; | ||||
|  | ||||
| 	      /* Advance to next dependency.  */ | ||||
| 	      ent = (ElfW(Verneed) *) ((char *) ent + ent->vn_next); | ||||
| 	    } | ||||
| 	} | ||||
|  | ||||
|       /* And insert the defined versions.  */ | ||||
|       if (def != NULL) | ||||
| 	{ | ||||
| 	  ElfW(Verdef) *ent; | ||||
| 	  ent = (ElfW(Verdef)  *) (map->l_addr + def->d_un.d_ptr); | ||||
| 	  while (1) | ||||
| 	    { | ||||
| 	      ElfW(Verdaux) *aux; | ||||
| 	      aux = (ElfW(Verdaux) *) ((char *) ent + ent->vd_aux); | ||||
|  | ||||
| 	      if ((ent->vd_flags & VER_FLG_BASE) == 0) | ||||
| 		{ | ||||
| 		  /* The name of the base version should not be | ||||
| 		     available for matching a versioned symbol.  */ | ||||
| 		  ElfW(Half) ndx = ent->vd_ndx & 0x7fff; | ||||
| 		  map->l_versions[ndx].hash = ent->vd_hash; | ||||
| 		  map->l_versions[ndx].name = &strtab[aux->vda_name]; | ||||
| 		  map->l_versions[ndx].filename = NULL; | ||||
| 		} | ||||
|  | ||||
| 	      if (ent->vd_next == 0) | ||||
| 		/* No more definitions.  */ | ||||
| 		break; | ||||
|  | ||||
| 	      ent = (ElfW(Verdef) *) ((char *) ent + ent->vd_next); | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   return result; | ||||
| } | ||||
|  | ||||
|  | ||||
| int | ||||
| internal_function | ||||
| _dl_check_all_versions (struct link_map *map, int verbose, int trace_mode) | ||||
| { | ||||
|   struct link_map *l; | ||||
|   int result = 0; | ||||
|  | ||||
|   for (l = map; l != NULL; l = l->l_next) | ||||
|     result |= ! l->l_faked && _dl_check_map_versions (l, verbose, trace_mode); | ||||
|  | ||||
|   return result; | ||||
| } | ||||
							
								
								
									
										84
									
								
								newlib/libc/sys/linux/dl/dlfcn.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								newlib/libc/sys/linux/dl/dlfcn.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| /* User functions for run-time dynamic loading. | ||||
|    Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #ifndef	_DLFCN_H | ||||
| #define	_DLFCN_H 1 | ||||
|  | ||||
| #include <features.h> | ||||
|  | ||||
| /* Collect various system dependent definitions and declarations.  */ | ||||
| #include <sys/dlfcn.h> | ||||
|  | ||||
|  | ||||
| /* If the first argument of `dlsym' or `dlvsym' is set to RTLD_NEXT | ||||
|    the run-time address of the symbol called NAME in the next shared | ||||
|    object is returned.  The "next" relation is defined by the order | ||||
|    the shared objects were loaded.  */ | ||||
| # define RTLD_NEXT	((void *) -1l) | ||||
|  | ||||
| /* If the first argument to `dlsym' or `dlvsym' is set to RTLD_DEFAULT | ||||
|    the run-time address of the symbol called NAME in the global scope | ||||
|    is returned.  */ | ||||
| # define RTLD_DEFAULT	((void *) 0) | ||||
|  | ||||
|  | ||||
| __BEGIN_DECLS | ||||
|  | ||||
| /* Open the shared object FILE and map it in; return a handle that can be | ||||
|    passed to `dlsym' to get symbol values from it.  */ | ||||
| extern void *dlopen (__const char *__file, int __mode) __THROW; | ||||
|  | ||||
| /* Unmap and close a shared object opened by `dlopen'. | ||||
|    The handle cannot be used again after calling `dlclose'.  */ | ||||
| extern int dlclose (void *__handle) __THROW; | ||||
|  | ||||
| /* Find the run-time address in the shared object HANDLE refers to | ||||
|    of the symbol called NAME.  */ | ||||
| extern void *dlsym (void *__restrict __handle, | ||||
| 		    __const char *__restrict __name) __THROW; | ||||
|  | ||||
| /* Find the run-time address in the shared object HANDLE refers to | ||||
|    of the symbol called NAME with VERSION.  */ | ||||
| extern void *dlvsym (void *__restrict __handle, | ||||
| 		     __const char *__restrict __name, | ||||
| 		     __const char *__restrict __version) __THROW; | ||||
|  | ||||
| /* When any of the above functions fails, call this function | ||||
|    to return a string describing the error.  Each call resets | ||||
|    the error string so that a following call returns null.  */ | ||||
| extern char *dlerror (void) __THROW; | ||||
|  | ||||
|  | ||||
| /* Structure containing information about object searched using | ||||
|    `dladdr'.  */ | ||||
| typedef struct | ||||
| { | ||||
|   __const char *dli_fname;	/* File name of defining object.  */ | ||||
|   void *dli_fbase;		/* Load address of that object.  */ | ||||
|   __const char *dli_sname;	/* Name of nearest symbol.  */ | ||||
|   void *dli_saddr;		/* Exact value of nearest symbol.  */ | ||||
| } Dl_info; | ||||
|  | ||||
| /* Fill in *INFO with the following information about ADDRESS. | ||||
|    Returns 0 iff no shared object's segments contain that address.  */ | ||||
| extern int dladdr (__const void *__address, Dl_info *__info) __THROW; | ||||
|  | ||||
| __END_DECLS | ||||
|  | ||||
| #endif	/* dlfcn.h */ | ||||
							
								
								
									
										200
									
								
								newlib/libc/sys/linux/dl/do-lookup.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								newlib/libc/sys/linux/dl/do-lookup.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,200 @@ | ||||
| /* Look up a symbol in the loaded objects. | ||||
|    Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #if VERSIONED | ||||
| # define FCT do_lookup_versioned | ||||
| # define ARG const struct r_found_version *const version, | ||||
| #else | ||||
| # define FCT do_lookup | ||||
| # define ARG | ||||
| #endif | ||||
|  | ||||
| /* Inner part of the lookup functions.  We return a value > 0 if we | ||||
|    found the symbol, the value 0 if nothing is found and < 0 if | ||||
|    something bad happened.  */ | ||||
| static inline int | ||||
| FCT (const char *undef_name, unsigned long int hash, const ElfW(Sym) *ref, | ||||
|      struct sym_val *result, struct r_scope_elem *scope, size_t i, ARG | ||||
|      struct link_map *skip, int type_class) | ||||
| { | ||||
|   struct link_map **list = scope->r_list; | ||||
|   size_t n = scope->r_nlist; | ||||
|   struct link_map *map; | ||||
|  | ||||
|   do | ||||
|     { | ||||
|       const ElfW(Sym) *symtab; | ||||
|       const char *strtab; | ||||
|       const ElfW(Half) *verstab; | ||||
|       Elf_Symndx symidx; | ||||
|       const ElfW(Sym) *sym; | ||||
| #if ! VERSIONED | ||||
|       int num_versions = 0; | ||||
|       const ElfW(Sym) *versioned_sym = NULL; | ||||
| #endif | ||||
|  | ||||
|       map = list[i]; | ||||
|  | ||||
|       /* Here come the extra test needed for `_dl_lookup_symbol_skip'.  */ | ||||
|       if (skip != NULL && map == skip) | ||||
| 	continue; | ||||
|  | ||||
|       /* Don't search the executable when resolving a copy reloc.  */ | ||||
|       if ((type_class & ELF_RTYPE_CLASS_COPY) && map->l_type == lt_executable) | ||||
| 	continue; | ||||
|  | ||||
|       /* Print some debugging info if wanted.  */ | ||||
|       if (__builtin_expect (_dl_debug_mask & DL_DEBUG_SYMBOLS, 0)) | ||||
| 	_dl_debug_printf ("symbol=%s;  lookup in file=%s\n", undef_name, | ||||
| 			  map->l_name[0] ? map->l_name : _dl_argv[0]); | ||||
|  | ||||
|       symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]); | ||||
|       strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); | ||||
|       verstab = map->l_versyms; | ||||
|  | ||||
|       /* Search the appropriate hash bucket in this object's symbol table | ||||
| 	 for a definition for the same symbol name.  */ | ||||
|       for (symidx = map->l_buckets[hash % map->l_nbuckets]; | ||||
| 	   symidx != STN_UNDEF; | ||||
| 	   symidx = map->l_chain[symidx]) | ||||
| 	{ | ||||
| 	  sym = &symtab[symidx]; | ||||
|  | ||||
| 	  assert (ELF_RTYPE_CLASS_PLT == 1); | ||||
| 	  if (sym->st_value == 0 || /* No value.  */ | ||||
| 	      /* ((type_class & ELF_RTYPE_CLASS_PLT) | ||||
| 		  && (sym->st_shndx == SHN_UNDEF)) */ | ||||
| 	      (type_class & (sym->st_shndx == SHN_UNDEF))) | ||||
| 	    continue; | ||||
|  | ||||
| 	  if (ELFW(ST_TYPE) (sym->st_info) > STT_FUNC) | ||||
| 	    /* Ignore all but STT_NOTYPE, STT_OBJECT and STT_FUNC entries | ||||
| 	       since these are no code/data definitions.  */ | ||||
| 	    continue; | ||||
|  | ||||
| 	  if (sym != ref && strcmp (strtab + sym->st_name, undef_name)) | ||||
| 	    /* Not the symbol we are looking for.  */ | ||||
| 	    continue; | ||||
|  | ||||
| #if VERSIONED | ||||
| 	  if (__builtin_expect (verstab == NULL, 0)) | ||||
| 	    { | ||||
| 	      /* We need a versioned symbol but haven't found any.  If | ||||
| 		 this is the object which is referenced in the verneed | ||||
| 		 entry it is a bug in the library since a symbol must | ||||
| 		 not simply disappear. | ||||
|  | ||||
| 		 It would also be a bug in the object since it means that | ||||
| 		 the list of required versions is incomplete and so the | ||||
| 		 tests in dl-version.c haven't found a problem.*/ | ||||
| 	      assert (version->filename == NULL | ||||
| 		      || ! _dl_name_match_p (version->filename, map)); | ||||
|  | ||||
| 	      /* Otherwise we accept the symbol.  */ | ||||
| 	    } | ||||
| 	  else | ||||
| 	    { | ||||
| 	      /* We can match the version information or use the | ||||
| 		 default one if it is not hidden.  */ | ||||
| 	      ElfW(Half) ndx = verstab[symidx] & 0x7fff; | ||||
| 	      if ((map->l_versions[ndx].hash != version->hash | ||||
| 		   || strcmp (map->l_versions[ndx].name, version->name)) | ||||
| 		  && (version->hidden || map->l_versions[ndx].hash | ||||
| 		      || (verstab[symidx] & 0x8000))) | ||||
| 		/* It's not the version we want.  */ | ||||
| 		continue; | ||||
| 	    } | ||||
| #else | ||||
| 	  /* No specific version is selected.  When the object file | ||||
| 	     also does not define a version we have a match. | ||||
| 	     Otherwise we accept the default version, or in case there | ||||
| 	     is only one version defined, this one version.  */ | ||||
| 	  if (verstab != NULL) | ||||
| 	    { | ||||
| 	      ElfW(Half) ndx = verstab[symidx] & 0x7fff; | ||||
| 	      if (ndx > 2) /* map->l_versions[ndx].hash != 0) */ | ||||
| 		{ | ||||
| 		  /* Don't accept hidden symbols.  */ | ||||
| 		  if ((verstab[symidx] & 0x8000) == 0 && num_versions++ == 0) | ||||
| 		    /* No version so far.  */ | ||||
| 		    versioned_sym = sym; | ||||
| 		  continue; | ||||
| 		} | ||||
| 	    } | ||||
| #endif | ||||
|  | ||||
| 	  /* There cannot be another entry for this symbol so stop here.  */ | ||||
| 	  goto found_it; | ||||
| 	} | ||||
|  | ||||
|       /* If we have seen exactly one versioned symbol while we are | ||||
| 	 looking for an unversioned symbol and the version is not the | ||||
| 	 default version we still accept this symbol since there are | ||||
| 	 no possible ambiguities.  */ | ||||
| #if VERSIONED | ||||
|       sym = NULL; | ||||
| #else | ||||
|       sym = num_versions == 1 ? versioned_sym : NULL; | ||||
| #endif | ||||
|  | ||||
|       if (sym != NULL) | ||||
| 	{ | ||||
| 	found_it: | ||||
| 	  switch (ELFW(ST_BIND) (sym->st_info)) | ||||
| 	    { | ||||
| 	    case STB_WEAK: | ||||
| 	      /* Weak definition.  Use this value if we don't find another.  */ | ||||
| 	      if (__builtin_expect (_dl_dynamic_weak, 0)) | ||||
| 		{ | ||||
| 		  if (! result->s) | ||||
| 		    { | ||||
| 		      result->s = sym; | ||||
| 		      result->m = map; | ||||
| 		    } | ||||
| 		  break; | ||||
| 		} | ||||
| 	      /* FALLTHROUGH */ | ||||
| 	    case STB_GLOBAL: | ||||
| 	      /* Global definition.  Just what we need.  */ | ||||
| 	      result->s = sym; | ||||
| 	      result->m = map; | ||||
| 	      return 1; | ||||
| 	    default: | ||||
| 	      /* Local symbols are ignored.  */ | ||||
| 	      break; | ||||
| 	    } | ||||
| 	} | ||||
|  | ||||
| #if VERSIONED | ||||
|       /* If this current map is the one mentioned in the verneed entry | ||||
| 	 and we have not found a weak entry, it is a bug.  */ | ||||
|       if (symidx == STN_UNDEF && version->filename != NULL | ||||
| 	  && __builtin_expect (_dl_name_match_p (version->filename, map), 0)) | ||||
| 	return -1; | ||||
| #endif | ||||
|     } | ||||
|   while (++i < n); | ||||
|  | ||||
|   /* We have not found anything until now.  */ | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| #undef FCT | ||||
| #undef ARG | ||||
| #undef VERSIONED | ||||
							
								
								
									
										118
									
								
								newlib/libc/sys/linux/dl/do-rel.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								newlib/libc/sys/linux/dl/do-rel.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | ||||
| /* Do relocations for ELF dynamic linking. | ||||
|    Copyright (C) 1995,96,97,98,99,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| /* This file may be included twice, to define both | ||||
|    `elf_dynamic_do_rel' and `elf_dynamic_do_rela'.  */ | ||||
|  | ||||
| #include <machine/weakalias.h> | ||||
|  | ||||
| #ifdef DO_RELA | ||||
| # define elf_dynamic_do_rel		elf_dynamic_do_rela | ||||
| # define RELCOUNT_IDX			VERSYMIDX (DT_RELACOUNT) | ||||
| # define Rel				Rela | ||||
| # define elf_machine_rel		elf_machine_rela | ||||
| # define elf_machine_rel_relative	elf_machine_rela_relative | ||||
| #else | ||||
| # define RELCOUNT_IDX			VERSYMIDX (DT_RELCOUNT) | ||||
| #endif | ||||
|  | ||||
| #ifndef VERSYMIDX | ||||
| # define VERSYMIDX(sym)	(DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) | ||||
| #endif | ||||
|  | ||||
| /* Perform the relocations in MAP on the running program image as specified | ||||
|    by RELTAG, SZTAG.  If LAZY is nonzero, this is the first pass on PLT | ||||
|    relocations; they should be set up to call _dl_runtime_resolve, rather | ||||
|    than fully resolved now.  */ | ||||
|  | ||||
| static inline void | ||||
| elf_dynamic_do_rel (struct link_map *map, | ||||
| 		    ElfW(Addr) reladdr, ElfW(Addr) relsize, | ||||
| 		    int lazy) | ||||
| { | ||||
|   const ElfW(Rel) *r = (const void *) reladdr; | ||||
|   const ElfW(Rel) *end = (const void *) (reladdr + relsize); | ||||
|   ElfW(Addr) l_addr = map->l_addr; | ||||
|  | ||||
| #ifndef RTLD_BOOTSTRAP | ||||
|   /* We never bind lazily during ld.so bootstrap.  Unfortunately gcc is | ||||
|      not clever enough to see through all the function calls to realize | ||||
|      that.  */ | ||||
|   if (lazy) | ||||
|     { | ||||
|       /* Doing lazy PLT relocations; they need very little info.  */ | ||||
|       for (; r < end; ++r) | ||||
| 	elf_machine_lazy_rel (map, l_addr, r); | ||||
|     } | ||||
|   else | ||||
| #endif | ||||
|     { | ||||
|       const ElfW(Sym) *const symtab = | ||||
| 	(const void *) D_PTR (map, l_info[DT_SYMTAB]); | ||||
|       ElfW(Word) nrelative = (map->l_info[RELCOUNT_IDX] == NULL | ||||
| 			      ? 0 : map->l_info[RELCOUNT_IDX]->d_un.d_val); | ||||
|       const ElfW(Rel) *relative = r; | ||||
|       r = MIN (r + nrelative, end); | ||||
|  | ||||
| #ifndef RTLD_BOOTSTRAP | ||||
|       /* This is defined in rtld.c, but nowhere in the static libc.a; make | ||||
| 	 the reference weak so static programs can still link.  This | ||||
| 	 declaration cannot be done when compiling rtld.c (i.e. #ifdef | ||||
| 	 RTLD_BOOTSTRAP) because rtld.c contains the common defn for | ||||
| 	 _dl_rtld_map, which is incompatible with a weak decl in the same | ||||
| 	 file.  */ | ||||
|       weak_extern (_dl_rtld_map); | ||||
|       if (map != &_dl_rtld_map) /* Already done in rtld itself.  */ | ||||
| # ifndef DO_RELA | ||||
| 	/* Rela platforms get the offset from r_addend and this must | ||||
| 	   be copied in the relocation address.  Therefore we can skip | ||||
| 	   the relative relocations only if this is for rel | ||||
| 	   relocations.  */ | ||||
| 	if (l_addr != 0) | ||||
| # endif | ||||
| #endif | ||||
| 	  for (; relative < r; ++relative) | ||||
| 	    elf_machine_rel_relative (l_addr, relative, | ||||
| 				      (void *) (l_addr + relative->r_offset)); | ||||
|  | ||||
|       if (map->l_info[VERSYMIDX (DT_VERSYM)]) | ||||
| 	{ | ||||
| 	  const ElfW(Half) *const version = | ||||
| 	    (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); | ||||
|  | ||||
| 	  for (; r < end; ++r) | ||||
| 	    { | ||||
| 	      ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)]; | ||||
| 	      elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], | ||||
| 			       &map->l_versions[ndx], | ||||
| 			       (void *) (l_addr + r->r_offset)); | ||||
| 	    } | ||||
| 	} | ||||
|       else | ||||
| 	for (; r < end; ++r) | ||||
| 	  elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, | ||||
| 			   (void *) (l_addr + r->r_offset)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| #undef elf_dynamic_do_rel | ||||
| #undef Rel | ||||
| #undef elf_machine_rel | ||||
| #undef elf_machine_rel_relative | ||||
| #undef RELCOUNT_IDX | ||||
							
								
								
									
										244
									
								
								newlib/libc/sys/linux/dl/dynamic-link.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								newlib/libc/sys/linux/dl/dynamic-link.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | ||||
| /* Inline functions for dynamic linking. | ||||
|    Copyright (C) 1995,96,97,98,99,2000 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <elf.h> | ||||
| #include <machine/dl-machine.h> | ||||
| #include <assert.h> | ||||
|  | ||||
| #ifndef VERSYMIDX | ||||
| # define VERSYMIDX(sym)	(DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym)) | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* Global read-only variable defined in rtld.c which is nonzero if we | ||||
|    shall give more warning messages.  */ | ||||
| extern int _dl_verbose __attribute__ ((unused)); | ||||
|  | ||||
|  | ||||
| /* Read the dynamic section at DYN and fill in INFO with indices DT_*.  */ | ||||
|  | ||||
| static inline void __attribute__ ((unused)) | ||||
| elf_get_dynamic_info (struct link_map *l) | ||||
| { | ||||
|   ElfW(Dyn) *dyn = l->l_ld; | ||||
|   ElfW(Addr) l_addr; | ||||
|   ElfW(Dyn) **info; | ||||
|  | ||||
|   if (! dyn) | ||||
|     return; | ||||
|  | ||||
|   l_addr = l->l_addr; | ||||
|   info = l->l_info; | ||||
|  | ||||
|   while (dyn->d_tag != DT_NULL) | ||||
|     { | ||||
|       if (dyn->d_tag < DT_NUM) | ||||
| 	info[dyn->d_tag] = dyn; | ||||
|       else if (dyn->d_tag >= DT_LOPROC && | ||||
| 	       dyn->d_tag < DT_LOPROC + DT_THISPROCNUM) | ||||
| 	info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn; | ||||
|       else if ((Elf32_Word) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM) | ||||
| 	info[VERSYMIDX (dyn->d_tag)] = dyn; | ||||
|       else if ((Elf32_Word) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM) | ||||
| 	info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM | ||||
| 	     + DT_VERSIONTAGNUM] = dyn; | ||||
|       else | ||||
| 	assert (! "bad dynamic tag"); | ||||
|       ++dyn; | ||||
|     } | ||||
| #ifndef DL_RO_DYN_SECTION | ||||
|   if (info[DT_PLTGOT] != NULL) | ||||
|     info[DT_PLTGOT]->d_un.d_ptr += l_addr; | ||||
|   if (info[DT_STRTAB] != NULL) | ||||
|     info[DT_STRTAB]->d_un.d_ptr += l_addr; | ||||
|   if (info[DT_SYMTAB] != NULL) | ||||
|     info[DT_SYMTAB]->d_un.d_ptr += l_addr; | ||||
| # if ! ELF_MACHINE_NO_RELA | ||||
|   if (info[DT_RELA] != NULL) | ||||
|     { | ||||
|       assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela))); | ||||
|       info[DT_RELA]->d_un.d_ptr += l_addr; | ||||
|     } | ||||
| # endif | ||||
| # if ! ELF_MACHINE_NO_REL | ||||
|   if (info[DT_REL] != NULL) | ||||
|     { | ||||
|       assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel))); | ||||
|       info[DT_REL]->d_un.d_ptr += l_addr; | ||||
|     } | ||||
| # endif | ||||
| #endif | ||||
|   if (info[DT_PLTREL] != NULL) | ||||
|     { | ||||
| # if ELF_MACHINE_NO_RELA | ||||
|       assert (info[DT_PLTREL]->d_un.d_val == DT_REL); | ||||
| # elif ELF_MACHINE_NO_REL | ||||
|       assert (info[DT_PLTREL]->d_un.d_val == DT_RELA); | ||||
| # else | ||||
|       assert (info[DT_PLTREL]->d_un.d_val == DT_REL | ||||
| 	      || info[DT_PLTREL]->d_un.d_val == DT_RELA); | ||||
| # endif | ||||
|     } | ||||
| #ifndef DL_RO_DYN_SECTION | ||||
|   if (info[DT_JMPREL] != NULL) | ||||
|     info[DT_JMPREL]->d_un.d_ptr += l_addr; | ||||
|   if (info[VERSYMIDX (DT_VERSYM)] != NULL) | ||||
|     info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr += l_addr; | ||||
| #endif | ||||
|   if (info[DT_FLAGS] != NULL) | ||||
|     { | ||||
|       /* Flags are used.  Translate to the old form where available. | ||||
| 	 Since these l_info entries are only tested for NULL pointers it | ||||
| 	 is ok if they point to the DT_FLAGS entry.  */ | ||||
|       ElfW(Word) flags = info[DT_FLAGS]->d_un.d_val; | ||||
|       if (flags & DF_SYMBOLIC) | ||||
| 	info[DT_SYMBOLIC] = info[DT_FLAGS]; | ||||
|       if (flags & DF_TEXTREL) | ||||
| 	info[DT_TEXTREL] = info[DT_FLAGS]; | ||||
|       if (flags & DF_BIND_NOW) | ||||
| 	info[DT_BIND_NOW] = info[DT_FLAGS]; | ||||
|     } | ||||
|   if (info[VERSYMIDX (DT_FLAGS_1)] != NULL) | ||||
|     l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val; | ||||
|   if (info[DT_RUNPATH] != NULL) | ||||
|     /* If both RUNPATH and RPATH are given, the latter is ignored.  */ | ||||
|     info[DT_RPATH] = NULL; | ||||
| } | ||||
|  | ||||
| #ifdef RESOLVE | ||||
|  | ||||
| /* Get the definitions of `elf_dynamic_do_rel' and `elf_dynamic_do_rela'. | ||||
|    These functions are almost identical, so we use cpp magic to avoid | ||||
|    duplicating their code.  It cannot be done in a more general function | ||||
|    because we must be able to completely inline.  */ | ||||
|  | ||||
| /* On some machines, notably SPARC, DT_REL* includes DT_JMPREL in its | ||||
|    range.  Note that according to the ELF spec, this is completely legal! | ||||
|    But conditionally define things so that on machines we know this will | ||||
|    not happen we do something more optimal.  */ | ||||
|  | ||||
| # ifdef ELF_MACHINE_PLTREL_OVERLAP | ||||
| #  define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \ | ||||
|   do {									      \ | ||||
|     struct { ElfW(Addr) start, size; int lazy; } ranges[3];		      \ | ||||
|     int ranges_index;							      \ | ||||
| 									      \ | ||||
|     ranges[0].lazy = ranges[2].lazy = 0;				      \ | ||||
|     ranges[1].lazy = 1;							      \ | ||||
|     ranges[0].size = ranges[1].size = ranges[2].size = 0;		      \ | ||||
| 									      \ | ||||
|     if ((map)->l_info[DT_##RELOC])					      \ | ||||
|       {									      \ | ||||
| 	ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]);		      \ | ||||
| 	ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val;	      \ | ||||
|       }									      \ | ||||
| 									      \ | ||||
|      if ((do_lazy)							      \ | ||||
| 	&& (map)->l_info[DT_PLTREL]					      \ | ||||
| 	&& (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \ | ||||
|       {									      \ | ||||
| 	ranges[1].start = D_PTR ((map), l_info[DT_JMPREL]);		      \ | ||||
| 	ranges[1].size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val;	      \ | ||||
| 	ranges[2].start = ranges[1].start + ranges[1].size;		      \ | ||||
| 	ranges[2].size = ranges[0].start + ranges[0].size - ranges[2].start;  \ | ||||
| 	ranges[0].size = ranges[1].start - ranges[0].start;		      \ | ||||
|       }									      \ | ||||
| 									      \ | ||||
|     for (ranges_index = 0; ranges_index < 3; ++ranges_index)		      \ | ||||
|       elf_dynamic_do_##reloc ((map),					      \ | ||||
| 			      ranges[ranges_index].start,		      \ | ||||
| 			      ranges[ranges_index].size,		      \ | ||||
| 			      ranges[ranges_index].lazy);		      \ | ||||
|   } while (0) | ||||
| # else | ||||
| #  define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \ | ||||
|   do {									      \ | ||||
|     struct { ElfW(Addr) start, size; int lazy; } ranges[2];		      \ | ||||
|     int ranges_index;							      \ | ||||
|     ranges[0].lazy = 0;							      \ | ||||
|     ranges[0].size = ranges[1].size = 0;				      \ | ||||
|     ranges[0].start = 0;						      \ | ||||
| 									      \ | ||||
|     if ((map)->l_info[DT_##RELOC])					      \ | ||||
|       {									      \ | ||||
|         ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]);		      \ | ||||
|         ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val;	      \ | ||||
|       }									      \ | ||||
|     if ((map)->l_info[DT_PLTREL]					      \ | ||||
| 	&& (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \ | ||||
|       {									      \ | ||||
| 	ElfW(Addr) start = D_PTR ((map), l_info[DT_JMPREL]);		      \ | ||||
| 									      \ | ||||
| 	if ((do_lazy)							      \ | ||||
| 	    /* This test does not only detect whether the relocation	      \ | ||||
| 	       sections are in the right order, it also checks whether	      \ | ||||
| 	       there is a DT_REL/DT_RELA section.  */			      \ | ||||
| 	    || ranges[0].start + ranges[0].size != start)		      \ | ||||
| 	  {								      \ | ||||
| 	    ranges[1].start = start;					      \ | ||||
| 	    ranges[1].size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val;	      \ | ||||
| 	    ranges[1].lazy = (do_lazy);					      \ | ||||
| 	  }								      \ | ||||
| 	else								      \ | ||||
| 	  /* Combine processing the sections.  */			      \ | ||||
| 	  ranges[0].size += (map)->l_info[DT_PLTRELSZ]->d_un.d_val;	      \ | ||||
|       }									      \ | ||||
| 									      \ | ||||
|     for (ranges_index = 0; ranges_index < 2; ++ranges_index)		      \ | ||||
|       elf_dynamic_do_##reloc ((map),					      \ | ||||
| 			      ranges[ranges_index].start,		      \ | ||||
| 			      ranges[ranges_index].size,		      \ | ||||
| 			      ranges[ranges_index].lazy);		      \ | ||||
|   } while (0) | ||||
| # endif | ||||
|  | ||||
| # if ELF_MACHINE_NO_REL || ELF_MACHINE_NO_RELA | ||||
| #  define _ELF_CHECK_REL 0 | ||||
| # else | ||||
| #  define _ELF_CHECK_REL 1 | ||||
| # endif | ||||
|  | ||||
| # if ! ELF_MACHINE_NO_REL | ||||
| #  include "do-rel.h" | ||||
| #  define ELF_DYNAMIC_DO_REL(map, lazy) \ | ||||
|   _ELF_DYNAMIC_DO_RELOC (REL, rel, map, lazy, _ELF_CHECK_REL) | ||||
| # else | ||||
| #  define ELF_DYNAMIC_DO_REL(map, lazy) /* Nothing to do.  */ | ||||
| # endif | ||||
|  | ||||
| # if ! ELF_MACHINE_NO_RELA | ||||
| #  define DO_RELA | ||||
| #  include "do-rel.h" | ||||
| #  define ELF_DYNAMIC_DO_RELA(map, lazy) \ | ||||
|   _ELF_DYNAMIC_DO_RELOC (RELA, rela, map, lazy, _ELF_CHECK_REL) | ||||
| # else | ||||
| #  define ELF_DYNAMIC_DO_RELA(map, lazy) /* Nothing to do.  */ | ||||
| # endif | ||||
|  | ||||
| /* This can't just be an inline function because GCC is too dumb | ||||
|    to inline functions containing inlines themselves.  */ | ||||
| # define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile) \ | ||||
|   do {									      \ | ||||
|     int edr_lazy = elf_machine_runtime_setup ((map), (lazy),		      \ | ||||
| 					      (consider_profile));	      \ | ||||
|     ELF_DYNAMIC_DO_REL ((map), edr_lazy);				      \ | ||||
|     ELF_DYNAMIC_DO_RELA ((map), edr_lazy);				      \ | ||||
|   } while (0) | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										193
									
								
								newlib/libc/sys/linux/dl/kernel-features.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								newlib/libc/sys/linux/dl/kernel-features.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,193 @@ | ||||
| /* Set flags signalling availability of kernel features based on given | ||||
|    kernel version number. | ||||
|    Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| /* This file must not contain any C code.  At least it must be protected | ||||
|    to allow using the file also in assembler files.  */ | ||||
|  | ||||
| #ifndef __LINUX_KERNEL_VERSION | ||||
| /* We assume the worst; all kernels should be supported.  */ | ||||
| # define __LINUX_KERNEL_VERSION	0 | ||||
| #endif | ||||
|  | ||||
| /* We assume for __LINUX_KERNEL_VERSION the same encoding used in | ||||
|    linux/version.h.  I.e., the major, minor, and subminor all get a | ||||
|    byte with the major number being in the highest byte.  This means | ||||
|    we can do numeric comparisons. | ||||
|  | ||||
|    In the following we will define certain symbols depending on | ||||
|    whether the describes kernel feature is available in the kernel | ||||
|    version given by __LINUX_KERNEL_VERSION.  We are not always exactly | ||||
|    recording the correct versions in which the features were | ||||
|    introduced.  If somebody cares these values can afterwards be | ||||
|    corrected.  Most of the numbers here are set corresponding to | ||||
|    2.2.0.  */ | ||||
|  | ||||
| /* `getcwd' system call.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131584 | ||||
| # define __ASSUME_GETCWD_SYSCALL	1 | ||||
| #endif | ||||
|  | ||||
| /* Real-time signal became usable in 2.1.70.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131398 | ||||
| # define __ASSUME_REALTIME_SIGNALS	1 | ||||
| #endif | ||||
|  | ||||
| /* When were the `pread'/`pwrite' syscalls introduced?  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131584 | ||||
| # define __ASSUME_PREAD_SYSCALL		1 | ||||
| # define __ASSUME_PWRITE_SYSCALL	1 | ||||
| #endif | ||||
|  | ||||
| /* When was `poll' introduced?  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131584 | ||||
| # define __ASSUME_POLL_SYSCALL		1 | ||||
| #endif | ||||
|  | ||||
| /* The `lchown' syscall was introduced in 2.1.80.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131408 | ||||
| # define __ASSUME_LCHOWN_SYSCALL	1 | ||||
| #endif | ||||
|  | ||||
| /* When did the `setresuid' sysall became available?  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131584 && !defined __sparc__ | ||||
| # define __ASSUME_SETRESUID_SYSCALL	1 | ||||
| #endif | ||||
|  | ||||
| /* The SIOCGIFNAME ioctl is available starting with 2.1.50.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131408 | ||||
| # define __ASSUME_SIOCGIFNAME		1 | ||||
| #endif | ||||
|  | ||||
| /* On x86 another `getrlimit' syscall was added in 2.3.25.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131865 && defined __i386__ | ||||
| # define __ASSUME_NEW_GETRLIMIT_SYSCALL	1 | ||||
| #endif | ||||
|  | ||||
| /* On x86 the truncate64/ftruncate64 syscalls were introduced in 2.3.31.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131871 && defined __i386__ | ||||
| # define __ASSUME_TRUNCATE64_SYSCALL	1 | ||||
| #endif | ||||
|  | ||||
| /* On x86 the mmap2 syscall was introduced in 2.3.31.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131871 && defined __i386__ | ||||
| # define __ASSUME_MMAP2_SYSCALL	1 | ||||
| #endif | ||||
|  | ||||
| /* On x86 the stat64/lstat64/fstat64 syscalls were introduced in 2.3.34.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131874 && defined __i386__ | ||||
| # define __ASSUME_STAT64_SYSCALL	1 | ||||
| #endif | ||||
|  | ||||
| /* On sparc and ARM the truncate64/ftruncate64/mmap2/stat64/lstat64/fstat64 | ||||
|    syscalls were introduced in 2.3.35.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131875 && (defined __sparc__ || defined __arm__) | ||||
| # define __ASSUME_TRUNCATE64_SYSCALL	1 | ||||
| # define __ASSUME_MMAP2_SYSCALL		1 | ||||
| # define __ASSUME_STAT64_SYSCALL	1 | ||||
| #endif | ||||
|  | ||||
| /* I know for sure that these are in 2.3.35 on powerpc.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131875 && defined __powerpc__ | ||||
| # define __ASSUME_TRUNCATE64_SYSCALL	1 | ||||
| # define __ASSUME_STAT64_SYSCALL	1 | ||||
| # define __ASSUME_NEW_GETRLIMIT_SYSCALL	1 | ||||
| #endif | ||||
|  | ||||
| /* Linux 2.3.39 introduced 32bit UID/GIDs and IPC64.  Some platforms had 32 | ||||
|    bit type all along.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131879 || defined __powerpc__ || defined __mips__ | ||||
| # define __ASSUME_32BITUIDS		1 | ||||
| # ifndef __powerpc__ | ||||
| #  define __ASSUME_IPC64		1 | ||||
| # endif | ||||
| # ifdef __sparc__ | ||||
| #  define __ASSUME_SETRESUID_SYSCALL	1 | ||||
| # endif | ||||
| #endif | ||||
|  | ||||
| /* Linux 2.4.0 on PPC introduced a correct IPC64.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 132096 && defined __powerpc__ | ||||
| # define __ASSUME_IPC64			1 | ||||
| #endif | ||||
|  | ||||
| /* We can use the LDTs for threading with Linux 2.3.99 and newer.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131939 | ||||
| # define __ASSUME_LDT_WORKS		1 | ||||
| #endif | ||||
|  | ||||
| /* The changed st_ino field appeared in 2.4.0-test6.  But we cannot | ||||
|    distinguish this version from other 2.4.0 releases.  Therefore play | ||||
|    save and assume it available is for 2.4.1 and up.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 132097 | ||||
| # define __ASSUME_ST_INO_64_BIT		1 | ||||
| #endif | ||||
|  | ||||
| /* To support locking of large files a new fcntl() syscall was introduced | ||||
|    in 2.4.0-test7.  We test for 2.4.1 for the earliest version we know | ||||
|    the syscall is available.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 132097 && (defined __i386__ || defined __sparc__) | ||||
| # define __ASSUME_FCNTL64		1 | ||||
| #endif | ||||
|  | ||||
| /* Arm got fcntl64 in 2.4.4, PowerPC and SH have it also in 2.4.4 (I | ||||
|    don't know when it got introduced).  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 132100 \ | ||||
|     && (defined __arm__ || defined __powerpc__ || defined __sh__) | ||||
| # define __ASSUME_FCNTL64		1 | ||||
| #endif | ||||
|  | ||||
| /* The getdents64 syscall was introduced in 2.4.0-test7.  We test for | ||||
|    2.4.1 for the earliest version we know the syscall is available.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 132097 | ||||
| # define __ASSUME_GETDENTS64_SYSCALL	1 | ||||
| #endif | ||||
|  | ||||
| /* When did O_DIRECTORY became available?  Early in 2.3 but when? | ||||
|    Be safe, use 2.3.99.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 131939 | ||||
| # define __ASSUME_O_DIRECTORY		1 | ||||
| #endif | ||||
|  | ||||
| /* Starting with one of the 2.4.0 pre-releases the Linux kernel passes | ||||
|    up the page size information.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= 132097 | ||||
| # define __ASSUME_AT_PAGESIZE		1 | ||||
| #endif | ||||
|  | ||||
| /* Starting with 2.4.5 kernels PPC passes the AUXV in the standard way | ||||
|    and the mmap2 syscall made it into the official kernel.  */ | ||||
| #if __LINUX_KERNEL_VERSION >= (132096+5) && defined __powerpc__ | ||||
| # define __ASSUME_STD_AUXV		1 | ||||
| # define __ASSUME_MMAP2_SYSCALL		1 | ||||
| #endif | ||||
|  | ||||
| /* There are an infinite number of PA-RISC kernel versions numbered | ||||
|    2.4.0.  But they've not really been released as such.  We require | ||||
|    and expect the final version here.  */ | ||||
| #ifdef __hppa__ | ||||
| # define __ASSUME_32BITUIDS		1 | ||||
| # define __ASSUME_TRUNCATE64_SYSCALL	1 | ||||
| # define __ASSUME_MMAP2_SYSCALL		1 | ||||
| # define __ASSUME_STAT64_SYSCALL	1 | ||||
| # define __ASSUME_IPC64			1 | ||||
| # define __ASSUME_ST_INO_64_BIT		1 | ||||
| # define __ASSUME_FCNTL64		1 | ||||
| # define __ASSUME_GETDENTS64_SYSCALL	1 | ||||
| #endif | ||||
							
								
								
									
										535
									
								
								newlib/libc/sys/linux/dl/ldsodefs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										535
									
								
								newlib/libc/sys/linux/dl/ldsodefs.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,535 @@ | ||||
| /* Run-time dynamic linker data structures for loaded ELF shared objects. | ||||
|    Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #ifndef	_LDSODEFS_H | ||||
| #define	_LDSODEFS_H	1 | ||||
|  | ||||
| #include <features.h> | ||||
|  | ||||
| #define __need_size_t | ||||
| #define __need_NULL | ||||
| #include <stddef.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include <elf.h> | ||||
| #include <dlfcn.h> | ||||
| #include <link.h> | ||||
| #include <dl-lookupcfg.h> | ||||
| #include <bits/libc-lock.h> | ||||
|  | ||||
| __BEGIN_DECLS | ||||
|  | ||||
| /* We use this macro to refer to ELF types independent of the native wordsize. | ||||
|    `ElfW(TYPE)' is used in place of `Elf32_TYPE' or `Elf64_TYPE'.  */ | ||||
| #define ELFW(type)	_ElfW (ELF, __ELF_NATIVE_CLASS, type) | ||||
|  | ||||
| #define internal_function  | ||||
| /* All references to the value of l_info[DT_PLTGOT], | ||||
|   l_info[DT_STRTAB], l_info[DT_SYMTAB], l_info[DT_RELA], | ||||
|   l_info[DT_REL], l_info[DT_JMPREL], and l_info[VERSYMIDX (DT_VERSYM)] | ||||
|   have to be accessed via the D_PTR macro.  The macro is needed since for | ||||
|   most architectures the entry is already relocated - but for some not | ||||
|   and we need to relocate at access time.  */ | ||||
| #ifdef DL_RO_DYN_SECTION | ||||
| # define D_PTR(map,i) (map->i->d_un.d_ptr + map->l_addr) | ||||
| #else | ||||
| # define D_PTR(map,i) map->i->d_un.d_ptr | ||||
| #endif | ||||
|  | ||||
| /* On some platforms more information than just the address of the symbol | ||||
|    is needed from the lookup functions.  In this case we return the whole | ||||
|    link map.  */ | ||||
| #ifdef DL_LOOKUP_RETURNS_MAP | ||||
| typedef struct link_map *lookup_t; | ||||
| # define LOOKUP_VALUE(map) map | ||||
| # define LOOKUP_VALUE_ADDRESS(map) (map ? map->l_addr : 0) | ||||
| #else | ||||
| typedef ElfW(Addr) lookup_t; | ||||
| # define LOOKUP_VALUE(map) map->l_addr | ||||
| # define LOOKUP_VALUE_ADDRESS(address) address | ||||
| #endif | ||||
|  | ||||
| /* on some architectures a pointer to a function is not just a pointer | ||||
|    to the actual code of the function but rather an architecture | ||||
|    specific descriptor. */ | ||||
| #ifndef ELF_FUNCTION_PTR_IS_SPECIAL | ||||
| # define DL_SYMBOL_ADDRESS(map, ref) \ | ||||
|  (void *) (LOOKUP_VALUE_ADDRESS (map) + ref->st_value) | ||||
| # define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr)) | ||||
| # define DL_DT_INIT_ADDRESS(map, start) (start) | ||||
| # define DL_DT_FINI_ADDRESS(map, start) (start) | ||||
| #endif | ||||
|  | ||||
| /* Unmap a loaded object, called by _dl_close (). */ | ||||
| #ifndef DL_UNMAP_IS_SPECIAL | ||||
| # define DL_UNMAP(map) \ | ||||
|  __munmap ((void *) (map)->l_map_start,					      \ | ||||
| 	   (map)->l_map_end - (map)->l_map_start) | ||||
| #endif | ||||
|  | ||||
| /* By default we do not need special support to initialize DSOs loaded | ||||
|    by statically linked binaries.  */ | ||||
| #ifndef DL_STATIC_INIT | ||||
| # define DL_STATIC_INIT(map) | ||||
| #endif | ||||
|  | ||||
| /* Reloc type classes as returned by elf_machine_type_class(). | ||||
|    ELF_RTYPE_CLASS_PLT means this reloc should not be satisfied by | ||||
|    some PLT symbol, ELF_RTYPE_CLASS_COPY means this reloc should not be | ||||
|    satisfied by any symbol in the executable.  */ | ||||
| #define ELF_RTYPE_CLASS_PLT 1 | ||||
| #define ELF_RTYPE_CLASS_COPY 2 | ||||
|  | ||||
| /* ELF uses the PF_x macros to specify the segment permissions, mmap | ||||
|    uses PROT_xxx.  In most cases the three macros have the values 1, 2, | ||||
|    and 3 but not in a matching order.  The following macros allows | ||||
|    converting from the PF_x values to PROT_xxx values.  */ | ||||
| #define PF_TO_PROT \ | ||||
|   ((PROT_READ << (PF_R * 4))						      \ | ||||
|    | (PROT_WRITE << (PF_W * 4))						      \ | ||||
|    | (PROT_EXEC << (PF_X * 4))						      \ | ||||
|    | ((PROT_READ | PROT_WRITE) << ((PF_R | PF_W) * 4))			      \ | ||||
|    | ((PROT_READ | PROT_EXEC) << ((PF_R | PF_X) * 4))			      \ | ||||
|    | ((PROT_WRITE | PROT_EXEC) << (PF_W | PF_X) * 4)			      \ | ||||
|    | ((PROT_READ | PROT_WRITE | PROT_EXEC) << ((PF_R | PF_W | PF_X) * 4))) | ||||
|  | ||||
|  | ||||
| /* For the version handling we need an array with only names and their | ||||
|    hash values.  */ | ||||
| struct r_found_version | ||||
|   { | ||||
|     const char *name; | ||||
|     ElfW(Word) hash; | ||||
|  | ||||
|     int hidden; | ||||
|     const char *filename; | ||||
|   }; | ||||
|  | ||||
| /* We want to cache information about the searches for shared objects.  */ | ||||
|  | ||||
| enum r_dir_status { unknown, nonexisting, existing }; | ||||
|  | ||||
| struct r_search_path_elem | ||||
|   { | ||||
|     /* This link is only used in the `all_dirs' member of `r_search_path'.  */ | ||||
|     struct r_search_path_elem *next; | ||||
|  | ||||
|     /* Strings saying where the definition came from.  */ | ||||
|     const char *what; | ||||
|     const char *where; | ||||
|  | ||||
|     /* Basename for this search path element.  The string must end with | ||||
|        a slash character.  */ | ||||
|     const char *dirname; | ||||
|     size_t dirnamelen; | ||||
|  | ||||
|     enum r_dir_status status[0]; | ||||
|   }; | ||||
|  | ||||
| struct r_strlenpair | ||||
|   { | ||||
|     const char *str; | ||||
|     size_t len; | ||||
|   }; | ||||
|  | ||||
|  | ||||
| /* A data structure for a simple single linked list of strings.  */ | ||||
| struct libname_list | ||||
|   { | ||||
|     const char *name;		/* Name requested (before search).  */ | ||||
|     struct libname_list *next;	/* Link to next name for this object.  */ | ||||
|     int dont_free;		/* Flag whether this element should be freed | ||||
| 				   if the object is not entirely unloaded.  */ | ||||
|   }; | ||||
|  | ||||
|  | ||||
| /* Test whether given NAME matches any of the names of the given object.  */ | ||||
| static __inline int | ||||
| __attribute__ ((unused)) | ||||
| _dl_name_match_p (const char *__name, struct link_map *__map) | ||||
| { | ||||
|   int __found = strcmp (__name, __map->l_name) == 0; | ||||
|   struct libname_list *__runp = __map->l_libname; | ||||
|  | ||||
|   while (! __found && __runp != NULL) | ||||
|     if (strcmp (__name, __runp->name) == 0) | ||||
|       __found = 1; | ||||
|     else | ||||
|       __runp = __runp->next; | ||||
|  | ||||
|   return __found; | ||||
| } | ||||
|  | ||||
| /* Function used as argument for `_dl_receive_error' function.  The | ||||
|    arguments are the error code, error string, and the objname the | ||||
|    error occurred in.  */ | ||||
| typedef void (*receiver_fct) (int, const char *, const char *); | ||||
|  | ||||
| /* Internal functions of the run-time dynamic linker. | ||||
|    These can be accessed if you link again the dynamic linker | ||||
|    as a shared library, as in `-lld' or `/lib/ld.so' explicitly; | ||||
|    but are not normally of interest to user programs. | ||||
|  | ||||
|    The `-ldl' library functions in <dlfcn.h> provide a simple | ||||
|    user interface to run-time dynamic linking.  */ | ||||
|  | ||||
|  | ||||
| /* Parameters passed to the dynamic linker.  */ | ||||
| extern char **_dl_argv; | ||||
|  | ||||
| /* Cached value of `getpagesize ()'.  */ | ||||
| extern size_t _dl_pagesize; | ||||
|  | ||||
| /* OS version.  */ | ||||
| extern unsigned int _dl_osversion; | ||||
|  | ||||
| /* File descriptor referring to the zero-fill device.  */ | ||||
| extern int _dl_zerofd; | ||||
|  | ||||
| /* Name of the shared object to be profiled (if any).  */ | ||||
| extern const char *_dl_profile; | ||||
| /* Map of shared object to be profiled.  */ | ||||
| extern struct link_map *_dl_profile_map; | ||||
| /* Filename of the output file.  */ | ||||
| extern const char *_dl_profile_output; | ||||
|  | ||||
| /* If nonzero the appropriate debug information is printed.  */ | ||||
| extern int _dl_debug_mask; | ||||
| #define DL_DEBUG_LIBS	    (1 << 0) | ||||
| #define DL_DEBUG_IMPCALLS   (1 << 1) | ||||
| #define DL_DEBUG_BINDINGS   (1 << 2) | ||||
| #define DL_DEBUG_SYMBOLS    (1 << 3) | ||||
| #define DL_DEBUG_VERSIONS   (1 << 4) | ||||
| #define DL_DEBUG_RELOC      (1 << 5) | ||||
| #define DL_DEBUG_FILES      (1 << 6) | ||||
| #define DL_DEBUG_STATISTICS (1 << 7) | ||||
| /* This one is used only internally.  */ | ||||
| #define DL_DEBUG_HELP       (1 << 8) | ||||
|  | ||||
| /* Expect cache ID.  */ | ||||
| extern int _dl_correct_cache_id; | ||||
|  | ||||
| /* Mask for hardware capabilities that are available.  */ | ||||
| extern unsigned long int _dl_hwcap; | ||||
|  | ||||
| /* Mask for important hardware capabilities we honour. */ | ||||
| extern unsigned long int _dl_hwcap_mask; | ||||
|  | ||||
| /* File descriptor to write debug messages to.  */ | ||||
| extern int _dl_debug_fd; | ||||
|  | ||||
| /* Names of shared object for which the RPATH should be ignored.  */ | ||||
| extern const char *_dl_inhibit_rpath; | ||||
|  | ||||
| /* Nonzero if references should be treated as weak during runtime linking.  */ | ||||
| extern int _dl_dynamic_weak; | ||||
|  | ||||
| /* The array with message we print as a last resort.  */ | ||||
| extern const char _dl_out_of_memory[]; | ||||
|  | ||||
| /* Nonzero if runtime lookups should not update the .got/.plt.  */ | ||||
| extern int _dl_bind_not; | ||||
|  | ||||
| /* List of search directories.  */ | ||||
| extern struct r_search_path_elem *_dl_all_dirs; | ||||
| extern struct r_search_path_elem *_dl_init_all_dirs; | ||||
|  | ||||
| /* OS-dependent function to open the zero-fill device.  */ | ||||
| extern int _dl_sysdep_open_zero_fill (void); /* dl-sysdep.c */ | ||||
|  | ||||
|  | ||||
| /* During the program run we must not modify the global data of | ||||
|    loaded shared object simultanously in two threads.  Therefore we | ||||
|    protect `_dl_open' and `_dl_close' in dl-close.c. | ||||
|  | ||||
|    This must be a recursive lock since the initializer function of | ||||
|    the loaded object might as well require a call to this function. | ||||
|    At this time it is not anymore a problem to modify the tables.  */ | ||||
| __libc_lock_define_recursive (extern, _dl_load_lock) | ||||
|  | ||||
|  | ||||
| /* Write message on the debug file descriptor.  The parameters are | ||||
|    interpreted as for a `printf' call.  All the lines start with a | ||||
|    tag showing the PID.  */ | ||||
| extern void _dl_debug_printf (const char *fmt, ...) | ||||
|      __attribute__ ((__format__ (__printf__, 1, 2))); | ||||
|  | ||||
| /* Write message on the debug file descriptor.  The parameters are | ||||
|    interpreted as for a `printf' call.  All the lines buf the first | ||||
|    start with a tag showing the PID.  */ | ||||
| extern void _dl_debug_printf_c (const char *fmt, ...) | ||||
|      __attribute__ ((__format__ (__printf__, 1, 2))); | ||||
|  | ||||
|  | ||||
| /* Write a message on the specified descriptor FD.  The parameters are | ||||
|    interpreted as for a `printf' call.  */ | ||||
| extern void _dl_dprintf (int fd, const char *fmt, ...) | ||||
|      __attribute__ ((__format__ (__printf__, 2, 3))); | ||||
|  | ||||
| /* Write a message on the specified descriptor standard output.  The | ||||
|    parameters are interpreted as for a `printf' call.  */ | ||||
| #define _dl_printf(fmt, args...) \ | ||||
|   _dl_dprintf (STDOUT_FILENO, fmt, ##args) | ||||
|  | ||||
| /* Write a message on the specified descriptor standard error.  The | ||||
|    parameters are interpreted as for a `printf' call.  */ | ||||
| #define _dl_error_printf(fmt, args...) \ | ||||
|   _dl_dprintf (STDERR_FILENO, fmt, ##args) | ||||
|  | ||||
| /* Write a message on the specified descriptor standard error and exit | ||||
|    the program.  The parameters are interpreted as for a `printf' call.  */ | ||||
| #define _dl_fatal_printf(fmt, args...) \ | ||||
|   do									      \ | ||||
|     {									      \ | ||||
|       _dl_dprintf (STDERR_FILENO, fmt, ##args);				      \ | ||||
|       _exit (127);							      \ | ||||
|     }									      \ | ||||
|   while (1) | ||||
|  | ||||
|  | ||||
| /* This function is called by all the internal dynamic linker functions | ||||
|    when they encounter an error.  ERRCODE is either an `errno' code or | ||||
|    zero; OBJECT is the name of the problematical shared object, or null if | ||||
|    it is a general problem; ERRSTRING is a string describing the specific | ||||
|    problem.  */ | ||||
| extern void _dl_signal_error (int errcode, const char *object, | ||||
| 			      const char *occurred, const char *errstring) | ||||
|      internal_function | ||||
|      __attribute__ ((__noreturn__)); | ||||
|  | ||||
| /* Like _dl_signal_error, but may return when called in the context of | ||||
|    _dl_receive_error.  */ | ||||
| extern void _dl_signal_cerror (int errcode, const char *object, | ||||
| 			       const char *occation, const char *errstring) | ||||
|      internal_function; | ||||
|  | ||||
| /* Call OPERATE, receiving errors from `dl_signal_cerror'.  Unlike | ||||
|    `_dl_catch_error' the operation is resumed after the OPERATE | ||||
|    function returns. | ||||
|    ARGS is passed as argument to OPERATE.  */ | ||||
| extern void _dl_receive_error (receiver_fct fct, void (*operate) (void *), | ||||
| 			       void *args) | ||||
|      internal_function; | ||||
|  | ||||
|  | ||||
| /* Open the shared object NAME and map in its segments. | ||||
|    LOADER's DT_RPATH is used in searching for NAME. | ||||
|    If the object is already opened, returns its existing map. | ||||
|    For preloaded shared objects PRELOADED is set to a non-zero | ||||
|    value to allow additional security checks.  */ | ||||
| extern struct link_map *_dl_map_object (struct link_map *loader, | ||||
| 					const char *name, int preloaded, | ||||
| 					int type, int trace_mode, int mode) | ||||
|      internal_function; | ||||
|  | ||||
| /* Call _dl_map_object on the dependencies of MAP, and set up | ||||
|    MAP->l_searchlist.  PRELOADS points to a vector of NPRELOADS previously | ||||
|    loaded objects that will be inserted into MAP->l_searchlist after MAP | ||||
|    but before its dependencies.  */ | ||||
| extern void _dl_map_object_deps (struct link_map *map, | ||||
| 				 struct link_map **preloads, | ||||
| 				 unsigned int npreloads, int trace_mode) | ||||
|      internal_function; | ||||
|  | ||||
| /* Cache the locations of MAP's hash table.  */ | ||||
| extern void _dl_setup_hash (struct link_map *map) internal_function; | ||||
|  | ||||
|  | ||||
| /* Search loaded objects' symbol tables for a definition of the symbol | ||||
|    referred to by UNDEF.  *SYM is the symbol table entry containing the | ||||
|    reference; it is replaced with the defining symbol, and the base load | ||||
|    address of the defining object is returned.  SYMBOL_SCOPE is a | ||||
|    null-terminated list of object scopes to search; each object's | ||||
|    l_searchlist (i.e. the segment of the dependency tree starting at that | ||||
|    object) is searched in turn.  REFERENCE_NAME should name the object | ||||
|    containing the reference; it is used in error messages. | ||||
|    TYPE_CLASS describes the type of symbol we are looking for.  */ | ||||
| extern lookup_t _dl_lookup_symbol (const char *undef, | ||||
| 				   struct link_map *undef_map, | ||||
| 				   const ElfW(Sym) **sym, | ||||
| 				   struct r_scope_elem *symbol_scope[], | ||||
| 				   int type_class, int explicit) | ||||
|      internal_function; | ||||
|  | ||||
| /* Lookup versioned symbol.  */ | ||||
| extern lookup_t _dl_lookup_versioned_symbol (const char *undef, | ||||
| 					     struct link_map *undef_map, | ||||
| 					     const ElfW(Sym) **sym, | ||||
| 					     struct r_scope_elem *symbol_scope[], | ||||
| 					     const struct r_found_version *version, | ||||
| 					     int type_class, int explicit) | ||||
|      internal_function; | ||||
|  | ||||
| /* For handling RTLD_NEXT we must be able to skip shared objects.  */ | ||||
| extern lookup_t _dl_lookup_symbol_skip (const char *undef, | ||||
| 					struct link_map *undef_map, | ||||
| 					const ElfW(Sym) **sym, | ||||
| 					struct r_scope_elem *symbol_scope[], | ||||
| 					struct link_map *skip_this) | ||||
|      internal_function; | ||||
|  | ||||
| /* For handling RTLD_NEXT with versioned symbols we must be able to | ||||
|    skip shared objects.  */ | ||||
| extern lookup_t _dl_lookup_versioned_symbol_skip (const char *undef, | ||||
| 						  struct link_map *undef_map, | ||||
| 						  const ElfW(Sym) **sym, | ||||
| 						  struct r_scope_elem *symbol_scope[], | ||||
| 						  const struct r_found_version *version, | ||||
| 						  struct link_map *skip_this) | ||||
|      internal_function; | ||||
|  | ||||
| /* Look up symbol NAME in MAP's scope and return its run-time address.  */ | ||||
| extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name) | ||||
|      internal_function; | ||||
|  | ||||
|  | ||||
| /* Structure describing the dynamic linker itself.  */ | ||||
| extern struct link_map _dl_rtld_map; | ||||
| /* And a pointer to the map for the main map.  */ | ||||
| extern struct link_map *_dl_loaded; | ||||
| /* Number of object in the _dl_loaded list.  */ | ||||
| extern unsigned int _dl_nloaded; | ||||
| /* Array representing global scope.  */ | ||||
| extern struct r_scope_elem *_dl_global_scope[2]; | ||||
| /* Direct pointer to the searchlist of the main object.  */ | ||||
| extern struct r_scope_elem *_dl_main_searchlist; | ||||
| /* Copy of the content of `_dl_main_searchlist'.  */ | ||||
| extern struct r_scope_elem _dl_initial_searchlist; | ||||
| /* This is zero at program start to signal that the global scope map is | ||||
|    allocated by rtld.  Later it keeps the size of the map.  It might be | ||||
|    reset if in _dl_close if the last global object is removed.  */ | ||||
| extern size_t _dl_global_scope_alloc; | ||||
|  | ||||
| /* Allocate a `struct link_map' for a new object being loaded, | ||||
|    and enter it into the _dl_main_map list.  */ | ||||
| extern struct link_map *_dl_new_object (char *realname, const char *libname, | ||||
| 					int type, struct link_map *loader) | ||||
|      internal_function; | ||||
|  | ||||
| /* Relocate the given object (if it hasn't already been). | ||||
|    SCOPE is passed to _dl_lookup_symbol in symbol lookups. | ||||
|    If LAZY is nonzero, don't relocate its PLT.  */ | ||||
| extern void _dl_relocate_object (struct link_map *map, | ||||
| 				 struct r_scope_elem *scope[], | ||||
| 				 int lazy, int consider_profiling); | ||||
|  | ||||
| /* Call _dl_signal_error with a message about an unhandled reloc type. | ||||
|    TYPE is the result of ELFW(R_TYPE) (r_info), i.e. an R_<CPU>_* value. | ||||
|    PLT is nonzero if this was a PLT reloc; it just affects the message.  */ | ||||
| extern void _dl_reloc_bad_type (struct link_map *map, | ||||
| 				unsigned int type, int plt) | ||||
|      internal_function __attribute__ ((__noreturn__)); | ||||
|  | ||||
| /* Check the version dependencies of all objects available through | ||||
|    MAP.  If VERBOSE print some more diagnostics.  */ | ||||
| extern int _dl_check_all_versions (struct link_map *map, int verbose, | ||||
| 				   int trace_mode) | ||||
|      internal_function; | ||||
|  | ||||
| /* Check the version dependencies for MAP.  If VERBOSE print some more | ||||
|    diagnostics.  */ | ||||
| extern int _dl_check_map_versions (struct link_map *map, int verbose, | ||||
| 				   int trace_mode) | ||||
|      internal_function; | ||||
|  | ||||
| /* Initialize the object in SCOPE by calling the constructors with | ||||
|    ARGC, ARGV, and ENV as the parameters.  */ | ||||
| extern void _dl_init (struct link_map *main_map, int argc, char **argv, | ||||
| 		      char **env) internal_function; | ||||
|  | ||||
| /* Call the finalizer functions of all shared objects whose | ||||
|    initializer functions have completed.  */ | ||||
| extern void _dl_fini (void) internal_function; | ||||
|  | ||||
| /* The dynamic linker calls this function before and having changing | ||||
|    any shared object mappings.  The `r_state' member of `struct r_debug' | ||||
|    says what change is taking place.  This function's address is | ||||
|    the value of the `r_brk' member.  */ | ||||
| extern void _dl_debug_state (void); | ||||
|  | ||||
| /* Initialize `struct r_debug' if it has not already been done.  The | ||||
|    argument is the run-time load address of the dynamic linker, to be put | ||||
|    in the `r_ldbase' member.  Returns the address of the structure.  */ | ||||
| extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase) | ||||
|      internal_function; | ||||
|  | ||||
| /* Initialize the basic data structure for the search paths.  */ | ||||
| extern void _dl_init_paths (const char *library_path) internal_function; | ||||
|  | ||||
| /* Gather the information needed to install the profiling tables and start | ||||
|    the timers.  */ | ||||
| extern void _dl_start_profile (struct link_map *map, const char *output_dir) | ||||
|      internal_function; | ||||
|  | ||||
| /* The actual functions used to keep book on the calls.  */ | ||||
| extern void _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc); | ||||
|  | ||||
| /* This function is simply a wrapper around the _dl_mcount function | ||||
|    which does not require a FROMPC parameter since this is the | ||||
|    calling function.  */ | ||||
| extern void _dl_mcount_wrapper (void *selfpc); | ||||
|  | ||||
| /* Show the members of the auxiliary array passed up from the kernel.  */ | ||||
| extern void _dl_show_auxv (void) internal_function; | ||||
|  | ||||
| /* Return all environment variables starting with `LD_', one after the | ||||
|    other.  */ | ||||
| extern char *_dl_next_ld_env_entry (char ***position) internal_function; | ||||
|  | ||||
| /* Return an array with the names of the important hardware capabilities.  */ | ||||
| extern const struct r_strlenpair *_dl_important_hwcaps (const char *platform, | ||||
| 							size_t paltform_len, | ||||
| 							size_t *sz, | ||||
| 							size_t *max_capstrlen) | ||||
|      internal_function; | ||||
|  | ||||
| /* Look up NAME in ld.so.cache and return the file name stored there, | ||||
|    or null if none is found.  */ | ||||
| extern const char *_dl_load_cache_lookup (const char *name) | ||||
|      internal_function; | ||||
|  | ||||
| /* If the system does not support MAP_COPY we cannot leave the file open | ||||
|    all the time since this would create problems when the file is replaced. | ||||
|    Therefore we provide this function to close the file and open it again | ||||
|    once needed.  */ | ||||
| extern void _dl_unload_cache (void); | ||||
|  | ||||
| /* System-dependent function to read a file's whole contents in the | ||||
|    most convenient manner available.  *SIZEP gets the size of the | ||||
|    file.  On error MAP_FAILED is returned.  */ | ||||
| extern void *_dl_sysdep_read_whole_file (const char *file, size_t *sizep, | ||||
| 					 int prot) | ||||
|      internal_function; | ||||
|  | ||||
| /* System-specific function to do initial startup for the dynamic linker. | ||||
|    After this, file access calls and getenv must work.  This is responsible | ||||
|    for setting __libc_enable_secure if we need to be secure (e.g. setuid), | ||||
|    and for setting _dl_argc and _dl_argv, and then calling _dl_main.  */ | ||||
| extern ElfW(Addr) _dl_sysdep_start (void **start_argptr, | ||||
| 				    void (*dl_main) (const ElfW(Phdr) *phdr, | ||||
| 						     ElfW(Word) phnum, | ||||
| 						     ElfW(Addr) *user_entry)); | ||||
|  | ||||
| extern void _dl_sysdep_start_cleanup (void) | ||||
|      internal_function; | ||||
|  | ||||
|  | ||||
| __END_DECLS | ||||
|  | ||||
| #endif /* ldsodefs.h */ | ||||
							
								
								
									
										2
									
								
								newlib/libc/sys/linux/dl/libintl.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								newlib/libc/sys/linux/dl/libintl.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| #define N_(x) x | ||||
|  | ||||
							
								
								
									
										7
									
								
								newlib/libc/sys/linux/dl/trusted-dirs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								newlib/libc/sys/linux/dl/trusted-dirs.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| #define SYSTEM_DIRS \ | ||||
|   "/usr/local/lib/" | ||||
|  | ||||
| #define SYSTEM_DIRS_LEN \ | ||||
|   15 | ||||
|  | ||||
| #define SYSTEM_DIRS_MAX_LEN	15 | ||||
							
								
								
									
										19
									
								
								newlib/libc/sys/linux/dl/unsecvars.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								newlib/libc/sys/linux/dl/unsecvars.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| /* Environment variable to be removed for SUID programs.  The names are | ||||
|    all stuffed in a single string which means they have to be terminated | ||||
|    with a '\0' explicitly.  */ | ||||
| #define UNSECURE_ENVVARS \ | ||||
|   "LD_PRELOAD\0"							      \ | ||||
|   "LD_LIBRARY_PATH\0"							      \ | ||||
|   "LD_ORIGIN_PATH\0"							      \ | ||||
|   "LD_DEBUG_OUTPUT\0"							      \ | ||||
|   "LD_PROFILE\0"							      \ | ||||
|   "GCONV_PATH\0"							      \ | ||||
|   "HOSTALIASES\0"							      \ | ||||
|   "LOCALDOMAIN\0"							      \ | ||||
|   "LOCPATH\0"								      \ | ||||
|   "MALLOC_TRACE\0"							      \ | ||||
|   "NLSPATH\0"								      \ | ||||
|   "RESOLV_HOST_CONF\0"							      \ | ||||
|   "RES_OPTIONS\0"							      \ | ||||
|   "TMPDIR\0"								      \ | ||||
|   "TZDIR\0" | ||||
							
								
								
									
										114
									
								
								newlib/libc/sys/linux/gethostid.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								newlib/libc/sys/linux/gethostid.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| /* Copyright (C) 1995,1996,1998,1999,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <alloca.h> | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <unistd.h> | ||||
| #include <netdb.h> | ||||
|  | ||||
| #define HOSTIDFILE "/etc/hostid" | ||||
| #define OLD_HOSTIDFILE "/etc/hostid" | ||||
|  | ||||
| #if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 2 | ||||
| # define OPEN __open64 | ||||
| #else | ||||
| # define OPEN __open | ||||
| #endif | ||||
|  | ||||
| #ifdef SET_PROCEDURE | ||||
| int | ||||
| sethostid (id) | ||||
|      long int id; | ||||
| { | ||||
|   int fd; | ||||
|   ssize_t written; | ||||
|  | ||||
|   /* Open file for writing.  Everybody is allowed to read this file.  */ | ||||
|   fd = OPEN (HOSTIDFILE, O_CREAT|O_WRONLY|O_TRUNC, 0644); | ||||
|   if (fd < 0) | ||||
|     return -1; | ||||
|  | ||||
|   written = __write (fd, &id, sizeof (id)); | ||||
|  | ||||
|   __close (fd); | ||||
|  | ||||
|   return written != sizeof (id) ? -1 : 0; | ||||
| } | ||||
|  | ||||
| #else | ||||
| # include <string.h> | ||||
| # include <sys/param.h> | ||||
| # include <netdb.h> | ||||
| # include <netinet/in.h> | ||||
|  | ||||
| long int | ||||
| gethostid () | ||||
| { | ||||
|   char hostname[MAXHOSTNAMELEN + 1]; | ||||
|   size_t buflen; | ||||
|   char *buffer; | ||||
|   struct hostent hostbuf, *hp; | ||||
|   unsigned long int id; | ||||
|   struct in_addr in; | ||||
|   int herr; | ||||
|   int fd; | ||||
|  | ||||
|   /* First try to get the ID from a former invocation of sethostid.  */ | ||||
|   fd = OPEN (HOSTIDFILE, O_RDONLY); | ||||
|   if (fd >= 0) | ||||
|     { | ||||
|       ssize_t n = __read (fd, &id, sizeof (id)); | ||||
|  | ||||
|       __close (fd); | ||||
|  | ||||
|       if (n == sizeof (id)) | ||||
| 	return id; | ||||
|     } | ||||
|  | ||||
|   /* Getting from the file was not successful.  An intelligent guess for | ||||
|      a unique number of a host is its IP address.  Return this.  */ | ||||
|   if (__gethostname (hostname, MAXHOSTNAMELEN) < 0 || hostname[0] == '\0') | ||||
|     /* This also fails.  Return and arbitrary value.  */ | ||||
|     return 0; | ||||
|  | ||||
|   buflen = 1024; | ||||
|   buffer = alloca (buflen); | ||||
|  | ||||
|   /* To get the IP address we need to know the host name.  */ | ||||
|   while (__gethostbyname_r (hostname, &hostbuf, buffer, buflen, &hp, &herr) | ||||
| 	 != 0 | ||||
| 	 || hp == NULL) | ||||
|     if (herr != NETDB_INTERNAL || errno != ERANGE) | ||||
|       return 0; | ||||
|     else | ||||
|       { | ||||
| 	/* Enlarge buffer.  */ | ||||
| 	buflen *= 2; | ||||
| 	buffer = alloca (buflen); | ||||
|       } | ||||
|  | ||||
|   in.s_addr = 0; | ||||
|   memcpy (&in, hp->h_addr, | ||||
| 	  (int) sizeof (in) < hp->h_length ? sizeof (in) : hp->h_length); | ||||
|  | ||||
|   /* For the return value to be not exactly the IP address we do some | ||||
|      bit fiddling.  */ | ||||
|   return in.s_addr << 16 | in.s_addr >> 16; | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										27
									
								
								newlib/libc/sys/linux/iconv/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								newlib/libc/sys/linux/iconv/Makefile.am
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| ## Process this file with automake to generate Makefile.in | ||||
|  | ||||
| AUTOMAKE_OPTIONS = cygnus | ||||
|  | ||||
| INCLUDES = -DGCONV_DIR='"$(pkglibdir)"' -DGCONV_PATH='"$(pkglibdir)"' -I$(srcdir) -I$(srcdir)/.. $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) | ||||
|  | ||||
| LIB_SOURCES = \ | ||||
| 	iconv.h gconv.h \ | ||||
| 	iconv_open.c iconv.c iconv_close.c \ | ||||
| 	gconv_open.c gconv.c gconv_close.c \ | ||||
| 	gconv_db.c gconv_dl.c gconv_conf.c gconv_builtin.c \ | ||||
| 	gconv_simple.c gconv_trans.c gconv_cache.c | ||||
|  | ||||
| libiconv_la_CFLAGS = | ||||
| libiconv_la_LDFLAGS = -Xcompiler -nostdlib | ||||
|  | ||||
| if USE_LIBTOOL | ||||
| noinst_LTLIBRARIES = libiconv.la | ||||
| libiconv_la_SOURCES = $(LIB_SOURCES) | ||||
| noinst_DATA = objectlist.awk.in | ||||
| else | ||||
| noinst_LIBRARIES = lib.a | ||||
| lib_a_SOURCES = $(LIB_SOURCES) | ||||
| noinst_DATA = | ||||
| endif # USE_LIBTOOL | ||||
|  | ||||
| include $(srcdir)/../../../../Makefile.shared | ||||
							
								
								
									
										375
									
								
								newlib/libc/sys/linux/iconv/Makefile.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										375
									
								
								newlib/libc/sys/linux/iconv/Makefile.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,375 @@ | ||||
| # Makefile.in generated automatically by automake 1.4 from Makefile.am | ||||
|  | ||||
| # Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. | ||||
| # This Makefile.in is free software; the Free Software Foundation | ||||
| # gives unlimited permission to copy and/or distribute it, | ||||
| # with or without modifications, as long as this notice is preserved. | ||||
|  | ||||
| # This program is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY, to the extent permitted by law; without | ||||
| # even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||||
| # PARTICULAR PURPOSE. | ||||
|  | ||||
|  | ||||
|  | ||||
| SHELL = @SHELL@ | ||||
|  | ||||
| srcdir = @srcdir@ | ||||
| top_srcdir = @top_srcdir@ | ||||
| VPATH = @srcdir@ | ||||
| prefix = @prefix@ | ||||
| exec_prefix = @exec_prefix@ | ||||
|  | ||||
| bindir = @bindir@ | ||||
| sbindir = @sbindir@ | ||||
| libexecdir = @libexecdir@ | ||||
| datadir = @datadir@ | ||||
| sysconfdir = @sysconfdir@ | ||||
| sharedstatedir = @sharedstatedir@ | ||||
| localstatedir = @localstatedir@ | ||||
| libdir = @libdir@ | ||||
| infodir = @infodir@ | ||||
| mandir = @mandir@ | ||||
| includedir = @includedir@ | ||||
| oldincludedir = /usr/include | ||||
|  | ||||
| DESTDIR = | ||||
|  | ||||
| pkgdatadir = $(datadir)/@PACKAGE@ | ||||
| pkglibdir = $(libdir)/@PACKAGE@ | ||||
| pkgincludedir = $(includedir)/@PACKAGE@ | ||||
|  | ||||
| top_builddir = .. | ||||
|  | ||||
| ACLOCAL = @ACLOCAL@ | ||||
| AUTOCONF = @AUTOCONF@ | ||||
| AUTOMAKE = @AUTOMAKE@ | ||||
| AUTOHEADER = @AUTOHEADER@ | ||||
|  | ||||
| INSTALL = @INSTALL@ | ||||
| INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) | ||||
| INSTALL_DATA = @INSTALL_DATA@ | ||||
| INSTALL_SCRIPT = @INSTALL_SCRIPT@ | ||||
| transform = @program_transform_name@ | ||||
|  | ||||
| NORMAL_INSTALL = : | ||||
| PRE_INSTALL = : | ||||
| POST_INSTALL = : | ||||
| NORMAL_UNINSTALL = : | ||||
| PRE_UNINSTALL = : | ||||
| POST_UNINSTALL = : | ||||
| build_alias = @build_alias@ | ||||
| build_triplet = @build@ | ||||
| host_alias = @host_alias@ | ||||
| host_triplet = @host@ | ||||
| target_alias = @target_alias@ | ||||
| target_triplet = @target@ | ||||
| AR = @AR@ | ||||
| AS = @AS@ | ||||
| AWK = @AWK@ | ||||
| CC = @CC@ | ||||
| CPP = @CPP@ | ||||
| CXX = @CXX@ | ||||
| CXXCPP = @CXXCPP@ | ||||
| DLLTOOL = @DLLTOOL@ | ||||
| EXEEXT = @EXEEXT@ | ||||
| GCJ = @GCJ@ | ||||
| GCJFLAGS = @GCJFLAGS@ | ||||
| LDFLAGS = @LDFLAGS@ | ||||
| LIBTOOL = @LIBTOOL@ | ||||
| LINUX_MACH_LIB = @LINUX_MACH_LIB@ | ||||
| LN_S = @LN_S@ | ||||
| MAINT = @MAINT@ | ||||
| MAKEINFO = @MAKEINFO@ | ||||
| NEWLIB_CFLAGS = @NEWLIB_CFLAGS@ | ||||
| OBJDUMP = @OBJDUMP@ | ||||
| OBJEXT = @OBJEXT@ | ||||
| PACKAGE = @PACKAGE@ | ||||
| RANLIB = @RANLIB@ | ||||
| STRIP = @STRIP@ | ||||
| VERSION = @VERSION@ | ||||
| aext = @aext@ | ||||
| libm_machine_dir = @libm_machine_dir@ | ||||
| machine_dir = @machine_dir@ | ||||
| newlib_basedir = @newlib_basedir@ | ||||
| oext = @oext@ | ||||
| sys_dir = @sys_dir@ | ||||
|  | ||||
| AUTOMAKE_OPTIONS = cygnus | ||||
|  | ||||
| INCLUDES = -DGCONV_DIR='"$(pkglibdir)"' -DGCONV_PATH='"$(pkglibdir)"' -I$(srcdir) -I$(srcdir)/.. $(NEWLIB_CFLAGS) $(CROSS_CFLAGS) $(TARGET_CFLAGS) | ||||
|  | ||||
| LIB_SOURCES = \ | ||||
| 	iconv.h gconv.h \ | ||||
| 	iconv_open.c iconv.c iconv_close.c \ | ||||
| 	gconv_open.c gconv.c gconv_close.c \ | ||||
| 	gconv_db.c gconv_dl.c gconv_conf.c gconv_builtin.c \ | ||||
| 	gconv_simple.c gconv_trans.c gconv_cache.c | ||||
|  | ||||
|  | ||||
| libiconv_la_CFLAGS =  | ||||
| libiconv_la_LDFLAGS = -Xcompiler -nostdlib | ||||
|  | ||||
| @USE_LIBTOOL_TRUE@noinst_LTLIBRARIES = @USE_LIBTOOL_TRUE@libiconv.la | ||||
| @USE_LIBTOOL_TRUE@libiconv_la_SOURCES = @USE_LIBTOOL_TRUE@$(LIB_SOURCES) | ||||
| @USE_LIBTOOL_TRUE@noinst_DATA = @USE_LIBTOOL_TRUE@objectlist.awk.in | ||||
| @USE_LIBTOOL_FALSE@noinst_DATA =  | ||||
| @USE_LIBTOOL_FALSE@noinst_LIBRARIES = @USE_LIBTOOL_FALSE@lib.a | ||||
| @USE_LIBTOOL_FALSE@lib_a_SOURCES = @USE_LIBTOOL_FALSE@$(LIB_SOURCES) | ||||
| mkinstalldirs = $(SHELL) $(top_srcdir)/../../../../mkinstalldirs | ||||
| CONFIG_CLEAN_FILES =  | ||||
| LIBRARIES =  $(noinst_LIBRARIES) | ||||
|  | ||||
|  | ||||
| DEFS = @DEFS@ -I. -I$(srcdir)  | ||||
| CPPFLAGS = @CPPFLAGS@ | ||||
| LIBS = @LIBS@ | ||||
| lib_a_LIBADD =  | ||||
| @USE_LIBTOOL_FALSE@lib_a_OBJECTS =  iconv_open.$(OBJEXT) iconv.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@iconv_close.$(OBJEXT) gconv_open.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@gconv.$(OBJEXT) gconv_close.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@gconv_db.$(OBJEXT) gconv_dl.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@gconv_conf.$(OBJEXT) gconv_builtin.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@gconv_simple.$(OBJEXT) gconv_trans.$(OBJEXT) \ | ||||
| @USE_LIBTOOL_FALSE@gconv_cache.$(OBJEXT) | ||||
| LTLIBRARIES =  $(noinst_LTLIBRARIES) | ||||
|  | ||||
| libiconv_la_LIBADD =  | ||||
| @USE_LIBTOOL_TRUE@libiconv_la_OBJECTS =  iconv_open.lo iconv.lo \ | ||||
| @USE_LIBTOOL_TRUE@iconv_close.lo gconv_open.lo gconv.lo gconv_close.lo \ | ||||
| @USE_LIBTOOL_TRUE@gconv_db.lo gconv_dl.lo gconv_conf.lo \ | ||||
| @USE_LIBTOOL_TRUE@gconv_builtin.lo gconv_simple.lo gconv_trans.lo \ | ||||
| @USE_LIBTOOL_TRUE@gconv_cache.lo | ||||
| CFLAGS = @CFLAGS@ | ||||
| COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) | ||||
| LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) | ||||
| CCLD = $(CC) | ||||
| LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ | ||||
| DATA =  $(noinst_DATA) | ||||
|  | ||||
| DIST_COMMON =  Makefile.am Makefile.in | ||||
|  | ||||
|  | ||||
| DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) | ||||
|  | ||||
| TAR = gtar | ||||
| GZIP_ENV = --best | ||||
| SOURCES = $(lib_a_SOURCES) $(libiconv_la_SOURCES) | ||||
| OBJECTS = $(lib_a_OBJECTS) $(libiconv_la_OBJECTS) | ||||
|  | ||||
| all: all-redirect | ||||
| .SUFFIXES: | ||||
| .SUFFIXES: .S .c .lo .o .obj .s | ||||
| $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(srcdir)/../../../../Makefile.shared | ||||
| 	cd $(top_srcdir) && $(AUTOMAKE) --cygnus iconv/Makefile | ||||
|  | ||||
| Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status | ||||
| 	cd $(top_builddir) \ | ||||
| 	  && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status | ||||
|  | ||||
|  | ||||
| mostlyclean-noinstLIBRARIES: | ||||
|  | ||||
| clean-noinstLIBRARIES: | ||||
| 	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) | ||||
|  | ||||
| distclean-noinstLIBRARIES: | ||||
|  | ||||
| maintainer-clean-noinstLIBRARIES: | ||||
|  | ||||
| .c.o: | ||||
| 	$(COMPILE) -c $< | ||||
|  | ||||
| # FIXME: We should only use cygpath when building on Windows, | ||||
| # and only if it is available. | ||||
| .c.obj: | ||||
| 	$(COMPILE) -c `cygpath -w $<` | ||||
|  | ||||
| .s.o: | ||||
| 	$(COMPILE) -c $< | ||||
|  | ||||
| .S.o: | ||||
| 	$(COMPILE) -c $< | ||||
|  | ||||
| mostlyclean-compile: | ||||
| 	-rm -f *.o core *.core | ||||
| 	-rm -f *.$(OBJEXT) | ||||
|  | ||||
| clean-compile: | ||||
|  | ||||
| distclean-compile: | ||||
| 	-rm -f *.tab.c | ||||
|  | ||||
| maintainer-clean-compile: | ||||
|  | ||||
| .c.lo: | ||||
| 	$(LIBTOOL) --mode=compile $(COMPILE) -c $< | ||||
|  | ||||
| .s.lo: | ||||
| 	$(LIBTOOL) --mode=compile $(COMPILE) -c $< | ||||
|  | ||||
| .S.lo: | ||||
| 	$(LIBTOOL) --mode=compile $(COMPILE) -c $< | ||||
|  | ||||
| mostlyclean-libtool: | ||||
| 	-rm -f *.lo | ||||
|  | ||||
| clean-libtool: | ||||
| 	-rm -rf .libs _libs | ||||
|  | ||||
| distclean-libtool: | ||||
|  | ||||
| maintainer-clean-libtool: | ||||
|  | ||||
| lib.a: $(lib_a_OBJECTS) $(lib_a_DEPENDENCIES) | ||||
| 	-rm -f lib.a | ||||
| 	$(AR) cru lib.a $(lib_a_OBJECTS) $(lib_a_LIBADD) | ||||
| 	$(RANLIB) lib.a | ||||
|  | ||||
| mostlyclean-noinstLTLIBRARIES: | ||||
|  | ||||
| clean-noinstLTLIBRARIES: | ||||
| 	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) | ||||
|  | ||||
| distclean-noinstLTLIBRARIES: | ||||
|  | ||||
| maintainer-clean-noinstLTLIBRARIES: | ||||
|  | ||||
| libiconv.la: $(libiconv_la_OBJECTS) $(libiconv_la_DEPENDENCIES) | ||||
| 	$(LINK)  $(libiconv_la_LDFLAGS) $(libiconv_la_OBJECTS) $(libiconv_la_LIBADD) $(LIBS) | ||||
|  | ||||
| tags: TAGS | ||||
|  | ||||
| ID: $(HEADERS) $(SOURCES) $(LISP) | ||||
| 	list='$(SOURCES) $(HEADERS)'; \ | ||||
| 	unique=`for i in $$list; do echo $$i; done | \ | ||||
| 	  awk '    { files[$$0] = 1; } \ | ||||
| 	       END { for (i in files) print i; }'`; \ | ||||
| 	here=`pwd` && cd $(srcdir) \ | ||||
| 	  && mkid -f$$here/ID $$unique $(LISP) | ||||
|  | ||||
| TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP) | ||||
| 	tags=; \ | ||||
| 	here=`pwd`; \ | ||||
| 	list='$(SOURCES) $(HEADERS)'; \ | ||||
| 	unique=`for i in $$list; do echo $$i; done | \ | ||||
| 	  awk '    { files[$$0] = 1; } \ | ||||
| 	       END { for (i in files) print i; }'`; \ | ||||
| 	test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ | ||||
| 	  || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS) | ||||
|  | ||||
| mostlyclean-tags: | ||||
|  | ||||
| clean-tags: | ||||
|  | ||||
| distclean-tags: | ||||
| 	-rm -f TAGS ID | ||||
|  | ||||
| maintainer-clean-tags: | ||||
|  | ||||
| distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) | ||||
|  | ||||
| subdir = iconv | ||||
|  | ||||
| distdir: $(DISTFILES) | ||||
| 	@for file in $(DISTFILES); do \ | ||||
| 	  if test -f $$file; then d=.; else d=$(srcdir); fi; \ | ||||
| 	  if test -d $$d/$$file; then \ | ||||
| 	    cp -pr $$d/$$file $(distdir)/$$file; \ | ||||
| 	  else \ | ||||
| 	    test -f $(distdir)/$$file \ | ||||
| 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ | ||||
| 	    || cp -p $$d/$$file $(distdir)/$$file || :; \ | ||||
| 	  fi; \ | ||||
| 	done | ||||
| info-am: | ||||
| info: info-am | ||||
| dvi-am: | ||||
| dvi: dvi-am | ||||
| check-am: | ||||
| check: check-am | ||||
| installcheck-am: | ||||
| installcheck: installcheck-am | ||||
| install-info-am:  | ||||
| install-info: install-info-am | ||||
| install-exec-am: | ||||
| install-exec: install-exec-am | ||||
|  | ||||
| install-data-am: | ||||
| install-data: install-data-am | ||||
|  | ||||
| install-am: all-am | ||||
| 	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am | ||||
| install: install-am | ||||
| uninstall-am: | ||||
| uninstall: uninstall-am | ||||
| all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(DATA) | ||||
| all-redirect: all-am | ||||
| install-strip: | ||||
| 	$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install | ||||
| installdirs: | ||||
|  | ||||
|  | ||||
| mostlyclean-generic: | ||||
|  | ||||
| clean-generic: | ||||
|  | ||||
| distclean-generic: | ||||
| 	-rm -f Makefile $(CONFIG_CLEAN_FILES) | ||||
| 	-rm -f config.cache config.log stamp-h stamp-h[0-9]* | ||||
|  | ||||
| maintainer-clean-generic: | ||||
| mostlyclean-am:  mostlyclean-noinstLIBRARIES mostlyclean-compile \ | ||||
| 		mostlyclean-libtool mostlyclean-noinstLTLIBRARIES \ | ||||
| 		mostlyclean-tags mostlyclean-generic | ||||
|  | ||||
| mostlyclean: mostlyclean-am | ||||
|  | ||||
| clean-am:  clean-noinstLIBRARIES clean-compile clean-libtool \ | ||||
| 		clean-noinstLTLIBRARIES clean-tags clean-generic \ | ||||
| 		mostlyclean-am | ||||
|  | ||||
| clean: clean-am | ||||
|  | ||||
| distclean-am:  distclean-noinstLIBRARIES distclean-compile \ | ||||
| 		distclean-libtool distclean-noinstLTLIBRARIES \ | ||||
| 		distclean-tags distclean-generic clean-am | ||||
| 	-rm -f libtool | ||||
|  | ||||
| distclean: distclean-am | ||||
|  | ||||
| maintainer-clean-am:  maintainer-clean-noinstLIBRARIES \ | ||||
| 		maintainer-clean-compile maintainer-clean-libtool \ | ||||
| 		maintainer-clean-noinstLTLIBRARIES \ | ||||
| 		maintainer-clean-tags maintainer-clean-generic \ | ||||
| 		distclean-am | ||||
| 	@echo "This command is intended for maintainers to use;" | ||||
| 	@echo "it deletes files that may require special tools to rebuild." | ||||
|  | ||||
| maintainer-clean: maintainer-clean-am | ||||
|  | ||||
| .PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ | ||||
| clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ | ||||
| mostlyclean-compile distclean-compile clean-compile \ | ||||
| maintainer-clean-compile mostlyclean-libtool distclean-libtool \ | ||||
| clean-libtool maintainer-clean-libtool mostlyclean-noinstLTLIBRARIES \ | ||||
| distclean-noinstLTLIBRARIES clean-noinstLTLIBRARIES \ | ||||
| maintainer-clean-noinstLTLIBRARIES tags mostlyclean-tags distclean-tags \ | ||||
| clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ | ||||
| check-am installcheck-am installcheck install-info-am install-info \ | ||||
| install-exec-am install-exec install-data-am install-data install-am \ | ||||
| install uninstall-am uninstall all-redirect all-am all installdirs \ | ||||
| mostlyclean-generic distclean-generic clean-generic \ | ||||
| maintainer-clean-generic clean mostlyclean distclean maintainer-clean | ||||
|  | ||||
|  | ||||
| objectlist.awk.in: $(noinst_LTLIBRARIES) | ||||
| 	-rm -f objectlist.awk.in | ||||
| 	for i in `ls *.lo` ; \ | ||||
| 	do \ | ||||
| 	  echo $$i `pwd`/$$i >> objectlist.awk.in ; \ | ||||
| 	done | ||||
|  | ||||
| # Tell versions [3.59,3.63) of GNU make to not export all variables. | ||||
| # Otherwise a system limit (for SysV at least) may be exceeded. | ||||
| .NOEXPORT: | ||||
							
								
								
									
										344
									
								
								newlib/libc/sys/linux/iconv/categories.def
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										344
									
								
								newlib/libc/sys/linux/iconv/categories.def
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,344 @@ | ||||
| /* Definition of all available locale categories and their items.  -*- C -*- | ||||
|    Copyright (C) 1995-2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| /* These definitions are used by the locale-related files in the C library | ||||
|    and the programs `localedef' and `locale'. | ||||
|  | ||||
|    The general format of the descriptions is like this: | ||||
|  | ||||
|      DEFINE_CATEGORY (ID, name, ( items ), setlocale-postload) | ||||
|  | ||||
|    where items itself is an array of entries in the form | ||||
|  | ||||
|      { ID, name, standard, value-type, min, max } | ||||
|  | ||||
|    The usage of the load, check, output functions depends on the individual | ||||
|    program code which loads this file. | ||||
|  | ||||
|    The various value types for the items are `string', `stringarray', `byte' | ||||
|    `bytearray', and `word'.  These cover all possible values in the current | ||||
|    locale definitions.  `min' and `max' can be individually used again.  */ | ||||
|  | ||||
| #ifndef NO_POSTLOAD | ||||
| #define NO_POSTLOAD NULL | ||||
| #endif | ||||
|  | ||||
| DEFINE_CATEGORY | ||||
| ( | ||||
|  LC_COLLATE, "LC_COLLATE", | ||||
|  ( | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_NRULES,           "collate-nrules",           std, word) | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_RULESETS,         "collate-rulesets",         std, string) | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_TABLEMB,          "collate-tablemb",          std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_WEIGHTMB,         "collate-weightmb",         std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_EXTRAMB,          "collate-extramb",          std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_INDIRECTMB,       "collate-indirectmb",       std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_TABLEWC,          "collate-tablewc",          std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_WEIGHTWC,         "collate-weightwc",         std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_EXTRAWC,          "collate-extrawc",          std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_INDIRECTWC,       "collate-indirectwc",       std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_SYMB_HASH_SIZEMB, "collate-symb-hash-sizemb", std, word) | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_SYMB_TABLEMB,     "collate-symb-tablemb",     std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_SYMB_EXTRAMB,     "collate-symb-extramb",     std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_COLLSEQMB,        "collate-collseqmb",        std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_COLLSEQWC,        "collate-collseqwc",        std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_COLLATE_CODESET,		"collate-codeset",	    std, string) | ||||
|   ), NO_POSTLOAD) | ||||
|  | ||||
|  | ||||
| /* The actual definition of ctype is meaningless here.  It is hard coded in | ||||
|    the code because it has to be handled very specially.  Only the names of | ||||
|    the functions and the value types are important.  */ | ||||
| DEFINE_CATEGORY | ||||
| ( | ||||
|  LC_CTYPE, "LC_CTYPE", | ||||
|  ( | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_CLASS,	  "ctype-class",        std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_TOUPPER,      "ctype-toupper",      std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_TOLOWER,      "ctype-tolower",      std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_CLASS32,      "ctype-class32",      std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_CLASS_NAMES,  "ctype-class-names",  std, stringlist, 10, 32) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_MAP_NAMES,	  "ctype-map-names",    std, stringlist, 2, 32) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_WIDTH,	  "ctype-width",        std, bytearray) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_MB_CUR_MAX,	  "ctype-mb-cur-max",   std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_CODESET_NAME, "charmap",		std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_TOUPPER32,    "ctype-toupper32",    std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_TOLOWER32,    "ctype-tolower32",    std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_CLASS_OFFSET, "ctype-class-offset", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_MAP_OFFSET,   "ctype-map-offset",   std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS_MB_LEN, "ctype-indigits_mb-len", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS0_MB, "ctype-indigits0_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS1_MB, "ctype-indigits1_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS2_MB, "ctype-indigits2_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS3_MB, "ctype-indigits3_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS4_MB, "ctype-indigits4_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS5_MB, "ctype-indigits5_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS6_MB, "ctype-indigits6_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS7_MB, "ctype-indigits7_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS8_MB, "ctype-indigits8_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS9_MB, "ctype-indigits9_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS_WC_LEN, "ctype-indigits_wc-len", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS0_WC, "ctype-indigits0_wc", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS1_WC, "ctype-indigits1_wc", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS2_WC, "ctype-indigits2_wc", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS3_WC, "ctype-indigits3_wc", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS4_WC, "ctype-indigits4_wc", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS5_WC, "ctype-indigits5_wc", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS6_WC, "ctype-indigits6_wc", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS7_WC, "ctype-indigits7_wc", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS8_WC, "ctype-indigits8_wc", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_INDIGITS9_WC, "ctype-indigits9_wc", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT0_MB, "ctype-outdigit0_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT1_MB, "ctype-outdigit1_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT2_MB, "ctype-outdigit2_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT3_MB, "ctype-outdigit3_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT4_MB, "ctype-outdigit4_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT5_MB, "ctype-outdigit5_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT6_MB, "ctype-outdigit6_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT7_MB, "ctype-outdigit7_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT8_MB, "ctype-outdigit8_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT9_MB, "ctype-outdigit9_mb", std, string) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT0_WC, "ctype-outdigit0_wc", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT1_WC, "ctype-outdigit1_wc", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT2_WC, "ctype-outdigit2_wc", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT3_WC, "ctype-outdigit3_wc", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT4_WC, "ctype-outdigit4_wc", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT5_WC, "ctype-outdigit5_wc", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT6_WC, "ctype-outdigit6_wc", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT7_WC, "ctype-outdigit7_wc", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT8_WC, "ctype-outdigit8_wc", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT9_WC, "ctype-outdigit9_wc", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_TAB_SIZE, "ctype-translit-tab-size", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_FROM_IDX, "ctype-translit-from-idx", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_FROM_TBL, "ctype-translit-from-tbl", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_TO_IDX, "ctype-translit-to-idx", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_TO_TBL, "ctype-translit-to-tbl", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN, "ctype-translit-default-missing-len", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_DEFAULT_MISSING, "ctype-translit-default-missing", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_IGNORE_LEN, "ctype-translit-ignore-len", std, word) | ||||
|   DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_IGNORE, "ctype-translit-ignore", std, string) | ||||
|   ), _nl_postload_ctype) | ||||
|  | ||||
|  | ||||
| DEFINE_CATEGORY | ||||
| ( | ||||
|  LC_MONETARY, "LC_MONETARY", | ||||
|  ( | ||||
|   DEFINE_ELEMENT (INT_CURR_SYMBOL,                     "int_curr_symbol",        std, string) | ||||
|   DEFINE_ELEMENT (CURRENCY_SYMBOL,                     "currency_symbol",        std, string) | ||||
|   DEFINE_ELEMENT (MON_DECIMAL_POINT,                   "mon_decimal_point",      std, string) | ||||
|   DEFINE_ELEMENT (MON_THOUSANDS_SEP,                   "mon_thousands_sep",      std, string) | ||||
|   DEFINE_ELEMENT (MON_GROUPING,                        "mon_grouping",           std, bytearray) | ||||
|   DEFINE_ELEMENT (POSITIVE_SIGN,                       "positive_sign",          std, string) | ||||
|   DEFINE_ELEMENT (NEGATIVE_SIGN,                       "negative_sign",          std, string) | ||||
|   DEFINE_ELEMENT (INT_FRAC_DIGITS,                     "int_frac_digits",        std, byte) | ||||
|   DEFINE_ELEMENT (FRAC_DIGITS,                         "frac_digits",            std, byte) | ||||
|   DEFINE_ELEMENT (P_CS_PRECEDES,                       "p_cs_precedes",          std, byte, 0, 1) | ||||
|   DEFINE_ELEMENT (P_SEP_BY_SPACE,                      "p_sep_by_space",         std, byte, 0, 2) | ||||
|   DEFINE_ELEMENT (N_CS_PRECEDES,                       "n_cs_precedes",          std, byte, 0, 1) | ||||
|   DEFINE_ELEMENT (N_SEP_BY_SPACE,                      "n_sep_by_space",         std, byte, 0, 2) | ||||
|   DEFINE_ELEMENT (P_SIGN_POSN,                         "p_sign_posn",            std, byte, 0, 4) | ||||
|   DEFINE_ELEMENT (N_SIGN_POSN,                         "n_sign_posn",            std, byte, 0, 4) | ||||
|   DEFINE_ELEMENT (__INT_P_CS_PRECEDES,                 "int_p_cs_precedes",      std, byte, 0, 1) | ||||
|   DEFINE_ELEMENT (__INT_P_SEP_BY_SPACE,                "int_p_sep_by_space",     std, byte, 0, 2) | ||||
|   DEFINE_ELEMENT (__INT_N_CS_PRECEDES,                 "int_n_cs_precedes",      std, byte, 0, 1) | ||||
|   DEFINE_ELEMENT (__INT_N_SEP_BY_SPACE,                "int_n_sep_by_space",     std, byte, 0, 2) | ||||
|   DEFINE_ELEMENT (__INT_P_SIGN_POSN,                   "int_p_sign_posn",        std, byte, 0, 4) | ||||
|   DEFINE_ELEMENT (__INT_N_SIGN_POSN,                   "int_n_sign_posn",        std, byte, 0, 4) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_CURR_SYMBOL,    "duo_int_curr_symbol",    std, string) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_CURRENCY_SYMBOL,    "duo_currency_symbol",    std, string) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_FRAC_DIGITS,    "duo_int_frac_digits",    std, byte) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_FRAC_DIGITS,        "duo_frac_digits",        std, byte) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_P_CS_PRECEDES,      "duo_p_cs_precedes",      std, byte, 0, 1) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_P_SEP_BY_SPACE,     "duo_p_sep_by_space",     std, byte, 0, 2) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_N_CS_PRECEDES,      "duo_n_cs_precedes",      std, byte, 0, 1) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_N_SEP_BY_SPACE,     "duo_n_sep_by_space",     std, byte, 0, 2) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_P_CS_PRECEDES,  "duo_int_p_cs_precedes",  std, byte, 0, 1) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_P_SEP_BY_SPACE, "duo_int_p_sep_by_space", std, byte, 0, 2) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_N_CS_PRECEDES,  "duo_int_n_cs_precedes",  std, byte, 0, 1) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_N_SEP_BY_SPACE, "duo_int_n_sep_by_space", std, byte, 0, 2) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_P_SIGN_POSN,        "duo_p_sign_posn",        std, byte, 0, 4) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_N_SIGN_POSN,        "duo_n_sign_posn",        std, byte, 0, 4) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_P_SIGN_POSN,    "duo_int_p_sign_posn",    std, byte, 0, 4) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_N_SIGN_POSN,    "duo_int_n_sign_posn",    std, byte, 0, 4) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_UNO_VALID_FROM,         "uno_valid_from",         std, word) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_UNO_VALID_TO,           "uno_valid_to",           std, word) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_VALID_FROM,         "duo_valid_from",         std, word) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DUO_VALID_TO,           "duo_valid_to",           std, word) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_CONVERSION_RATE,        "conversion_rate",         std, wordarray, 2, 2) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_DECIMAL_POINT_WC,       "monetary-decimal-point-wc", std, word) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_THOUSANDS_SEP_WC,       "monetary-thousands-sep-wc", std, word) | ||||
|   DEFINE_ELEMENT (_NL_MONETARY_CODESET,		       "monetary-codeset",	    std, string) | ||||
|   ), NO_POSTLOAD) | ||||
|  | ||||
|  | ||||
| DEFINE_CATEGORY | ||||
| ( | ||||
|  LC_NUMERIC, "LC_NUMERIC", | ||||
|  ( | ||||
|   DEFINE_ELEMENT (DECIMAL_POINT, "decimal_point", std, string) | ||||
|   DEFINE_ELEMENT (THOUSANDS_SEP, "thousands_sep", std, string) | ||||
|   DEFINE_ELEMENT (GROUPING,      "grouping",      std, bytearray) | ||||
|   DEFINE_ELEMENT (_NL_NUMERIC_DECIMAL_POINT_WC, "numeric-decimal-point-wc", std, word) | ||||
|   DEFINE_ELEMENT (_NL_NUMERIC_THOUSANDS_SEP_WC, "numeric-thousands-sep-wc", std, word) | ||||
|   DEFINE_ELEMENT (_NL_NUMERIC_CODESET,		"numeric-codeset",	    std, string) | ||||
|  | ||||
|   ), NO_POSTLOAD) | ||||
|  | ||||
|  | ||||
| DEFINE_CATEGORY | ||||
| ( | ||||
|  LC_TIME, "LC_TIME", | ||||
|  ( | ||||
|   DEFINE_ELEMENT (ABDAY_1,     "abday",       std, stringarray,  7,  7) | ||||
|   DEFINE_ELEMENT (DAY_1,       "day",         std, stringarray,  7,  7) | ||||
|   DEFINE_ELEMENT (ABMON_1,     "abmon",       std, stringarray, 12, 12) | ||||
|   DEFINE_ELEMENT (MON_1,       "mon",         std, stringarray, 12, 12) | ||||
|   DEFINE_ELEMENT (AM_STR,      "am_pm",       std, stringarray,  2,  2) | ||||
|   DEFINE_ELEMENT (D_T_FMT,     "d_t_fmt",     std, string) | ||||
|   DEFINE_ELEMENT (D_FMT,       "d_fmt",       std, string) | ||||
|   DEFINE_ELEMENT (T_FMT,       "t_fmt",       std, string) | ||||
|   DEFINE_ELEMENT (T_FMT_AMPM,  "t_fmt_ampm",  std, string) | ||||
|   DEFINE_ELEMENT (ERA,         "era",         opt, stringlist, 0, 100) | ||||
|   DEFINE_ELEMENT (ERA_YEAR,    "era_year",    opt, string) | ||||
|   DEFINE_ELEMENT (ERA_D_FMT,   "era_d_fmt",   opt, string) | ||||
|   DEFINE_ELEMENT (ALT_DIGITS,  "alt_digits",  opt, stringlist,  100, 100) | ||||
|   DEFINE_ELEMENT (ERA_D_T_FMT, "era_d_t_fmt", opt, string) | ||||
|   DEFINE_ELEMENT (ERA_T_FMT,   "era_t_fmt",   opt, string) | ||||
|   DEFINE_ELEMENT (_NL_TIME_ERA_NUM_ENTRIES,    "time-era-num-entries",    opt, word) | ||||
|   DEFINE_ELEMENT (_NL_TIME_ERA_ENTRIES,   "time-era-entries", opt, string) | ||||
|   DEFINE_ELEMENT (_NL_WABDAY_1,  "wide-abday",    std, wstringarray,  7,  7) | ||||
|   DEFINE_ELEMENT (_NL_WDAY_1,    "wide-day",      std, wstringarray,  7,  7) | ||||
|   DEFINE_ELEMENT (_NL_WABMON_1,  "wide-abmon",    std, wstringarray, 12, 12) | ||||
|   DEFINE_ELEMENT (_NL_WMON_1,    "wide-mon",      std, wstringarray, 12, 12) | ||||
|   DEFINE_ELEMENT (_NL_WAM_STR,   "wide-am_pm",    std, wstringarray,  2,  2) | ||||
|   DEFINE_ELEMENT (_NL_WD_T_FMT,  "wide-d_t_fmt",  std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_WD_FMT,    "wide-d_fmt",    std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_WT_FMT,    "wide-t_fmt",    std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_WT_FMT_AMPM, "wide-t_fmt_ampm", std, wstring) | ||||
|   DEFINE_ELEMENT (_NL_WERA_YEAR,   "wide-era_year",    opt, wstring) | ||||
|   DEFINE_ELEMENT (_NL_WERA_D_FMT,  "wide-era_d_fmt",   opt, wstring) | ||||
|   DEFINE_ELEMENT (_NL_WALT_DIGITS,  "wide-alt_digits",  opt, wstringlist, 1000, 100) | ||||
|   DEFINE_ELEMENT (_NL_WERA_D_T_FMT, "wide-era_d_t_fmt", opt, wstring) | ||||
|   DEFINE_ELEMENT (_NL_WERA_T_FMT,   "wide-era_t_fmt",   opt, wstring) | ||||
|   DEFINE_ELEMENT (_NL_TIME_WEEK_NDAYS,      "week-ndays",          std, byte) | ||||
|   DEFINE_ELEMENT (_NL_TIME_WEEK_1STDAY,     "week-1stday",         std, word) | ||||
|   DEFINE_ELEMENT (_NL_TIME_WEEK_1STWEEK,    "week-1stweek",        std, byte) | ||||
|   DEFINE_ELEMENT (_NL_TIME_FIRST_WEEKDAY,   "first_weekday",       std, byte) | ||||
|   DEFINE_ELEMENT (_NL_TIME_FIRST_WORKDAY,   "first_workday",       std, byte) | ||||
|   DEFINE_ELEMENT (_NL_TIME_CAL_DIRECTION,   "cal_direction",       std, byte) | ||||
|   DEFINE_ELEMENT (_NL_TIME_TIMEZONE,        "timezone",            std, string) | ||||
|   DEFINE_ELEMENT (_DATE_FMT,                "date_fmt",            opt, string) | ||||
|   DEFINE_ELEMENT (_NL_W_DATE_FMT,           "wide-date_fmt",       opt, wstring) | ||||
|   DEFINE_ELEMENT (_NL_TIME_CODESET,	    "time-codeset",	   std, string) | ||||
|   ), _nl_postload_time) | ||||
|  | ||||
|  | ||||
| DEFINE_CATEGORY | ||||
| ( | ||||
|  LC_MESSAGES, "LC_MESSAGES", | ||||
|  ( | ||||
|   DEFINE_ELEMENT (YESEXPR, "yesexpr", std, string) | ||||
|   DEFINE_ELEMENT (NOEXPR,  "noexpr",  std, string) | ||||
|   DEFINE_ELEMENT (YESSTR,  "yesstr",  opt, string) | ||||
|   DEFINE_ELEMENT (NOSTR,   "nostr",   opt, string) | ||||
|   DEFINE_ELEMENT (_NL_MESSAGES_CODESET, "messages-codeset", std, string) | ||||
|   ), NO_POSTLOAD) | ||||
|  | ||||
| DEFINE_CATEGORY | ||||
| ( | ||||
|  LC_PAPER, "LC_PAPER", | ||||
|  ( | ||||
|   DEFINE_ELEMENT (_NL_PAPER_HEIGHT, "height", std, word) | ||||
|   DEFINE_ELEMENT (_NL_PAPER_WIDTH,  "width",  std, word) | ||||
|   DEFINE_ELEMENT (_NL_PAPER_CODESET, "paper-codeset", std, string) | ||||
|   ), NO_POSTLOAD) | ||||
|  | ||||
| DEFINE_CATEGORY | ||||
| ( | ||||
|  LC_NAME, "LC_NAME", | ||||
|  ( | ||||
|   DEFINE_ELEMENT (_NL_NAME_NAME_FMT,  "name_fmt",  std, string) | ||||
|   DEFINE_ELEMENT (_NL_NAME_NAME_GEN,  "name_gen",  std, string) | ||||
|   DEFINE_ELEMENT (_NL_NAME_NAME_MR,   "name_mr",   std, string) | ||||
|   DEFINE_ELEMENT (_NL_NAME_NAME_MRS,  "name_mrs",  std, string) | ||||
|   DEFINE_ELEMENT (_NL_NAME_NAME_MISS, "name_miss", std, string) | ||||
|   DEFINE_ELEMENT (_NL_NAME_NAME_MS,   "name_ms",   std, string) | ||||
|   DEFINE_ELEMENT (_NL_NAME_CODESET,   "name-codeset", std, string) | ||||
|   ), NO_POSTLOAD) | ||||
|  | ||||
| DEFINE_CATEGORY | ||||
| ( | ||||
|  LC_ADDRESS, "LC_ADDRESS", | ||||
|  ( | ||||
|   DEFINE_ELEMENT (_NL_ADDRESS_POSTAL_FMT,      "postal_fmt",      std, string) | ||||
|   DEFINE_ELEMENT (_NL_ADDRESS_COUNTRY_NAME,    "country_name",    std, string) | ||||
|   DEFINE_ELEMENT (_NL_ADDRESS_COUNTRY_POST,    "country_post",    std, string) | ||||
|   DEFINE_ELEMENT (_NL_ADDRESS_COUNTRY_AB2,     "country_ab2",     std, string) | ||||
|   DEFINE_ELEMENT (_NL_ADDRESS_COUNTRY_AB3,     "country_ab3",     std, string) | ||||
|   DEFINE_ELEMENT (_NL_ADDRESS_COUNTRY_CAR,     "country_car",     std, string) | ||||
|   DEFINE_ELEMENT (_NL_ADDRESS_COUNTRY_NUM,     "country_num",     std, word) | ||||
|   DEFINE_ELEMENT (_NL_ADDRESS_COUNTRY_ISBN,    "country_isbn",    std, string) | ||||
|   DEFINE_ELEMENT (_NL_ADDRESS_LANG_NAME,       "lang_name",       std, string) | ||||
|   DEFINE_ELEMENT (_NL_ADDRESS_LANG_AB,         "lang_ab",         std, string) | ||||
|   DEFINE_ELEMENT (_NL_ADDRESS_LANG_TERM,       "lang_term",       std, string) | ||||
|   DEFINE_ELEMENT (_NL_ADDRESS_LANG_LIB,        "lang_lib",        std, string) | ||||
|   DEFINE_ELEMENT (_NL_ADDRESS_CODESET,	       "address-codeset", std, string) | ||||
|   ), NO_POSTLOAD) | ||||
|  | ||||
| DEFINE_CATEGORY | ||||
| ( | ||||
|  LC_TELEPHONE, "LC_TELEPHONE", | ||||
|  ( | ||||
|   DEFINE_ELEMENT (_NL_TELEPHONE_TEL_INT_FMT, "tel_int_fmt", std, string) | ||||
|   DEFINE_ELEMENT (_NL_TELEPHONE_TEL_DOM_FMT, "tel_dom_fmt", std, string) | ||||
|   DEFINE_ELEMENT (_NL_TELEPHONE_INT_SELECT,  "int_select",  std, string) | ||||
|   DEFINE_ELEMENT (_NL_TELEPHONE_INT_PREFIX,  "int_prefix",  std, string) | ||||
|   DEFINE_ELEMENT (_NL_TELEPHONE_CODESET,     "telephone-codeset", std, string) | ||||
|   ), NO_POSTLOAD) | ||||
|  | ||||
| DEFINE_CATEGORY | ||||
| ( | ||||
|  LC_MEASUREMENT, "LC_MEASUREMENT", | ||||
|  ( | ||||
|   DEFINE_ELEMENT (_NL_MEASUREMENT_MEASUREMENT, "measurement", std, byte) | ||||
|   DEFINE_ELEMENT (_NL_MEASUREMENT_CODESET,     "measurement-codeset", std, string) | ||||
|   ), NO_POSTLOAD) | ||||
|  | ||||
| DEFINE_CATEGORY | ||||
| ( | ||||
|  LC_IDENTIFICATION, "LC_IDENTIFICATION", | ||||
|  ( | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_TITLE,        "title",        std, string) | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_SOURCE,       "source",       std, string) | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_ADDRESS,      "address",      std, string) | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_CONTACT,      "contact",      std, string) | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_EMAIL,        "email",        std, string) | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_TEL,          "tel",          std, string) | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_FAX,          "fax",          std, string) | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_LANGUAGE,     "language",     std, string) | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_TERRITORY,    "territory",    std, string) | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_AUDIENCE,     "audience",     std, string) | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_APPLICATION,  "applcation",   std, string) | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_ABBREVIATION, "abbreviation", std, string) | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_REVISION,     "revision",     std, string) | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_DATE,         "date",         std, string) | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_CATEGORY,     "category",     std, stringarray, 13, 13) | ||||
|   DEFINE_ELEMENT (_NL_IDENTIFICATION_CODESET,	   "identification-codeset", std, string) | ||||
|   ), NO_POSTLOAD) | ||||
							
								
								
									
										37
									
								
								newlib/libc/sys/linux/iconv/dummy-repertoire.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								newlib/libc/sys/linux/iconv/dummy-repertoire.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| /* Copyright (C) 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| /* For iconv we don't have to handle repertoire maps.  Provide dummy | ||||
|    definitions to allow the use of linereader.c unchanged.  */ | ||||
| #include <repertoire.h> | ||||
|  | ||||
|  | ||||
| uint32_t | ||||
| repertoire_find_value (const struct repertoire_t *repertoire, const char *name, | ||||
| 		       size_t len) | ||||
| { | ||||
|   return ILLEGAL_CHAR_VALUE; | ||||
| } | ||||
|  | ||||
|  | ||||
| const char * | ||||
| repertoire_find_symbol (const struct repertoire_t *repertoire, uint32_t ucs) | ||||
| { | ||||
|   return NULL; | ||||
| } | ||||
							
								
								
									
										73
									
								
								newlib/libc/sys/linux/iconv/gconv.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								newlib/libc/sys/linux/iconv/gconv.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| /* Convert characters in input buffer using conversion descriptor to | ||||
|    output buffer. | ||||
|    Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <gconv_int.h> | ||||
| #include <sys/param.h> | ||||
| #include <dlfcn.h> | ||||
| #include <stddef.h> | ||||
|  | ||||
| int | ||||
| internal_function | ||||
| __gconv (__gconv_t cd, const unsigned char **inbuf, | ||||
| 	 const unsigned char *inbufend, unsigned char **outbuf, | ||||
| 	 unsigned char *outbufend, size_t *irreversible) | ||||
| { | ||||
|   size_t last_step; | ||||
|   int result; | ||||
|  | ||||
|   if (cd == (__gconv_t) -1L) | ||||
|     return __GCONV_ILLEGAL_DESCRIPTOR; | ||||
|  | ||||
|   last_step = cd->__nsteps - 1; | ||||
|  | ||||
|   assert (irreversible != NULL); | ||||
|   *irreversible = 0; | ||||
|  | ||||
|   cd->__data[last_step].__outbuf = outbuf != NULL ? *outbuf : NULL; | ||||
|   cd->__data[last_step].__outbufend = outbufend; | ||||
|  | ||||
|   if (inbuf == NULL || *inbuf == NULL) | ||||
|     /* We just flush.  */ | ||||
|     result = cd->__steps->__fct (cd->__steps, cd->__data, NULL, NULL, NULL, | ||||
|                                  irreversible, | ||||
|                                  cd->__data[last_step].__outbuf == NULL ? 2 : 1, 0); | ||||
|   else | ||||
|     { | ||||
|       const unsigned char *last_start; | ||||
|  | ||||
|       assert (outbuf != NULL && *outbuf != NULL); | ||||
|  | ||||
|       do | ||||
| 	{ | ||||
| 	  last_start = *inbuf; | ||||
| 	  result = cd->__steps->__fct (cd->__steps, cd->__data, inbuf, inbufend, | ||||
| 				 NULL, irreversible, 0, 0); | ||||
| 	} | ||||
|       while (result == __GCONV_EMPTY_INPUT && last_start != *inbuf | ||||
| 	     && *inbuf + cd->__steps->__min_needed_from <= inbufend); | ||||
|     } | ||||
|  | ||||
|   if (outbuf != NULL && *outbuf != NULL) | ||||
|     *outbuf = cd->__data[last_step].__outbuf; | ||||
|  | ||||
|   return result; | ||||
| } | ||||
							
								
								
									
										84
									
								
								newlib/libc/sys/linux/iconv/gconv_builtin.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								newlib/libc/sys/linux/iconv/gconv_builtin.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,84 @@ | ||||
| /* Table for builtin transformation mapping. | ||||
|    Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <endian.h> | ||||
| #include <limits.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include <gconv_int.h> | ||||
|  | ||||
| #include <assert.h> | ||||
|  | ||||
|  | ||||
| static struct builtin_map | ||||
| { | ||||
|   const char *name; | ||||
|   __gconv_fct fct; | ||||
|  | ||||
|   int min_needed_from; | ||||
|   int max_needed_from; | ||||
|   int min_needed_to; | ||||
|   int max_needed_to; | ||||
|  | ||||
| } map[] = | ||||
| { | ||||
| #define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, MinF, MaxF, \ | ||||
| 			       MinT, MaxT) \ | ||||
|   {									      \ | ||||
|     .name = Name,							      \ | ||||
|     .fct = Fct,								      \ | ||||
| 									      \ | ||||
|     .min_needed_from = MinF,						      \ | ||||
|     .max_needed_from = MaxF,						      \ | ||||
|     .min_needed_to = MinT,						      \ | ||||
|     .max_needed_to = MaxT						      \ | ||||
|   }, | ||||
| #define BUILTIN_ALIAS(From, To) | ||||
|  | ||||
| #include <gconv_builtin.h> | ||||
| }; | ||||
|  | ||||
|  | ||||
| void | ||||
| internal_function | ||||
| __gconv_get_builtin_trans (const char *name, struct __gconv_step *step) | ||||
| { | ||||
|   size_t cnt; | ||||
|  | ||||
|   for (cnt = 0; cnt < sizeof (map) / sizeof (map[0]); ++cnt) | ||||
|     if (strcmp (name, map[cnt].name) == 0) | ||||
|       break; | ||||
|  | ||||
|   assert (cnt < sizeof (map) / sizeof (map[0])); | ||||
|  | ||||
|   step->__fct = map[cnt].fct; | ||||
|   step->__init_fct = NULL; | ||||
|   step->__end_fct = NULL; | ||||
|   step->__shlib_handle = NULL; | ||||
|   step->__modname = NULL; | ||||
|  | ||||
|   step->__min_needed_from = map[cnt].min_needed_from; | ||||
|   step->__max_needed_from = map[cnt].max_needed_from; | ||||
|   step->__min_needed_to = map[cnt].min_needed_to; | ||||
|   step->__max_needed_to = map[cnt].max_needed_to; | ||||
|  | ||||
|   /* None of the builtin converters handles stateful encoding.  */ | ||||
|   step->__stateful = 0; | ||||
| } | ||||
							
								
								
									
										115
									
								
								newlib/libc/sys/linux/iconv/gconv_builtin.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								newlib/libc/sys/linux/iconv/gconv_builtin.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| /* Builtin transformations. | ||||
|    Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| BUILTIN_ALIAS ("UCS4//", "ISO-10646/UCS4/") | ||||
| BUILTIN_ALIAS ("UCS-4//", "ISO-10646/UCS4/") | ||||
| BUILTIN_ALIAS ("UCS-4BE//", "ISO-10646/UCS4/") | ||||
| BUILTIN_ALIAS ("CSUCS4//", "ISO-10646/UCS4/") | ||||
| BUILTIN_ALIAS ("ISO-10646//", "ISO-10646/UCS4/") | ||||
| BUILTIN_ALIAS ("10646-1:1993//", "ISO-10646/UCS4/") | ||||
| BUILTIN_ALIAS ("10646-1:1993/UCS4/", "ISO-10646/UCS4/") | ||||
| BUILTIN_ALIAS ("OSF00010104//", "ISO-10646/UCS4/") /* level 1 */ | ||||
| BUILTIN_ALIAS ("OSF00010105//", "ISO-10646/UCS4/") /* level 2 */ | ||||
| BUILTIN_ALIAS ("OSF00010106//", "ISO-10646/UCS4/") /* level 3 */ | ||||
|  | ||||
| BUILTIN_TRANSFORMATION ("INTERNAL", "ISO-10646/UCS4/", 1, "=INTERNAL->ucs4", | ||||
| 			__gconv_transform_internal_ucs4, 4, 4, 4, 4) | ||||
| BUILTIN_TRANSFORMATION ("ISO-10646/UCS4/", "INTERNAL", 1, "=ucs4->INTERNAL", | ||||
| 			__gconv_transform_ucs4_internal, 4, 4, 4, 4) | ||||
|  | ||||
| BUILTIN_TRANSFORMATION ("INTERNAL", "UCS-4LE//", 1, "=INTERNAL->ucs4le", | ||||
| 			__gconv_transform_internal_ucs4le, 4, 4, 4, 4) | ||||
| BUILTIN_TRANSFORMATION ("UCS-4LE//", "INTERNAL", 1, "=ucs4le->INTERNAL", | ||||
| 			__gconv_transform_ucs4le_internal, 4, 4, 4, 4) | ||||
|  | ||||
| BUILTIN_ALIAS ("WCHAR_T//", "INTERNAL") | ||||
|  | ||||
| BUILTIN_ALIAS ("UTF8//", "ISO-10646/UTF8/") | ||||
| BUILTIN_ALIAS ("UTF-8//", "ISO-10646/UTF8/") | ||||
| BUILTIN_ALIAS ("ISO-IR-193//", "ISO-10646/UTF8/") | ||||
| BUILTIN_ALIAS ("OSF05010001//", "ISO-10646/UTF8/") | ||||
| BUILTIN_ALIAS ("ISO-10646/UTF-8/", "ISO-10646/UTF8/") | ||||
|  | ||||
| BUILTIN_TRANSFORMATION ("INTERNAL", "ISO-10646/UTF8/", 1, "=INTERNAL->utf8", | ||||
| 			__gconv_transform_internal_utf8, 4, 4, 1, 6) | ||||
|  | ||||
| BUILTIN_TRANSFORMATION ("ISO-10646/UTF8/", "INTERNAL", 1, "=utf8->INTERNAL", | ||||
| 			__gconv_transform_utf8_internal, 1, 6, 4, 4) | ||||
|  | ||||
| BUILTIN_ALIAS ("UCS2//", "ISO-10646/UCS2/") | ||||
| BUILTIN_ALIAS ("UCS-2//", "ISO-10646/UCS2/") | ||||
| BUILTIN_ALIAS ("OSF00010100//", "ISO-10646/UCS2/") /* level 1 */ | ||||
| BUILTIN_ALIAS ("OSF00010101//", "ISO-10646/UCS2/") /* level 2 */ | ||||
| BUILTIN_ALIAS ("OSF00010102//", "ISO-10646/UCS2/") /* level 3 */ | ||||
|  | ||||
| BUILTIN_TRANSFORMATION ("ISO-10646/UCS2/", "INTERNAL", 1, "=ucs2->INTERNAL", | ||||
| 			__gconv_transform_ucs2_internal, 2, 2, 4, 4) | ||||
|  | ||||
| BUILTIN_TRANSFORMATION ("INTERNAL", "ISO-10646/UCS2/", 1, "=INTERNAL->ucs2", | ||||
| 			__gconv_transform_internal_ucs2, 4, 4, 2, 2) | ||||
|  | ||||
|  | ||||
| BUILTIN_ALIAS ("ANSI_X3.4//", "ANSI_X3.4-1968//") | ||||
| BUILTIN_ALIAS ("ISO-IR-6//", "ANSI_X3.4-1968//") | ||||
| BUILTIN_ALIAS ("ANSI_X3.4-1986//", "ANSI_X3.4-1968//") | ||||
| BUILTIN_ALIAS ("ISO_646.IRV:1991//", "ANSI_X3.4-1968//") | ||||
| BUILTIN_ALIAS ("ASCII//", "ANSI_X3.4-1968//") | ||||
| BUILTIN_ALIAS ("ISO646-US//", "ANSI_X3.4-1968//") | ||||
| BUILTIN_ALIAS ("US-ASCII//", "ANSI_X3.4-1968//") | ||||
| BUILTIN_ALIAS ("US//", "ANSI_X3.4-1968//") | ||||
| BUILTIN_ALIAS ("IBM367//", "ANSI_X3.4-1968//") | ||||
| BUILTIN_ALIAS ("CP367//", "ANSI_X3.4-1968//") | ||||
| BUILTIN_ALIAS ("CSASCII//", "ANSI_X3.4-1968//") | ||||
| BUILTIN_ALIAS ("OSF00010020//", "ANSI_X3.4-1968//") | ||||
|  | ||||
| BUILTIN_TRANSFORMATION ("ANSI_X3.4-1968//", "INTERNAL", 1, "=ascii->INTERNAL", | ||||
| 			__gconv_transform_ascii_internal, 4, 4, 1, 1) | ||||
|  | ||||
| BUILTIN_TRANSFORMATION ("INTERNAL", "ANSI_X3.4-1968//", 1, "=INTERNAL->ascii", | ||||
| 			__gconv_transform_internal_ascii, 4, 4, 1, 1) | ||||
|  | ||||
|  | ||||
| #if BYTE_ORDER == BIG_ENDIAN | ||||
| BUILTIN_ALIAS ("UNICODEBIG//", "ISO-10646/UCS2/") | ||||
| BUILTIN_ALIAS ("UCS-2BE//", "ISO-10646/UCS2/") | ||||
|  | ||||
| BUILTIN_ALIAS ("UCS-2LE//", "UNICODELITTLE//") | ||||
|  | ||||
| BUILTIN_TRANSFORMATION ("UNICODELITTLE//", "INTERNAL", 1, | ||||
| 			"=ucs2reverse->INTERNAL", | ||||
| 			__gconv_transform_ucs2reverse_internal, 2, 2, 4, 4) | ||||
|  | ||||
| BUILTIN_TRANSFORMATION ("INTERNAL", "UNICODELITTLE//", 1, | ||||
| 			"=INTERNAL->ucs2reverse", | ||||
| 			__gconv_transform_internal_ucs2reverse, 4, 4, 2, 2) | ||||
| #else | ||||
| BUILTIN_ALIAS ("UNICODELITTLE//", "ISO-10646/UCS2/") | ||||
| BUILTIN_ALIAS ("UCS-2LE//", "ISO-10646/UCS2/") | ||||
|  | ||||
| BUILTIN_ALIAS ("UCS-2BE//", "UNICODEBIG//") | ||||
|  | ||||
| BUILTIN_TRANSFORMATION ("UNICODEBIG//", "INTERNAL", 1, | ||||
| 			"=ucs2reverse->INTERNAL", | ||||
| 			__gconv_transform_ucs2reverse_internal, 2, 2, 4, 4) | ||||
|  | ||||
| BUILTIN_TRANSFORMATION ("INTERNAL", "UNICODEBIG//", 1, | ||||
| 			"=INTERNAL->ucs2reverse", | ||||
| 			__gconv_transform_internal_ucs2reverse, 4, 4, 2, 2) | ||||
| #endif | ||||
							
								
								
									
										459
									
								
								newlib/libc/sys/linux/iconv/gconv_cache.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										459
									
								
								newlib/libc/sys/linux/iconv/gconv_cache.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,459 @@ | ||||
| /* Cache handling for iconv modules. | ||||
|    Copyright (C) 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 2001. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <dlfcn.h> | ||||
| #include <fcntl.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/mman.h> | ||||
| #include <sys/stat.h> | ||||
|  | ||||
| #include <gconv_int.h> | ||||
| #include <iconvconfig.h> | ||||
|  | ||||
| #include "hash-string.h" | ||||
|  | ||||
| void *__gconv_cache; | ||||
| static size_t cache_size; | ||||
| static int cache_malloced; | ||||
|  | ||||
|  | ||||
| int | ||||
| internal_function | ||||
| __gconv_load_cache (void) | ||||
| { | ||||
|   int fd; | ||||
|   struct stat64 st; | ||||
|   struct gconvcache_header *header; | ||||
|  | ||||
|   /* We cannot use the cache if the GCONV_PATH environment variable is | ||||
|      set.  */ | ||||
|   __gconv_path_envvar = getenv ("GCONV_PATH"); | ||||
|   if (__gconv_path_envvar != NULL) | ||||
|     return -1; | ||||
|  | ||||
|   /* See whether the cache file exists.  */ | ||||
|   fd = open (GCONV_MODULES_CACHE, O_RDONLY); | ||||
|   if (__builtin_expect (fd, 0) == -1) | ||||
|     /* Not available.  */ | ||||
|     return -1; | ||||
|  | ||||
| #ifdef	_POSIX_ASYNC_IO | ||||
|   /* Get information about the file.  */ | ||||
|   if (__builtin_expect (fstat64 (fd, &st), 0) < 0 | ||||
|       /* We do not have to start looking at the file if it cannot contain | ||||
| 	 at least the cache header.  */ | ||||
|       || st.st_size < sizeof (struct gconvcache_header)) | ||||
|     { | ||||
| #endif | ||||
|     close_and_exit: | ||||
|       close (fd); | ||||
|       return -1; | ||||
| #ifdef	_POSIX_ASYNC_IO | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|   /* Make the file content available.  */ | ||||
|   cache_size = st.st_size; | ||||
| #ifdef _POSIX_MAPPED_FILES | ||||
|   __gconv_cache = mmap (NULL, cache_size, PROT_READ, MAP_SHARED, fd, 0); | ||||
|   if (__builtin_expect (__gconv_cache == MAP_FAILED, 0)) | ||||
| #endif | ||||
|     { | ||||
|       size_t already_read; | ||||
|  | ||||
|       __gconv_cache = malloc (cache_size); | ||||
|       if (__gconv_cache == NULL) | ||||
| 	goto close_and_exit; | ||||
|  | ||||
|       already_read = 0; | ||||
|       do | ||||
| 	{ | ||||
| 	  ssize_t n = read (fd, (char *) __gconv_cache + already_read, | ||||
| 			      cache_size - already_read); | ||||
| 	  if (__builtin_expect (n, 0) == -1) | ||||
| 	    { | ||||
| 	      free (__gconv_cache); | ||||
| 	      __gconv_cache = NULL; | ||||
| 	      goto close_and_exit; | ||||
| 	    } | ||||
|  | ||||
| 	  already_read += n; | ||||
| 	} | ||||
|       while (already_read < cache_size); | ||||
|  | ||||
|       cache_malloced = 1; | ||||
|     } | ||||
|  | ||||
|   /* We don't need the file descriptor anymore.  */ | ||||
|   close (fd); | ||||
|  | ||||
|   /* Check the consistency.  */ | ||||
|   header = (struct gconvcache_header *) __gconv_cache; | ||||
|   if (__builtin_expect (header->magic, GCONVCACHE_MAGIC) != GCONVCACHE_MAGIC | ||||
|       || __builtin_expect (header->string_offset >= cache_size, 0) | ||||
|       || __builtin_expect (header->hash_offset >= cache_size, 0) | ||||
|       || __builtin_expect (header->hash_size == 0, 0) | ||||
|       || __builtin_expect ((header->hash_offset | ||||
| 			    + header->hash_size * sizeof (struct hash_entry)) | ||||
| 			   > cache_size, 0) | ||||
|       || __builtin_expect (header->module_offset >= cache_size, 0) | ||||
|       || __builtin_expect (header->otherconv_offset > cache_size, 0)) | ||||
|     { | ||||
|       if (cache_malloced) | ||||
| 	{ | ||||
| 	  free (__gconv_cache); | ||||
| 	  cache_malloced = 0; | ||||
| 	} | ||||
| #ifdef _POSIX_MAPPED_FILES | ||||
|       else | ||||
| 	__munmap (__gconv_cache, cache_size); | ||||
| #endif | ||||
|       __gconv_cache = NULL; | ||||
|  | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   /* That worked.  */ | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int | ||||
| internal_function | ||||
| find_module_idx (const char *str, size_t *idxp) | ||||
| { | ||||
|   unsigned int idx; | ||||
|   unsigned int hval; | ||||
|   unsigned int hval2; | ||||
|   const struct gconvcache_header *header; | ||||
|   const char *strtab; | ||||
|   const struct hash_entry *hashtab; | ||||
|   unsigned int limit; | ||||
|  | ||||
|   header = (const struct gconvcache_header *) __gconv_cache; | ||||
|   strtab = (char *) __gconv_cache + header->string_offset; | ||||
|   hashtab = (struct hash_entry *) ((char *) __gconv_cache | ||||
| 				   + header->hash_offset); | ||||
|  | ||||
|   hval = hash_string (str); | ||||
|   idx = hval % header->hash_size; | ||||
|   hval2 = 1 + hval % (header->hash_size - 2); | ||||
|  | ||||
|   limit = cache_size - header->string_offset; | ||||
|   while (hashtab[idx].string_offset != 0) | ||||
|     if (hashtab[idx].string_offset < limit | ||||
| 	&& strcmp (str, strtab + hashtab[idx].string_offset) == 0) | ||||
|       { | ||||
| 	*idxp = hashtab[idx].module_idx; | ||||
| 	return 0; | ||||
|       } | ||||
|     else | ||||
|       if ((idx += hval2) >= header->hash_size) | ||||
| 	idx -= header->hash_size; | ||||
|  | ||||
|   /* Nothing found.  */ | ||||
|   return -1; | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifndef STATIC_GCONV | ||||
| static int | ||||
| internal_function | ||||
| find_module (const char *directory, const char *filename, | ||||
| 	     struct __gconv_step *result) | ||||
| { | ||||
|   size_t dirlen = strlen (directory); | ||||
|   size_t fnamelen = strlen (filename) + 1; | ||||
|   char fullname[dirlen + fnamelen]; | ||||
|   int status = __GCONV_NOCONV; | ||||
|   char *tmp; | ||||
|  | ||||
|   tmp = mempcpy (fullname, directory, dirlen); | ||||
|   tmp += dirlen; | ||||
|   memcpy (tmp, filename, fnamelen); | ||||
|  | ||||
|   result->__shlib_handle = __gconv_find_shlib (fullname); | ||||
|   if (result->__shlib_handle != NULL) | ||||
|     { | ||||
|       status = __GCONV_OK; | ||||
|  | ||||
|       result->__modname = NULL; | ||||
|       result->__fct = result->__shlib_handle->fct; | ||||
|       result->__init_fct = result->__shlib_handle->init_fct; | ||||
|       result->__end_fct = result->__shlib_handle->end_fct; | ||||
|  | ||||
|       result->__data = NULL; | ||||
|       if (result->__init_fct != NULL) | ||||
| 	status = result->__init_fct (result); | ||||
|     } | ||||
|  | ||||
|   return status; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| int | ||||
| internal_function | ||||
| __gconv_compare_alias_cache (const char *name1, const char *name2, int *result) | ||||
| { | ||||
|   size_t name1_idx; | ||||
|   size_t name2_idx; | ||||
|  | ||||
|   if (__gconv_cache == NULL) | ||||
|     return -1; | ||||
|  | ||||
|   if (find_module_idx (name1, &name1_idx) != 0 | ||||
|       || find_module_idx (name2, &name2_idx) != 0) | ||||
|     *result = strcmp (name1, name2); | ||||
|   else | ||||
|     *result = (int) (name1_idx - name2_idx); | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| int | ||||
| internal_function | ||||
| __gconv_lookup_cache (const char *toset, const char *fromset, | ||||
| 		      struct __gconv_step **handle, size_t *nsteps, int flags) | ||||
| { | ||||
|   const struct gconvcache_header *header; | ||||
|   const char *strtab; | ||||
|   size_t fromidx; | ||||
|   size_t toidx; | ||||
|   const struct module_entry *modtab; | ||||
|   const struct module_entry *from_module; | ||||
|   const struct module_entry *to_module; | ||||
|   struct __gconv_step *result; | ||||
|  | ||||
|   if (__gconv_cache == NULL) | ||||
|     /* We have no cache available.  */ | ||||
|     return __GCONV_NODB; | ||||
|  | ||||
|   header = (const struct gconvcache_header *) __gconv_cache; | ||||
|   strtab = (char *) __gconv_cache + header->string_offset; | ||||
|   modtab = (const struct module_entry *) ((char *) __gconv_cache | ||||
| 					  + header->module_offset); | ||||
|  | ||||
|   if (find_module_idx (fromset, &fromidx) != 0 | ||||
|       || (header->module_offset + (fromidx + 1) * sizeof (struct module_entry) | ||||
| 	  > cache_size)) | ||||
|     return __GCONV_NOCONV; | ||||
|   from_module = &modtab[fromidx]; | ||||
|  | ||||
|   if (find_module_idx (toset, &toidx) != 0 | ||||
|       || (header->module_offset + (toidx + 1) * sizeof (struct module_entry) | ||||
| 	  > cache_size)) | ||||
|     return __GCONV_NOCONV; | ||||
|   to_module = &modtab[toidx]; | ||||
|  | ||||
|   /* Avoid copy-only transformations if the user requests.   */ | ||||
|   if (__builtin_expect (flags & GCONV_AVOID_NOCONV, 0) && fromidx == toidx) | ||||
|     return __GCONV_NOCONV; | ||||
|  | ||||
|   /* If there are special conversions available examine them first.  */ | ||||
|   if (fromidx != 0 && toidx != 0 | ||||
|       && __builtin_expect (from_module->extra_offset, 0) != 0) | ||||
|     { | ||||
|       /* Search through the list to see whether there is a module | ||||
| 	 matching the destination character set.  */ | ||||
|       const struct extra_entry *extra; | ||||
|  | ||||
|       /* Note the -1.  This is due to the offset added in iconvconfig. | ||||
| 	 See there for more explanations.  */ | ||||
|       extra = (const struct extra_entry *) ((char *) __gconv_cache | ||||
| 					    + header->otherconv_offset | ||||
| 					    + from_module->extra_offset - 1); | ||||
|       while (extra->module_cnt != 0 | ||||
| 	     && extra->module[extra->module_cnt - 1].outname_offset != toidx) | ||||
| 	extra = (const struct extra_entry *) ((char *) extra | ||||
| 					      + sizeof (struct extra_entry) | ||||
| 					      + (extra->module_cnt | ||||
| 						 * sizeof (struct extra_entry_module))); | ||||
|  | ||||
|       if (extra->module_cnt != 0) | ||||
| 	{ | ||||
| 	  /* Use the extra module.  First determine how many steps.  */ | ||||
| 	  char *fromname; | ||||
| 	  int idx; | ||||
|  | ||||
| 	  *nsteps = extra->module_cnt; | ||||
| 	  *handle = result = | ||||
| 	    (struct __gconv_step *) malloc (extra->module_cnt | ||||
| 					    * sizeof (struct __gconv_step)); | ||||
| 	  if (result == NULL) | ||||
| 	    return __GCONV_NOMEM; | ||||
|  | ||||
| 	  fromname = (char *) strtab + from_module->canonname_offset; | ||||
| 	  idx = 0; | ||||
| 	  do | ||||
| 	    { | ||||
| 	      result[idx].__from_name = fromname; | ||||
| 	      fromname = result[idx].__to_name = | ||||
| 		(char *) strtab + modtab[extra->module[idx].outname_offset].canonname_offset; | ||||
|  | ||||
| 	      result[idx].__counter = 1; | ||||
| 	      result[idx].__data = NULL; | ||||
|  | ||||
| #ifndef STATIC_GCONV | ||||
| 	      if (strtab[extra->module[idx].dir_offset] != '\0') | ||||
| 		{ | ||||
| 		  /* Load the module, return handle for it.  */ | ||||
| 		  int res; | ||||
|  | ||||
| 		  res = find_module (strtab + extra->module[idx].dir_offset, | ||||
| 				     strtab + extra->module[idx].name_offset, | ||||
| 				     &result[idx]); | ||||
| 		  if (__builtin_expect (res, __GCONV_OK) != __GCONV_OK) | ||||
| 		    { | ||||
| 		      /* Something went wrong.  */ | ||||
| 		      free (result); | ||||
| 		      goto try_internal; | ||||
| 		    } | ||||
| 		} | ||||
| 	      else | ||||
| #endif | ||||
| 		/* It's a builtin transformation.  */ | ||||
| 		__gconv_get_builtin_trans (strtab | ||||
| 					   + extra->module[idx].name_offset, | ||||
| 					   &result[idx]); | ||||
|  | ||||
| 	    } | ||||
| 	  while (++idx < extra->module_cnt); | ||||
|  | ||||
| 	  return __GCONV_OK; | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|  try_internal: | ||||
|   /* See whether we can convert via the INTERNAL charset.  */ | ||||
|   if ((fromidx != 0 && __builtin_expect (from_module->fromname_offset, 1) == 0) | ||||
|       || (toidx != 0 && __builtin_expect (to_module->toname_offset, 1) == 0) | ||||
|       || (fromidx == 0 && toidx == 0)) | ||||
|     /* Not possible.  Nothing we can do.  */ | ||||
|     return __GCONV_NOCONV; | ||||
|  | ||||
|   /* We will use up to two modules.  Always allocate room for two.  */ | ||||
|   result = (struct __gconv_step *) malloc (2 * sizeof (struct __gconv_step)); | ||||
|   if (result == NULL) | ||||
|     return __GCONV_NOMEM; | ||||
|  | ||||
|   *handle = result; | ||||
|   *nsteps = 0; | ||||
|  | ||||
|   /* Generate data structure for conversion to INTERNAL.  */ | ||||
|   if (fromidx != 0) | ||||
|     { | ||||
|       result[0].__from_name = (char *) strtab + from_module->canonname_offset; | ||||
|       result[0].__to_name = (char *) "INTERNAL"; | ||||
|  | ||||
|       result[0].__counter = 1; | ||||
|       result[0].__data = NULL; | ||||
|  | ||||
| #ifndef STATIC_GCONV | ||||
|       if (strtab[from_module->todir_offset] != '\0') | ||||
| 	{ | ||||
| 	  /* Load the module, return handle for it.  */ | ||||
| 	  int res = find_module (strtab + from_module->todir_offset, | ||||
| 				 strtab + from_module->toname_offset, | ||||
| 				 &result[0]); | ||||
| 	  if (__builtin_expect (res, __GCONV_OK) != __GCONV_OK) | ||||
| 	    { | ||||
| 	      /* Something went wrong.  */ | ||||
| 	      free (result); | ||||
| 	      return res; | ||||
| 	    } | ||||
| 	} | ||||
|       else | ||||
| #endif | ||||
| 	/* It's a builtin transformation.  */ | ||||
| 	__gconv_get_builtin_trans (strtab + from_module->toname_offset, | ||||
| 				   &result[0]); | ||||
|  | ||||
|       ++*nsteps; | ||||
|     } | ||||
|  | ||||
|   /* Generate data structure for conversion from INTERNAL.  */ | ||||
|   if (toidx != 0) | ||||
|     { | ||||
|       int idx = *nsteps; | ||||
|  | ||||
|       result[idx].__from_name = (char *) "INTERNAL"; | ||||
|       result[idx].__to_name = (char *) strtab + to_module->canonname_offset; | ||||
|  | ||||
|       result[idx].__counter = 1; | ||||
|       result[idx].__data = NULL; | ||||
|  | ||||
| #ifndef STATIC_GCONV | ||||
|       if (strtab[to_module->fromdir_offset] != '\0') | ||||
| 	{ | ||||
| 	  /* Load the module, return handle for it.  */ | ||||
| 	  int res = find_module (strtab + to_module->fromdir_offset, | ||||
| 				 strtab + to_module->fromname_offset, | ||||
| 				 &result[idx]); | ||||
| 	  if (__builtin_expect (res, __GCONV_OK) != __GCONV_OK) | ||||
| 	    { | ||||
| 	      /* Something went wrong.  */ | ||||
| 	      if (idx != 0) | ||||
| 		__gconv_release_step (&result[0]); | ||||
| 	      free (result); | ||||
| 	      return res; | ||||
| 	    } | ||||
| 	} | ||||
|       else | ||||
| #endif | ||||
| 	/* It's a builtin transformation.  */ | ||||
| 	__gconv_get_builtin_trans (strtab + to_module->fromname_offset, | ||||
| 				   &result[idx]); | ||||
|  | ||||
|       ++*nsteps; | ||||
|     } | ||||
|  | ||||
|   return __GCONV_OK; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Free memory allocated for the transformation record.  */ | ||||
| void | ||||
| internal_function | ||||
| __gconv_release_cache (struct __gconv_step *steps, size_t nsteps) | ||||
| { | ||||
|   if (__gconv_cache != NULL) | ||||
|     /* The only thing we have to deallocate is the record with the | ||||
|        steps.  */ | ||||
|     free (steps); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Free all resources if necessary.  */ | ||||
| static void __attribute__ ((unused)) | ||||
| free_mem (void) | ||||
| { | ||||
|   if (cache_malloced) | ||||
|     free (__gconv_cache); | ||||
| #ifdef _POSIX_MAPPED_FILES | ||||
|   else | ||||
|     __munmap (__gconv_cache, cache_size); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| text_set_element (__libc_subfreeres, free_mem); | ||||
							
								
								
									
										73
									
								
								newlib/libc/sys/linux/iconv/gconv_charset.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								newlib/libc/sys/linux/iconv/gconv_charset.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| /* Charset name normalization. | ||||
|    Copyright (C) 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 2001. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <ctype.h> | ||||
| #include <locale.h> | ||||
|  | ||||
|  | ||||
| static inline void | ||||
| strip (char *wp, const char *s) | ||||
| { | ||||
|   int slash_count = 0; | ||||
|   char old_locale[20], *old_locale_p; | ||||
|  | ||||
|   /* Set locale to default C locale. */ | ||||
|   old_locale_p = setlocale(LC_ALL, "C"); | ||||
|   strncpy(old_locale, old_locale_p, 20); | ||||
|   while (*s != '\0') | ||||
|     { | ||||
|       if (isalnum (*s) | ||||
| 	  || *s == '_' || *s == '-' || *s == '.') | ||||
| 	*wp++ = toupper (*s); | ||||
|       else if (*s == '/') | ||||
| 	{ | ||||
| 	  if (++slash_count == 3) | ||||
| 	    break; | ||||
| 	  *wp++ = '/'; | ||||
| 	} | ||||
|       ++s; | ||||
|     } | ||||
|  | ||||
|   while (slash_count++ < 2) | ||||
|     *wp++ = '/'; | ||||
|  | ||||
|   *wp = '\0'; | ||||
|   setlocale(LC_ALL, old_locale); | ||||
| } | ||||
|  | ||||
|  | ||||
| static char * __attribute__ ((unused)) | ||||
| upstr (char *dst, const char *str) | ||||
| { | ||||
|   char *cp = dst; | ||||
|   char old_locale[20], *old_locale_p; | ||||
|   /* Set locale to default C locale. */ | ||||
|   old_locale_p = setlocale(LC_ALL, "C"); | ||||
|   strncpy(old_locale, old_locale_p, 20); | ||||
|   while ((*cp++ = toupper (*str++)) != '\0') | ||||
|     /* nothing */; | ||||
|   setlocale(LC_ALL, old_locale); | ||||
|   return dst; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* If NAME is an codeset alias expand it.  */ | ||||
| extern int __gconv_compare_alias (const char *name1, const char *name2) | ||||
|      internal_function; | ||||
							
								
								
									
										65
									
								
								newlib/libc/sys/linux/iconv/gconv_close.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								newlib/libc/sys/linux/iconv/gconv_close.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| /* Release any resource associated with given conversion descriptor. | ||||
|    Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <stdlib.h> | ||||
|  | ||||
| #include <gconv_int.h> | ||||
|  | ||||
|  | ||||
| int | ||||
| internal_function | ||||
| __gconv_close (__gconv_t cd) | ||||
| { | ||||
|   struct __gconv_step *srunp; | ||||
|   struct __gconv_step_data *drunp; | ||||
|   size_t nsteps; | ||||
|  | ||||
|   /* Free all resources by calling destructor functions and release | ||||
|      the implementations.  */ | ||||
|   srunp = cd->__steps; | ||||
|   nsteps = cd->__nsteps; | ||||
|   drunp = cd->__data; | ||||
|   do | ||||
|     { | ||||
|       struct __gconv_trans_data *transp; | ||||
|  | ||||
|       transp = drunp->__trans; | ||||
|       while (transp != NULL) | ||||
| 	{ | ||||
| 	  struct __gconv_trans_data *curp = transp; | ||||
| 	  transp = transp->__next; | ||||
|  | ||||
| 	  if (__builtin_expect (curp->__trans_end_fct != NULL, 0)) | ||||
| 	    curp->__trans_end_fct (curp->__data); | ||||
|  | ||||
| 	  free (curp); | ||||
| 	} | ||||
|  | ||||
|       if (!(drunp->__flags & __GCONV_IS_LAST) && drunp->__outbuf != NULL) | ||||
| 	free (drunp->__outbuf); | ||||
|     } | ||||
|   while (!((drunp++)->__flags & __GCONV_IS_LAST)); | ||||
|  | ||||
|   /* Free the data allocated for the descriptor.  */ | ||||
|   free (cd); | ||||
|  | ||||
|   /* Close the participating modules.  */ | ||||
|   return __gconv_close_transform (srunp, nsteps); | ||||
| } | ||||
							
								
								
									
										680
									
								
								newlib/libc/sys/linux/iconv/gconv_conf.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										680
									
								
								newlib/libc/sys/linux/iconv/gconv_conf.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,680 @@ | ||||
| /* Handle configuration data. | ||||
|    Copyright (C) 1997,98,99,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <ctype.h> | ||||
| #include <errno.h> | ||||
| #include <limits.h> | ||||
| #include <locale.h> | ||||
| #include <search.h> | ||||
| #include <stddef.h> | ||||
| #include <stdio.h> | ||||
| #include <stdio_ext.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/param.h> | ||||
|  | ||||
| #include <dirent.h> | ||||
| #include <gconv_int.h> | ||||
|  | ||||
| /* This is the default path where we look for module lists.  */ | ||||
| static const char default_gconv_path[] = GCONV_PATH; | ||||
|  | ||||
| /* The path elements, as determined by the __gconv_get_path function. | ||||
|    All path elements end in a slash.  */ | ||||
| struct path_elem *__gconv_path_elem; | ||||
| /* Maximum length of a single path element in __gconv_path_elem.  */ | ||||
| size_t __gconv_max_path_elem_len; | ||||
|  | ||||
| /* We use the following struct if we couldn't allocate memory.  */ | ||||
| static const struct path_elem empty_path_elem; | ||||
|  | ||||
| /* Name of the file containing the module information in the directories | ||||
|    along the path.  */ | ||||
| static const char gconv_conf_filename[] = "gconv-modules"; | ||||
|  | ||||
| /* Filename extension for the modules.  */ | ||||
| #ifndef MODULE_EXT | ||||
| # define MODULE_EXT ".so" | ||||
| #endif | ||||
| static const char gconv_module_ext[] = MODULE_EXT; | ||||
|  | ||||
| /* We have a few builtin transformations.  */ | ||||
| static struct gconv_module builtin_modules[] = | ||||
| { | ||||
| #define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, MinF, MaxF, \ | ||||
| 			       MinT, MaxT) \ | ||||
|   {									      \ | ||||
|     from_string: From,							      \ | ||||
|     to_string: To,							      \ | ||||
|     cost_hi: Cost,							      \ | ||||
|     cost_lo: INT_MAX,							      \ | ||||
|     module_name: Name							      \ | ||||
|   }, | ||||
| #define BUILTIN_ALIAS(From, To) | ||||
|  | ||||
| #include "gconv_builtin.h" | ||||
| }; | ||||
|  | ||||
| #undef BUILTIN_TRANSFORMATION | ||||
| #undef BUILTIN_ALIAS | ||||
|  | ||||
| static const char *builtin_aliases[] = | ||||
| { | ||||
| #define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, MinF, MaxF, \ | ||||
| 			       MinT, MaxT) | ||||
| #define BUILTIN_ALIAS(From, To) From " " To, | ||||
|  | ||||
| #include "gconv_builtin.h" | ||||
| }; | ||||
|  | ||||
| #ifdef USE_IN_LIBIO | ||||
| # include <libio/libioP.h> | ||||
| # define __getdelim(line, len, c, fp) _IO_getdelim (line, len, c, fp) | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* Value of the GCONV_PATH environment variable.  */ | ||||
| const char *__gconv_path_envvar; | ||||
|  | ||||
|  | ||||
| /* Test whether there is already a matching module known.  */ | ||||
| static int | ||||
| internal_function | ||||
| detect_conflict (const char *alias) | ||||
| { | ||||
|   struct gconv_module *node = __gconv_modules_db; | ||||
|  | ||||
|   while (node != NULL) | ||||
|     { | ||||
|       int cmpres = strcmp (alias, node->from_string); | ||||
|  | ||||
|       if (cmpres == 0) | ||||
| 	/* We have a conflict.  */ | ||||
| 	return 1; | ||||
|       else if (cmpres < 0) | ||||
| 	node = node->left; | ||||
|       else | ||||
| 	node = node->right; | ||||
|     } | ||||
|  | ||||
|   return node != NULL; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Add new alias.  */ | ||||
| static inline void | ||||
| add_alias (char *rp, void *modules) | ||||
| { | ||||
|   /* We now expect two more string.  The strings are normalized | ||||
|      (converted to UPPER case) and strored in the alias database.  */ | ||||
|   struct gconv_alias *new_alias; | ||||
|   char *from, *to, *wp; | ||||
|   char old_locale[20], *old_locale_p; | ||||
|  | ||||
|   /* Set locale to default C locale. */ | ||||
|   old_locale_p = setlocale(LC_ALL, "C"); | ||||
|   strncpy(old_locale, old_locale_p, 20); | ||||
|  | ||||
|   while (isspace (*rp)) | ||||
|     ++rp; | ||||
|   from = wp = rp; | ||||
|   while (*rp != '\0' && !isspace (*rp)) | ||||
|     *wp++ = toupper (*rp++); | ||||
|   if (*rp == '\0') | ||||
|     { | ||||
|       setlocale(LC_ALL, old_locale); | ||||
|       /* There is no `to' string on the line.  Ignore it.  */ | ||||
|       return; | ||||
|     } | ||||
|   *wp++ = '\0'; | ||||
|   to = ++rp; | ||||
|   while (isspace (*rp)) | ||||
|     ++rp; | ||||
|   while (*rp != '\0' && !isspace (*rp)) | ||||
|     *wp++ = toupper (*rp++); | ||||
|   if (to == wp) | ||||
|     { | ||||
|       setlocale(LC_ALL, old_locale); | ||||
|       /* No `to' string, ignore the line.  */ | ||||
|       return; | ||||
|     } | ||||
|   *wp++ = '\0'; | ||||
|  | ||||
|   /* Test whether this alias conflicts with any available module.  */ | ||||
|   if (detect_conflict (from)) | ||||
|     { | ||||
|       setlocale(LC_ALL, old_locale); | ||||
|       /* It does conflict, don't add the alias.  */ | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   new_alias = (struct gconv_alias *) malloc (sizeof (struct gconv_alias) + (wp - from)); | ||||
|   if (new_alias != NULL) | ||||
|     { | ||||
|       void **inserted; | ||||
|  | ||||
|       new_alias->fromname = memcpy ((char *) new_alias | ||||
| 				    + sizeof (struct gconv_alias), | ||||
| 				    from, wp - from); | ||||
|       new_alias->toname = new_alias->fromname + (to - from); | ||||
|  | ||||
|       inserted = (void **) tsearch (new_alias, &__gconv_alias_db, | ||||
| 				      __gconv_alias_compare); | ||||
|       if (inserted == NULL || *inserted != new_alias) | ||||
| 	/* Something went wrong, free this entry.  */ | ||||
| 	free (new_alias); | ||||
|     } | ||||
|   setlocale(LC_ALL, old_locale); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Insert a data structure for a new module in the search tree.  */ | ||||
| static inline void | ||||
| internal_function | ||||
| insert_module (struct gconv_module *newp, int tobefreed) | ||||
| { | ||||
|   struct gconv_module **rootp = &__gconv_modules_db; | ||||
|  | ||||
|   while (*rootp != NULL) | ||||
|     { | ||||
|       struct gconv_module *root = *rootp; | ||||
|       int cmpres; | ||||
|  | ||||
|       cmpres = strcmp (newp->from_string, root->from_string); | ||||
|       if (cmpres == 0) | ||||
| 	{ | ||||
| 	  /* Both strings are identical.  Insert the string at the | ||||
| 	     end of the `same' list if it is not already there.  */ | ||||
| 	  while (strcmp (newp->from_string, root->from_string) != 0 | ||||
| 		 || strcmp (newp->to_string, root->to_string) != 0) | ||||
| 	    { | ||||
| 	      rootp = &root->same; | ||||
| 	      root = *rootp; | ||||
| 	      if (root == NULL) | ||||
| 		break; | ||||
| 	    } | ||||
|  | ||||
| 	  if (root != NULL) | ||||
| 	    { | ||||
| 	      /* This is a no new conversion.  But maybe the cost is | ||||
| 		 better.  */ | ||||
| 	      if (newp->cost_hi < root->cost_hi | ||||
| 		  || (newp->cost_hi == root->cost_hi | ||||
| 		      && newp->cost_lo < root->cost_lo)) | ||||
| 		{ | ||||
| 		  newp->left = root->left; | ||||
| 		  newp->right = root->right; | ||||
| 		  newp->same = root->same; | ||||
| 		  *rootp = newp; | ||||
|  | ||||
| 		  free (root); | ||||
| 		} | ||||
| 	      else if (tobefreed) | ||||
| 		free (newp); | ||||
| 	      return; | ||||
| 	    } | ||||
|  | ||||
| 	  break; | ||||
| 	} | ||||
|       else if (cmpres < 0) | ||||
| 	rootp = &root->left; | ||||
|       else | ||||
| 	rootp = &root->right; | ||||
|     } | ||||
|  | ||||
|   /* Plug in the new node here.  */ | ||||
|   *rootp = newp; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Add new module.  */ | ||||
| static void | ||||
| internal_function | ||||
| add_module (char *rp, const char *directory, size_t dir_len, void **modules, | ||||
| 	    size_t *nmodules, int modcounter) | ||||
| { | ||||
|   /* We expect now | ||||
|      1. `from' name | ||||
|      2. `to' name | ||||
|      3. filename of the module | ||||
|      4. an optional cost value | ||||
|   */ | ||||
|   struct gconv_alias fake_alias; | ||||
|   struct gconv_module *new_module; | ||||
|   char *from, *to, *module, *wp; | ||||
|   int need_ext; | ||||
|   int cost_hi; | ||||
|   char old_locale[20], *old_locale_p; | ||||
|   char *old; | ||||
|   size_t len; | ||||
|   char *new; | ||||
|  | ||||
|   /* Set locale to default C locale. */ | ||||
|   old_locale_p = setlocale(LC_ALL, "C"); | ||||
|   strncpy(old_locale, old_locale_p, 20); | ||||
|  | ||||
|   while (isspace (*rp)) | ||||
|     ++rp; | ||||
|   from = rp; | ||||
|   while (*rp != '\0' && !isspace (*rp)) | ||||
|     { | ||||
|       *rp = toupper (*rp); | ||||
|       ++rp; | ||||
|     } | ||||
|   if (*rp == '\0') | ||||
|     { | ||||
|       setlocale(LC_ALL, old_locale); | ||||
|       return; | ||||
|     } | ||||
|   *rp++ = '\0'; | ||||
|   to = wp = rp; | ||||
|   while (isspace (*rp)) | ||||
|     { | ||||
|       setlocale(LC_ALL, old_locale); | ||||
|       ++rp; | ||||
|     } | ||||
|   while (*rp != '\0' && !isspace (*rp)) | ||||
|     *wp++ = toupper (*rp++); | ||||
|   if (*rp == '\0') | ||||
|     { | ||||
|       setlocale(LC_ALL, old_locale); | ||||
|       return; | ||||
|     } | ||||
|   *wp++ = '\0'; | ||||
|   do | ||||
|     ++rp; | ||||
|   while (isspace (*rp)); | ||||
|   module = wp; | ||||
|   while (*rp != '\0' && !isspace (*rp)) | ||||
|     *wp++ = *rp++; | ||||
|   if (*rp == '\0') | ||||
|     { | ||||
|       /* There is no cost, use one by default.  */ | ||||
|       *wp++ = '\0'; | ||||
|       cost_hi = 1; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* There might be a cost value.  */ | ||||
|       char *endp; | ||||
|  | ||||
|       *wp++ = '\0'; | ||||
|       cost_hi = strtol (rp, &endp, 10); | ||||
|       if (rp == endp || cost_hi < 1) | ||||
| 	/* No useful information.  */ | ||||
| 	cost_hi = 1; | ||||
|     } | ||||
|  | ||||
|   if (module[0] == '\0') | ||||
|     { | ||||
|       setlocale(LC_ALL, old_locale); | ||||
|       /* No module name given.  */ | ||||
|       return; | ||||
|     } | ||||
|   if (module[0] == '/') | ||||
|     dir_len = 0; | ||||
|  | ||||
|   /* See whether we must add the ending.  */ | ||||
|   need_ext = 0; | ||||
|   if (wp - module < (ptrdiff_t) sizeof (gconv_module_ext) | ||||
|       || memcmp (wp - sizeof (gconv_module_ext), gconv_module_ext, | ||||
| 		 sizeof (gconv_module_ext)) != 0) | ||||
|     /* We must add the module extension.  */ | ||||
|     need_ext = sizeof (gconv_module_ext) - 1; | ||||
|  | ||||
|   /* See whether we have already an alias with this name defined.  */ | ||||
|   old = from; | ||||
|   len = strnlen (old, to - from); | ||||
|   new = (char *) alloca (len + 1); | ||||
|   new[len] = '\0'; | ||||
|   fake_alias.fromname = (char *) memcpy (new, old, len); | ||||
|  | ||||
|   if (tfind (&fake_alias, &__gconv_alias_db, __gconv_alias_compare) != NULL) | ||||
|     { | ||||
|       setlocale(LC_ALL, old_locale); | ||||
|       /* This module duplicates an alias.  */ | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   new_module = (struct gconv_module *) calloc (1, | ||||
| 					       sizeof (struct gconv_module) | ||||
| 					       + (wp - from) | ||||
| 					       + dir_len + need_ext); | ||||
|   if (new_module != NULL) | ||||
|     { | ||||
|       char *tmp; | ||||
|  | ||||
|       new_module->from_string = tmp = (char *) (new_module + 1); | ||||
|       tmp = memcpy (tmp, from, to - from); | ||||
|       tmp += (to - from); | ||||
|  | ||||
|       new_module->to_string = tmp; | ||||
|       tmp = memcpy (tmp, to, module - to); | ||||
|       tmp += (module - to); | ||||
|  | ||||
|       new_module->cost_hi = cost_hi; | ||||
|       new_module->cost_lo = modcounter; | ||||
|  | ||||
|       new_module->module_name = tmp; | ||||
|  | ||||
|       if (dir_len != 0) | ||||
|         { | ||||
|           tmp = memcpy (tmp, directory, dir_len); | ||||
|           tmp += dir_len; | ||||
|         } | ||||
|  | ||||
|       tmp = memcpy (tmp, module, wp - module); | ||||
|       tmp += (wp - module); | ||||
|  | ||||
|       if (need_ext) | ||||
| 	memcpy (tmp - 1, gconv_module_ext, sizeof (gconv_module_ext)); | ||||
|  | ||||
|       /* Now insert the new module data structure in our search tree.  */ | ||||
|       insert_module (new_module, 1); | ||||
|     } | ||||
|   setlocale(LC_ALL, old_locale); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Read the next configuration file.  */ | ||||
| static void | ||||
| internal_function | ||||
| read_conf_file (const char *filename, const char *directory, size_t dir_len, | ||||
| 		void **modules, size_t *nmodules) | ||||
| { | ||||
|   FILE *fp = fopen (filename, "r"); | ||||
|   char *line = NULL; | ||||
|   size_t line_len = 0; | ||||
|   static int modcounter; | ||||
|   char old_locale[20], *old_locale_p; | ||||
|  | ||||
|   /* Don't complain if a file is not present or readable, simply silently | ||||
|      ignore it.  */ | ||||
|   if (fp == NULL) | ||||
|     return; | ||||
|  | ||||
|   /* Set locale to default C locale. */ | ||||
|   old_locale_p = setlocale(LC_ALL, "C"); | ||||
|   strncpy(old_locale, old_locale_p, 20); | ||||
|  | ||||
|   /* Process the known entries of the file.  Comments start with `#' and | ||||
|      end with the end of the line.  Empty lines are ignored.  */ | ||||
|   while (!feof (fp)) | ||||
|     { | ||||
|       char *rp, *endp, *word; | ||||
|       ssize_t n = __getdelim (&line, &line_len, '\n', fp); | ||||
|       if (n < 0) | ||||
| 	/* An error occurred.  */ | ||||
| 	break; | ||||
|  | ||||
|       rp = line; | ||||
|       /* Terminate the line (excluding comments or newline) by an NUL byte | ||||
| 	 to simplify the following code.  */ | ||||
|       endp = strchr (rp, '#'); | ||||
|       if (endp != NULL) | ||||
| 	*endp = '\0'; | ||||
|       else | ||||
| 	if (rp[n - 1] == '\n') | ||||
| 	  rp[n - 1] = '\0'; | ||||
|  | ||||
|       while (isspace (*rp)) | ||||
| 	++rp; | ||||
|  | ||||
|       /* If this is an empty line go on with the next one.  */ | ||||
|       if (rp == endp) | ||||
| 	continue; | ||||
|  | ||||
|       word = rp; | ||||
|       while (*rp != '\0' && !isspace (*rp)) | ||||
| 	++rp; | ||||
|  | ||||
|       if (rp - word == sizeof ("alias") - 1 | ||||
| 	  && memcmp (word, "alias", sizeof ("alias") - 1) == 0) | ||||
| 	add_alias (rp, *modules); | ||||
|       else if (rp - word == sizeof ("module") - 1 | ||||
| 	       && memcmp (word, "module", sizeof ("module") - 1) == 0) | ||||
| 	add_module (rp, directory, dir_len, modules, nmodules, modcounter++); | ||||
|       /* else */ | ||||
| 	/* Otherwise ignore the line.  */ | ||||
|     } | ||||
|  | ||||
|   free (line); | ||||
|  | ||||
|   fclose (fp); | ||||
|  | ||||
|   setlocale(LC_ALL, old_locale); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Determine the directories we are looking for data in.  */ | ||||
| void | ||||
| __gconv_get_path (void) | ||||
| { | ||||
|   struct path_elem *result; | ||||
|   __LOCK_INIT(static, path_lock); | ||||
|  | ||||
| #ifdef HAVE_DD_LOCK | ||||
|   __lock_acquire(path_lock); | ||||
| #endif | ||||
|  | ||||
|   /* Make sure there wasn't a second thread doing it already.  */ | ||||
|   result = (struct path_elem *) __gconv_path_elem; | ||||
|   if (result == NULL) | ||||
|     { | ||||
|       /* Determine the complete path first.  */ | ||||
|       char *gconv_path; | ||||
|       size_t gconv_path_len; | ||||
|       char *elem; | ||||
|       char *oldp; | ||||
|       char *cp; | ||||
|       int nelems; | ||||
|       char *cwd; | ||||
|       size_t cwdlen; | ||||
|  | ||||
|       if (__gconv_path_envvar == NULL) | ||||
| 	{ | ||||
|           char * old = default_gconv_path; | ||||
|           size_t len = strlen (old) + 1; | ||||
|           char *new = (char *) alloca (len); | ||||
|  | ||||
| 	  /* No user-defined path.  Make a modifiable copy of the | ||||
| 	     default path.  */ | ||||
|           gconv_path = (char *) memcpy (new, old, len); | ||||
| 	  gconv_path_len = sizeof (default_gconv_path); | ||||
| 	  cwd = NULL; | ||||
| 	  cwdlen = 0; | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  /* Append the default path to the user-defined path.  */ | ||||
| 	  size_t user_len = strlen (__gconv_path_envvar); | ||||
|           char *tmp; | ||||
|  | ||||
| 	  gconv_path_len = user_len + 1 + sizeof (default_gconv_path); | ||||
| 	  gconv_path = alloca (gconv_path_len); | ||||
|           tmp = memcpy (gconv_path, __gconv_path_envvar, | ||||
|                         user_len); | ||||
|           tmp += user_len; | ||||
|           memcpy (tmp, ":", 1); | ||||
|           tmp += 1; | ||||
| 	  memcpy (tmp, | ||||
|                   default_gconv_path, sizeof (default_gconv_path)); | ||||
|  | ||||
| 	  cwd = getcwd (NULL, 0); | ||||
| 	  cwdlen = strlen (cwd); | ||||
| 	} | ||||
|       assert (default_gconv_path[0] == '/'); | ||||
|  | ||||
|       /* In a first pass we calculate the number of elements.  */ | ||||
|       oldp = NULL; | ||||
|       cp = strchr (gconv_path, ':'); | ||||
|       nelems = 1; | ||||
|       while (cp != NULL) | ||||
| 	{ | ||||
| 	  if (cp != oldp + 1) | ||||
| 	    ++nelems; | ||||
| 	  oldp = cp; | ||||
| 	  cp =  strchr (cp + 1, ':'); | ||||
| 	} | ||||
|  | ||||
|       /* Allocate the memory for the result.  */ | ||||
|       result = (struct path_elem *) malloc ((nelems + 1) | ||||
| 					    * sizeof (struct path_elem) | ||||
| 					    + gconv_path_len + nelems | ||||
| 					    + (nelems - 1) * (cwdlen + 1)); | ||||
|       if (result != NULL) | ||||
| 	{ | ||||
| 	  char *strspace = (char *) &result[nelems + 1]; | ||||
| 	  int n = 0; | ||||
|  | ||||
| 	  /* Separate the individual parts.  */ | ||||
| 	  __gconv_max_path_elem_len = 0; | ||||
| 	  elem = strtok_r (gconv_path, ":", &gconv_path); | ||||
| 	  assert (elem != NULL); | ||||
| 	  do | ||||
| 	    { | ||||
| 	      result[n].name = strspace; | ||||
| 	      if (elem[0] != '/') | ||||
| 		{ | ||||
| 		  assert (cwd != NULL); | ||||
| 		  strspace = memcpy (strspace, cwd, cwdlen); | ||||
|                   strspace += cwdlen; | ||||
| 		  *strspace++ = '/'; | ||||
| 		} | ||||
| 	      strspace = strcpy (strspace, elem); | ||||
|               while(*strspace != '\0') strspace++; | ||||
|  | ||||
| 	      if (strspace[-1] != '/') | ||||
| 		*strspace++ = '/'; | ||||
|  | ||||
| 	      result[n].len = strspace - result[n].name; | ||||
| 	      if (result[n].len > __gconv_max_path_elem_len) | ||||
| 		__gconv_max_path_elem_len = result[n].len; | ||||
|  | ||||
| 	      *strspace++ = '\0'; | ||||
| 	      ++n; | ||||
| 	    } | ||||
| 	  while ((elem = strtok_r (NULL, ":", &gconv_path)) != NULL); | ||||
|  | ||||
| 	  result[n].name = NULL; | ||||
| 	  result[n].len = 0; | ||||
| 	} | ||||
|  | ||||
|       __gconv_path_elem = result ?: (struct path_elem *) &empty_path_elem; | ||||
|  | ||||
|       if (cwd != NULL) | ||||
| 	free (cwd); | ||||
|     } | ||||
|  | ||||
| #ifdef HAVE_DD_LOCK | ||||
|   __lock_release(path_lock); | ||||
| #endif | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Read all configuration files found in the user-specified and the default | ||||
|    path.  */ | ||||
| void | ||||
| __gconv_read_conf (void) | ||||
| { | ||||
|   void *modules = NULL; | ||||
|   size_t nmodules = 0; | ||||
|   int save_errno = errno; | ||||
|   size_t cnt; | ||||
|   char *filename; | ||||
|   char *tmp; | ||||
|   const char *elem; | ||||
|   size_t elem_len; | ||||
|  | ||||
|   /* First see whether we should use the cache.  */ | ||||
|   if (__gconv_load_cache () == 0) | ||||
|     { | ||||
|       /* Yes, we are done.  */ | ||||
|       __set_errno (save_errno); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
| #ifndef STATIC_GCONV | ||||
|   /* Find out where we have to look.  */ | ||||
|   if (__gconv_path_elem == NULL) | ||||
|     __gconv_get_path (); | ||||
|  | ||||
|   for (cnt = 0; __gconv_path_elem[cnt].name != NULL; ++cnt) | ||||
|     { | ||||
|       elem = __gconv_path_elem[cnt].name; | ||||
|       elem_len = __gconv_path_elem[cnt].len; | ||||
|  | ||||
|       /* No slash needs to be inserted between elem and gconv_conf_filename; | ||||
| 	 elem already ends in a slash.  */ | ||||
|       filename = alloca (elem_len + sizeof (gconv_conf_filename)); | ||||
|       tmp = memcpy (filename, elem, elem_len); | ||||
|       tmp += elem_len; | ||||
|       memcpy (tmp, gconv_conf_filename, sizeof (gconv_conf_filename)); | ||||
|  | ||||
|       /* Read the next configuration file.  */ | ||||
|       read_conf_file (filename, elem, elem_len, &modules, &nmodules); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|   /* Add the internal modules.  */ | ||||
|   for (cnt = 0; cnt < sizeof (builtin_modules) / sizeof (builtin_modules[0]); | ||||
|        ++cnt) | ||||
|     { | ||||
|       struct gconv_alias fake_alias; | ||||
|  | ||||
|       fake_alias.fromname = (char *) builtin_modules[cnt].from_string; | ||||
|  | ||||
|       if (tfind (&fake_alias, &__gconv_alias_db, __gconv_alias_compare) | ||||
| 	  != NULL) | ||||
| 	/* It'll conflict so don't add it.  */ | ||||
| 	continue; | ||||
|  | ||||
|       insert_module (&builtin_modules[cnt], 0); | ||||
|     } | ||||
|  | ||||
|   /* Add aliases for builtin conversions.  */ | ||||
|   cnt = sizeof (builtin_aliases) / sizeof (builtin_aliases[0]); | ||||
|   while (cnt > 0) | ||||
|     { | ||||
|       char * old = builtin_aliases[--cnt]; | ||||
|       size_t len = strlen (old) + 1; | ||||
|       char *new = (char *) alloca (len); | ||||
|       char *copy = (char *) memcpy (new, old, len); | ||||
|  | ||||
|       add_alias (copy, modules); | ||||
|     } | ||||
|  | ||||
|   /* Restore the error number.  */ | ||||
|   __set_errno (save_errno); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Free all resources if necessary.  */ | ||||
| static void __attribute__ ((unused)) | ||||
| free_mem (void) | ||||
| { | ||||
|   if (__gconv_path_elem != NULL && __gconv_path_elem != &empty_path_elem) | ||||
|     free ((void *) __gconv_path_elem); | ||||
| } | ||||
|  | ||||
| text_set_element (__libc_subfreeres, free_mem); | ||||
							
								
								
									
										803
									
								
								newlib/libc/sys/linux/iconv/gconv_db.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										803
									
								
								newlib/libc/sys/linux/iconv/gconv_db.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,803 @@ | ||||
| /* Provide access to the collection of available transformation modules. | ||||
|    Copyright (C) 1997,98,99,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <limits.h> | ||||
| #include <search.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <sys/param.h> | ||||
| #include <dirent.h> | ||||
|  | ||||
| #include <dlfcn.h> | ||||
| #include <gconv_int.h> | ||||
| #include <gconv_charset.h> | ||||
|  | ||||
|  | ||||
| /* Simple data structure for alias mapping.  We have two names, `from' | ||||
|    and `to'.  */ | ||||
| void *__gconv_alias_db; | ||||
|  | ||||
| /* Array with available modules.  */ | ||||
| struct gconv_module *__gconv_modules_db; | ||||
|  | ||||
| /* We modify global data.   */ | ||||
| __LOCK_INIT(static, lock); | ||||
|  | ||||
|  | ||||
| /* Function for searching alias.  */ | ||||
| int | ||||
| __gconv_alias_compare (const void *p1, const void *p2) | ||||
| { | ||||
|   const struct gconv_alias *s1 = (const struct gconv_alias *) p1; | ||||
|   const struct gconv_alias *s2 = (const struct gconv_alias *) p2; | ||||
|   return strcmp (s1->fromname, s2->fromname); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* To search for a derivation we create a list of intermediate steps. | ||||
|    Each element contains a pointer to the element which precedes it | ||||
|    in the derivation order.  */ | ||||
| struct derivation_step | ||||
| { | ||||
|   const char *result_set; | ||||
|   size_t result_set_len; | ||||
|   int cost_lo; | ||||
|   int cost_hi; | ||||
|   struct gconv_module *code; | ||||
|   struct derivation_step *last; | ||||
|   struct derivation_step *next; | ||||
| }; | ||||
|  | ||||
| #define NEW_STEP(result, hi, lo, module, last_mod) \ | ||||
|   ({ struct derivation_step *newp = alloca (sizeof (struct derivation_step)); \ | ||||
|      newp->result_set = result;						      \ | ||||
|      newp->result_set_len = strlen (result);				      \ | ||||
|      newp->cost_hi = hi;						      \ | ||||
|      newp->cost_lo = lo;						      \ | ||||
|      newp->code = module;						      \ | ||||
|      newp->last = last_mod;						      \ | ||||
|      newp->next = NULL;							      \ | ||||
|      newp; }) | ||||
|  | ||||
|  | ||||
| /* If a specific transformation is used more than once we should not need | ||||
|    to start looking for it again.  Instead cache each successful result.  */ | ||||
| struct known_derivation | ||||
| { | ||||
|   const char *from; | ||||
|   const char *to; | ||||
|   struct __gconv_step *steps; | ||||
|   size_t nsteps; | ||||
| }; | ||||
|  | ||||
| /* Compare function for database of found derivations.  */ | ||||
| static int | ||||
| derivation_compare (const void *p1, const void *p2) | ||||
| { | ||||
|   const struct known_derivation *s1 = (const struct known_derivation *) p1; | ||||
|   const struct known_derivation *s2 = (const struct known_derivation *) p2; | ||||
|   int result; | ||||
|  | ||||
|   result = strcmp (s1->from, s2->from); | ||||
|   if (result == 0) | ||||
|     result = strcmp (s1->to, s2->to); | ||||
|   return result; | ||||
| } | ||||
|  | ||||
| /* The search tree for known derivations.  */ | ||||
| static void *known_derivations; | ||||
|  | ||||
| /* Look up whether given transformation was already requested before.  */ | ||||
| static int | ||||
| internal_function | ||||
| derivation_lookup (const char *fromset, const char *toset, | ||||
| 		   struct __gconv_step **handle, size_t *nsteps) | ||||
| { | ||||
|   struct known_derivation key = { fromset, toset, NULL, 0 }; | ||||
|   struct known_derivation **result; | ||||
|  | ||||
|   result = tfind (&key, &known_derivations, derivation_compare); | ||||
|  | ||||
|   if (result == NULL) | ||||
|     return __GCONV_NOCONV; | ||||
|  | ||||
|   *handle = (*result)->steps; | ||||
|   *nsteps = (*result)->nsteps; | ||||
|  | ||||
|   /* Please note that we return GCONV_OK even if the last search for | ||||
|      this transformation was unsuccessful.  */ | ||||
|   return __GCONV_OK; | ||||
| } | ||||
|  | ||||
| /* Add new derivation to list of known ones.  */ | ||||
| static void | ||||
| internal_function | ||||
| add_derivation (const char *fromset, const char *toset, | ||||
| 		struct __gconv_step *handle, size_t nsteps) | ||||
| { | ||||
|   struct known_derivation *new_deriv; | ||||
|   size_t fromset_len = strlen (fromset) + 1; | ||||
|   size_t toset_len = strlen (toset) + 1; | ||||
|  | ||||
|   new_deriv = (struct known_derivation *) | ||||
|     malloc (sizeof (struct known_derivation) + fromset_len + toset_len); | ||||
|   if (new_deriv != NULL) | ||||
|     { | ||||
|       char *tmp; | ||||
|       new_deriv->from = (char *) (new_deriv + 1); | ||||
|       tmp = memcpy (new_deriv + 1, fromset, fromset_len); | ||||
|       tmp += fromset_len; | ||||
|  | ||||
|       new_deriv->to = memcpy (tmp, | ||||
| 			      toset, toset_len); | ||||
|  | ||||
|       new_deriv->steps = handle; | ||||
|       new_deriv->nsteps = nsteps; | ||||
|  | ||||
|       if (tsearch (new_deriv, &known_derivations, derivation_compare) | ||||
| 	  == NULL) | ||||
| 	/* There is some kind of memory allocation problem.  */ | ||||
| 	free (new_deriv); | ||||
|     } | ||||
|   /* Please note that we don't complain if the allocation failed.  This | ||||
|      is not tragically but in case we use the memory debugging facilities | ||||
|      not all memory will be freed.  */ | ||||
| } | ||||
|  | ||||
| static void | ||||
| free_derivation (void *p) | ||||
| { | ||||
|   struct known_derivation *deriv = (struct known_derivation *) p; | ||||
|   size_t cnt; | ||||
|  | ||||
|   for (cnt = 0; cnt < deriv->nsteps; ++cnt) | ||||
|     if (deriv->steps[cnt].__counter > 0 | ||||
| 	&& deriv->steps[cnt].__end_fct != NULL) | ||||
|       deriv->steps[cnt].__end_fct (&deriv->steps[cnt]); | ||||
|  | ||||
|   /* Free the name strings.  */ | ||||
|   free ((char *) deriv->steps[0].__from_name); | ||||
|   free ((char *) deriv->steps[deriv->nsteps - 1].__to_name); | ||||
|  | ||||
|   free ((struct __gconv_step *) deriv->steps); | ||||
|   free (deriv); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Decrement the reference count for a single step in a steps array.  */ | ||||
| void | ||||
| internal_function | ||||
| __gconv_release_step (struct __gconv_step *step) | ||||
| { | ||||
|   if (--step->__counter == 0) | ||||
|     { | ||||
|       /* Call the destructor.  */ | ||||
|       if (step->__end_fct != NULL) | ||||
| 	step->__end_fct (step); | ||||
|  | ||||
| #ifndef STATIC_GCONV | ||||
|       /* Skip builtin modules; they are not reference counted.  */ | ||||
|       if (step->__shlib_handle != NULL) | ||||
| 	{ | ||||
| 	  /* Release the loaded module.  */ | ||||
| 	  __gconv_release_shlib (step->__shlib_handle); | ||||
| 	  step->__shlib_handle = NULL; | ||||
| 	} | ||||
| #endif | ||||
|     } | ||||
| } | ||||
|  | ||||
| static int | ||||
| internal_function | ||||
| gen_steps (struct derivation_step *best, const char *toset, | ||||
| 	   const char *fromset, struct __gconv_step **handle, size_t *nsteps) | ||||
| { | ||||
|   size_t step_cnt = 0; | ||||
|   struct __gconv_step *result; | ||||
|   struct derivation_step *current; | ||||
|   int status = __GCONV_NOMEM; | ||||
|  | ||||
|   /* First determine number of steps.  */ | ||||
|   for (current = best; current->last != NULL; current = current->last) | ||||
|     ++step_cnt; | ||||
|  | ||||
|   result = (struct __gconv_step *) malloc (sizeof (struct __gconv_step) | ||||
| 					   * step_cnt); | ||||
|   if (result != NULL) | ||||
|     { | ||||
|       int failed = 0; | ||||
|  | ||||
|       status = __GCONV_OK; | ||||
|       *nsteps = step_cnt; | ||||
|       current = best; | ||||
|       while (step_cnt-- > 0) | ||||
| 	{ | ||||
| 	  result[step_cnt].__from_name = (step_cnt == 0 | ||||
| 					  ? strdup (fromset) | ||||
| 					  : (char *)current->last->result_set); | ||||
| 	  result[step_cnt].__to_name = (step_cnt + 1 == *nsteps | ||||
| 					? strdup (current->result_set) | ||||
| 					: result[step_cnt + 1].__from_name); | ||||
|  | ||||
| 	  result[step_cnt].__counter = 1; | ||||
| 	  result[step_cnt].__data = NULL; | ||||
|  | ||||
| #ifndef STATIC_GCONV | ||||
| 	  if (current->code->module_name[0] == '/') | ||||
| 	    { | ||||
| 	      /* Load the module, return handle for it.  */ | ||||
| 	      struct __gconv_loaded_object *shlib_handle = | ||||
| 		__gconv_find_shlib (current->code->module_name); | ||||
|  | ||||
| 	      if (shlib_handle == NULL) | ||||
| 		{ | ||||
| 		  failed = 1; | ||||
| 		  break; | ||||
| 		} | ||||
|  | ||||
| 	      result[step_cnt].__shlib_handle = shlib_handle; | ||||
| 	      result[step_cnt].__modname = shlib_handle->name; | ||||
| 	      result[step_cnt].__fct = shlib_handle->fct; | ||||
| 	      result[step_cnt].__init_fct = shlib_handle->init_fct; | ||||
| 	      result[step_cnt].__end_fct = shlib_handle->end_fct; | ||||
|  | ||||
| 	      /* Call the init function.  */ | ||||
| 	      if (result[step_cnt].__init_fct != NULL) | ||||
| 		{ | ||||
| 		  status = result[step_cnt].__init_fct (&result[step_cnt]); | ||||
|  | ||||
| 		  if (__builtin_expect (status, __GCONV_OK) != __GCONV_OK) | ||||
| 		    { | ||||
| 		      failed = 1; | ||||
| 		      /* Make sure we unload this modules.  */ | ||||
| 		      --step_cnt; | ||||
| 		      result[step_cnt].__end_fct = NULL; | ||||
| 		      break; | ||||
| 		    } | ||||
| 		} | ||||
| 	    } | ||||
| 	  else | ||||
| #endif | ||||
| 	    /* It's a builtin transformation.  */ | ||||
| 	    __gconv_get_builtin_trans (current->code->module_name, | ||||
| 				       &result[step_cnt]); | ||||
|  | ||||
| 	  current = current->last; | ||||
| 	} | ||||
|  | ||||
|       if (__builtin_expect (failed, 0) != 0) | ||||
| 	{ | ||||
| 	  /* Something went wrong while initializing the modules.  */ | ||||
| 	  while (++step_cnt < *nsteps) | ||||
| 	    __gconv_release_step (&result[step_cnt]); | ||||
| 	  free (result); | ||||
| 	  *nsteps = 0; | ||||
| 	  *handle = NULL; | ||||
| 	  if (status == __GCONV_OK) | ||||
| 	    status = __GCONV_NOCONV; | ||||
| 	} | ||||
|       else | ||||
| 	*handle = result; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       *nsteps = 0; | ||||
|       *handle = NULL; | ||||
|     } | ||||
|  | ||||
|   return status; | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifndef STATIC_GCONV | ||||
| static int | ||||
| internal_function | ||||
| increment_counter (struct __gconv_step *steps, size_t nsteps) | ||||
| { | ||||
|   /* Increment the user counter.  */ | ||||
|   size_t cnt = nsteps; | ||||
|   int result = __GCONV_OK; | ||||
|  | ||||
|   while (cnt-- > 0) | ||||
|     { | ||||
|       struct __gconv_step *step = &steps[cnt]; | ||||
|  | ||||
|       if (step->__counter++ == 0) | ||||
| 	{ | ||||
| 	  /* Skip builtin modules.  */ | ||||
| 	  if (step->__modname != NULL) | ||||
| 	    { | ||||
| 	      /* Reopen a previously used module.  */ | ||||
| 	      step->__shlib_handle = __gconv_find_shlib (step->__modname); | ||||
| 	      if (step->__shlib_handle == NULL) | ||||
| 		{ | ||||
| 		  /* Oops, this is the second time we use this module | ||||
| 		     (after unloading) and this time loading failed!?  */ | ||||
| 		  --step->__counter; | ||||
| 		  while (++cnt < nsteps) | ||||
| 		    __gconv_release_step (&steps[cnt]); | ||||
| 		  result = __GCONV_NOCONV; | ||||
| 		  break; | ||||
| 		} | ||||
|  | ||||
| 	      /* The function addresses defined by the module may | ||||
| 		 have changed.  */ | ||||
| 	      step->__fct = step->__shlib_handle->fct; | ||||
| 	      step->__init_fct = step->__shlib_handle->init_fct; | ||||
| 	      step->__end_fct = step->__shlib_handle->end_fct; | ||||
| 	    } | ||||
|  | ||||
| 	  if (step->__init_fct != NULL) | ||||
| 	    step->__init_fct (step); | ||||
| 	} | ||||
|     } | ||||
|   return result; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* The main function: find a possible derivation from the `fromset' (either | ||||
|    the given name or the alias) to the `toset' (again with alias).  */ | ||||
| static int | ||||
| internal_function | ||||
| find_derivation (const char *toset, const char *toset_expand, | ||||
| 		 const char *fromset, const char *fromset_expand, | ||||
| 		 struct __gconv_step **handle, size_t *nsteps) | ||||
| { | ||||
|   struct derivation_step *first, *current, **lastp, *solution = NULL; | ||||
|   int best_cost_hi = INT_MAX; | ||||
|   int best_cost_lo = INT_MAX; | ||||
|   int result; | ||||
|  | ||||
|   /* Look whether an earlier call to `find_derivation' has already | ||||
|      computed a possible derivation.  If so, return it immediately.  */ | ||||
|   result = derivation_lookup (fromset_expand ?: fromset, toset_expand ?: toset, | ||||
| 			      handle, nsteps); | ||||
|   if (result == __GCONV_OK) | ||||
|     { | ||||
| #ifndef STATIC_GCONV | ||||
|       result = increment_counter (*handle, *nsteps); | ||||
| #endif | ||||
|       return result; | ||||
|     } | ||||
|  | ||||
|   /* The task is to find a sequence of transformations, backed by the | ||||
|      existing modules - whether builtin or dynamically loadable -, | ||||
|      starting at `fromset' (or `fromset_expand') and ending at `toset' | ||||
|      (or `toset_expand'), and with minimal cost. | ||||
|  | ||||
|      For computer scientists, this is a shortest path search in the | ||||
|      graph where the nodes are all possible charsets and the edges are | ||||
|      the transformations listed in __gconv_modules_db. | ||||
|  | ||||
|      For now we use a simple algorithm with quadratic runtime behaviour. | ||||
|      A breadth-first search, starting at `fromset' and `fromset_expand'. | ||||
|      The list starting at `first' contains all nodes that have been | ||||
|      visited up to now, in the order in which they have been visited -- | ||||
|      excluding the goal nodes `toset' and `toset_expand' which get | ||||
|      managed in the list starting at `solution'. | ||||
|      `current' walks through the list starting at `first' and looks | ||||
|      which nodes are reachable from the current node, adding them to | ||||
|      the end of the list [`first' or `solution' respectively] (if | ||||
|      they are visited the first time) or updating them in place (if | ||||
|      they have have already been visited). | ||||
|      In each node of either list, cost_lo and cost_hi contain the | ||||
|      minimum cost over any paths found up to now, starting at `fromset' | ||||
|      or `fromset_expand', ending at that node.  best_cost_lo and | ||||
|      best_cost_hi represent the minimum over the elements of the | ||||
|      `solution' list.  */ | ||||
|  | ||||
|   if (fromset_expand != NULL) | ||||
|     { | ||||
|       first = NEW_STEP (fromset_expand, 0, 0, NULL, NULL); | ||||
|       first->next = NEW_STEP (fromset, 0, 0, NULL, NULL); | ||||
|       lastp = &first->next->next; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       first = NEW_STEP (fromset, 0, 0, NULL, NULL); | ||||
|       lastp = &first->next; | ||||
|     } | ||||
|  | ||||
|   for (current = first; current != NULL; current = current->next) | ||||
|     { | ||||
|       /* Now match all the available module specifications against the | ||||
|          current charset name.  If any of them matches check whether | ||||
|          we already have a derivation for this charset.  If yes, use the | ||||
|          one with the lower costs.  Otherwise add the new charset at the | ||||
|          end. | ||||
|  | ||||
| 	 The module database is organized in a tree form which allows | ||||
| 	 searching for prefixes.  So we search for the first entry with a | ||||
| 	 matching prefix and any other matching entry can be found from | ||||
| 	 this place.  */ | ||||
|       struct gconv_module *node; | ||||
|  | ||||
|       /* Maybe it is not necessary anymore to look for a solution for | ||||
| 	 this entry since the cost is already as high (or higher) as | ||||
| 	 the cost for the best solution so far.  */ | ||||
|       if (current->cost_hi > best_cost_hi | ||||
| 	  || (current->cost_hi == best_cost_hi | ||||
| 	      && current->cost_lo >= best_cost_lo)) | ||||
| 	continue; | ||||
|  | ||||
|       node = __gconv_modules_db; | ||||
|       while (node != NULL) | ||||
| 	{ | ||||
| 	  int cmpres = strcmp (current->result_set, node->from_string); | ||||
| 	  if (cmpres == 0) | ||||
| 	    { | ||||
| 	      /* Walk through the list of modules with this prefix and | ||||
| 		 try to match the name.  */ | ||||
| 	      struct gconv_module *runp; | ||||
|  | ||||
| 	      /* Check all the modules with this prefix.  */ | ||||
| 	      runp = node; | ||||
| 	      do | ||||
| 		{ | ||||
| 		  const char *result_set = (strcmp (runp->to_string, "-") == 0 | ||||
| 					    ? (toset_expand ?: toset) | ||||
| 					    : runp->to_string); | ||||
| 		  int cost_hi = runp->cost_hi + current->cost_hi; | ||||
| 		  int cost_lo = runp->cost_lo + current->cost_lo; | ||||
| 		  struct derivation_step *step; | ||||
|  | ||||
| 		  /* We managed to find a derivation.  First see whether | ||||
| 		     we have reached one of the goal nodes.  */ | ||||
| 		  if (strcmp (result_set, toset) == 0 | ||||
| 		      || (toset_expand != NULL | ||||
| 			  && strcmp (result_set, toset_expand) == 0)) | ||||
| 		    { | ||||
| 		      /* Append to the `solution' list if there | ||||
| 			 is no entry with this name.  */ | ||||
| 		      for (step = solution; step != NULL; step = step->next) | ||||
| 			if (strcmp (result_set, step->result_set) == 0) | ||||
| 			  break; | ||||
|  | ||||
| 		      if (step == NULL) | ||||
| 			{ | ||||
| 			  step = NEW_STEP (result_set, | ||||
| 					   cost_hi, cost_lo, | ||||
| 					   runp, current); | ||||
| 			  step->next = solution; | ||||
| 			  solution = step; | ||||
| 			} | ||||
| 		      else if (step->cost_hi > cost_hi | ||||
| 			       || (step->cost_hi == cost_hi | ||||
| 				   && step->cost_lo > cost_lo)) | ||||
| 			{ | ||||
| 			  /* A better path was found for the node, | ||||
| 			     on the `solution' list.  */ | ||||
| 			  step->code = runp; | ||||
| 			  step->last = current; | ||||
| 			  step->cost_hi = cost_hi; | ||||
| 			  step->cost_lo = cost_lo; | ||||
| 			} | ||||
|  | ||||
| 		      /* Update best_cost accordingly.  */ | ||||
| 		      if (cost_hi < best_cost_hi | ||||
| 			  || (cost_hi == best_cost_hi | ||||
| 			      && cost_lo < best_cost_lo)) | ||||
| 			{ | ||||
| 			  best_cost_hi = cost_hi; | ||||
| 			  best_cost_lo = cost_lo; | ||||
| 			} | ||||
| 		    } | ||||
| 		  else if (cost_hi < best_cost_hi | ||||
| 			   || (cost_hi == best_cost_hi | ||||
| 			       && cost_lo < best_cost_lo)) | ||||
| 		    { | ||||
| 		      /* Append at the end of the `first' list if there | ||||
| 			 is no entry with this name.  */ | ||||
| 		      for (step = first; step != NULL; step = step->next) | ||||
| 			if (strcmp (result_set, step->result_set) == 0) | ||||
| 			  break; | ||||
|  | ||||
| 		      if (step == NULL) | ||||
| 			{ | ||||
| 			  *lastp = NEW_STEP (result_set, | ||||
| 					     cost_hi, cost_lo, | ||||
| 					     runp, current); | ||||
| 			  lastp = &(*lastp)->next; | ||||
| 			} | ||||
| 		      else if (step->cost_hi > cost_hi | ||||
| 			       || (step->cost_hi == cost_hi | ||||
| 				   && step->cost_lo > cost_lo)) | ||||
| 			{ | ||||
| 			  /* A better path was found for the node, | ||||
| 			     on the `first' list.  */ | ||||
| 			  step->code = runp; | ||||
| 			  step->last = current; | ||||
|  | ||||
| 			  /* Update the cost for all steps.  */ | ||||
| 			  for (step = first; step != NULL; | ||||
| 			       step = step->next) | ||||
| 			    /* But don't update the start nodes.  */ | ||||
| 			    if (step->code != NULL) | ||||
| 			      { | ||||
| 				struct derivation_step *back; | ||||
| 				int hi, lo; | ||||
|  | ||||
| 				hi = step->code->cost_hi; | ||||
| 				lo = step->code->cost_lo; | ||||
|  | ||||
| 				for (back = step->last; back->code != NULL; | ||||
| 				     back = back->last) | ||||
| 				  { | ||||
| 				    hi += back->code->cost_hi; | ||||
| 				    lo += back->code->cost_lo; | ||||
| 				  } | ||||
|  | ||||
| 				step->cost_hi = hi; | ||||
| 				step->cost_lo = lo; | ||||
| 			      } | ||||
|  | ||||
| 			  /* Likewise for the nodes on the solution list. | ||||
| 			     Also update best_cost accordingly.  */ | ||||
| 			  for (step = solution; step != NULL; | ||||
| 			       step = step->next) | ||||
| 			    { | ||||
| 			      step->cost_hi = (step->code->cost_hi | ||||
| 					       + step->last->cost_hi); | ||||
| 			      step->cost_lo = (step->code->cost_lo | ||||
| 					       + step->last->cost_lo); | ||||
|  | ||||
| 			      if (step->cost_hi < best_cost_hi | ||||
| 				  || (step->cost_hi == best_cost_hi | ||||
| 				      && step->cost_lo < best_cost_lo)) | ||||
| 				{ | ||||
| 				  best_cost_hi = step->cost_hi; | ||||
| 				  best_cost_lo = step->cost_lo; | ||||
| 				} | ||||
| 			    } | ||||
| 			} | ||||
| 		    } | ||||
|  | ||||
| 		  runp = runp->same; | ||||
| 		} | ||||
| 	      while (runp != NULL); | ||||
|  | ||||
| 	      break; | ||||
| 	    } | ||||
| 	  else if (cmpres < 0) | ||||
| 	    node = node->left; | ||||
| 	  else | ||||
| 	    node = node->right; | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   if (solution != NULL) | ||||
|     { | ||||
|       /* We really found a way to do the transformation.  */ | ||||
|  | ||||
|       /* Choose the best solution.  This is easy because we know that | ||||
| 	 the solution list has at most length 2 (one for every possible | ||||
| 	 goal node).  */ | ||||
|       if (solution->next != NULL) | ||||
| 	{ | ||||
| 	  struct derivation_step *solution2 = solution->next; | ||||
|  | ||||
| 	  if (solution2->cost_hi < solution->cost_hi | ||||
| 	      || (solution2->cost_hi == solution->cost_hi | ||||
| 		  && solution2->cost_lo < solution->cost_lo)) | ||||
| 	    solution = solution2; | ||||
| 	} | ||||
|  | ||||
|       /* Now build a data structure describing the transformation steps.  */ | ||||
|       result = gen_steps (solution, toset_expand ?: toset, | ||||
| 			  fromset_expand ?: fromset, handle, nsteps); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* We haven't found a transformation.  Clear the result values.  */ | ||||
|       *handle = NULL; | ||||
|       *nsteps = 0; | ||||
|     } | ||||
|  | ||||
|   /* Add result in any case to list of known derivations.  */ | ||||
|   add_derivation (fromset_expand ?: fromset, toset_expand ?: toset, | ||||
| 		  *handle, *nsteps); | ||||
|  | ||||
|   return result; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Control of initialization.  */ | ||||
| __libc_once_define (static, once); | ||||
|  | ||||
|  | ||||
| static const char * | ||||
| do_lookup_alias (const char *name) | ||||
| { | ||||
|   struct gconv_alias key; | ||||
|   struct gconv_alias **found; | ||||
|  | ||||
|   key.fromname = (char *) name; | ||||
|   found = tfind (&key, &__gconv_alias_db, __gconv_alias_compare); | ||||
|   return found != NULL ? (*found)->toname : NULL; | ||||
| } | ||||
|  | ||||
|  | ||||
| int | ||||
| internal_function | ||||
| __gconv_compare_alias (const char *name1, const char *name2) | ||||
| { | ||||
|   int result; | ||||
|  | ||||
|   /* Ensure that the configuration data is read.  */ | ||||
|   __libc_once (once, __gconv_read_conf); | ||||
|  | ||||
|   if (__gconv_compare_alias_cache (name1, name2, &result) != 0) | ||||
|     result = strcmp (do_lookup_alias (name1) ?: name1, | ||||
| 		     do_lookup_alias (name2) ?: name2); | ||||
|  | ||||
|   return result; | ||||
| } | ||||
|  | ||||
|  | ||||
| int | ||||
| internal_function | ||||
| __gconv_find_transform (const char *toset, const char *fromset, | ||||
| 			struct __gconv_step **handle, size_t *nsteps, | ||||
| 			int flags) | ||||
| { | ||||
|   const char *fromset_expand; | ||||
|   const char *toset_expand; | ||||
|   int result; | ||||
|  | ||||
|   /* Ensure that the configuration data is read.  */ | ||||
|   __libc_once (once, __gconv_read_conf); | ||||
|  | ||||
|   /* Acquire the lock.  */ | ||||
| #ifdef HAVE_DD_LOCK | ||||
|   __lock_acquire(lock); | ||||
| #endif | ||||
|  | ||||
|   result = __gconv_lookup_cache (toset, fromset, handle, nsteps, flags); | ||||
|   if (result != __GCONV_NODB) | ||||
|     { | ||||
|       /* We have a cache and could resolve the request, successful or not.  */ | ||||
| #ifdef HAVE_DD_LOCK | ||||
|       __lock_release(lock); | ||||
| #endif | ||||
|  | ||||
|       return result; | ||||
|     } | ||||
|  | ||||
|   /* If we don't have a module database return with an error.  */ | ||||
|   if (__gconv_modules_db == NULL) | ||||
|     { | ||||
| #ifdef HAVE_DD_LOCK | ||||
|   __lock_release(lock); | ||||
| #endif | ||||
|  | ||||
|       return __GCONV_NOCONV; | ||||
|     } | ||||
|  | ||||
|   /* See whether the names are aliases.  */ | ||||
|   fromset_expand = do_lookup_alias (fromset); | ||||
|   toset_expand = do_lookup_alias (toset); | ||||
|  | ||||
|   if (__builtin_expect (flags & GCONV_AVOID_NOCONV, 0) | ||||
|       /* We are not supposed to create a pseudo transformation (means | ||||
| 	 copying) when the input and output character set are the same.  */ | ||||
|       && (strcmp (toset, fromset) == 0 | ||||
| 	  || (toset_expand != NULL && strcmp (toset_expand, fromset) == 0) | ||||
| 	  || (fromset_expand != NULL | ||||
| 	      && (strcmp (toset, fromset_expand) == 0 | ||||
| 		  || (toset_expand != NULL | ||||
| 		      && strcmp (toset_expand, fromset_expand) == 0))))) | ||||
|     { | ||||
|       /* Both character sets are the same.  */ | ||||
| #ifdef HAVE_DD_LOCK | ||||
|   __lock_release(lock); | ||||
| #endif | ||||
|  | ||||
|       return __GCONV_NOCONV; | ||||
|     } | ||||
|  | ||||
|   result = find_derivation (toset, toset_expand, fromset, fromset_expand, | ||||
| 			    handle, nsteps); | ||||
|  | ||||
|   /* Release the lock.  */ | ||||
| #ifdef HAVE_DD_LOCK | ||||
|   __lock_release(lock); | ||||
| #endif | ||||
|  | ||||
|  | ||||
|   /* The following code is necessary since `find_derivation' will return | ||||
|      GCONV_OK even when no derivation was found but the same request | ||||
|      was processed before.  I.e., negative results will also be cached.  */ | ||||
|   return (result == __GCONV_OK | ||||
| 	  ? (*handle == NULL ? __GCONV_NOCONV : __GCONV_OK) | ||||
| 	  : result); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Release the entries of the modules list.  */ | ||||
| int | ||||
| internal_function | ||||
| __gconv_close_transform (struct __gconv_step *steps, size_t nsteps) | ||||
| { | ||||
|   int result = __GCONV_OK; | ||||
|   size_t cnt; | ||||
|  | ||||
|   /* Acquire the lock.  */ | ||||
| #ifdef HAVE_DD_LOCK | ||||
|   __lock_acquire(lock); | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #ifndef STATIC_GCONV | ||||
|   cnt = nsteps; | ||||
|   while (cnt-- > 0) | ||||
|     __gconv_release_step (&steps[cnt]); | ||||
| #endif | ||||
|  | ||||
|   /* If we use the cache we free a bit more since we don't keep any | ||||
|      transformation records around, they are cheap enough to | ||||
|      recreate.  */ | ||||
|   __gconv_release_cache (steps, nsteps); | ||||
|  | ||||
|   /* Release the lock.  */ | ||||
| #ifdef HAVE_DD_LOCK | ||||
|   __lock_release(lock); | ||||
| #endif | ||||
|  | ||||
|  | ||||
|   return result; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Free the modules mentioned.  */ | ||||
| static void | ||||
| internal_function | ||||
| free_modules_db (struct gconv_module *node) | ||||
| { | ||||
|   if (node->left != NULL) | ||||
|     free_modules_db (node->left); | ||||
|   if (node->right != NULL) | ||||
|     free_modules_db (node->right); | ||||
|   do | ||||
|     { | ||||
|       struct gconv_module *act = node; | ||||
|       node = node->same; | ||||
|       if (act->module_name[0] == '/') | ||||
| 	free (act); | ||||
|     } | ||||
|   while (node != NULL); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Free all resources if necessary.  */ | ||||
| static void __attribute__ ((unused)) | ||||
| free_mem (void) | ||||
| { | ||||
|   if (__gconv_alias_db != NULL) | ||||
|     tdestroy (__gconv_alias_db, free); | ||||
|  | ||||
|   if (__gconv_modules_db != NULL) | ||||
|     free_modules_db (__gconv_modules_db); | ||||
|  | ||||
|   if (known_derivations != NULL) | ||||
|     tdestroy (known_derivations, free_derivation); | ||||
| } | ||||
|  | ||||
| text_set_element (__libc_subfreeres, free_mem); | ||||
							
								
								
									
										237
									
								
								newlib/libc/sys/linux/iconv/gconv_dl.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								newlib/libc/sys/linux/iconv/gconv_dl.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,237 @@ | ||||
| /* Handle loading/unloading of shared object for transformation. | ||||
|    Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <dlfcn.h> | ||||
| #include <search.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <bits/libc-lock.h> | ||||
| #include <sys/param.h> | ||||
| #include <ltdl.h> | ||||
|  | ||||
| #include <gconv_int.h> | ||||
|  | ||||
|  | ||||
| #ifdef DEBUG | ||||
| /* For debugging purposes.  */ | ||||
| static void print_all (void); | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* This is a tuning parameter.  If a transformation module is not used | ||||
|    anymore it gets not immediately unloaded.  Instead we wait a certain | ||||
|    number of load attempts for further modules.  If none of the | ||||
|    subsequent load attempts name the same object it finally gets unloaded. | ||||
|    Otherwise it is still available which hopefully is the frequent case. | ||||
|    The following number is the number of unloading attempts we wait | ||||
|    before unloading.  */ | ||||
| #define TRIES_BEFORE_UNLOAD	2 | ||||
|  | ||||
| /* Array of loaded objects.  This is shared by all threads so we have | ||||
|    to use semaphores to access it.  */ | ||||
| static void *loaded; | ||||
|  | ||||
| /* Comparison function for searching `loaded_object' tree.  */ | ||||
| static int | ||||
| known_compare (const void *p1, const void *p2) | ||||
| { | ||||
|   const struct __gconv_loaded_object *s1 = | ||||
|     (const struct __gconv_loaded_object *) p1; | ||||
|   const struct __gconv_loaded_object *s2 = | ||||
|     (const struct __gconv_loaded_object *) p2; | ||||
|  | ||||
|   return strcmp (s1->name, s2->name); | ||||
| } | ||||
|  | ||||
| /* Open the gconv database if necessary.  A non-negative return value | ||||
|    means success.  */ | ||||
| struct __gconv_loaded_object * | ||||
| internal_function | ||||
| __gconv_find_shlib (const char *name) | ||||
| { | ||||
|   struct __gconv_loaded_object *found; | ||||
|   void *keyp; | ||||
|  | ||||
|    | ||||
|  | ||||
|   /* Search the tree of shared objects previously requested.  Data in | ||||
|      the tree are `loaded_object' structures, whose first member is a | ||||
|      `const char *', the lookup key.  The search returns a pointer to | ||||
|      the tree node structure; the first member of the is a pointer to | ||||
|      our structure (i.e. what will be a `loaded_object'); since the | ||||
|      first member of that is the lookup key string, &FCT_NAME is close | ||||
|      enough to a pointer to our structure to use as a lookup key that | ||||
|      will be passed to `known_compare' (above).  */ | ||||
|  | ||||
|   keyp = tfind (&name, &loaded, known_compare); | ||||
|   if (keyp == NULL) | ||||
|     { | ||||
|       /* This name was not known before.  */ | ||||
|       size_t namelen = strlen (name) + 1; | ||||
|  | ||||
|       found = malloc (sizeof (struct __gconv_loaded_object) + namelen); | ||||
|       if (found != NULL) | ||||
| 	{ | ||||
| 	  /* Point the tree node at this new structure.  */ | ||||
| 	  found->name = (char *) memcpy (found + 1, name, namelen); | ||||
| 	  found->counter = -TRIES_BEFORE_UNLOAD - 1; | ||||
| 	  found->handle = NULL; | ||||
|  | ||||
| 	  if (__builtin_expect (tsearch (found, &loaded, known_compare) | ||||
| 				== NULL, 0)) | ||||
| 	    { | ||||
| 	      /* Something went wrong while inserting the entry.  */ | ||||
| 	      free (found); | ||||
| 	      found = NULL; | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|   else | ||||
|     found = *(struct __gconv_loaded_object **) keyp; | ||||
|  | ||||
|   /* Try to load the shared object if the usage count is 0.  This | ||||
|      implies that if the shared object is not loadable, the handle is | ||||
|      NULL and the usage count > 0.  */ | ||||
|   if (found != NULL) | ||||
|     { | ||||
|       if (found->counter < -TRIES_BEFORE_UNLOAD) | ||||
| 	{ | ||||
| 	  assert (found->handle == NULL); | ||||
| 	  found->handle = __libc_dlopen (found->name); | ||||
| 	  if (found->handle != NULL) | ||||
| 	    { | ||||
| 	      found->fct = __libc_dlsym (found->handle, "gconv"); | ||||
| 	      if (found->fct == NULL) | ||||
| 		{ | ||||
| 		  /* Argh, no conversion function.  There is something | ||||
|                      wrong here.  */ | ||||
| 		  __gconv_release_shlib (found); | ||||
| 		  found = NULL; | ||||
| 		} | ||||
| 	      else | ||||
| 		{ | ||||
| 		  found->init_fct = __libc_dlsym (found->handle, "gconv_init"); | ||||
| 		  found->end_fct = __libc_dlsym (found->handle, "gconv_end"); | ||||
|  | ||||
| 		  /* We have succeeded in loading the shared object.  */ | ||||
| 		  found->counter = 1; | ||||
| 		} | ||||
| 	    } | ||||
| 	  else | ||||
| 	    /* Error while loading the shared object.  */ | ||||
| 	    found = NULL; | ||||
| 	} | ||||
|       else if (found->handle != NULL) | ||||
| 	found->counter = MAX (found->counter + 1, 1); | ||||
|     } | ||||
|  | ||||
|   return found; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* This is very ugly but the tsearch functions provide no way to pass | ||||
|    information to the walker function.  So we use a global variable. | ||||
|    It is MT safe since we use a lock.  */ | ||||
| static struct __gconv_loaded_object *release_handle; | ||||
|  | ||||
| static void | ||||
| do_release_shlib (void *nodep, VISIT value, int level) | ||||
| { | ||||
|   struct __gconv_loaded_object *obj = *(struct __gconv_loaded_object **) nodep; | ||||
|  | ||||
|    | ||||
|  | ||||
|   if (value != preorder && value != leaf) | ||||
|     return; | ||||
|  | ||||
|   if (obj == release_handle) | ||||
|     { | ||||
|       /* This is the object we want to unload.  Now decrement the | ||||
| 	 reference counter.  */ | ||||
|       assert (obj->counter > 0); | ||||
|       --obj->counter; | ||||
|     } | ||||
|   else if (obj->counter <= 0 && obj->counter >= -TRIES_BEFORE_UNLOAD | ||||
| 	   && --obj->counter < -TRIES_BEFORE_UNLOAD && obj->handle != NULL) | ||||
|     { | ||||
|       /* Unload the shared object.  */ | ||||
|       __libc_dlclose (obj->handle); | ||||
|       obj->handle = NULL; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Notify system that a shared object is not longer needed.  */ | ||||
| void | ||||
| internal_function | ||||
| __gconv_release_shlib (struct __gconv_loaded_object *handle) | ||||
| { | ||||
|   /* Urgh, this is ugly but we have no other possibility.  */ | ||||
|   release_handle = handle; | ||||
|  | ||||
|   /* Process all entries.  Please note that we also visit entries | ||||
|      with release counts <= 0.  This way we can finally unload them | ||||
|      if necessary.  */ | ||||
|   twalk (loaded, (void *) do_release_shlib); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* We run this if we debug the memory allocation.  */ | ||||
| static void | ||||
| do_release_all (void *nodep) | ||||
| { | ||||
|   struct __gconv_loaded_object *obj = (struct __gconv_loaded_object *) nodep; | ||||
|  | ||||
|    | ||||
|   /* Unload the shared object.  */ | ||||
|   if (obj->handle != NULL) | ||||
|     __libc_dlclose (obj->handle); | ||||
|  | ||||
|   free (obj); | ||||
| } | ||||
|  | ||||
| static void __attribute__ ((unused)) | ||||
| free_mem (void) | ||||
| { | ||||
|   tdestroy (loaded, do_release_all); | ||||
| } | ||||
| text_set_element (__libc_subfreeres, free_mem); | ||||
|  | ||||
|  | ||||
| #ifdef DEBUG | ||||
| static void | ||||
| do_print (const void *nodep, VISIT value, int level) | ||||
| { | ||||
|   struct __gconv_loaded_object *obj = *(struct __gconv_loaded_object **) nodep; | ||||
|  | ||||
|   printf ("%10s: \"%s\", %d\n", | ||||
| 	  value == leaf ? "leaf" : | ||||
| 	  value == preorder ? "preorder" : | ||||
| 	  value == postorder ? "postorder" : "endorder", | ||||
| 	  obj->name, obj->counter); | ||||
| } | ||||
|  | ||||
| static void | ||||
| print_all (void) | ||||
| { | ||||
|   __twalk (loaded, do_print); | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										288
									
								
								newlib/libc/sys/linux/iconv/gconv_int.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										288
									
								
								newlib/libc/sys/linux/iconv/gconv_int.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,288 @@ | ||||
| /* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #ifndef _GCONV_INT_H | ||||
| #define _GCONV_INT_H	1 | ||||
|  | ||||
| #include "gconv.h" | ||||
| #include <libc-symbols.h> | ||||
|  | ||||
| __BEGIN_DECLS | ||||
|  | ||||
|  | ||||
| /* Type to represent search path.  */ | ||||
| struct path_elem | ||||
| { | ||||
|   const char *name; | ||||
|   size_t len; | ||||
| }; | ||||
|  | ||||
| /* Variable with search path for `gconv' implementation.  */ | ||||
| extern struct path_elem *__gconv_path_elem; | ||||
| /* Maximum length of a single path element.  */ | ||||
| extern size_t __gconv_max_path_elem_len; | ||||
|  | ||||
|  | ||||
| /* Structure for alias definition.  Simply two strings.  */ | ||||
| struct gconv_alias | ||||
| { | ||||
|   char *fromname; | ||||
|   char *toname; | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* How many character should be conveted in one call?  */ | ||||
| #define GCONV_NCHAR_GOAL	8160 | ||||
|  | ||||
|  | ||||
| /* Structure describing one loaded shared object.  This normally are | ||||
|    objects to perform conversation but as a special case the db shared | ||||
|    object is also handled.  */ | ||||
| struct __gconv_loaded_object | ||||
| { | ||||
|   /* Name of the object.  It must be the first structure element.  */ | ||||
|   const char *name; | ||||
|  | ||||
|   /* Reference counter for the db functionality.  If no conversion is | ||||
|      needed we unload the db library.  */ | ||||
|   int counter; | ||||
|  | ||||
|   /* The handle for the shared object.  */ | ||||
|   void *handle; | ||||
|  | ||||
|   /* Pointer to the functions the module defines.  */ | ||||
|   __gconv_fct fct; | ||||
|   __gconv_init_fct init_fct; | ||||
|   __gconv_end_fct end_fct; | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* Description for an available conversion module.  */ | ||||
| struct gconv_module | ||||
| { | ||||
|   const char *from_string; | ||||
|   const char *to_string; | ||||
|  | ||||
|   int cost_hi; | ||||
|   int cost_lo; | ||||
|  | ||||
|   const char *module_name; | ||||
|  | ||||
|   struct gconv_module *left;	/* Prefix smaller.  */ | ||||
|   struct gconv_module *same;	/* List of entries with identical prefix.  */ | ||||
|   struct gconv_module *right;	/* Prefix larger.  */ | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* Internal data structure to represent transliteration module.  */ | ||||
| struct trans_struct | ||||
| { | ||||
|   const char *name; | ||||
|   struct trans_struct *next; | ||||
|  | ||||
|   const char **csnames; | ||||
|   size_t ncsnames; | ||||
|   __gconv_trans_fct trans_fct; | ||||
|   __gconv_trans_context_fct trans_context_fct; | ||||
|   __gconv_trans_init_fct trans_init_fct; | ||||
|   __gconv_trans_end_fct trans_end_fct; | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* Flags for `gconv_open'.  */ | ||||
| enum | ||||
| { | ||||
|   GCONV_AVOID_NOCONV = 1 << 0 | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* Global variables.  */ | ||||
|  | ||||
| /* Database of alias names.  */ | ||||
| extern void *__gconv_alias_db; | ||||
|  | ||||
| /* Array with available modules.  */ | ||||
| extern size_t __gconv_nmodules; | ||||
| extern struct gconv_module *__gconv_modules_db; | ||||
|  | ||||
| /* Value of the GCONV_PATH environment variable.  */ | ||||
| extern const char *__gconv_path_envvar; | ||||
|  | ||||
|  | ||||
| /* The gconv functions expects the name to be in upper case and complete, | ||||
|    including the trailing slashes if necessary.  */ | ||||
| #define norm_add_slashes(str,suffix) \ | ||||
|   ({									      \ | ||||
|     const char *cp = (str);						      \ | ||||
|     char *result;							      \ | ||||
|     char *tmp;								      \ | ||||
|     size_t cnt = 0;							      \ | ||||
|     size_t suffix_len = (suffix) == NULL ? 0 : strlen (suffix);		      \ | ||||
| 									      \ | ||||
|     while (*cp != '\0')							      \ | ||||
|       if (*cp++ == '/')							      \ | ||||
| 	++cnt;								      \ | ||||
| 									      \ | ||||
|     tmp = result = alloca (cp - (str) + 3 + suffix_len);		      \ | ||||
|     cp = (str);								      \ | ||||
|     while (*cp != '\0')							      \ | ||||
|       *tmp++ = __toupper_l (*cp++, &_nl_C_locobj);			      \ | ||||
|     if (cnt < 2)							      \ | ||||
|       {									      \ | ||||
| 	*tmp++ = '/';							      \ | ||||
| 	if (cnt < 1)							      \ | ||||
| 	  {								      \ | ||||
| 	    *tmp++ = '/';						      \ | ||||
| 	    if (suffix != NULL)						      \ | ||||
|             {                                                                 \ | ||||
| 	      tmp = memcpy (tmp, suffix, suffix_len);		              \ | ||||
|               tmp += suffix_len;                                              \ | ||||
|             }                                                                 \ | ||||
| 	  }								      \ | ||||
|       }									      \ | ||||
|     *tmp = '\0';							      \ | ||||
|     result;								      \ | ||||
|   }) | ||||
|  | ||||
|  | ||||
| /* Return in *HANDLE decriptor for transformation from FROMSET to TOSET.  */ | ||||
| extern int __gconv_open (const char *toset, const char *fromset, | ||||
| 			 __gconv_t *handle, int flags) | ||||
|      internal_function; | ||||
|  | ||||
| /* Free resources associated with transformation descriptor CD.  */ | ||||
| extern int __gconv_close (__gconv_t cd) | ||||
|      internal_function; | ||||
|  | ||||
| /* Transform at most *INBYTESLEFT bytes from buffer starting at *INBUF | ||||
|    according to rules described by CD and place up to *OUTBYTESLEFT | ||||
|    bytes in buffer starting at *OUTBUF.  Return number of non-identical | ||||
|    conversions in *IRREVERSIBLE if this pointer is not null.  */ | ||||
| extern int __gconv (__gconv_t cd, const unsigned char **inbuf, | ||||
| 		    const unsigned char *inbufend, unsigned char **outbuf, | ||||
| 		    unsigned char *outbufend, size_t *irreversible) | ||||
|      internal_function; | ||||
|  | ||||
| /* Return in *HANDLE a pointer to an array with *NSTEPS elements describing | ||||
|    the single steps necessary for transformation from FROMSET to TOSET.  */ | ||||
| extern int __gconv_find_transform (const char *toset, const char *fromset, | ||||
| 				   struct __gconv_step **handle, | ||||
| 				   size_t *nsteps, int flags) | ||||
|      internal_function; | ||||
|  | ||||
| /* Search for transformation in cache data.  */ | ||||
| extern int __gconv_lookup_cache (const char *toset, const char *fromset, | ||||
| 				 struct __gconv_step **handle, size_t *nsteps, | ||||
| 				 int flags) | ||||
|      internal_function; | ||||
|  | ||||
| /* Compare the two name for whether they are after alias expansion the | ||||
|    same.  This function uses the cache and fails if none is | ||||
|    loaded.  */ | ||||
| extern int __gconv_compare_alias_cache (const char *name1, const char *name2, | ||||
| 					int *result) internal_function; | ||||
|  | ||||
| /* Free data associated with a step's structure.  */ | ||||
| extern void __gconv_release_step (struct __gconv_step *step) | ||||
|      internal_function; | ||||
|  | ||||
| /* Read all the configuration data and cache it.  */ | ||||
| extern void __gconv_read_conf (void); | ||||
|  | ||||
| /* Try to read module cache file.  */ | ||||
| extern int __gconv_load_cache (void) internal_function; | ||||
|  | ||||
| /* Determine the directories we are looking in.  */ | ||||
| extern void __gconv_get_path (void); | ||||
|  | ||||
| /* Comparison function to search alias.  */ | ||||
| extern int __gconv_alias_compare (const void *p1, const void *p2); | ||||
|  | ||||
| /* Clear reference to transformation step implementations which might | ||||
|    cause the code to be unloaded.  */ | ||||
| extern int __gconv_close_transform (struct __gconv_step *steps, | ||||
| 				    size_t nsteps) | ||||
|      internal_function; | ||||
|  | ||||
| /* Free all resources allocated for the transformation record when | ||||
|    using the cache.  */ | ||||
| extern void __gconv_release_cache (struct __gconv_step *steps, size_t nsteps) | ||||
|      internal_function; | ||||
|  | ||||
| /* Load shared object named by NAME.  If already loaded increment reference | ||||
|    count.  */ | ||||
| extern struct __gconv_loaded_object *__gconv_find_shlib (const char *name) | ||||
|      internal_function; | ||||
|  | ||||
| /* Release shared object.  If no further reference is available unload | ||||
|    the object.  */ | ||||
| extern void __gconv_release_shlib (struct __gconv_loaded_object *handle) | ||||
|      internal_function; | ||||
|  | ||||
| /* Fill STEP with information about builtin module with NAME.  */ | ||||
| extern void __gconv_get_builtin_trans (const char *name, | ||||
| 				       struct __gconv_step *step) | ||||
|      internal_function; | ||||
|  | ||||
| /* Try to load transliteration step module.  */ | ||||
| extern int __gconv_translit_find (struct trans_struct *trans) | ||||
|      internal_function; | ||||
|  | ||||
| /* Transliteration using the locale's data.  */ | ||||
| extern int __gconv_transliterate (struct __gconv_step *step, | ||||
| 				  struct __gconv_step_data *step_data, | ||||
| 				  void *trans_data, | ||||
| 				  __const unsigned char *inbufstart, | ||||
| 				  __const unsigned char **inbufp, | ||||
| 				  __const unsigned char *inbufend, | ||||
| 				  unsigned char **outbufstart, | ||||
| 				  size_t *irreversible); | ||||
|  | ||||
|  | ||||
| /* Builtin transformations.  */ | ||||
| #ifdef _LIBC | ||||
| # define __BUILTIN_TRANS(Name) \ | ||||
|   extern int Name (struct __gconv_step *step,				      \ | ||||
| 		   struct __gconv_step_data *data,			      \ | ||||
| 		   const unsigned char **inbuf,				      \ | ||||
| 		   const unsigned char *inbufend,			      \ | ||||
| 		   unsigned char **outbufstart, size_t *irreversible,	      \ | ||||
| 		   int do_flush, int consume_incomplete) | ||||
|  | ||||
| __BUILTIN_TRANS (__gconv_transform_ascii_internal); | ||||
| __BUILTIN_TRANS (__gconv_transform_internal_ascii); | ||||
| __BUILTIN_TRANS (__gconv_transform_utf8_internal); | ||||
| __BUILTIN_TRANS (__gconv_transform_internal_utf8); | ||||
| __BUILTIN_TRANS (__gconv_transform_ucs2_internal); | ||||
| __BUILTIN_TRANS (__gconv_transform_internal_ucs2); | ||||
| __BUILTIN_TRANS (__gconv_transform_ucs2reverse_internal); | ||||
| __BUILTIN_TRANS (__gconv_transform_internal_ucs2reverse); | ||||
| __BUILTIN_TRANS (__gconv_transform_internal_ucs4); | ||||
| __BUILTIN_TRANS (__gconv_transform_ucs4_internal); | ||||
| __BUILTIN_TRANS (__gconv_transform_internal_ucs4le); | ||||
| __BUILTIN_TRANS (__gconv_transform_ucs4le_internal); | ||||
| __BUILTIN_TRANS (__gconv_transform_internal_utf16); | ||||
| __BUILTIN_TRANS (__gconv_transform_utf16_internal); | ||||
| # undef __BUITLIN_TRANS | ||||
|  | ||||
| #endif | ||||
|  | ||||
| __END_DECLS | ||||
|  | ||||
| #endif /* gconv_int.h */ | ||||
							
								
								
									
										326
									
								
								newlib/libc/sys/linux/iconv/gconv_open.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										326
									
								
								newlib/libc/sys/linux/iconv/gconv_open.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,326 @@ | ||||
| /* Find matching transformation algorithms and initialize steps. | ||||
|    Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <locale.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include <gconv_int.h> | ||||
|  | ||||
| int | ||||
| internal_function | ||||
| __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, | ||||
| 	      int flags) | ||||
| { | ||||
|   struct __gconv_step *steps; | ||||
|   size_t nsteps; | ||||
|   __gconv_t result = NULL; | ||||
|   size_t cnt = 0; | ||||
|   int res; | ||||
|   int conv_flags = 0; | ||||
|   const char *errhand; | ||||
|   const char *ignore; | ||||
|   struct trans_struct *trans = NULL; | ||||
|   char old_locale[20], *old_locale_p; | ||||
|   char *old, *new; | ||||
|   size_t len; | ||||
|  | ||||
|   /* Find out whether any error handling method is specified.  */ | ||||
|   errhand = strchr (toset, '/'); | ||||
|   if (errhand != NULL) | ||||
|     errhand = strchr (errhand + 1, '/'); | ||||
|   if (__builtin_expect (errhand != NULL, 1)) | ||||
|     { | ||||
|       if (*++errhand == '\0') | ||||
| 	errhand = NULL; | ||||
|       else | ||||
| 	{ | ||||
| 	  /* Make copy without the error handling description.  */ | ||||
| 	  char *newtoset = (char *) alloca (errhand - toset + 1); | ||||
| 	  char *tok; | ||||
| 	  char *ptr; | ||||
|  | ||||
| 	  newtoset[errhand - toset] = '\0'; | ||||
| 	  toset = memcpy (newtoset, toset, errhand - toset); | ||||
|  | ||||
| 	  /* Find the appropriate transliteration handlers.  */ | ||||
|           old = (char *)(errhand); | ||||
|           len = strlen (old) + 1; | ||||
|           new = (char *) alloca (len); | ||||
|           tok = (char *) memcpy (new, old, len); | ||||
|  | ||||
| 	  tok = strtok_r (tok, ",", &ptr); | ||||
|  | ||||
|           /* Set locale to default C locale. */ | ||||
|           old_locale_p = setlocale(LC_ALL, "C"); | ||||
|           strncpy(old_locale, old_locale_p, 20); | ||||
|  | ||||
| 	  while (tok != NULL) | ||||
| 	    { | ||||
| 	      if (strcasecmp (tok, "TRANSLIT") == 0) | ||||
| 		{ | ||||
| 		  /* It's the builtin transliteration handling.  We only | ||||
| 		     support it for working on the internal encoding.  */ | ||||
| 		  static const char *internal_trans_names[1] = { "INTERNAL" }; | ||||
| 		  struct trans_struct *lastp = NULL; | ||||
| 		  struct trans_struct *runp; | ||||
|  | ||||
| 		  for (runp = trans; runp != NULL; runp = runp->next) | ||||
| 		    if (runp->trans_fct == __gconv_transliterate) | ||||
| 		      break; | ||||
| 		    else | ||||
| 		      lastp = runp; | ||||
|  | ||||
| 		  if (runp == NULL) | ||||
| 		    { | ||||
| 		      struct trans_struct *newp; | ||||
|  | ||||
| 		      newp = (struct trans_struct *) alloca (sizeof (*newp)); | ||||
| 		      memset (newp, '\0', sizeof (*newp)); | ||||
|  | ||||
| 		      /* We leave the `name' field zero to signal that | ||||
| 			 this is an internal transliteration step.  */ | ||||
| 		      newp->csnames = internal_trans_names; | ||||
| 		      newp->ncsnames = 1; | ||||
| 		      newp->trans_fct = __gconv_transliterate; | ||||
|  | ||||
| 		      if (lastp == NULL) | ||||
| 			trans = newp; | ||||
| 		      else | ||||
| 			lastp->next = newp; | ||||
| 		    } | ||||
| 		} | ||||
| 	      else if (strcasecmp (tok, "IGNORE") == 0) | ||||
| 		/* Set the flag to ignore all errors.  */ | ||||
| 		conv_flags |= __GCONV_IGNORE_ERRORS; | ||||
| 	      else | ||||
| 		{ | ||||
| 		  /* `tok' is possibly a module name.  We'll see later | ||||
| 		     whether we can find it.  But first see that we do | ||||
| 		     not already a module of this name.  */ | ||||
| 		  struct trans_struct *lastp = NULL; | ||||
| 		  struct trans_struct *runp; | ||||
|  | ||||
| 		  for (runp = trans; runp != NULL; runp = runp->next) | ||||
| 		    if (runp->name != NULL | ||||
| 			&& strcasecmp (tok, runp->name) == 0) | ||||
| 		      break; | ||||
| 		    else | ||||
| 		      lastp = runp; | ||||
|  | ||||
| 		  if (runp == NULL) | ||||
| 		    { | ||||
| 		      struct trans_struct *newp; | ||||
|  | ||||
| 		      newp = (struct trans_struct *) alloca (sizeof (*newp)); | ||||
| 		      memset (newp, '\0', sizeof (*newp)); | ||||
| 		      newp->name = tok; | ||||
|  | ||||
| 		      if (lastp == NULL) | ||||
| 			trans = newp; | ||||
| 		      else | ||||
| 			lastp->next = newp; | ||||
| 		    } | ||||
| 		} | ||||
|  | ||||
| 	      tok = strtok_r (NULL, ",", &ptr); | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   /* For the source character set we ignore the error handler specification. | ||||
|      XXX Is this really always the best?  */ | ||||
|   ignore = strchr (fromset, '/'); | ||||
|   if (ignore != NULL && (ignore = strchr (ignore + 1, '/')) != NULL | ||||
|       && *++ignore != '\0') | ||||
|     { | ||||
|       char *newfromset = (char *) alloca (ignore - fromset + 1); | ||||
|  | ||||
|       newfromset[ignore - fromset] = '\0'; | ||||
|       fromset = memcpy (newfromset, fromset, ignore - fromset); | ||||
|     } | ||||
|  | ||||
|   res = __gconv_find_transform (toset, fromset, &steps, &nsteps, flags); | ||||
|   if (res == __GCONV_OK) | ||||
|     { | ||||
|       /* Find the modules.  */ | ||||
|       struct trans_struct *lastp = NULL; | ||||
|       struct trans_struct *runp; | ||||
|  | ||||
|       for (runp = trans; runp != NULL; runp = runp->next) | ||||
| 	{ | ||||
| 	  if (runp->name == NULL | ||||
| 	      || __builtin_expect (__gconv_translit_find (runp), 0) == 0) | ||||
| 	    lastp = runp; | ||||
| 	  else | ||||
| 	    /* This means we haven't found the module.  Remove it.  */ | ||||
| 	    (lastp == NULL ? trans : lastp->next) = runp->next; | ||||
| 	} | ||||
|  | ||||
|       /* Allocate room for handle.  */ | ||||
|       result = (__gconv_t) malloc (sizeof (struct __gconv_info) | ||||
| 				   + (nsteps | ||||
| 				      * sizeof (struct __gconv_step_data))); | ||||
|       if (result == NULL) | ||||
| 	res = __GCONV_NOMEM; | ||||
|       else | ||||
| 	{ | ||||
| 	  size_t n; | ||||
|  | ||||
| 	  /* Remember the list of steps.  */ | ||||
| 	  result->__steps = steps; | ||||
| 	  result->__nsteps = nsteps; | ||||
|  | ||||
| 	  /* Clear the array for the step data.  */ | ||||
| 	  memset (result->__data, '\0', | ||||
| 		  nsteps * sizeof (struct __gconv_step_data)); | ||||
|  | ||||
| 	  /* Call all initialization functions for the transformation | ||||
| 	     step implementations.  */ | ||||
| 	  for (cnt = 0; cnt < nsteps; ++cnt) | ||||
| 	    { | ||||
| 	      size_t size; | ||||
|  | ||||
| 	      /* Would have to be done if we would not clear the whole | ||||
|                  array above.  */ | ||||
| #if 0 | ||||
| 	      /* Reset the counter.  */ | ||||
| 	      result->__data[cnt].__invocation_counter = 0; | ||||
|  | ||||
| 	      /* It's a regular use.  */ | ||||
| 	      result->__data[cnt].__internal_use = 0; | ||||
| #endif | ||||
|  | ||||
| 	      /* We use the `mbstate_t' member in DATA.  */ | ||||
| 	      result->__data[cnt].__statep = &result->__data[cnt].__state; | ||||
|  | ||||
| 	      /* Now see whether we can use any of the transliteration | ||||
| 		 modules for this step.  */ | ||||
| 	      for (runp = trans; runp != NULL; runp = runp->next) | ||||
| 		for (n = 0; n < runp->ncsnames; ++n) | ||||
| 		  if (strcasecmp (steps[cnt].__from_name, runp->csnames[n]) == 0) | ||||
| 		    { | ||||
| 		      void *data = NULL; | ||||
|  | ||||
| 		      /* Match!  Now try the initializer.  */ | ||||
| 		      if (runp->trans_init_fct == NULL | ||||
| 			  || (runp->trans_init_fct (&data, | ||||
| 						    steps[cnt].__to_name) | ||||
| 			      == __GCONV_OK)) | ||||
| 			{ | ||||
| 			  /* Append at the end of the list.  */ | ||||
| 			  struct __gconv_trans_data *newp; | ||||
| 			  struct __gconv_trans_data **lastp; | ||||
|  | ||||
| 			  newp = (struct __gconv_trans_data *) | ||||
| 			    malloc (sizeof (struct __gconv_trans_data)); | ||||
| 			  if (newp == NULL) | ||||
| 			    { | ||||
| 			      res = __GCONV_NOMEM; | ||||
| 			      goto bail; | ||||
| 			    } | ||||
|  | ||||
| 			  newp->__trans_fct = runp->trans_fct; | ||||
| 			  newp->__trans_context_fct = runp->trans_context_fct; | ||||
| 			  newp->__trans_end_fct = runp->trans_end_fct; | ||||
| 			  newp->__data = data; | ||||
| 			  newp->__next = NULL; | ||||
|  | ||||
| 			  lastp = &result->__data[cnt].__trans; | ||||
| 			  while (*lastp != NULL) | ||||
| 			    lastp = &(*lastp)->__next; | ||||
|  | ||||
| 			  *lastp = newp; | ||||
| 			} | ||||
| 		      break; | ||||
| 		    } | ||||
|  | ||||
| 	      /* If this is the last step we must not allocate an | ||||
| 		 output buffer.  */ | ||||
| 	      if (cnt < nsteps - 1) | ||||
| 		{ | ||||
| 		  result->__data[cnt].__flags = conv_flags; | ||||
|  | ||||
| 		  /* Allocate the buffer.  */ | ||||
| 		  size = (GCONV_NCHAR_GOAL * steps[cnt].__max_needed_to); | ||||
|  | ||||
| 		  result->__data[cnt].__outbuf = (char *) malloc (size); | ||||
| 		  if (result->__data[cnt].__outbuf == NULL) | ||||
| 		    { | ||||
| 		      res = __GCONV_NOMEM; | ||||
| 		      goto bail; | ||||
| 		    } | ||||
|  | ||||
| 		  result->__data[cnt].__outbufend = | ||||
| 		    result->__data[cnt].__outbuf + size; | ||||
| 		} | ||||
| 	      else | ||||
| 		{ | ||||
| 		  /* Handle the last entry.  */ | ||||
| 		  result->__data[cnt].__flags = conv_flags | __GCONV_IS_LAST; | ||||
|  | ||||
| 		  break; | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
|  | ||||
|       if (res != __GCONV_OK) | ||||
| 	{ | ||||
| 	  /* Something went wrong.  Free all the resources.  */ | ||||
| 	  int serrno; | ||||
| 	bail: | ||||
| 	  serrno = errno; | ||||
|  | ||||
| 	  if (result != NULL) | ||||
| 	    { | ||||
| 	      while (cnt-- > 0) | ||||
| 		{ | ||||
| 		  struct __gconv_trans_data *transp; | ||||
|  | ||||
| 		  transp = result->__data[cnt].__trans; | ||||
| 		  while (transp != NULL) | ||||
| 		    { | ||||
| 		      struct __gconv_trans_data *curp = transp; | ||||
| 		      transp = transp->__next; | ||||
|  | ||||
| 		      if (__builtin_expect (curp->__trans_end_fct != NULL, 0)) | ||||
| 			curp->__trans_end_fct (curp->__data); | ||||
|  | ||||
| 		      free (curp); | ||||
| 		    } | ||||
|  | ||||
| 		  free (result->__data[cnt].__outbuf); | ||||
| 		} | ||||
|  | ||||
| 	      free (result); | ||||
| 	      result = NULL; | ||||
| 	    } | ||||
|  | ||||
| 	  __gconv_close_transform (steps, nsteps); | ||||
|  | ||||
| 	  __set_errno (serrno); | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   *handle = result; | ||||
|   setlocale(LC_ALL, old_locale); | ||||
|   return res; | ||||
| } | ||||
							
								
								
									
										1327
									
								
								newlib/libc/sys/linux/iconv/gconv_simple.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1327
									
								
								newlib/libc/sys/linux/iconv/gconv_simple.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										230
									
								
								newlib/libc/sys/linux/iconv/gconv_trans.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								newlib/libc/sys/linux/iconv/gconv_trans.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,230 @@ | ||||
| /* Transliteration using the locale's data. | ||||
|    Copyright (C) 2000 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 2000. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <dlfcn.h> | ||||
| #include <search.h> | ||||
| #include <stdint.h> | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| #include <dirent.h> | ||||
| #include <ltdl.h> | ||||
|  | ||||
| #include "gconv_int.h" | ||||
| #include "localeinfo.h" | ||||
|  | ||||
| int | ||||
| __gconv_transliterate (struct __gconv_step *step, | ||||
| 		       struct __gconv_step_data *step_data, | ||||
| 		       void *trans_data __attribute__ ((unused)), | ||||
| 		       const unsigned char *inbufstart, | ||||
| 		       const unsigned char **inbufp, | ||||
| 		       const unsigned char *inbufend, | ||||
| 		       unsigned char **outbufstart, size_t *irreversible) | ||||
| { | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Structure to represent results of found (or not) transliteration | ||||
|    modules.  */ | ||||
| struct known_trans | ||||
| { | ||||
|   /* This structure must remain the first member.  */ | ||||
|   struct trans_struct info; | ||||
|  | ||||
|   char *fname; | ||||
|   void *handle; | ||||
|   int open_count; | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* Tree with results of previous calls to __gconv_translit_find.  */ | ||||
| static void *search_tree; | ||||
|  | ||||
| /* We modify global data.   */ | ||||
| __LOCK_INIT(static, lock); | ||||
|  | ||||
| /* Compare two transliteration entries.  */ | ||||
| static int | ||||
| trans_compare (const void *p1, const void *p2) | ||||
| { | ||||
|   const struct known_trans *s1 = (const struct known_trans *) p1; | ||||
|   const struct known_trans *s2 = (const struct known_trans *) p2; | ||||
|  | ||||
|   return strcmp (s1->info.name, s2->info.name); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Open (maybe reopen) the module named in the struct.  Get the function | ||||
|    and data structure pointers we need.  */ | ||||
| static int | ||||
| open_translit (struct known_trans *trans) | ||||
| { | ||||
|   __gconv_trans_query_fct queryfct; | ||||
|  | ||||
|   trans->handle = __libc_dlopen (trans->fname); | ||||
|   if (trans->handle == NULL) | ||||
|     /* Not available.  */ | ||||
|     return 1; | ||||
|  | ||||
|   /* Find the required symbol.  */ | ||||
|   queryfct = __libc_dlsym (trans->handle, "gconv_trans_context"); | ||||
|   if (queryfct == NULL) | ||||
|     { | ||||
|       /* We cannot live with that.  */ | ||||
|     close_and_out: | ||||
|       __libc_dlclose (trans->handle); | ||||
|       trans->handle = NULL; | ||||
|       return 1; | ||||
|     } | ||||
|  | ||||
|   /* Get the context.  */ | ||||
|   if (queryfct (trans->info.name, &trans->info.csnames, &trans->info.ncsnames) | ||||
|       != 0) | ||||
|     goto close_and_out; | ||||
|  | ||||
|   /* Of course we also have to have the actual function.  */ | ||||
|   trans->info.trans_fct = __libc_dlsym (trans->handle, "gconv_trans"); | ||||
|   if (trans->info.trans_fct == NULL) | ||||
|     goto close_and_out; | ||||
|  | ||||
|   /* Now the optional functions.  */ | ||||
|   trans->info.trans_init_fct = | ||||
|     __libc_dlsym (trans->handle, "gconv_trans_init"); | ||||
|   trans->info.trans_context_fct = | ||||
|     __libc_dlsym (trans->handle, "gconv_trans_context"); | ||||
|   trans->info.trans_end_fct = | ||||
|     __libc_dlsym (trans->handle, "gconv_trans_end"); | ||||
|  | ||||
|   trans->open_count = 1; | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| int | ||||
| internal_function | ||||
| __gconv_translit_find (struct trans_struct *trans) | ||||
| { | ||||
|   struct known_trans **found; | ||||
|   const struct path_elem *runp; | ||||
|   int res = 1; | ||||
|  | ||||
|   /* We have to have a name.  */ | ||||
|   assert (trans->name != NULL); | ||||
|  | ||||
|   /* Acquire the lock.  */ | ||||
| #ifdef HAVE_DD_LOCK | ||||
|   __lock_acquire(lock); | ||||
| #endif | ||||
|  | ||||
|   /* See whether we know this module already.  */ | ||||
|   found = tfind (trans, &search_tree, trans_compare); | ||||
|   if (found != NULL) | ||||
|     { | ||||
|       /* Is this module available?  */ | ||||
|       if ((*found)->handle != NULL) | ||||
| 	{ | ||||
| 	  /* Maybe we have to reopen the file.  */ | ||||
| 	  if ((*found)->handle != (void *) -1) | ||||
| 	    /* The object is not unloaded.  */ | ||||
| 	    res = 0; | ||||
| 	  else if (open_translit (*found) == 0) | ||||
| 	    { | ||||
| 	      /* Copy the data.  */ | ||||
| 	      *trans = (*found)->info; | ||||
| 	      (*found)->open_count++; | ||||
| 	      res = 0; | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       size_t name_len = strlen (trans->name) + 1; | ||||
|       int need_so = 0; | ||||
|       struct known_trans *newp; | ||||
|  | ||||
|       /* We have to continue looking for the module.  */ | ||||
|       if (__gconv_path_elem == NULL) | ||||
| 	__gconv_get_path (); | ||||
|  | ||||
|       /* See whether we have to append .so.  */ | ||||
|       if (name_len <= 4 || memcmp (&trans->name[name_len - 4], ".so", 3) != 0) | ||||
| 	need_so = 1; | ||||
|  | ||||
|       /* Create a new entry.  */ | ||||
|       newp = (struct known_trans *) malloc (sizeof (struct known_trans) | ||||
| 					    + (__gconv_max_path_elem_len | ||||
| 					       + name_len + 3) | ||||
| 					    + name_len); | ||||
|       if (newp != NULL) | ||||
| 	{ | ||||
| 	  char *cp; | ||||
|  | ||||
| 	  /* Clear the struct.  */ | ||||
| 	  memset (newp, '\0', sizeof (struct known_trans)); | ||||
|  | ||||
| 	  /* Store a copy of the module name.  */ | ||||
| 	  newp->info.name = cp = (char *) (newp + 1); | ||||
| 	  cp = memcpy (cp, trans->name, name_len); | ||||
|           cp += name_len; | ||||
|  | ||||
| 	  newp->fname = cp; | ||||
|  | ||||
| 	  /* Search in all the directories.  */ | ||||
| 	  for (runp = __gconv_path_elem; runp->name != NULL; ++runp) | ||||
| 	    { | ||||
|               strcpy ((char *) newp->fname, runp->name); | ||||
|               while(newp->fname != '\0') newp->fname++; | ||||
|  | ||||
| 	      cp = memcpy (newp->fname, | ||||
|                             trans->name, name_len); | ||||
|               cp += name_len; | ||||
| 	      if (need_so) | ||||
| 		memcpy (cp, ".so", sizeof (".so")); | ||||
|  | ||||
| 	      if (open_translit (newp) == 0) | ||||
| 		{ | ||||
| 		  /* We found a module.  */ | ||||
| 		  res = 0; | ||||
| 		  break; | ||||
| 		} | ||||
| 	    } | ||||
|  | ||||
| 	  if (res) | ||||
| 	    newp->fname = NULL; | ||||
|  | ||||
| 	  /* In any case we'll add the entry to our search tree.  */ | ||||
| 	  if (tsearch (newp, &search_tree, trans_compare) == NULL) | ||||
| 	    { | ||||
| 	      /* Yickes, this should not happen.  Unload the object.  */ | ||||
| 	      res = 1; | ||||
| 	      /* XXX unload here.  */ | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|  | ||||
| #ifdef HAVE_DD_LOCK | ||||
|   __lock_release(lock); | ||||
| #endif | ||||
|  | ||||
|   return res; | ||||
| } | ||||
							
								
								
									
										60
									
								
								newlib/libc/sys/linux/iconv/hash-string.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								newlib/libc/sys/linux/iconv/hash-string.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| /* Implements a string hashing function. | ||||
|    Copyright (C) 1995, 1997, 1998, 2000 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| /* @@ end of prolog @@ */ | ||||
|  | ||||
| #ifndef PARAMS | ||||
| # if __STDC__ | ||||
| #  define PARAMS(Args) Args | ||||
| # else | ||||
| #  define PARAMS(Args) () | ||||
| # endif | ||||
| #endif | ||||
|  | ||||
| /* We assume to have `unsigned long int' value with at least 32 bits.  */ | ||||
| #define HASHWORDBITS 32 | ||||
|  | ||||
|  | ||||
| /* Defines the so called `hashpjw' function by P.J. Weinberger | ||||
|    [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, | ||||
|    1986, 1987 Bell Telephone Laboratories, Inc.]  */ | ||||
| static unsigned long int hash_string PARAMS ((const char *__str_param)); | ||||
|  | ||||
| static inline unsigned long int | ||||
| hash_string (str_param) | ||||
|      const char *str_param; | ||||
| { | ||||
|   unsigned long int hval, g; | ||||
|   const char *str = str_param; | ||||
|  | ||||
|   /* Compute the hash value for the given string.  */ | ||||
|   hval = 0; | ||||
|   while (*str != '\0') | ||||
|     { | ||||
|       hval <<= 4; | ||||
|       hval += (unsigned long int) *str++; | ||||
|       g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4)); | ||||
|       if (g != 0) | ||||
| 	{ | ||||
| 	  hval ^= g >> (HASHWORDBITS - 8); | ||||
| 	  hval ^= g; | ||||
| 	} | ||||
|     } | ||||
|   return hval; | ||||
| } | ||||
							
								
								
									
										96
									
								
								newlib/libc/sys/linux/iconv/iconv.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								newlib/libc/sys/linux/iconv/iconv.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| /* Convert characters in input buffer using conversion descriptor to | ||||
|    output buffer. | ||||
|    Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <stddef.h> /* for NULL */ | ||||
| #include <errno.h> | ||||
| #include <iconv.h> | ||||
|  | ||||
| #include <gconv_int.h> | ||||
|  | ||||
| #include <assert.h> | ||||
|  | ||||
|  | ||||
| size_t | ||||
| iconv (iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, | ||||
|        size_t *outbytesleft) | ||||
| { | ||||
|   __gconv_t gcd = (__gconv_t) cd; | ||||
|   char *outstart = outbuf ? *outbuf : NULL; | ||||
|   size_t irreversible; | ||||
|   int result; | ||||
|  | ||||
|   if (__builtin_expect (inbuf == NULL || *inbuf == NULL, 0)) | ||||
|     { | ||||
|       if (outbuf == NULL || *outbuf == NULL) | ||||
| 	result = __gconv (gcd, NULL, NULL, NULL, NULL, &irreversible); | ||||
|       else | ||||
| 	result = __gconv (gcd, NULL, NULL, (unsigned char **) outbuf, | ||||
| 			  (unsigned char *) (outstart + *outbytesleft), | ||||
| 			  &irreversible); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       const char *instart = *inbuf; | ||||
|  | ||||
|       result = __gconv (gcd, (const unsigned char **) inbuf, | ||||
| 			(const unsigned char *)  (*inbuf + *inbytesleft), | ||||
| 			(unsigned char **) outbuf, | ||||
| 			(unsigned char *) (*outbuf + *outbytesleft), | ||||
| 			&irreversible); | ||||
|  | ||||
|       *inbytesleft -= *inbuf - instart; | ||||
|     } | ||||
|   if (outstart != NULL) | ||||
|     *outbytesleft -= *outbuf - outstart; | ||||
|  | ||||
|   switch (__builtin_expect (result, __GCONV_OK)) | ||||
|     { | ||||
|     case __GCONV_ILLEGAL_DESCRIPTOR: | ||||
|       __set_errno (EBADF); | ||||
|       irreversible = (size_t) -1L; | ||||
|       break; | ||||
|  | ||||
|     case __GCONV_ILLEGAL_INPUT: | ||||
|       __set_errno (EILSEQ); | ||||
|       irreversible = (size_t) -1L; | ||||
|       break; | ||||
|  | ||||
|     case __GCONV_FULL_OUTPUT: | ||||
|       __set_errno (E2BIG); | ||||
|       irreversible = (size_t) -1L; | ||||
|       break; | ||||
|  | ||||
|     case __GCONV_INCOMPLETE_INPUT: | ||||
|       __set_errno (EINVAL); | ||||
|       irreversible = (size_t) -1L; | ||||
|       break; | ||||
|  | ||||
|     case __GCONV_EMPTY_INPUT: | ||||
|     case __GCONV_OK: | ||||
|       /* Nothing.  */ | ||||
|       break; | ||||
|  | ||||
|     default: | ||||
|       assert (!"Nothing like this should happen"); | ||||
|     } | ||||
|  | ||||
|   return irreversible; | ||||
| } | ||||
							
								
								
									
										51
									
								
								newlib/libc/sys/linux/iconv/iconv.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								newlib/libc/sys/linux/iconv/iconv.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| /* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #ifndef _ICONV_H | ||||
| #define _ICONV_H	1 | ||||
|  | ||||
| #include <features.h> | ||||
| #define __need_size_t | ||||
| #include <stddef.h> | ||||
|  | ||||
|  | ||||
| __BEGIN_DECLS | ||||
|  | ||||
| /* Identifier for conversion method from one codeset to another.  */ | ||||
| typedef void *iconv_t; | ||||
|  | ||||
|  | ||||
| /* Allocate descriptor for code conversion from codeset FROMCODE to | ||||
|    codeset TOCODE.  */ | ||||
| extern iconv_t iconv_open (__const char *__tocode, __const char *__fromcode) | ||||
|      __THROW; | ||||
|  | ||||
| /* Convert at most *INBYTESLEFT bytes from *INBUF according to the | ||||
|    code conversion algorithm specified by CD and place up to | ||||
|    *OUTBYTESLEFT bytes in buffer at *OUTBUF.  */ | ||||
| extern size_t iconv (iconv_t __cd, char **__restrict __inbuf, | ||||
| 		     size_t *__restrict __inbytesleft, | ||||
| 		     char **__restrict __outbuf, | ||||
| 		     size_t *__restrict __outbytesleft); | ||||
|  | ||||
| /* Free resources allocated for descriptor CD for code conversion.  */ | ||||
| extern int iconv_close (iconv_t __cd) __THROW; | ||||
|  | ||||
| __END_DECLS | ||||
|  | ||||
| #endif /* iconv.h */ | ||||
							
								
								
									
										563
									
								
								newlib/libc/sys/linux/iconv/iconv_charmap.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										563
									
								
								newlib/libc/sys/linux/iconv/iconv_charmap.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,563 @@ | ||||
| /* Convert using charmaps and possibly iconv(). | ||||
|    Copyright (C) 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@redhat.com>, 2001. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <errno.h> | ||||
| #include <error.h> | ||||
| #include <fcntl.h> | ||||
| #include <iconv.h> | ||||
| #include <libintl.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/mman.h> | ||||
| #include <sys/stat.h> | ||||
|  | ||||
| #include "iconv_prog.h" | ||||
|  | ||||
|  | ||||
| /* Prototypes for a few program-wide used functions.  */ | ||||
| extern void *xmalloc (size_t __n); | ||||
| extern void *xcalloc (size_t __n, size_t __s); | ||||
|  | ||||
|  | ||||
| struct convtable | ||||
| { | ||||
|   int term[256 / 8]; | ||||
|   union | ||||
|   { | ||||
|     struct convtable *sub; | ||||
|     struct charseq *out; | ||||
|   } val[256]; | ||||
| }; | ||||
|  | ||||
|  | ||||
| static inline struct convtable * | ||||
| allocate_table (void) | ||||
| { | ||||
|   return (struct convtable *) xcalloc (1, sizeof (struct convtable)); | ||||
| } | ||||
|  | ||||
|  | ||||
| static inline int | ||||
| is_term (struct convtable *tbl, unsigned int idx) | ||||
| { | ||||
|   return tbl->term[idx / 8] & (1 << (idx % 8)); | ||||
| } | ||||
|  | ||||
|  | ||||
| static inline void | ||||
| clear_term (struct convtable *tbl, unsigned int idx) | ||||
| { | ||||
|   tbl->term[idx / 8] &= ~(1 << (idx % 8)); | ||||
| } | ||||
|  | ||||
|  | ||||
| static inline void | ||||
| set_term (struct convtable *tbl, unsigned int idx) | ||||
| { | ||||
|   tbl->term[idx / 8] |= 1 << (idx % 8); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Generate the conversion table.  */ | ||||
| static struct convtable *use_from_charmap (struct charmap_t *from_charmap, | ||||
| 					   const char *to_code); | ||||
| static struct convtable *use_to_charmap (const char *from_code, | ||||
| 					 struct charmap_t *to_charmap); | ||||
| static struct convtable *use_both_charmaps (struct charmap_t *from_charmap, | ||||
| 					    struct charmap_t *to_charmap); | ||||
|  | ||||
| /* Prototypes for the functions doing the actual work.  */ | ||||
| static int process_block (struct convtable *tbl, char *addr, size_t len, | ||||
| 			  FILE *output); | ||||
| static int process_fd (struct convtable *tbl, int fd, FILE *output); | ||||
| static int process_file (struct convtable *tbl, FILE *input, FILE *output); | ||||
|  | ||||
|  | ||||
| int | ||||
| charmap_conversion (const char *from_code, struct charmap_t *from_charmap, | ||||
| 		    const char *to_code, struct charmap_t *to_charmap, | ||||
| 		    int argc, int remaining, char *argv[], FILE *output) | ||||
| { | ||||
|   struct convtable *cvtbl; | ||||
|   int status = EXIT_SUCCESS; | ||||
|  | ||||
|   /* We have three different cases to handle: | ||||
|  | ||||
|      - both, from_charmap and to_charmap, are available.  This means we | ||||
|        can assume that the symbolic names match and use them to create | ||||
|        the mapping. | ||||
|  | ||||
|      - only from_charmap is available.  In this case we can only hope that | ||||
|        the symbolic names used are of the <Uxxxx> form in which case we | ||||
|        can use a UCS4->"to_code" iconv() conversion for the second step. | ||||
|  | ||||
|      - only to_charmap is available.  This is similar, only that we would | ||||
|        use iconv() for the "to_code"->UCS4 conversion. | ||||
|  | ||||
|        We first create a table which maps input bytes into output bytes. | ||||
|        Once this is done we can handle all three of the cases above | ||||
|        equally.  */ | ||||
|   if (from_charmap != NULL) | ||||
|     { | ||||
|       if (to_charmap == NULL) | ||||
| 	cvtbl = use_from_charmap (from_charmap, to_code); | ||||
|       else | ||||
| 	cvtbl = use_both_charmaps (from_charmap, to_charmap); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       assert (to_charmap != NULL); | ||||
|       cvtbl = use_to_charmap (from_code, to_charmap); | ||||
|     } | ||||
|  | ||||
|   /* If we couldn't generate a table stop now.  */ | ||||
|   if (cvtbl == NULL) | ||||
|     return EXIT_FAILURE; | ||||
|  | ||||
|   /* We can now start the conversion.  */ | ||||
|   if (remaining == argc) | ||||
|     { | ||||
|       if (process_file (cvtbl, stdin, output) != 0) | ||||
| 	status = EXIT_FAILURE; | ||||
|     } | ||||
|   else | ||||
|     do | ||||
|       { | ||||
| 	struct stat st; | ||||
| 	char *addr; | ||||
| 	int fd; | ||||
|  | ||||
| 	if (verbose) | ||||
| 	  printf ("%s:\n", argv[remaining]); | ||||
| 	if (strcmp (argv[remaining], "-") == 0) | ||||
| 	  fd = 0; | ||||
| 	else | ||||
| 	  { | ||||
| 	    fd = open (argv[remaining], O_RDONLY); | ||||
|  | ||||
| 	    if (fd == -1) | ||||
| 	      { | ||||
| 		error (0, errno, _("cannot open input file `%s'"), | ||||
| 		       argv[remaining]); | ||||
| 		status = EXIT_FAILURE; | ||||
| 		continue; | ||||
| 	      } | ||||
| 	  } | ||||
|  | ||||
| #ifdef _POSIX_MAPPED_FILES | ||||
| 	/* We have possibilities for reading the input file.  First try | ||||
| 	   to mmap() it since this will provide the fastest solution.  */ | ||||
| 	if (fstat (fd, &st) == 0 | ||||
| 	    && ((addr = mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE, | ||||
| 			      fd, 0)) != MAP_FAILED)) | ||||
| 	  { | ||||
| 	    /* Yes, we can use mmap().  The descriptor is not needed | ||||
| 	       anymore.  */ | ||||
| 	    if (close (fd) != 0) | ||||
| 	      error (EXIT_FAILURE, errno, | ||||
| 		     _("error while closing input `%s'"), argv[remaining]); | ||||
|  | ||||
| 	    if (process_block (cvtbl, addr, st.st_size, output) < 0) | ||||
| 	      { | ||||
| 		/* Something went wrong.  */ | ||||
| 		status = EXIT_FAILURE; | ||||
|  | ||||
| 		/* We don't need the input data anymore.  */ | ||||
| 		munmap ((void *) addr, st.st_size); | ||||
|  | ||||
| 		/* We cannot go on with producing output since it might | ||||
| 		   lead to problem because the last output might leave | ||||
| 		   the output stream in an undefined state.  */ | ||||
| 		break; | ||||
| 	      } | ||||
|  | ||||
| 	    /* We don't need the input data anymore.  */ | ||||
| 	    munmap ((void *) addr, st.st_size); | ||||
| 	  } | ||||
| 	else | ||||
| #endif	/* _POSIX_MAPPED_FILES */ | ||||
| 	  { | ||||
| 	    /* Read the file in pieces.  */ | ||||
| 	    if (process_fd (cvtbl, fd, output) != 0) | ||||
| 	      { | ||||
| 		/* Something went wrong.  */ | ||||
| 		status = EXIT_FAILURE; | ||||
|  | ||||
| 		/* We don't need the input file anymore.  */ | ||||
| 		close (fd); | ||||
|  | ||||
| 		/* We cannot go on with producing output since it might | ||||
| 		   lead to problem because the last output might leave | ||||
| 		   the output stream in an undefined state.  */ | ||||
| 		break; | ||||
| 	      } | ||||
|  | ||||
| 	    /* Now close the file.  */ | ||||
| 	    close (fd); | ||||
| 	  } | ||||
|       } | ||||
|     while (++remaining < argc); | ||||
|  | ||||
|   /* All done.  */ | ||||
|   return status; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void | ||||
| add_bytes (struct convtable *tbl, struct charseq *in, struct charseq *out) | ||||
| { | ||||
|   int n = 0; | ||||
|   unsigned int byte; | ||||
|  | ||||
|   assert (in->nbytes > 0); | ||||
|  | ||||
|   byte = ((unsigned char *) in->bytes)[n]; | ||||
|   while (n + 1 < in->nbytes) | ||||
|     { | ||||
|       if (is_term (tbl, byte) || tbl->val[byte].sub == NULL) | ||||
| 	{ | ||||
| 	  /* Note that we simply ignore a definition for a byte sequence | ||||
| 	     which is also the prefix for a longer one.  */ | ||||
| 	  clear_term (tbl, byte); | ||||
| 	  tbl->val[byte].sub = | ||||
| 	    (struct convtable *) xcalloc (1, sizeof (struct convtable)); | ||||
| 	} | ||||
|  | ||||
|       tbl = tbl->val[byte].sub; | ||||
|  | ||||
|       byte = ((unsigned char *) in->bytes)[++n]; | ||||
|     } | ||||
|  | ||||
|   /* Only add the new sequence if there is none yet and the byte sequence | ||||
|      is not part of an even longer one.  */ | ||||
|   if (! is_term (tbl, byte) && tbl->val[byte].sub == NULL) | ||||
|     { | ||||
|       set_term (tbl, byte); | ||||
|       tbl->val[byte].out = out; | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
| static struct convtable * | ||||
| use_from_charmap (struct charmap_t *from_charmap, const char *to_code) | ||||
| { | ||||
|   /* We iterate over all entries in the from_charmap and for those which | ||||
|      have a known UCS4 representation we use an iconv() call to determine | ||||
|      the mapping to the to_code charset.  */ | ||||
|   struct convtable *rettbl; | ||||
|   iconv_t cd; | ||||
|   void *ptr = NULL; | ||||
|   const void *key; | ||||
|   size_t keylen; | ||||
|   void *data; | ||||
|  | ||||
|   cd = iconv_open (to_code, "WCHAR_T"); | ||||
|   if (cd == (iconv_t) -1) | ||||
|     /* We cannot do anything.  */ | ||||
|     return NULL; | ||||
|  | ||||
|   rettbl = allocate_table (); | ||||
|  | ||||
|   while (iterate_table (&from_charmap->char_table, &ptr, &key, &keylen, &data) | ||||
| 	 >= 0) | ||||
|     { | ||||
|       struct charseq *in = (struct charseq *) data; | ||||
|  | ||||
|       if (in->ucs4 != UNINITIALIZED_CHAR_VALUE) | ||||
| 	{ | ||||
| 	  /* There is a chance.  Try the iconv module.  */ | ||||
| 	  wchar_t inbuf[1] = { in->ucs4 }; | ||||
| 	  unsigned char outbuf[64]; | ||||
| 	  char *inptr = (char *) inbuf; | ||||
| 	  size_t inlen = sizeof (inbuf); | ||||
| 	  char *outptr = (char *) outbuf; | ||||
| 	  size_t outlen = sizeof (outbuf); | ||||
|  | ||||
| 	  (void) iconv (cd, &inptr, &inlen, &outptr, &outlen); | ||||
|  | ||||
| 	  if (outptr != (char *) outbuf) | ||||
| 	    { | ||||
| 	      /* We got some output.  Good, use it.  */ | ||||
| 	      struct charseq *newp; | ||||
|  | ||||
| 	      outlen = sizeof (outbuf) - outlen; | ||||
| 	      assert ((char *) outbuf + outlen == outptr); | ||||
|  | ||||
| 	      newp = (struct charseq *) xmalloc (sizeof (struct charseq) | ||||
| 						 + outlen); | ||||
| 	      newp->name = in->name; | ||||
| 	      newp->ucs4 = in->ucs4; | ||||
| 	      newp->nbytes = outlen; | ||||
| 	      memcpy (newp->bytes, outbuf, outlen); | ||||
|  | ||||
| 	      add_bytes (rettbl, in, newp); | ||||
| 	    } | ||||
|  | ||||
| 	  /* Clear any possible state left behind.  */ | ||||
| 	  (void) iconv (cd, NULL, NULL, NULL, NULL); | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   iconv_close (cd); | ||||
|  | ||||
|   return rettbl; | ||||
| } | ||||
|  | ||||
|  | ||||
| static struct convtable * | ||||
| use_to_charmap (const char *from_code, struct charmap_t *to_charmap) | ||||
| { | ||||
|   /* We iterate over all entries in the to_charmap and for those which | ||||
|      have a known UCS4 representation we use an iconv() call to determine | ||||
|      the mapping to the from_code charset.  */ | ||||
|   struct convtable *rettbl; | ||||
|   iconv_t cd; | ||||
|   void *ptr = NULL; | ||||
|   const void *key; | ||||
|   size_t keylen; | ||||
|   void *data; | ||||
|  | ||||
|   /* Note that the conversion we use here is the reverse direction.  Without | ||||
|      exhaustive search we cannot figure out which input yields the UCS4 | ||||
|      character we are looking for.  Therefore we determine it the other | ||||
|      way round.  */ | ||||
|   cd = iconv_open (from_code, "WCHAR_T"); | ||||
|   if (cd == (iconv_t) -1) | ||||
|     /* We cannot do anything.  */ | ||||
|     return NULL; | ||||
|  | ||||
|   rettbl = allocate_table (); | ||||
|  | ||||
|   while (iterate_table (&to_charmap->char_table, &ptr, &key, &keylen, &data) | ||||
| 	 >= 0) | ||||
|     { | ||||
|       struct charseq *out = (struct charseq *) data; | ||||
|  | ||||
|       if (out->ucs4 != UNINITIALIZED_CHAR_VALUE) | ||||
| 	{ | ||||
| 	  /* There is a chance.  Try the iconv module.  */ | ||||
| 	  wchar_t inbuf[1] = { out->ucs4 }; | ||||
| 	  unsigned char outbuf[64]; | ||||
| 	  char *inptr = (char *) inbuf; | ||||
| 	  size_t inlen = sizeof (inbuf); | ||||
| 	  char *outptr = (char *) outbuf; | ||||
| 	  size_t outlen = sizeof (outbuf); | ||||
|  | ||||
| 	  (void) iconv (cd, &inptr, &inlen, &outptr, &outlen); | ||||
|  | ||||
| 	  if (outptr != (char *) outbuf) | ||||
| 	    { | ||||
| 	      /* We got some output.  Good, use it.  */ | ||||
| 	      struct charseq *newp; | ||||
|  | ||||
| 	      outlen = sizeof (outbuf) - outlen; | ||||
| 	      assert ((char *) outbuf + outlen == outptr); | ||||
|  | ||||
| 	      newp = (struct charseq *) xmalloc (sizeof (struct charseq) | ||||
| 						 + outlen); | ||||
| 	      newp->name = out->name; | ||||
| 	      newp->ucs4 = out->ucs4; | ||||
| 	      newp->nbytes = outlen; | ||||
| 	      memcpy (newp->bytes, outbuf, outlen); | ||||
|  | ||||
| 	      add_bytes (rettbl, newp, out); | ||||
| 	    } | ||||
|  | ||||
| 	  /* Clear any possible state left behind.  */ | ||||
| 	  (void) iconv (cd, NULL, NULL, NULL, NULL); | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   iconv_close (cd); | ||||
|  | ||||
|   return rettbl; | ||||
| } | ||||
|  | ||||
|  | ||||
| static struct convtable * | ||||
| use_both_charmaps (struct charmap_t *from_charmap, | ||||
| 		   struct charmap_t *to_charmap) | ||||
| { | ||||
|   /* In this case we iterate over all the entries in the from_charmap, | ||||
|      determine the internal name, and find an appropriate entry in the | ||||
|      to_charmap (if it exists).  */ | ||||
|   struct convtable *rettbl = allocate_table (); | ||||
|   void *ptr = NULL; | ||||
|   const void *key; | ||||
|   size_t keylen; | ||||
|   void *data; | ||||
|  | ||||
|   while (iterate_table (&from_charmap->char_table, &ptr, &key, &keylen, &data) | ||||
| 	 >= 0) | ||||
|     { | ||||
|       struct charseq *in = (struct charseq *) data; | ||||
|       struct charseq *out = charmap_find_value (to_charmap, key, keylen); | ||||
|  | ||||
|       if (out != NULL) | ||||
| 	add_bytes (rettbl, in, out); | ||||
|     } | ||||
|  | ||||
|   return rettbl; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int | ||||
| process_block (struct convtable *tbl, char *addr, size_t len, FILE *output) | ||||
| { | ||||
|   size_t n = 0; | ||||
|  | ||||
|   while (n < len) | ||||
|     { | ||||
|       struct convtable *cur = tbl; | ||||
|       unsigned char *curp = (unsigned char *) addr; | ||||
|       unsigned int byte = *curp; | ||||
|       int cnt; | ||||
|       struct charseq *out; | ||||
|  | ||||
|       while (! is_term (cur, byte)) | ||||
| 	if (cur->val[byte].sub == NULL) | ||||
| 	  { | ||||
| 	    /* This is a invalid sequence.  Skip the first byte if we are | ||||
| 	       ignoring errors.  Otherwise punt.  */ | ||||
| 	    if (! omit_invalid) | ||||
| 	      { | ||||
| 		error (0, 0, _("illegal input sequence at position %Zd"), n); | ||||
| 		return -1; | ||||
| 	      } | ||||
|  | ||||
| 	    n -= curp - (unsigned char *) addr; | ||||
|  | ||||
| 	    byte = *(curp = (unsigned char *) ++addr); | ||||
| 	    if (++n >= len) | ||||
| 	      /* All converted.  */ | ||||
| 	      return 0; | ||||
|  | ||||
| 	    cur = tbl; | ||||
| 	  } | ||||
| 	else | ||||
| 	  { | ||||
| 	    cur = cur->val[byte].sub; | ||||
|  | ||||
| 	    if (++n >= len) | ||||
| 	      { | ||||
| 		error (0, 0, _("\ | ||||
| incomplete character or shift sequence at end of buffer")); | ||||
| 		return -1; | ||||
| 	      } | ||||
|  | ||||
| 	    byte = *++curp; | ||||
| 	  } | ||||
|  | ||||
|       /* We found a final byte.  Write the output bytes.  */ | ||||
|       out = cur->val[byte].out; | ||||
|       for (cnt = 0; cnt < out->nbytes; ++cnt) | ||||
| 	fputc_unlocked (out->bytes[cnt], output); | ||||
|  | ||||
|       addr = (char *) curp + 1; | ||||
|       ++n; | ||||
|     } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int | ||||
| process_fd (struct convtable *tbl, int fd, FILE *output) | ||||
| { | ||||
|   /* we have a problem with reading from a desriptor since we must not | ||||
|      provide the iconv() function an incomplete character or shift | ||||
|      sequence at the end of the buffer.  Since we have to deal with | ||||
|      arbitrary encodings we must read the whole text in a buffer and | ||||
|      process it in one step.  */ | ||||
|   static char *inbuf = NULL; | ||||
|   static size_t maxlen = 0; | ||||
|   char *inptr = NULL; | ||||
|   size_t actlen = 0; | ||||
|  | ||||
|   while (actlen < maxlen) | ||||
|     { | ||||
|       ssize_t n = read (fd, inptr, maxlen - actlen); | ||||
|  | ||||
|       if (n == 0) | ||||
| 	/* No more text to read.  */ | ||||
| 	break; | ||||
|  | ||||
|       if (n == -1) | ||||
| 	{ | ||||
| 	  /* Error while reading.  */ | ||||
| 	  error (0, errno, _("error while reading the input")); | ||||
| 	  return -1; | ||||
| 	} | ||||
|  | ||||
|       inptr += n; | ||||
|       actlen += n; | ||||
|     } | ||||
|  | ||||
|   if (actlen == maxlen) | ||||
|     while (1) | ||||
|       { | ||||
| 	ssize_t n; | ||||
|  | ||||
| 	/* Increase the buffer.  */ | ||||
| 	maxlen += 32768; | ||||
| 	inbuf = realloc (inbuf, maxlen); | ||||
| 	if (inbuf == NULL) | ||||
| 	  error (0, errno, _("unable to allocate buffer for input")); | ||||
| 	inptr = inbuf + actlen; | ||||
|  | ||||
| 	do | ||||
| 	  { | ||||
| 	    n = read (fd, inptr, maxlen - actlen); | ||||
|  | ||||
| 	    if (n == 0) | ||||
| 	      /* No more text to read.  */ | ||||
| 	      break; | ||||
|  | ||||
| 	    if (n == -1) | ||||
| 	      { | ||||
| 		/* Error while reading.  */ | ||||
| 		error (0, errno, _("error while reading the input")); | ||||
| 		return -1; | ||||
| 	      } | ||||
|  | ||||
| 	    inptr += n; | ||||
| 	    actlen += n; | ||||
| 	  } | ||||
| 	while (actlen < maxlen); | ||||
|  | ||||
| 	if (n == 0) | ||||
| 	  /* Break again so we leave both loops.  */ | ||||
| 	  break; | ||||
|       } | ||||
|  | ||||
|   /* Now we have all the input in the buffer.  Process it in one run.  */ | ||||
|   return process_block (tbl, inbuf, actlen, output); | ||||
| } | ||||
|  | ||||
|  | ||||
| static int | ||||
| process_file (struct convtable *tbl, FILE *input, FILE *output) | ||||
| { | ||||
|   /* This should be safe since we use this function only for `stdin' and | ||||
|      we haven't read anything so far.  */ | ||||
|   return process_fd (tbl, fileno (input), output); | ||||
| } | ||||
							
								
								
									
										37
									
								
								newlib/libc/sys/linux/iconv/iconv_close.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								newlib/libc/sys/linux/iconv/iconv_close.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| /* Release any resource associated with given conversion descriptor. | ||||
|    Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <iconv.h> | ||||
|  | ||||
| #include <gconv_int.h> | ||||
|  | ||||
|  | ||||
| int | ||||
| iconv_close (iconv_t cd) | ||||
| { | ||||
|   if (__builtin_expect (cd == (iconv_t *) -1L, 0)) | ||||
|     { | ||||
|       __set_errno (EBADF); | ||||
|       return -1; | ||||
|     } | ||||
|  | ||||
|   return __gconv_close ((__gconv_t) cd) ? -1 : 0; | ||||
| } | ||||
							
								
								
									
										65
									
								
								newlib/libc/sys/linux/iconv/iconv_open.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								newlib/libc/sys/linux/iconv/iconv_open.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
| /* Get descriptor for character set conversion. | ||||
|    Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <iconv.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include <gconv_int.h> | ||||
| #include "gconv_charset.h" | ||||
|  | ||||
|  | ||||
| iconv_t | ||||
| iconv_open (const char *tocode, const char *fromcode) | ||||
| { | ||||
|   char *tocode_conv; | ||||
|   char *fromcode_conv; | ||||
|   size_t tocode_len; | ||||
|   size_t fromcode_len; | ||||
|   __gconv_t cd; | ||||
|   int res; | ||||
|  | ||||
|   /* Normalize the name.  We remove all characters beside alpha-numeric, | ||||
|      '_', '-', '/', and '.'.  */ | ||||
|   tocode_len = strlen (tocode); | ||||
|   tocode_conv = alloca (tocode_len + 3); | ||||
|   strip (tocode_conv, tocode); | ||||
|   tocode = tocode_conv[2] == '\0' ? upstr (tocode_conv, tocode) : tocode_conv; | ||||
|  | ||||
|   fromcode_len = strlen (fromcode); | ||||
|   fromcode_conv = alloca (fromcode_len + 3); | ||||
|   strip (fromcode_conv, fromcode); | ||||
|   fromcode = (fromcode_conv[2] == '\0' | ||||
| 	      ? upstr (fromcode_conv, fromcode) : fromcode_conv); | ||||
|  | ||||
|   res = __gconv_open (tocode, fromcode, &cd, 0); | ||||
|  | ||||
|   if (__builtin_expect (res, __GCONV_OK) != __GCONV_OK) | ||||
|     { | ||||
|       /* We must set the error number according to the specs.  */ | ||||
|       if (res == __GCONV_NOCONV || res == __GCONV_NODB) | ||||
| 	__set_errno (EINVAL); | ||||
|  | ||||
|       return (iconv_t) -1; | ||||
|     } | ||||
|  | ||||
|   return (iconv_t) cd; | ||||
| } | ||||
							
								
								
									
										1176
									
								
								newlib/libc/sys/linux/iconv/iconvconfig.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1176
									
								
								newlib/libc/sys/linux/iconv/iconvconfig.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										67
									
								
								newlib/libc/sys/linux/iconv/iconvconfig.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								newlib/libc/sys/linux/iconv/iconvconfig.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| /* Copyright (C) 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@redhat.com>, 2000. | ||||
|  | ||||
|    The GNU C Library is free software; you can redistribute it and/or | ||||
|    modify it under the terms of the GNU Library General Public License as | ||||
|    published by the Free Software Foundation; either version 2 of the | ||||
|    License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 | ||||
|    Library General Public License for more details. | ||||
|  | ||||
|    You should have received a copy of the GNU Library General Public | ||||
|    License along with the GNU C Library; see the file COPYING.LIB.  If not, | ||||
|    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||||
|    Boston, MA 02111-1307, USA.  */ | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
|  | ||||
| typedef uint16_t gidx_t; | ||||
|  | ||||
|  | ||||
| struct gconvcache_header | ||||
| { | ||||
|   uint32_t magic; | ||||
|   gidx_t string_offset; | ||||
|   gidx_t hash_offset; | ||||
|   gidx_t hash_size; | ||||
|   gidx_t module_offset; | ||||
|   gidx_t otherconv_offset; | ||||
| }; | ||||
|  | ||||
| struct hash_entry | ||||
| { | ||||
|   gidx_t string_offset; | ||||
|   gidx_t module_idx; | ||||
| }; | ||||
|  | ||||
| struct module_entry | ||||
| { | ||||
|   gidx_t canonname_offset; | ||||
|   gidx_t fromdir_offset; | ||||
|   gidx_t fromname_offset; | ||||
|   gidx_t todir_offset; | ||||
|   gidx_t toname_offset; | ||||
|   gidx_t extra_offset; | ||||
| }; | ||||
|  | ||||
| struct extra_entry | ||||
| { | ||||
|   gidx_t module_cnt; | ||||
|   struct extra_entry_module | ||||
|   { | ||||
|     gidx_t outname_offset; | ||||
|     gidx_t dir_offset; | ||||
|     gidx_t name_offset; | ||||
|   } module[0]; | ||||
| }; | ||||
|  | ||||
|  | ||||
| #define GCONVCACHE_MAGIC	0x20010324 | ||||
|  | ||||
|  | ||||
| #define GCONV_MODULES_CACHE	GCONV_DIR "/gconv-modules.cache" | ||||
							
								
								
									
										100
									
								
								newlib/libc/sys/linux/iconv/loadinfo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								newlib/libc/sys/linux/iconv/loadinfo.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | ||||
| /* Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #ifndef _LOADINFO_H | ||||
| #define _LOADINFO_H	1 | ||||
|  | ||||
| #ifndef PARAMS | ||||
| # if __STDC__ | ||||
| #  define PARAMS(args) args | ||||
| # else | ||||
| #  define PARAMS(args) () | ||||
| # endif | ||||
| #endif | ||||
|  | ||||
| #ifndef internal_function | ||||
| # define internal_function | ||||
| #endif | ||||
|  | ||||
| /* Tell the compiler when a conditional or integer expression is | ||||
|    almost always true or almost always false.  */ | ||||
| #ifndef HAVE_BUILTIN_EXPECT | ||||
| # define __builtin_expect(expr, val) (expr) | ||||
| #endif | ||||
|  | ||||
| /* Encoding of locale name parts.  */ | ||||
| #define CEN_REVISION		1 | ||||
| #define CEN_SPONSOR		2 | ||||
| #define CEN_SPECIAL		4 | ||||
| #define XPG_NORM_CODESET	8 | ||||
| #define XPG_CODESET		16 | ||||
| #define TERRITORY		32 | ||||
| #define CEN_AUDIENCE		64 | ||||
| #define XPG_MODIFIER		128 | ||||
|  | ||||
| #define CEN_SPECIFIC	(CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE) | ||||
| #define XPG_SPECIFIC	(XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER) | ||||
|  | ||||
|  | ||||
| struct loaded_l10nfile | ||||
| { | ||||
|   const char *filename; | ||||
|   int decided; | ||||
|  | ||||
|   const void *data; | ||||
|  | ||||
|   struct loaded_l10nfile *next; | ||||
|   struct loaded_l10nfile *successor[1]; | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* Normalize codeset name.  There is no standard for the codeset | ||||
|    names.  Normalization allows the user to use any of the common | ||||
|    names.  The return value is dynamically allocated and has to be | ||||
|    freed by the caller.  */ | ||||
| extern const char *_nl_normalize_codeset PARAMS ((const char *codeset, | ||||
| 						  size_t name_len)); | ||||
|  | ||||
| extern struct loaded_l10nfile * | ||||
| _nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list, | ||||
| 			    const char *dirlist, size_t dirlist_len, int mask, | ||||
| 			    const char *language, const char *territory, | ||||
| 			    const char *codeset, | ||||
| 			    const char *normalized_codeset, | ||||
| 			    const char *modifier, const char *special, | ||||
| 			    const char *sponsor, const char *revision, | ||||
| 			    const char *filename, int do_allocate)); | ||||
|  | ||||
|  | ||||
| extern const char *_nl_expand_alias PARAMS ((const char *name)); | ||||
|  | ||||
| /* normalized_codeset is dynamically allocated and has to be freed by | ||||
|    the caller.  */ | ||||
| extern int _nl_explode_name PARAMS ((char *name, const char **language, | ||||
| 				     const char **modifier, | ||||
| 				     const char **territory, | ||||
| 				     const char **codeset, | ||||
| 				     const char **normalized_codeset, | ||||
| 				     const char **special, | ||||
| 				     const char **sponsor, | ||||
| 				     const char **revision)); | ||||
|  | ||||
| extern char *_nl_find_language PARAMS ((const char *name)); | ||||
|  | ||||
| #endif	/* loadinfo.h */ | ||||
							
								
								
									
										209
									
								
								newlib/libc/sys/linux/iconv/localeinfo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								newlib/libc/sys/linux/iconv/localeinfo.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,209 @@ | ||||
| /* Declarations for internal libc locale interfaces | ||||
|    Copyright (C) 1995, 96, 97, 98, 99,2000,2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| #ifndef _LOCALEINFO_H | ||||
| #define _LOCALEINFO_H 1 | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <langinfo.h> | ||||
| #include <limits.h> | ||||
| #include <time.h> | ||||
| #include <stdint.h> | ||||
| #include <sys/types.h> | ||||
|  | ||||
| /* This has to be changed whenever a new locale is defined.  */ | ||||
| #define __LC_LAST	13 | ||||
|  | ||||
| #include "loadinfo.h"	/* For loaded_l10nfile definition.  */ | ||||
|  | ||||
| /* Magic number at the beginning of a locale data file for CATEGORY.  */ | ||||
| #define	LIMAGIC(category)	((unsigned int) (0x20000828 ^ (category))) | ||||
|  | ||||
| /* Two special weight constants for the collation data.  */ | ||||
| #define IGNORE_CHAR	2 | ||||
|  | ||||
| /* We use a special value for the usage counter in `locale_data' to | ||||
|    signal that this data must never be removed anymore.  */ | ||||
| #define MAX_USAGE_COUNT (UINT_MAX - 1) | ||||
| #define UNDELETABLE	UINT_MAX | ||||
|  | ||||
| /* Structure describing locale data in core for a category.  */ | ||||
| struct locale_data | ||||
| { | ||||
|   const char *name; | ||||
|   const char *filedata;		/* Region mapping the file data.  */ | ||||
|   off_t filesize;		/* Size of the file (and the region).  */ | ||||
|   int mmaped;			/* If nonzero the data is mmaped.  */ | ||||
|  | ||||
|   unsigned int usage_count;	/* Counter for users.  */ | ||||
|  | ||||
|   int use_translit;		/* Nonzero if the mb*towv*() and wc*tomb() | ||||
| 				   functions should use transliteration.  */ | ||||
|   const char *options;		/* Extra options from the locale name, | ||||
| 				   not used in the path to the locale data.  */ | ||||
|  | ||||
|   unsigned int nstrings;	/* Number of strings below.  */ | ||||
|   union locale_data_value | ||||
|   { | ||||
|     const uint32_t *wstr; | ||||
|     const char *string; | ||||
|     unsigned int word; | ||||
|   } | ||||
|   values __flexarr;	/* Items, usually pointers into `filedata'.  */ | ||||
| }; | ||||
|  | ||||
| /* We know three kinds of collation sorting rules.  */ | ||||
| enum coll_sort_rule | ||||
| { | ||||
|   illegal_0__, | ||||
|   sort_forward, | ||||
|   sort_backward, | ||||
|   illegal_3__, | ||||
|   sort_position, | ||||
|   sort_forward_position, | ||||
|   sort_backward_position, | ||||
|   sort_mask | ||||
| }; | ||||
|  | ||||
| /* We can map the types of the entries into a few categories.  */ | ||||
| enum value_type | ||||
| { | ||||
|   none, | ||||
|   string, | ||||
|   stringarray, | ||||
|   byte, | ||||
|   bytearray, | ||||
|   word, | ||||
|   stringlist, | ||||
|   wordarray, | ||||
|   wstring, | ||||
|   wstringarray, | ||||
|   wstringlist | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* Definitions for `era' information from LC_TIME.  */ | ||||
| #define ERA_NAME_FORMAT_MEMBERS 4 | ||||
| #define ERA_M_NAME   0 | ||||
| #define ERA_M_FORMAT 1 | ||||
| #define ERA_W_NAME   2 | ||||
| #define ERA_W_FORMAT 3 | ||||
|  | ||||
|  | ||||
| /* Structure to access `era' information from LC_TIME.  */ | ||||
| struct era_entry | ||||
| { | ||||
|   uint32_t direction;		/* Contains '+' or '-'.  */ | ||||
|   int32_t offset; | ||||
|   int32_t start_date[3]; | ||||
|   int32_t stop_date[3]; | ||||
|   const char *era_name; | ||||
|   const char *era_format; | ||||
|   const wchar_t *era_wname; | ||||
|   const wchar_t *era_wformat; | ||||
|   int absolute_direction; | ||||
|   /* absolute direction: | ||||
|      +1 indicates that year number is higher in the future. (like A.D.) | ||||
|      -1 indicates that year number is higher in the past. (like B.C.)  */ | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* LC_CTYPE specific: | ||||
|    Hardwired indices for standard wide character translation mappings.  */ | ||||
| enum | ||||
| { | ||||
|   __TOW_toupper = 0, | ||||
|   __TOW_tolower = 1 | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* LC_CTYPE specific: | ||||
|    Access a wide character class with a single character index. | ||||
|    _ISCTYPE (c, desc) = iswctype (btowc (c), desc). | ||||
|    c must be an `unsigned char'.  desc must be a nonzero wctype_t.  */ | ||||
| #define _ISCTYPE(c, desc) \ | ||||
|   (((((const uint32_t *) (desc)) - 8)[(c) >> 5] >> ((c) & 0x1f)) & 1) | ||||
|  | ||||
|  | ||||
| /* For each category declare the variable for the current locale data.  */ | ||||
| #define DEFINE_CATEGORY(category, category_name, items, a) \ | ||||
| extern struct locale_data *_nl_current_##category; | ||||
| #include "categories.def" | ||||
| #undef	DEFINE_CATEGORY | ||||
|  | ||||
| extern const char *const _nl_category_names[__LC_LAST]; | ||||
| extern const size_t _nl_category_name_sizes[__LC_LAST]; | ||||
| extern struct locale_data * *const _nl_current[__LC_LAST]; | ||||
|  | ||||
| /* Extract the current CATEGORY locale's string for ITEM.  */ | ||||
| #define _NL_CURRENT(category, item) \ | ||||
|   (_nl_current_##category->values[_NL_ITEM_INDEX (item)].string) | ||||
|  | ||||
| /* Extract the current CATEGORY locale's string for ITEM.  */ | ||||
| #define _NL_CURRENT_WSTR(category, item) \ | ||||
|   ((wchar_t *) (_nl_current_##category->values[_NL_ITEM_INDEX (item)].wstr)) | ||||
|  | ||||
| /* Extract the current CATEGORY locale's word for ITEM.  */ | ||||
| #define _NL_CURRENT_WORD(category, item) \ | ||||
|   (_nl_current_##category->values[_NL_ITEM_INDEX (item)].word) | ||||
|  | ||||
| /* This is used in lc-CATEGORY.c to define _nl_current_CATEGORY.  */ | ||||
| #define _NL_CURRENT_DEFINE(category) \ | ||||
|   extern struct locale_data _nl_C_##category; \ | ||||
|   struct locale_data *_nl_current_##category = &_nl_C_##category | ||||
|  | ||||
| /* Load the locale data for CATEGORY from the file specified by *NAME. | ||||
|    If *NAME is "", use environment variables as specified by POSIX, | ||||
|    and fill in *NAME with the actual name used.  The directories | ||||
|    listed in LOCALE_PATH are searched for the locale files.  */ | ||||
| extern struct locale_data *_nl_find_locale (const char *locale_path, | ||||
| 					    size_t locale_path_len, | ||||
| 					    int category, const char **name); | ||||
|  | ||||
| /* Try to load the file described by FILE.  */ | ||||
| extern void _nl_load_locale (struct loaded_l10nfile *file, int category); | ||||
|  | ||||
| /* Free all resource.  */ | ||||
| extern void _nl_unload_locale (struct locale_data *locale); | ||||
|  | ||||
| /* Free the locale and give back all memory if the usage count is one.  */ | ||||
| extern void _nl_remove_locale (int locale, struct locale_data *data); | ||||
|  | ||||
|  | ||||
| /* Return `era' entry which corresponds to TP.  Used in strftime.  */ | ||||
| extern struct era_entry *_nl_get_era_entry (const struct tm *tp); | ||||
|  | ||||
| /* Return `era' cnt'th entry .  Used in strptime.  */ | ||||
| extern struct era_entry *_nl_select_era_entry (int cnt); | ||||
|  | ||||
| /* Return `alt_digit' which corresponds to NUMBER.  Used in strftime.  */ | ||||
| extern const char *_nl_get_alt_digit (unsigned int number); | ||||
|  | ||||
| /* Similar, but now for wide characters.  */ | ||||
| extern const wchar_t *_nl_get_walt_digit (unsigned int number); | ||||
|  | ||||
| /* Parse string as alternative digit and return numeric value.  */ | ||||
| extern int _nl_parse_alt_digit (const char **strp); | ||||
|  | ||||
| /* Postload processing.  */ | ||||
| extern void _nl_postload_ctype (void); | ||||
| extern void _nl_postload_time (void); | ||||
|  | ||||
|  | ||||
| #endif	/* localeinfo.h */ | ||||
							
								
								
									
										450
									
								
								newlib/libc/sys/linux/iconv/loop.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										450
									
								
								newlib/libc/sys/linux/iconv/loop.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,450 @@ | ||||
| /* Conversion loop frame work. | ||||
|    Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| /* This file provides a frame for the reader loop in all conversion modules. | ||||
|    The actual code must (of course) be provided in the actual module source | ||||
|    code but certain actions can be written down generically, with some | ||||
|    customization options which are these: | ||||
|  | ||||
|      MIN_NEEDED_INPUT	minimal number of input bytes needed for the next | ||||
| 			conversion. | ||||
|      MIN_NEEDED_OUTPUT	minimal number of bytes produced by the next round | ||||
| 			of conversion. | ||||
|  | ||||
|      MAX_NEEDED_INPUT	you guess it, this is the maximal number of input | ||||
| 			bytes needed.  It defaults to MIN_NEEDED_INPUT | ||||
|      MAX_NEEDED_OUTPUT	likewise for output bytes. | ||||
|  | ||||
|      LOOPFCT		name of the function created.  If not specified | ||||
| 			the name is `loop' but this prevents the use | ||||
| 			of multiple functions in the same file. | ||||
|  | ||||
|      BODY		this is supposed to expand to the body of the loop. | ||||
| 			The user must provide this. | ||||
|  | ||||
|      EXTRA_LOOP_DECLS	extra arguments passed from converion loop call. | ||||
|  | ||||
|      INIT_PARAMS	code to define and initialize variables from params. | ||||
|      UPDATE_PARAMS	code to store result in params. | ||||
| */ | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <machine/endian.h> | ||||
| #include <gconv.h> | ||||
| #include <stdint.h> | ||||
| #include <string.h> | ||||
| #include <wchar.h> | ||||
| #include <sys/param.h>		/* For MIN.  */ | ||||
| #define __need_size_t | ||||
| #include <stddef.h> | ||||
|  | ||||
|  | ||||
| /* We have to provide support for machines which are not able to handled | ||||
|    unaligned memory accesses.  Some of the character encodings have | ||||
|    representations with a fixed width of 2 or 4 bytes.  But if we cannot | ||||
|    access unaligned memory we still have to read byte-wise.  */ | ||||
| #undef FCTNAME2 | ||||
| #if defined _STRING_ARCH_unaligned || !defined DEFINE_UNALIGNED | ||||
| /* We can handle unaligned memory access.  */ | ||||
| # define get16(addr) *((__const uint16_t *) (addr)) | ||||
| # define get32(addr) *((__const uint32_t *) (addr)) | ||||
|  | ||||
| /* We need no special support for writing values either.  */ | ||||
| # define put16(addr, val) *((uint16_t *) (addr)) = (val) | ||||
| # define put32(addr, val) *((uint32_t *) (addr)) = (val) | ||||
|  | ||||
| # define FCTNAME2(name) name | ||||
| #else | ||||
| /* Distinguish between big endian and little endian.  */ | ||||
| # if __BYTE_ORDER == __LITTLE_ENDIAN | ||||
| #  define get16(addr) \ | ||||
|      (((__const unsigned char *) (addr))[1] << 8			      \ | ||||
|       | ((__const unsigned char *) (addr))[0]) | ||||
| #  define get32(addr) \ | ||||
|      (((((__const unsigned char *) (addr))[3] << 8			      \ | ||||
| 	| ((__const unsigned char *) (addr))[2]) << 8			      \ | ||||
|        | ((__const unsigned char *) (addr))[1]) << 8			      \ | ||||
|       | ((__const unsigned char *) (addr))[0]) | ||||
|  | ||||
| #  define put16(addr, val) \ | ||||
|      ({ uint16_t __val = (val);						      \ | ||||
| 	((unsigned char *) (addr))[0] = __val;				      \ | ||||
| 	((unsigned char *) (addr))[1] = __val >> 8;			      \ | ||||
| 	(void) 0; }) | ||||
| #  define put32(addr, val) \ | ||||
|      ({ uint32_t __val = (val);						      \ | ||||
| 	((unsigned char *) (addr))[0] = __val;				      \ | ||||
| 	__val >>= 8;							      \ | ||||
| 	((unsigned char *) (addr))[1] = __val;				      \ | ||||
| 	__val >>= 8;							      \ | ||||
| 	((unsigned char *) (addr))[2] = __val;				      \ | ||||
| 	__val >>= 8;							      \ | ||||
| 	((unsigned char *) (addr))[3] = __val;				      \ | ||||
| 	(void) 0; }) | ||||
| # else | ||||
| #  define get16(addr) \ | ||||
|      (((__const unsigned char *) (addr))[0] << 8			      \ | ||||
|       | ((__const unsigned char *) (addr))[1]) | ||||
| #  define get32(addr) \ | ||||
|      (((((__const unsigned char *) (addr))[0] << 8			      \ | ||||
| 	| ((__const unsigned char *) (addr))[1]) << 8			      \ | ||||
|        | ((__const unsigned char *) (addr))[2]) << 8			      \ | ||||
|       | ((__const unsigned char *) (addr))[3]) | ||||
|  | ||||
| #  define put16(addr, val) \ | ||||
|      ({ uint16_t __val = (val);						      \ | ||||
| 	((unsigned char *) (addr))[1] = __val;				      \ | ||||
| 	((unsigned char *) (addr))[0] = __val >> 8;			      \ | ||||
| 	(void) 0; }) | ||||
| #  define put32(addr, val) \ | ||||
|      ({ uint32_t __val = (val);						      \ | ||||
| 	((unsigned char *) (addr))[3] = __val;				      \ | ||||
| 	__val >>= 8;							      \ | ||||
| 	((unsigned char *) (addr))[2] = __val;				      \ | ||||
| 	__val >>= 8;							      \ | ||||
| 	((unsigned char *) (addr))[1] = __val;				      \ | ||||
| 	__val >>= 8;							      \ | ||||
| 	((unsigned char *) (addr))[0] = __val;				      \ | ||||
| 	(void) 0; }) | ||||
| # endif | ||||
|  | ||||
| # define FCTNAME2(name) name##_unaligned | ||||
| #endif | ||||
| #define FCTNAME(name) FCTNAME2(name) | ||||
|  | ||||
|  | ||||
| /* We need at least one byte for the next round.  */ | ||||
| #ifndef MIN_NEEDED_INPUT | ||||
| # error "MIN_NEEDED_INPUT definition missing" | ||||
| #endif | ||||
|  | ||||
| /* Let's see how many bytes we produce.  */ | ||||
| #ifndef MAX_NEEDED_INPUT | ||||
| # define MAX_NEEDED_INPUT	MIN_NEEDED_INPUT | ||||
| #endif | ||||
|  | ||||
| /* We produce at least one byte in the next round.  */ | ||||
| #ifndef MIN_NEEDED_OUTPUT | ||||
| # error "MIN_NEEDED_OUTPUT definition missing" | ||||
| #endif | ||||
|  | ||||
| /* Let's see how many bytes we produce.  */ | ||||
| #ifndef MAX_NEEDED_OUTPUT | ||||
| # define MAX_NEEDED_OUTPUT	MIN_NEEDED_OUTPUT | ||||
| #endif | ||||
|  | ||||
| /* Default name for the function.  */ | ||||
| #ifndef LOOPFCT | ||||
| # define LOOPFCT		loop | ||||
| #endif | ||||
|  | ||||
| /* Make sure we have a loop body.  */ | ||||
| #ifndef BODY | ||||
| # error "Definition of BODY missing for function" LOOPFCT | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* If no arguments have to passed to the loop function define the macro | ||||
|    as empty.  */ | ||||
| #ifndef EXTRA_LOOP_DECLS | ||||
| # define EXTRA_LOOP_DECLS | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* To make it easier for the writers of the modules, we define a macro | ||||
|    to test whether we have to ignore errors.  */ | ||||
| #define ignore_errors_p() \ | ||||
|   (irreversible != NULL && (flags & __GCONV_IGNORE_ERRORS)) | ||||
|  | ||||
|  | ||||
| /* Error handling with transliteration/transcription function use and | ||||
|    ignoring of errors.  Note that we cannot use the do while (0) trick | ||||
|    since `break' and `continue' must reach certain points.  */ | ||||
| #define STANDARD_ERR_HANDLER(Incr) \ | ||||
|   {									      \ | ||||
|     struct __gconv_trans_data *trans;					      \ | ||||
| 									      \ | ||||
|     result = __GCONV_ILLEGAL_INPUT;					      \ | ||||
| 									      \ | ||||
|     if (irreversible == NULL)						      \ | ||||
|       /* This means we are in call from __gconv_transliterate.  In this	      \ | ||||
| 	 case we are not doing any error recovery outself.  */		      \ | ||||
|       break;								      \ | ||||
| 									      \ | ||||
|     /* First try the transliteration methods.  */			      \ | ||||
|     for (trans = step_data->__trans; trans != NULL; trans = trans->__next)    \ | ||||
|       {									      \ | ||||
| 	result = trans->__trans_fct (step, step_data, trans->__data, *inptrp, \ | ||||
| 			       &inptr, inend, &outptr, irreversible);	      \ | ||||
| 	if (result != __GCONV_ILLEGAL_INPUT)				      \ | ||||
| 	  break;							      \ | ||||
|       }									      \ | ||||
|     /* If any of them recognized the input continue with the loop.  */	      \ | ||||
|     if (result != __GCONV_ILLEGAL_INPUT)				      \ | ||||
|       continue;								      \ | ||||
| 									      \ | ||||
|     /* Next see whether we have to ignore the error.  If not, stop.  */	      \ | ||||
|     if (! ignore_errors_p ())						      \ | ||||
|       break;								      \ | ||||
| 									      \ | ||||
|     /* When we come here it means we ignore the character.  */		      \ | ||||
|     ++*irreversible;							      \ | ||||
|     inptr += Incr;							      \ | ||||
|     continue;								      \ | ||||
|   } | ||||
|  | ||||
|  | ||||
| /* Handling of Unicode 3.1 TAG characters.  Unicode recommends | ||||
|    "If language codes are not relevant to the particular processing | ||||
|     operation, then they should be ignored." | ||||
|    This macro is usually called right before STANDARD_ERR_HANDLER (Incr).  */ | ||||
| #define UNICODE_TAG_HANDLER(Character, Incr) \ | ||||
|   {									      \ | ||||
|     /* TAG characters are those in the range U+E0000..U+E007F.  */	      \ | ||||
|     if (((Character) >> 7) == (0xe0000 >> 7))				      \ | ||||
|       {									      \ | ||||
| 	inptr += Incr;							      \ | ||||
| 	continue;							      \ | ||||
|       }									      \ | ||||
|   } | ||||
|  | ||||
|  | ||||
| /* The function returns the status, as defined in gconv.h.  */ | ||||
| static inline int | ||||
| FCTNAME (LOOPFCT) (struct __gconv_step *step, | ||||
| 		   struct __gconv_step_data *step_data, | ||||
| 		   const unsigned char **inptrp, const unsigned char *inend, | ||||
| 		   unsigned char **outptrp, const unsigned char *outend, | ||||
| 		   size_t *irreversible EXTRA_LOOP_DECLS) | ||||
| { | ||||
| #ifdef LOOP_NEED_STATE | ||||
|   mbstate_t *state = step_data->__statep; | ||||
| #endif | ||||
| #ifdef LOOP_NEED_FLAGS | ||||
|   int flags = step_data->__flags; | ||||
| #endif | ||||
| #ifdef LOOP_NEED_DATA | ||||
|   void *data = step->__data; | ||||
| #endif | ||||
|   int result = __GCONV_EMPTY_INPUT; | ||||
|   const unsigned char *inptr = *inptrp; | ||||
|   unsigned char *outptr = *outptrp; | ||||
|  | ||||
| #ifdef INIT_PARAMS | ||||
|   INIT_PARAMS; | ||||
| #endif | ||||
|  | ||||
|   while (inptr != inend) | ||||
|     { | ||||
|       /* `if' cases for MIN_NEEDED_OUTPUT ==/!= 1 is made to help the | ||||
| 	 compiler generating better code.  They will be optimized away | ||||
| 	 since MIN_NEEDED_OUTPUT is always a constant.  */ | ||||
|       if ((MIN_NEEDED_OUTPUT != 1 | ||||
| 	   && __builtin_expect (outptr + MIN_NEEDED_OUTPUT > outend, 0)) | ||||
| 	  || (MIN_NEEDED_OUTPUT == 1 | ||||
| 	      && __builtin_expect (outptr >= outend, 0))) | ||||
| 	{ | ||||
| 	  /* Overflow in the output buffer.  */ | ||||
| 	  result = __GCONV_FULL_OUTPUT; | ||||
| 	  break; | ||||
| 	} | ||||
|       if (MIN_NEEDED_INPUT > 1 | ||||
| 	  && __builtin_expect (inptr + MIN_NEEDED_INPUT > inend, 0)) | ||||
| 	{ | ||||
| 	  /* We don't have enough input for another complete input | ||||
| 	     character.  */ | ||||
| 	  result = __GCONV_INCOMPLETE_INPUT; | ||||
| 	  break; | ||||
| 	} | ||||
|  | ||||
|       /* Here comes the body the user provides.  It can stop with | ||||
| 	 RESULT set to GCONV_INCOMPLETE_INPUT (if the size of the | ||||
| 	 input characters vary in size), GCONV_ILLEGAL_INPUT, or | ||||
| 	 GCONV_FULL_OUTPUT (if the output characters vary in size).  */ | ||||
|       BODY | ||||
|     } | ||||
|  | ||||
|   /* Update the pointers pointed to by the parameters.  */ | ||||
|   *inptrp = inptr; | ||||
|   *outptrp = outptr; | ||||
| #ifdef UPDATE_PARAMS | ||||
|   UPDATE_PARAMS; | ||||
| #endif | ||||
|  | ||||
|   return result; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Include the file a second time to define the function to handle | ||||
|    unaligned access.  */ | ||||
| #if !defined DEFINE_UNALIGNED && !defined _STRING_ARCH_unaligned \ | ||||
|     && MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \ | ||||
|     && MIN_NEEDED_TO != 1 && MAX_NEEDED_TO % MIN_NEEDED_TO == 0 | ||||
| # undef get16 | ||||
| # undef get32 | ||||
| # undef put16 | ||||
| # undef put32 | ||||
| # undef unaligned | ||||
|  | ||||
| # define DEFINE_UNALIGNED | ||||
| # include "loop.c" | ||||
| # undef DEFINE_UNALIGNED | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #if MAX_NEEDED_INPUT > 1 | ||||
| # define SINGLE(fct) SINGLE2 (fct) | ||||
| # define SINGLE2(fct) fct##_single | ||||
| static inline int | ||||
| SINGLE(LOOPFCT) (struct __gconv_step *step, | ||||
| 		 struct __gconv_step_data *step_data, | ||||
| 		 const unsigned char **inptrp, const unsigned char *inend, | ||||
| 		 unsigned char **outptrp, unsigned char *outend, | ||||
| 		 size_t *irreversible EXTRA_LOOP_DECLS) | ||||
| { | ||||
|   mbstate_t *state = step_data->__statep; | ||||
| #ifdef LOOP_NEED_FLAGS | ||||
|   int flags = step_data->__flags; | ||||
| #endif | ||||
| #ifdef LOOP_NEED_DATA | ||||
|   void *data = step->__data; | ||||
| #endif | ||||
|   int result = __GCONV_OK; | ||||
|   unsigned char bytebuf[MAX_NEEDED_INPUT]; | ||||
|   const unsigned char *inptr = *inptrp; | ||||
|   unsigned char *outptr = *outptrp; | ||||
|   size_t inlen; | ||||
|  | ||||
| #ifdef INIT_PARAMS | ||||
|   INIT_PARAMS; | ||||
| #endif | ||||
|  | ||||
| #ifdef UNPACK_BYTES | ||||
|   UNPACK_BYTES | ||||
| #else | ||||
|   /* Add the bytes from the state to the input buffer.  */ | ||||
|   for (inlen = 0; inlen < (size_t) (state->__count & 7); ++inlen) | ||||
|     bytebuf[inlen] = state->__value.__wchb[inlen]; | ||||
| #endif | ||||
|  | ||||
|   /* Are there enough bytes in the input buffer?  */ | ||||
|   if (__builtin_expect (inptr + (MIN_NEEDED_INPUT - inlen) > inend, 0)) | ||||
|     { | ||||
|       *inptrp = inend; | ||||
| #ifdef STORE_REST | ||||
|       inptr = bytebuf; | ||||
|       inptrp = &inptr; | ||||
|       inend = &bytebuf[inlen]; | ||||
|  | ||||
|       STORE_REST | ||||
| #else | ||||
|       /* We don't have enough input for another complete input | ||||
| 	 character.  */ | ||||
|       while (inptr < inend) | ||||
| 	state->__value.__wchb[inlen++] = *inptr++; | ||||
| #endif | ||||
|  | ||||
|       return __GCONV_INCOMPLETE_INPUT; | ||||
|     } | ||||
|  | ||||
|   /* Enough space in output buffer.  */ | ||||
|   if ((MIN_NEEDED_OUTPUT != 1 && outptr + MIN_NEEDED_OUTPUT > outend) | ||||
|       || (MIN_NEEDED_OUTPUT == 1 && outptr >= outend)) | ||||
|     /* Overflow in the output buffer.  */ | ||||
|     return __GCONV_FULL_OUTPUT; | ||||
|  | ||||
|   /*  Now add characters from the normal input buffer.  */ | ||||
|   do | ||||
|     bytebuf[inlen++] = *inptr++; | ||||
|   while (inlen < MAX_NEEDED_INPUT && inptr < inend); | ||||
|  | ||||
|   inptr = bytebuf; | ||||
|   inend = &bytebuf[inlen]; | ||||
|  | ||||
|   do | ||||
|     { | ||||
|       BODY | ||||
|     } | ||||
|   while (0); | ||||
|  | ||||
|   /* Now we either have produced an output character and consumed all the | ||||
|      bytes from the state and at least one more, or the character is still | ||||
|      incomplete, or we have some other error (like illegal input character, | ||||
|      no space in output buffer).  */ | ||||
|   if (__builtin_expect (inptr != bytebuf, 1)) | ||||
|     { | ||||
|       /* We found a new character.  */ | ||||
|       assert (inptr - bytebuf > (state->__count & 7)); | ||||
|  | ||||
|       *inptrp += inptr - bytebuf - (state->__count & 7); | ||||
|       *outptrp = outptr; | ||||
|  | ||||
|       result = __GCONV_OK; | ||||
|  | ||||
|       /* Clear the state buffer.  */ | ||||
|       state->__count &= ~7; | ||||
|     } | ||||
|   else if (result == __GCONV_INCOMPLETE_INPUT) | ||||
|     { | ||||
|       /* This can only happen if we have less than MAX_NEEDED_INPUT bytes | ||||
| 	 available.  */ | ||||
|       assert (inend != &bytebuf[MAX_NEEDED_INPUT]); | ||||
|  | ||||
|       *inptrp += inend - bytebuf - (state->__count & 7); | ||||
| #ifdef STORE_REST | ||||
|       inptrp = &inptr; | ||||
|  | ||||
|       STORE_REST | ||||
| #else | ||||
|       /* We don't have enough input for another complete input | ||||
| 	 character.  */ | ||||
|       while (inptr < inend) | ||||
| 	state->__value.__wchb[inlen++] = *inptr++; | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|   return result; | ||||
| } | ||||
| # undef SINGLE | ||||
| # undef SINGLE2 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* We remove the macro definitions so that we can include this file again | ||||
|    for the definition of another function.  */ | ||||
| #undef MIN_NEEDED_INPUT | ||||
| #undef MAX_NEEDED_INPUT | ||||
| #undef MIN_NEEDED_OUTPUT | ||||
| #undef MAX_NEEDED_OUTPUT | ||||
| #undef LOOPFCT | ||||
| #undef BODY | ||||
| #undef LOOPFCT | ||||
| #undef EXTRA_LOOP_DECLS | ||||
| #undef INIT_PARAMS | ||||
| #undef UPDATE_PARAMS | ||||
| #undef UNPACK_BYTES | ||||
| #undef LOOP_NEED_STATE | ||||
| #undef LOOP_NEED_FLAGS | ||||
| #undef LOOP_NEED_DATA | ||||
| #undef get16 | ||||
| #undef get32 | ||||
| #undef put16 | ||||
| #undef put32 | ||||
| #undef unaligned | ||||
							
								
								
									
										696
									
								
								newlib/libc/sys/linux/iconv/skeleton.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										696
									
								
								newlib/libc/sys/linux/iconv/skeleton.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,696 @@ | ||||
| /* Skeleton for a conversion module. | ||||
|    Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
|    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. | ||||
|  | ||||
|    The GNU C 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.1 of the License, or (at your option) any later version. | ||||
|  | ||||
|    The GNU C 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 the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
|  | ||||
| /* This file can be included to provide definitions of several things | ||||
|    many modules have in common.  It can be customized using the following | ||||
|    macros: | ||||
|  | ||||
|      DEFINE_INIT	define the default initializer.  This requires the | ||||
| 			following symbol to be defined. | ||||
|  | ||||
|      CHARSET_NAME	string with official name of the coded character | ||||
| 			set (in all-caps) | ||||
|  | ||||
|      DEFINE_FINI	define the default destructor function. | ||||
|  | ||||
|      MIN_NEEDED_FROM	minimal number of bytes needed for the from-charset. | ||||
|      MIN_NEEDED_TO	likewise for the to-charset. | ||||
|  | ||||
|      MAX_NEEDED_FROM	maximal number of bytes needed for the from-charset. | ||||
| 			This macro is optional, it defaults to MIN_NEEDED_FROM. | ||||
|      MAX_NEEDED_TO	likewise for the to-charset. | ||||
|  | ||||
|      DEFINE_DIRECTION_OBJECTS | ||||
| 			two objects will be defined to be used when the | ||||
| 			`gconv' function must only distinguish two | ||||
| 			directions.  This is implied by DEFINE_INIT. | ||||
| 			If this macro is not defined the following | ||||
| 			macro must be available. | ||||
|  | ||||
|      FROM_DIRECTION	this macro is supposed to return a value != 0 | ||||
| 			if we convert from the current character set, | ||||
| 			otherwise it return 0. | ||||
|  | ||||
|      EMIT_SHIFT_TO_INIT	this symbol is optional.  If it is defined it | ||||
| 			defines some code which writes out a sequence | ||||
| 			of characters which bring the current state into | ||||
| 			the initial state. | ||||
|  | ||||
|      FROM_LOOP		name of the function implementing the conversion | ||||
| 			from the current characters. | ||||
|      TO_LOOP		likewise for the other direction | ||||
|  | ||||
|      ONE_DIRECTION	optional.  If defined to 1, only one conversion | ||||
| 			direction is defined instead of two.  In this | ||||
| 			case, FROM_DIRECTION should be defined to 1, and | ||||
| 			FROM_LOOP and TO_LOOP should have the same value. | ||||
|  | ||||
|      SAVE_RESET_STATE	in case of an error we must reset the state for | ||||
| 			the rerun so this macro must be defined for | ||||
| 			stateful encodings.  It takes an argument which | ||||
| 			is nonzero when saving. | ||||
|  | ||||
|      RESET_INPUT_BUFFER	If the input character sets allow this the macro | ||||
| 			can be defined to reset the input buffer pointers | ||||
| 			to cover only those characters up to the error. | ||||
|  | ||||
|      FUNCTION_NAME	if not set the conversion function is named `gconv'. | ||||
|  | ||||
|      PREPARE_LOOP	optional code preparing the conversion loop.  Can | ||||
| 			contain variable definitions. | ||||
|      END_LOOP		also optional, may be used to store information | ||||
|  | ||||
|      EXTRA_LOOP_ARGS	optional macro specifying extra arguments passed | ||||
| 			to loop function. | ||||
|  */ | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <gconv.h> | ||||
| #include <string.h> | ||||
| #define __need_size_t | ||||
| #define __need_NULL | ||||
| #include <stddef.h> | ||||
|  | ||||
| #include <wchar.h> | ||||
|  | ||||
| #ifndef STATIC_GCONV | ||||
| # include <dlfcn.h> | ||||
| #endif | ||||
|  | ||||
| # define DL_CALL_FCT(fct, args) fct args | ||||
|  | ||||
| /* The direction objects.  */ | ||||
| #if DEFINE_DIRECTION_OBJECTS || DEFINE_INIT | ||||
| static int from_object; | ||||
| static int to_object; | ||||
|  | ||||
| # ifndef FROM_DIRECTION | ||||
| #  define FROM_DIRECTION (step->__data == &from_object) | ||||
| # endif | ||||
| #else | ||||
| # ifndef FROM_DIRECTION | ||||
| #  error "FROM_DIRECTION must be provided if direction objects are not used" | ||||
| # endif | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* How many bytes are needed at most for the from-charset.  */ | ||||
| #ifndef MAX_NEEDED_FROM | ||||
| # define MAX_NEEDED_FROM	MIN_NEEDED_FROM | ||||
| #endif | ||||
|  | ||||
| /* Same for the to-charset.  */ | ||||
| #ifndef MAX_NEEDED_TO | ||||
| # define MAX_NEEDED_TO		MIN_NEEDED_TO | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* Define macros which can access unaligned buffers.  These macros are | ||||
|    supposed to be used only in code outside the inner loops.  For the inner | ||||
|    loops we have other definitions which allow optimized access.  */ | ||||
| #ifdef _STRING_ARCH_unaligned | ||||
| /* We can handle unaligned memory access.  */ | ||||
| # define get16u(addr) *((__const uint16_t *) (addr)) | ||||
| # define get32u(addr) *((__const uint32_t *) (addr)) | ||||
|  | ||||
| /* We need no special support for writing values either.  */ | ||||
| # define put16u(addr, val) *((uint16_t *) (addr)) = (val) | ||||
| # define put32u(addr, val) *((uint32_t *) (addr)) = (val) | ||||
| #else | ||||
| /* Distinguish between big endian and little endian.  */ | ||||
| # if __BYTE_ORDER == __LITTLE_ENDIAN | ||||
| #  define get16u(addr) \ | ||||
|      (((__const unsigned char *) (addr))[1] << 8			      \ | ||||
|       | ((__const unsigned char *) (addr))[0]) | ||||
| #  define get32u(addr) \ | ||||
|      (((((__const unsigned char *) (addr))[3] << 8			      \ | ||||
| 	| ((__const unsigned char *) (addr))[2]) << 8			      \ | ||||
|        | ((__const unsigned char *) (addr))[1]) << 8			      \ | ||||
|       | ((__const unsigned char *) (addr))[0]) | ||||
|  | ||||
| #  define put16u(addr, val) \ | ||||
|      ({ uint16_t __val = (val);						      \ | ||||
| 	((unsigned char *) (addr))[0] = __val;				      \ | ||||
| 	((unsigned char *) (addr))[1] = __val >> 8;			      \ | ||||
| 	(void) 0; }) | ||||
| #  define put32u(addr, val) \ | ||||
|      ({ uint32_t __val = (val);						      \ | ||||
| 	((unsigned char *) (addr))[0] = __val;				      \ | ||||
| 	__val >>= 8;							      \ | ||||
| 	((unsigned char *) (addr))[1] = __val;				      \ | ||||
| 	__val >>= 8;							      \ | ||||
| 	((unsigned char *) (addr))[2] = __val;				      \ | ||||
| 	__val >>= 8;							      \ | ||||
| 	((unsigned char *) (addr))[3] = __val;				      \ | ||||
| 	(void) 0; }) | ||||
| # else | ||||
| #  define get16u(addr) \ | ||||
|      (((__const unsigned char *) (addr))[0] << 8			      \ | ||||
|       | ((__const unsigned char *) (addr))[1]) | ||||
| #  define get32u(addr) \ | ||||
|      (((((__const unsigned char *) (addr))[0] << 8			      \ | ||||
| 	| ((__const unsigned char *) (addr))[1]) << 8			      \ | ||||
|        | ((__const unsigned char *) (addr))[2]) << 8			      \ | ||||
|       | ((__const unsigned char *) (addr))[3]) | ||||
|  | ||||
| #  define put16u(addr, val) \ | ||||
|      ({ uint16_t __val = (val);						      \ | ||||
| 	((unsigned char *) (addr))[1] = __val;				      \ | ||||
| 	((unsigned char *) (addr))[0] = __val >> 8;			      \ | ||||
| 	(void) 0; }) | ||||
| #  define put32u(addr, val) \ | ||||
|      ({ uint32_t __val = (val);						      \ | ||||
| 	((unsigned char *) (addr))[3] = __val;				      \ | ||||
| 	__val >>= 8;							      \ | ||||
| 	((unsigned char *) (addr))[2] = __val;				      \ | ||||
| 	__val >>= 8;							      \ | ||||
| 	((unsigned char *) (addr))[1] = __val;				      \ | ||||
| 	__val >>= 8;							      \ | ||||
| 	((unsigned char *) (addr))[0] = __val;				      \ | ||||
| 	(void) 0; }) | ||||
| # endif | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* For conversions from a fixed width character set to another fixed width | ||||
|    character set we can define RESET_INPUT_BUFFER in a very fast way.  */ | ||||
| #if !defined RESET_INPUT_BUFFER && !defined SAVE_RESET_STATE | ||||
| # if MIN_NEEDED_FROM == MAX_NEEDED_FROM && MIN_NEEDED_TO == MAX_NEEDED_TO | ||||
| /* We have to use these `if's here since the compiler cannot know that | ||||
|    (outbuf - outerr) is always divisible by MIN_NEEDED_TO.  */ | ||||
| #  define RESET_INPUT_BUFFER \ | ||||
|   if (MIN_NEEDED_FROM % MIN_NEEDED_TO == 0)				      \ | ||||
|     *inptrp -= (outbuf - outerr) * (MIN_NEEDED_FROM / MIN_NEEDED_TO);	      \ | ||||
|   else if (MIN_NEEDED_TO % MIN_NEEDED_FROM == 0)			      \ | ||||
|     *inptrp -= (outbuf - outerr) / (MIN_NEEDED_TO / MIN_NEEDED_FROM);	      \ | ||||
|   else									      \ | ||||
|     *inptrp -= ((outbuf - outerr) / MIN_NEEDED_TO) * MIN_NEEDED_FROM | ||||
| # endif | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* The default init function.  It simply matches the name and initializes | ||||
|    the step data to point to one of the objects above.  */ | ||||
| #if DEFINE_INIT | ||||
| # ifndef CHARSET_NAME | ||||
| #  error "CHARSET_NAME not defined" | ||||
| # endif | ||||
|  | ||||
| extern int gconv_init (struct __gconv_step *step); | ||||
| int | ||||
| gconv_init (struct __gconv_step *step) | ||||
| { | ||||
|   /* Determine which direction.  */ | ||||
|   if (strcmp (step->__from_name, CHARSET_NAME) == 0) | ||||
|     { | ||||
|       step->__data = &from_object; | ||||
|  | ||||
|       step->__min_needed_from = MIN_NEEDED_FROM; | ||||
|       step->__max_needed_from = MAX_NEEDED_FROM; | ||||
|       step->__min_needed_to = MIN_NEEDED_TO; | ||||
|       step->__max_needed_to = MAX_NEEDED_TO; | ||||
|     } | ||||
|   else if (__builtin_expect (strcmp (step->__to_name, CHARSET_NAME), 0) == 0) | ||||
|     { | ||||
|       step->__data = &to_object; | ||||
|  | ||||
|       step->__min_needed_from = MIN_NEEDED_TO; | ||||
|       step->__max_needed_from = MAX_NEEDED_TO; | ||||
|       step->__min_needed_to = MIN_NEEDED_FROM; | ||||
|       step->__max_needed_to = MAX_NEEDED_FROM; | ||||
|     } | ||||
|   else | ||||
|     return __GCONV_NOCONV; | ||||
|  | ||||
| #ifdef SAVE_RESET_STATE | ||||
|   step->__stateful = 1; | ||||
| #else | ||||
|   step->__stateful = 0; | ||||
| #endif | ||||
|  | ||||
|   return __GCONV_OK; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* The default destructor function does nothing in the moment and so | ||||
|    we don't define it at all.  But we still provide the macro just in | ||||
|    case we need it some day.  */ | ||||
| #if DEFINE_FINI | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* If no arguments have to passed to the loop function define the macro | ||||
|    as empty.  */ | ||||
| #ifndef EXTRA_LOOP_ARGS | ||||
| # define EXTRA_LOOP_ARGS | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* This is the actual conversion function.  */ | ||||
| #ifndef FUNCTION_NAME | ||||
| # define FUNCTION_NAME	gconv | ||||
| #endif | ||||
|  | ||||
| /* The macros are used to access the function to convert single characters.  */ | ||||
| #define SINGLE(fct) SINGLE2 (fct) | ||||
| #define SINGLE2(fct) fct##_single | ||||
|  | ||||
|  | ||||
| extern int FUNCTION_NAME (struct __gconv_step *step, | ||||
| 			  struct __gconv_step_data *data, | ||||
| 			  const unsigned char **inptrp, | ||||
| 			  const unsigned char *inend, | ||||
| 			  unsigned char **outbufstart, size_t *irreversible, | ||||
| 			  int do_flush, int consume_incomplete); | ||||
| int | ||||
| FUNCTION_NAME (struct __gconv_step *step, struct __gconv_step_data *data, | ||||
| 	       const unsigned char **inptrp, const unsigned char *inend, | ||||
| 	       unsigned char **outbufstart, size_t *irreversible, int do_flush, | ||||
| 	       int consume_incomplete) | ||||
| { | ||||
|   struct __gconv_step *next_step = step + 1; | ||||
|   struct __gconv_step_data *next_data = data + 1; | ||||
|   __gconv_fct fct; | ||||
|   int status; | ||||
|  | ||||
|   fct = (data->__flags & __GCONV_IS_LAST) ? NULL : next_step->__fct; | ||||
|  | ||||
|   /* If the function is called with no input this means we have to reset | ||||
|      to the initial state.  The possibly partly converted input is | ||||
|      dropped.  */ | ||||
|   if (__builtin_expect (do_flush, 0)) | ||||
|     { | ||||
|       /* This should never happen during error handling.  */ | ||||
|       assert (outbufstart == NULL); | ||||
|  | ||||
|       status = __GCONV_OK; | ||||
|  | ||||
| #ifdef EMIT_SHIFT_TO_INIT | ||||
|       if (do_flush == 1) | ||||
| 	{ | ||||
| 	  /* We preserve the initial values of the pointer variables.  */ | ||||
| 	  unsigned char *outbuf = data->__outbuf; | ||||
| 	  unsigned char *outstart = outbuf; | ||||
| 	  unsigned char *outend = data->__outbufend; | ||||
|  | ||||
| # ifdef PREPARE_LOOP | ||||
| 	  PREPARE_LOOP | ||||
| # endif | ||||
|  | ||||
| # ifdef SAVE_RESET_STATE | ||||
| 	  SAVE_RESET_STATE (1); | ||||
| # endif | ||||
|  | ||||
| 	  /* Emit the escape sequence to reset the state.  */ | ||||
| 	  EMIT_SHIFT_TO_INIT; | ||||
|  | ||||
| 	  /* Call the steps down the chain if there are any but only if we | ||||
| 	     successfully emitted the escape sequence.  This should only | ||||
| 	     fail if the output buffer is full.  If the input is invalid | ||||
| 	     it should be discarded since the user wants to start from a | ||||
| 	     clean state.  */ | ||||
| 	  if (status == __GCONV_OK) | ||||
| 	    { | ||||
| 	      if (data->__flags & __GCONV_IS_LAST) | ||||
| 		/* Store information about how many bytes are available.  */ | ||||
| 		data->__outbuf = outbuf; | ||||
| 	      else | ||||
| 		{ | ||||
| 		  /* Write out all output which was produced.  */ | ||||
| 		  if (outbuf > outstart) | ||||
| 		    { | ||||
| 		      const unsigned char *outerr = outstart; | ||||
| 		      int result; | ||||
|  | ||||
| 		      result = DL_CALL_FCT (fct, (next_step, next_data, | ||||
| 						  &outerr, outbuf, NULL, | ||||
| 						  irreversible, 0, | ||||
| 						  consume_incomplete)); | ||||
|  | ||||
| 		      if (result != __GCONV_EMPTY_INPUT) | ||||
| 			{ | ||||
| 			  if (__builtin_expect (outerr != outbuf, 0)) | ||||
| 			    { | ||||
| 			      /* We have a problem.  Undo the conversion.  */ | ||||
| 			      outbuf = outstart; | ||||
|  | ||||
| 			      /* Restore the state.  */ | ||||
| # ifdef SAVE_RESET_STATE | ||||
| 			      SAVE_RESET_STATE (0); | ||||
| # endif | ||||
| 			    } | ||||
|  | ||||
| 			  /* Change the status.  */ | ||||
| 			  status = result; | ||||
| 			} | ||||
| 		    } | ||||
|  | ||||
| 		  if (status == __GCONV_OK) | ||||
| 		    /* Now flush the remaining steps.  */ | ||||
| 		    status = DL_CALL_FCT (fct, (next_step, next_data, NULL, | ||||
| 						NULL, NULL, irreversible, 1, | ||||
| 						consume_incomplete)); | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
|       else | ||||
| #endif | ||||
| 	{ | ||||
| 	  /* Clear the state object.  There might be bytes in there from | ||||
| 	     previous calls with CONSUME_INCOMPLETE == 1.  But don't emit | ||||
| 	     escape sequences.  */ | ||||
| 	  memset (data->__statep, '\0', sizeof (*data->__statep)); | ||||
|  | ||||
| 	  if (! (data->__flags & __GCONV_IS_LAST)) | ||||
| 	    /* Now flush the remaining steps.  */ | ||||
| 	    status = DL_CALL_FCT (fct, (next_step, next_data, NULL, NULL, | ||||
| 					NULL, irreversible, do_flush, | ||||
| 					consume_incomplete)); | ||||
| 	} | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       /* We preserve the initial values of the pointer variables.  */ | ||||
|       const unsigned char *inptr = *inptrp; | ||||
|       unsigned char *outbuf = (__builtin_expect (outbufstart == NULL, 1) | ||||
| 			       ? data->__outbuf : *outbufstart); | ||||
|       unsigned char *outend = data->__outbufend; | ||||
|       unsigned char *outstart; | ||||
|       /* This variable is used to count the number of characters we | ||||
| 	 actually converted.  */ | ||||
|       size_t lirreversible = 0; | ||||
|       size_t *lirreversiblep = irreversible ? &lirreversible : NULL; | ||||
| #if defined _STRING_ARCH_unaligned \ | ||||
|     || MIN_NEEDED_FROM == 1 || MAX_NEEDED_FROM % MIN_NEEDED_FROM != 0 \ | ||||
|     || MIN_NEEDED_TO == 1 || MAX_NEEDED_TO % MIN_NEEDED_TO != 0 | ||||
| # define unaligned 0 | ||||
| #else | ||||
|       int unaligned; | ||||
| # define GEN_unaligned(name) GEN_unaligned2 (name) | ||||
| # define GEN_unaligned2(name) name##_unaligned | ||||
| #endif | ||||
|  | ||||
| #ifdef PREPARE_LOOP | ||||
|       PREPARE_LOOP | ||||
| #endif | ||||
|  | ||||
| #if MAX_NEEDED_FROM > 1 || MAX_NEEDED_TO > 1 | ||||
|       /* If the function is used to implement the mb*towc*() or wc*tomb*() | ||||
| 	 functions we must test whether any bytes from the last call are | ||||
| 	 stored in the `state' object.  */ | ||||
|       if (((MAX_NEEDED_FROM > 1 && MAX_NEEDED_TO > 1) | ||||
| 	   || (MAX_NEEDED_FROM > 1 && FROM_DIRECTION) | ||||
| 	   || (MAX_NEEDED_TO > 1 && !FROM_DIRECTION)) | ||||
| 	  && consume_incomplete && (data->__statep->__count & 7) != 0) | ||||
| 	{ | ||||
| 	  /* Yep, we have some bytes left over.  Process them now. | ||||
|              But this must not happen while we are called from an | ||||
|              error handler.  */ | ||||
| 	  assert (outbufstart == NULL); | ||||
|  | ||||
| # if MAX_NEEDED_FROM > 1 | ||||
| 	  if (MAX_NEEDED_TO == 1 || FROM_DIRECTION) | ||||
| 	    status = SINGLE(FROM_LOOP) (step, data, inptrp, inend, &outbuf, | ||||
| 					outend, lirreversiblep | ||||
| 					EXTRA_LOOP_ARGS); | ||||
| # endif | ||||
| # if MAX_NEEDED_FROM > 1 && MAX_NEEDED_TO > 1 && !ONE_DIRECTION | ||||
| 	  else | ||||
| # endif | ||||
| # if MAX_NEEDED_TO > 1 && !ONE_DIRECTION | ||||
| 	    status = SINGLE(TO_LOOP) (step, data, inptrp, inend, &outbuf, | ||||
| 				      outend, lirreversiblep EXTRA_LOOP_ARGS); | ||||
| # endif | ||||
|  | ||||
| 	  if (__builtin_expect (status, __GCONV_OK) != __GCONV_OK) | ||||
| 	    return status; | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| #if !defined _STRING_ARCH_unaligned \ | ||||
|     && MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \ | ||||
|     && MIN_NEEDED_TO != 1 && MAX_NEEDED_TO % MIN_NEEDED_TO == 0 | ||||
|       /* The following assumes that encodings, which have a variable length | ||||
| 	 what might unalign a buffer even though it is a aligned in the | ||||
| 	 beginning, either don't have the minimal number of bytes as a divisor | ||||
| 	 of the maximum length or have a minimum length of 1.  This is true | ||||
| 	 for all known and supported encodings.  */ | ||||
|       unaligned = ((FROM_DIRECTION | ||||
| 		    && ((uintptr_t) inptr % MIN_NEEDED_FROM != 0 | ||||
| 			|| ((data->__flags & __GCONV_IS_LAST) | ||||
| 			    && (uintptr_t) outbuf % MIN_NEEDED_TO != 0))) | ||||
| 		   || (!FROM_DIRECTION | ||||
| 		       && (((data->__flags & __GCONV_IS_LAST) | ||||
| 			    && (uintptr_t) outbuf % MIN_NEEDED_FROM != 0) | ||||
| 			   || (uintptr_t) inptr % MIN_NEEDED_TO != 0))); | ||||
| #endif | ||||
|  | ||||
|       while (1) | ||||
| 	{ | ||||
| 	  struct __gconv_trans_data *trans; | ||||
|  | ||||
| 	  /* Remember the start value for this round.  */ | ||||
| 	  inptr = *inptrp; | ||||
| 	  /* The outbuf buffer is empty.  */ | ||||
| 	  outstart = outbuf; | ||||
|  | ||||
| #ifdef SAVE_RESET_STATE | ||||
| 	  SAVE_RESET_STATE (1); | ||||
| #endif | ||||
|  | ||||
| 	  if (__builtin_expect (!unaligned, 1)) | ||||
| 	    { | ||||
| 	      if (FROM_DIRECTION) | ||||
| 		/* Run the conversion loop.  */ | ||||
| 		status = FROM_LOOP (step, data, inptrp, inend, &outbuf, outend, | ||||
| 				    lirreversiblep EXTRA_LOOP_ARGS); | ||||
| 	      else | ||||
| 		/* Run the conversion loop.  */ | ||||
| 		status = TO_LOOP (step, data, inptrp, inend, &outbuf, outend, | ||||
| 				  lirreversiblep EXTRA_LOOP_ARGS); | ||||
| 	    } | ||||
| #if !defined _STRING_ARCH_unaligned \ | ||||
|     && MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \ | ||||
|     && MIN_NEEDED_TO != 1 && MAX_NEEDED_TO % MIN_NEEDED_TO == 0 | ||||
| 	  else | ||||
| 	    { | ||||
| 	      if (FROM_DIRECTION) | ||||
| 		/* Run the conversion loop.  */ | ||||
| 		status = GEN_unaligned (FROM_LOOP) (step, data, inptrp, inend, | ||||
| 						    &outbuf, outend, | ||||
| 						    lirreversiblep | ||||
| 						    EXTRA_LOOP_ARGS); | ||||
| 	      else | ||||
| 		/* Run the conversion loop.  */ | ||||
| 		status = GEN_unaligned (TO_LOOP) (step, data, inptrp, inend, | ||||
| 						  &outbuf, outend, | ||||
| 						  lirreversiblep | ||||
| 						  EXTRA_LOOP_ARGS); | ||||
| 	    } | ||||
| #endif | ||||
|  | ||||
| 	  /* If we were called as part of an error handling module we | ||||
| 	     don't do anything else here.  */ | ||||
| 	  if (__builtin_expect (outbufstart != NULL, 0)) | ||||
| 	    { | ||||
| 	      *outbufstart = outbuf; | ||||
| 	      return status; | ||||
| 	    } | ||||
|  | ||||
| 	  /* Give the transliteration module the chance to store the | ||||
| 	     original text and the result in case it needs a context.  */ | ||||
| 	  for (trans = data->__trans; trans != NULL; trans = trans->__next) | ||||
| 	    if (trans->__trans_context_fct != NULL) | ||||
| 	      DL_CALL_FCT (trans->__trans_context_fct, | ||||
| 			   (trans->__data, inptr, *inptrp, outstart, outbuf)); | ||||
|  | ||||
| 	  /* We finished one use of the loops.  */ | ||||
| 	  ++data->__invocation_counter; | ||||
|  | ||||
| 	  /* If this is the last step leave the loop, there is nothing | ||||
|              we can do.  */ | ||||
| 	  if (__builtin_expect (data->__flags & __GCONV_IS_LAST, 0)) | ||||
| 	    { | ||||
| 	      /* Store information about how many bytes are available.  */ | ||||
| 	      data->__outbuf = outbuf; | ||||
|  | ||||
| 	      /* Remember how many non-identical characters we | ||||
|                  converted in a irreversible way.  */ | ||||
| 	      *irreversible += lirreversible; | ||||
|  | ||||
| 	      break; | ||||
| 	    } | ||||
|  | ||||
| 	  /* Write out all output which was produced.  */ | ||||
| 	  if (__builtin_expect (outbuf > outstart, 1)) | ||||
| 	    { | ||||
| 	      const unsigned char *outerr = data->__outbuf; | ||||
| 	      int result; | ||||
|  | ||||
| 	      result = DL_CALL_FCT (fct, (next_step, next_data, &outerr, | ||||
| 					  outbuf, NULL, irreversible, 0, | ||||
| 					  consume_incomplete)); | ||||
|  | ||||
| 	      if (result != __GCONV_EMPTY_INPUT) | ||||
| 		{ | ||||
| 		  if (__builtin_expect (outerr != outbuf, 0)) | ||||
| 		    { | ||||
| #ifdef RESET_INPUT_BUFFER | ||||
| 		      RESET_INPUT_BUFFER; | ||||
| #else | ||||
| 		      /* We have a problem with the in on of the functions | ||||
| 			 below.  Undo the conversion upto the error point.  */ | ||||
| 		      size_t nstatus; | ||||
|  | ||||
| 		      /* Reload the pointers.  */ | ||||
| 		      *inptrp = inptr; | ||||
| 		      outbuf = outstart; | ||||
|  | ||||
| 		      /* Restore the state.  */ | ||||
| # ifdef SAVE_RESET_STATE | ||||
| 		      SAVE_RESET_STATE (0); | ||||
| # endif | ||||
|  | ||||
| 		      if (__builtin_expect (!unaligned, 1)) | ||||
| 			{ | ||||
| 			  if (FROM_DIRECTION) | ||||
| 			    /* Run the conversion loop.  */ | ||||
| 			    nstatus = FROM_LOOP (step, data, inptrp, inend, | ||||
| 						 &outbuf, outerr, | ||||
| 						 lirreversiblep | ||||
| 						 EXTRA_LOOP_ARGS); | ||||
| 			  else | ||||
| 			    /* Run the conversion loop.  */ | ||||
| 			    nstatus = TO_LOOP (step, data, inptrp, inend, | ||||
| 					       &outbuf, outerr, | ||||
| 					       lirreversiblep | ||||
| 					       EXTRA_LOOP_ARGS); | ||||
| 			} | ||||
| # if !defined _STRING_ARCH_unaligned \ | ||||
|      && MIN_NEEDED_FROM != 1 && MAX_NEEDED_FROM % MIN_NEEDED_FROM == 0 \ | ||||
|      && MIN_NEEDED_TO != 1 && MAX_NEEDED_TO % MIN_NEEDED_TO == 0 | ||||
| 		      else | ||||
| 			{ | ||||
| 			  if (FROM_DIRECTION) | ||||
| 			    /* Run the conversion loop.  */ | ||||
| 			    nstatus = GEN_unaligned (FROM_LOOP) (step, data, | ||||
| 								 inptrp, inend, | ||||
| 								 &outbuf, | ||||
| 								 outerr, | ||||
| 								 lirreversiblep | ||||
| 								 EXTRA_LOOP_ARGS); | ||||
| 			  else | ||||
| 			    /* Run the conversion loop.  */ | ||||
| 			    nstatus = GEN_unaligned (TO_LOOP) (step, data, | ||||
| 							       inptrp, inend, | ||||
| 							       &outbuf, outerr, | ||||
| 							       lirreversiblep | ||||
| 							       EXTRA_LOOP_ARGS); | ||||
| 			} | ||||
| # endif | ||||
|  | ||||
| 		      /* We must run out of output buffer space in this | ||||
| 			 rerun.  */ | ||||
| 		      assert (outbuf == outerr); | ||||
| 		      assert (nstatus == __GCONV_FULL_OUTPUT); | ||||
|  | ||||
| 		      /* If we haven't consumed a single byte decrement | ||||
| 			 the invocation counter.  */ | ||||
| 		      if (__builtin_expect (outbuf == outstart, 0)) | ||||
| 			--data->__invocation_counter; | ||||
| #endif	/* reset input buffer */ | ||||
| 		    } | ||||
|  | ||||
| 		  /* Change the status.  */ | ||||
| 		  status = result; | ||||
| 		} | ||||
| 	      else | ||||
| 		/* All the output is consumed, we can make another run | ||||
| 		   if everything was ok.  */ | ||||
| 		if (status == __GCONV_FULL_OUTPUT) | ||||
| 		  { | ||||
| 		    status = __GCONV_OK; | ||||
| 		    outbuf = data->__outbuf; | ||||
| 		  } | ||||
| 	    } | ||||
|  | ||||
| 	  if (status != __GCONV_OK) | ||||
| 	    break; | ||||
|  | ||||
| 	  /* Reset the output buffer pointer for the next round.  */ | ||||
| 	  outbuf = data->__outbuf; | ||||
| 	} | ||||
|  | ||||
| #ifdef END_LOOP | ||||
|       END_LOOP | ||||
| #endif | ||||
|  | ||||
|       /* If we are supposed to consume all character store now all of the | ||||
| 	 remaining characters in the `state' object.  */ | ||||
| #if MAX_NEEDED_FROM > 1 || MAX_NEEDED_TO > 1 | ||||
|       if (((MAX_NEEDED_FROM > 1 && MAX_NEEDED_TO > 1) | ||||
| 	   || (MAX_NEEDED_FROM > 1 && FROM_DIRECTION) | ||||
| 	   || (MAX_NEEDED_TO > 1 && !FROM_DIRECTION)) | ||||
| 	  && __builtin_expect (consume_incomplete, 0) | ||||
| 	  && status == __GCONV_INCOMPLETE_INPUT) | ||||
| 	{ | ||||
| # ifdef STORE_REST | ||||
| 	  mbstate_t *state = data->__statep; | ||||
|  | ||||
| 	  STORE_REST | ||||
| # else | ||||
| 	  size_t cnt; | ||||
|  | ||||
| 	  /* Make sure the remaining bytes fit into the state objects | ||||
|              buffer.  */ | ||||
| 	  assert (inend - *inptrp < 4); | ||||
|  | ||||
| 	  for (cnt = 0; *inptrp < inend; ++cnt) | ||||
| 	    data->__statep->__value.__wchb[cnt] = *(*inptrp)++; | ||||
| 	  data->__statep->__count &= ~7; | ||||
| 	  data->__statep->__count |= cnt; | ||||
| # endif | ||||
| 	} | ||||
| #endif | ||||
|     } | ||||
|  | ||||
|   return status; | ||||
| } | ||||
|  | ||||
| #undef DEFINE_INIT | ||||
| #undef CHARSET_NAME | ||||
| #undef DEFINE_FINI | ||||
| #undef MIN_NEEDED_FROM | ||||
| #undef MIN_NEEDED_TO | ||||
| #undef MAX_NEEDED_FROM | ||||
| #undef MAX_NEEDED_TO | ||||
| #undef DEFINE_DIRECTION_OBJECTS | ||||
| #undef FROM_DIRECTION | ||||
| #undef EMIT_SHIFT_TO_INIT | ||||
| #undef FROM_LOOP | ||||
| #undef TO_LOOP | ||||
| #undef SAVE_RESET_STATE | ||||
| #undef RESET_INPUT_BUFFER | ||||
| #undef FUNCTION_NAME | ||||
| #undef PREPARE_LOOP | ||||
| #undef END_LOOP | ||||
| #undef ONE_DIRECTION | ||||
| #undef STORE_REST | ||||
							
								
								
									
										341
									
								
								newlib/libc/sys/linux/iconv/strtab.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										341
									
								
								newlib/libc/sys/linux/iconv/strtab.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,341 @@ | ||||
| /* C string table handling. | ||||
|    Copyright (C) 2000, 2001 Free Software Foundation, Inc. | ||||
|    Written by Ulrich Drepper <drepper@redhat.com>, 2000. | ||||
|  | ||||
|    This program is free software; you can redistribute it and/or modify | ||||
|    it under the terms of the GNU General Public License as published by | ||||
|    the Free Software Foundation; either version 2, or (at your option) | ||||
|    any later version. | ||||
|  | ||||
|    This program 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 General Public License for more details. | ||||
|  | ||||
|    You should have received a copy of the GNU General Public License | ||||
|    along with this program; if not, write to the Free Software Foundation, | ||||
|    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */ | ||||
|  | ||||
| #ifdef HAVE_CONFIG_H | ||||
| # include <config.h> | ||||
| #endif | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <inttypes.h> | ||||
| #include <stddef.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/cdefs.h> | ||||
| #include <sys/param.h> | ||||
|  | ||||
|  | ||||
| struct Strent | ||||
| { | ||||
|   const char *string; | ||||
|   size_t len; | ||||
|   struct Strent *next; | ||||
|   struct Strent *left; | ||||
|   struct Strent *right; | ||||
|   size_t offset; | ||||
|   char reverse[0]; | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct memoryblock | ||||
| { | ||||
|   struct memoryblock *next; | ||||
|   char memory[0]; | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct Strtab | ||||
| { | ||||
|   struct Strent *root; | ||||
|   struct memoryblock *memory; | ||||
|   char *backp; | ||||
|   size_t left; | ||||
|   size_t total; | ||||
|  | ||||
|   struct Strent null; | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* Cache for the pagesize.  We correct this value a bit so that `malloc' | ||||
|    is not allocating more than a page.  */ | ||||
| static size_t ps; | ||||
|  | ||||
|  | ||||
| extern void *xmalloc (size_t n) __attribute_malloc__; | ||||
|  | ||||
| /* Prototypes for our functions that are used from iconvconfig.c.  If | ||||
|    you change these, change also iconvconfig.c.  */ | ||||
| /* Create new C string table object in memory.  */ | ||||
| extern struct Strtab *strtabinit (void); | ||||
|  | ||||
| /* Free resources allocated for C string table ST.  */ | ||||
| extern void strtabfree (struct Strtab *st); | ||||
|  | ||||
| /* Add string STR (length LEN is != 0) to C string table ST.  */ | ||||
| extern struct Strent *strtabadd (struct Strtab *st, const char *str, | ||||
| 				 size_t len); | ||||
|  | ||||
| /* Finalize string table ST and store size in *SIZE and return a pointer.  */ | ||||
| extern void *strtabfinalize (struct Strtab *st, size_t *size); | ||||
|  | ||||
| /* Get offset in string table for string associated with SE.  */ | ||||
| extern size_t strtaboffset (struct Strent *se); | ||||
|  | ||||
|  | ||||
| struct Strtab * | ||||
| strtabinit (void) | ||||
| { | ||||
|   struct Strtab *ret; | ||||
|  | ||||
|   if (ps == 0) | ||||
|     { | ||||
|       ps = sysconf (_SC_PAGESIZE) - 2 * sizeof (void *); | ||||
|       assert (sizeof (struct memoryblock) < ps); | ||||
|     } | ||||
|  | ||||
|   ret = (struct Strtab *) calloc (1, sizeof (struct Strtab)); | ||||
|   if (ret != NULL) | ||||
|     { | ||||
|       ret->null.len = 1; | ||||
|       ret->null.string = ""; | ||||
|     } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void | ||||
| morememory (struct Strtab *st, size_t len) | ||||
| { | ||||
|   struct memoryblock *newmem; | ||||
|  | ||||
|   if (len < ps) | ||||
|     len = ps; | ||||
|   newmem = (struct memoryblock *) malloc (len); | ||||
|   if (newmem == NULL) | ||||
|     abort (); | ||||
|  | ||||
|   newmem->next = st->memory; | ||||
|   st->memory = newmem; | ||||
|   st->backp = newmem->memory; | ||||
|   st->left = len - offsetof (struct memoryblock, memory); | ||||
| } | ||||
|  | ||||
|  | ||||
| void | ||||
| strtabfree (struct Strtab *st) | ||||
| { | ||||
|   struct memoryblock *mb = st->memory; | ||||
|  | ||||
|   while (mb != NULL) | ||||
|     { | ||||
|       void *old = mb; | ||||
|       mb = mb->next; | ||||
|       free (old); | ||||
|     } | ||||
|  | ||||
|   free (st); | ||||
| } | ||||
|  | ||||
|  | ||||
| static struct Strent * | ||||
| newstring (struct Strtab *st, const char *str, size_t len) | ||||
| { | ||||
|   struct Strent *newstr; | ||||
|   size_t align; | ||||
|   int i; | ||||
|  | ||||
|   /* Compute the amount of padding needed to make the structure aligned.  */ | ||||
|   align = ((__alignof__ (struct Strent) | ||||
| 	    - (((uintptr_t) st->backp) | ||||
| 	       & (__alignof__ (struct Strent) - 1))) | ||||
| 	   & (__alignof__ (struct Strent) - 1)); | ||||
|  | ||||
|   /* Make sure there is enough room in the memory block.  */ | ||||
|   if (st->left < align + sizeof (struct Strent) + len) | ||||
|     { | ||||
|       morememory (st, sizeof (struct Strent) + len); | ||||
|       align = 0; | ||||
|     } | ||||
|  | ||||
|   /* Create the reserved string.  */ | ||||
|   newstr = (struct Strent *) (st->backp + align); | ||||
|   newstr->string = str; | ||||
|   newstr->len = len; | ||||
|   newstr->next = NULL; | ||||
|   newstr->left = NULL; | ||||
|   newstr->right = NULL; | ||||
|   newstr->offset = 0; | ||||
|   for (i = len - 2; i >= 0; --i) | ||||
|     newstr->reverse[i] = str[len - 2 - i]; | ||||
|   newstr->reverse[len - 1] = '\0'; | ||||
|   st->backp += align + sizeof (struct Strent) + len; | ||||
|   st->left -= align + sizeof (struct Strent) + len; | ||||
|  | ||||
|   return newstr; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* XXX This function should definitely be rewritten to use a balancing | ||||
|    tree algorith (AVL, red-black trees).  For now a simple, correct | ||||
|    implementation is enough.  */ | ||||
| static struct Strent ** | ||||
| searchstring (struct Strent **sep, struct Strent *newstr) | ||||
| { | ||||
|   int cmpres; | ||||
|  | ||||
|   /* More strings?  */ | ||||
|   if (*sep == NULL) | ||||
|     { | ||||
|       *sep = newstr; | ||||
|       return sep; | ||||
|     } | ||||
|  | ||||
|   /* Compare the strings.  */ | ||||
|   cmpres = memcmp ((*sep)->reverse, newstr->reverse, | ||||
| 		   MIN ((*sep)->len, newstr->len) - 1); | ||||
|   if (cmpres == 0) | ||||
|     /* We found a matching string.  */ | ||||
|     return sep; | ||||
|   else if (cmpres > 0) | ||||
|     return searchstring (&(*sep)->left, newstr); | ||||
|   else | ||||
|     return searchstring (&(*sep)->right, newstr); | ||||
| } | ||||
|  | ||||
|  | ||||
| /* Add new string.  The actual string is assumed to be permanent.  */ | ||||
| struct Strent * | ||||
| strtabadd (struct Strtab *st, const char *str, size_t len) | ||||
| { | ||||
|   struct Strent *newstr; | ||||
|   struct Strent **sep; | ||||
|  | ||||
|   /* Compute the string length if the caller doesn't know it.  */ | ||||
|   if (len == 0) | ||||
|     len = strlen (str) + 1; | ||||
|  | ||||
|   /* Make sure all "" strings get offset 0.  */ | ||||
|   if (len == 1) | ||||
|     return &st->null; | ||||
|  | ||||
|   /* Allocate memory for the new string and its associated information.  */ | ||||
|   newstr = newstring (st, str, len); | ||||
|  | ||||
|   /* Search in the array for the place to insert the string.  If there | ||||
|      is no string with matching prefix and no string with matching | ||||
|      leading substring, create a new entry.  */ | ||||
|   sep = searchstring (&st->root, newstr); | ||||
|   if (*sep != newstr) | ||||
|     { | ||||
|       /* This is not the same entry.  This means we have a prefix match.  */ | ||||
|       if ((*sep)->len > newstr->len) | ||||
| 	{ | ||||
| 	  struct Strent *subs; | ||||
|  | ||||
| 	  for (subs = (*sep)->next; subs; subs = subs->next) | ||||
| 	    if (subs->len == newstr->len) | ||||
| 	      { | ||||
| 		/* We have an exact match with a substring.  Free the memory | ||||
| 		   we allocated.  */ | ||||
| 		st->left += st->backp - (char *) newstr; | ||||
| 		st->backp = (char *) newstr; | ||||
|  | ||||
| 		return subs; | ||||
| 	      } | ||||
|  | ||||
| 	  /* We have a new substring.  This means we don't need the reverse | ||||
| 	     string of this entry anymore.  */ | ||||
| 	  st->backp -= newstr->len; | ||||
| 	  st->left += newstr->len; | ||||
|  | ||||
| 	  newstr->next = (*sep)->next; | ||||
| 	  (*sep)->next = newstr; | ||||
| 	} | ||||
|       else if ((*sep)->len != newstr->len) | ||||
| 	{ | ||||
| 	  /* When we get here it means that the string we are about to | ||||
| 	     add has a common prefix with a string we already have but | ||||
| 	     it is longer.  In this case we have to put it first.  */ | ||||
| 	  st->total += newstr->len - (*sep)->len; | ||||
| 	  newstr->next = *sep; | ||||
| 	  newstr->left = (*sep)->left; | ||||
| 	  newstr->right = (*sep)->right; | ||||
| 	  *sep = newstr; | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  /* We have an exact match.  Free the memory we allocated.  */ | ||||
| 	  st->left += st->backp - (char *) newstr; | ||||
| 	  st->backp = (char *) newstr; | ||||
|  | ||||
| 	  newstr = *sep; | ||||
| 	} | ||||
|     } | ||||
|   else | ||||
|     st->total += newstr->len; | ||||
|  | ||||
|   return newstr; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void | ||||
| copystrings (struct Strent *nodep, char **freep, size_t *offsetp) | ||||
| { | ||||
|   struct Strent *subs; | ||||
|  | ||||
|   if (nodep->left != NULL) | ||||
|     copystrings (nodep->left, freep, offsetp); | ||||
|  | ||||
|   /* Process the current node.  */ | ||||
|   nodep->offset = *offsetp; | ||||
|   *freep = (char *) memcpy (*freep, nodep->string, nodep->len); | ||||
|   *freep += nodep->len; | ||||
|   *offsetp += nodep->len; | ||||
|  | ||||
|   for (subs = nodep->next; subs != NULL; subs = subs->next) | ||||
|     { | ||||
|       assert (subs->len < nodep->len); | ||||
|       subs->offset = nodep->offset + nodep->len - subs->len; | ||||
|     } | ||||
|  | ||||
|   if (nodep->right != NULL) | ||||
|     copystrings (nodep->right, freep, offsetp); | ||||
| } | ||||
|  | ||||
|  | ||||
| void * | ||||
| strtabfinalize (struct Strtab *st, size_t *size) | ||||
| { | ||||
|   size_t copylen; | ||||
|   char *endp; | ||||
|   char *retval; | ||||
|  | ||||
|   /* Fill in the information.  */ | ||||
|   endp = retval = (char *) xmalloc (st->total + 1); | ||||
|  | ||||
|   /* Always put an empty string at the beginning so that a zero offset | ||||
|      can mean error.  */ | ||||
|   *endp++ = '\0'; | ||||
|  | ||||
|   /* Now run through the tree and add all the string while also updating | ||||
|      the offset members of the elfstrent records.  */ | ||||
|   copylen = 1; | ||||
|   copystrings (st->root, &endp, ©len); | ||||
|   assert (copylen == st->total + 1); | ||||
|   assert (endp = retval + st->total + 1); | ||||
|   *size = copylen; | ||||
|  | ||||
|   return retval; | ||||
| } | ||||
|  | ||||
|  | ||||
| size_t | ||||
| strtaboffset (struct Strent *se) | ||||
| { | ||||
|   return se->offset; | ||||
| } | ||||
							
								
								
									
										109
									
								
								newlib/libc/sys/linux/include/arpa/ftp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								newlib/libc/sys/linux/include/arpa/ftp.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | ||||
| /* | ||||
|  * Copyright (c) 1983, 1989, 1993 | ||||
|  *	The Regents of the University of California.  All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * 3. All advertising materials mentioning features or use of this software | ||||
|  *    must display the following acknowledgement: | ||||
|  *	This product includes software developed by the University of | ||||
|  *	California, Berkeley and its contributors. | ||||
|  * 4. Neither the name of the University nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  * | ||||
|  *	@(#)ftp.h	8.1 (Berkeley) 6/2/93 | ||||
|  */ | ||||
|  | ||||
| #ifndef _ARPA_FTP_H_ | ||||
| #define	_ARPA_FTP_H_ | ||||
|  | ||||
| /* Definitions for FTP; see RFC-765. */ | ||||
|  | ||||
| /* | ||||
|  * Reply codes. | ||||
|  */ | ||||
| #define PRELIM		1	/* positive preliminary */ | ||||
| #define COMPLETE	2	/* positive completion */ | ||||
| #define CONTINUE	3	/* positive intermediate */ | ||||
| #define TRANSIENT	4	/* transient negative completion */ | ||||
| #define ERROR		5	/* permanent negative completion */ | ||||
|  | ||||
| /* | ||||
|  * Type codes | ||||
|  */ | ||||
| #define	TYPE_A		1	/* ASCII */ | ||||
| #define	TYPE_E		2	/* EBCDIC */ | ||||
| #define	TYPE_I		3	/* image */ | ||||
| #define	TYPE_L		4	/* local byte size */ | ||||
|  | ||||
| #ifdef FTP_NAMES | ||||
| char *typenames[] =  {"0", "ASCII", "EBCDIC", "Image", "Local" }; | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * Form codes | ||||
|  */ | ||||
| #define	FORM_N		1	/* non-print */ | ||||
| #define	FORM_T		2	/* telnet format effectors */ | ||||
| #define	FORM_C		3	/* carriage control (ASA) */ | ||||
| #ifdef FTP_NAMES | ||||
| char *formnames[] =  {"0", "Nonprint", "Telnet", "Carriage-control" }; | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * Structure codes | ||||
|  */ | ||||
| #define	STRU_F		1	/* file (no record structure) */ | ||||
| #define	STRU_R		2	/* record structure */ | ||||
| #define	STRU_P		3	/* page structure */ | ||||
| #ifdef FTP_NAMES | ||||
| char *strunames[] =  {"0", "File", "Record", "Page" }; | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * Mode types | ||||
|  */ | ||||
| #define	MODE_S		1	/* stream */ | ||||
| #define	MODE_B		2	/* block */ | ||||
| #define	MODE_C		3	/* compressed */ | ||||
| #ifdef FTP_NAMES | ||||
| char *modenames[] =  {"0", "Stream", "Block", "Compressed" }; | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * Record Tokens | ||||
|  */ | ||||
| #define	REC_ESC		'\377'	/* Record-mode Escape */ | ||||
| #define	REC_EOR		'\001'	/* Record-mode End-of-Record */ | ||||
| #define REC_EOF		'\002'	/* Record-mode End-of-File */ | ||||
|  | ||||
| /* | ||||
|  * Block Header | ||||
|  */ | ||||
| #define	BLK_EOR		0x80	/* Block is End-of-Record */ | ||||
| #define	BLK_EOF		0x40	/* Block is End-of-File */ | ||||
| #define BLK_ERRORS	0x20	/* Block is suspected of containing errors */ | ||||
| #define	BLK_RESTART	0x10	/* Block is Restart Marker */ | ||||
|  | ||||
| #define	BLK_BYTECOUNT	2	/* Bytes in this block */ | ||||
|  | ||||
| #endif /* !_FTP_H_ */ | ||||
							
								
								
									
										156
									
								
								newlib/libc/sys/linux/include/arpa/inet.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								newlib/libc/sys/linux/include/arpa/inet.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,156 @@ | ||||
| /* | ||||
|  * Copyright (c) 1983, 1993 | ||||
|  *	The Regents of the University of California.  All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * 3. All advertising materials mentioning features or use of this software | ||||
|  *    must display the following acknowledgement: | ||||
|  *	This product includes software developed by the University of | ||||
|  *	California, Berkeley and its contributors. | ||||
|  * 4. Neither the name of the University nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  * - | ||||
|  * Portions Copyright (c) 1993 by Digital Equipment Corporation. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this software for any | ||||
|  * purpose with or without fee is hereby granted, provided that the above | ||||
|  * copyright notice and this permission notice appear in all copies, and that | ||||
|  * the name of Digital Equipment Corporation not be used in advertising or | ||||
|  * publicity pertaining to distribution of the document or software without | ||||
|  * specific, written prior permission. | ||||
|  *  | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL | ||||
|  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES | ||||
|  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT | ||||
|  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||||
|  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||||
|  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||||
|  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||||
|  * SOFTWARE. | ||||
|  * | ||||
|  *	@(#)inet.h	8.1 (Berkeley) 6/2/93 | ||||
|  *	From: Id: inet.h,v 8.5 1997/01/29 08:48:09 vixie Exp $ | ||||
|  * $FreeBSD: src/include/arpa/inet.h,v 1.22 2002/04/10 10:51:53 mike Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef _ARPA_INET_H_ | ||||
| #define	_ARPA_INET_H_ | ||||
|  | ||||
| /* External definitions for functions in inet(3), addr2ascii(3) */ | ||||
|  | ||||
| #include <sys/cdefs.h> | ||||
| #include <sys/types.h> | ||||
| #include <machine/ansi.h> | ||||
|  | ||||
| /* Required for byteorder(3) functions. */ | ||||
| #include <machine/endian.h> | ||||
|  | ||||
| #define	INET_ADDRSTRLEN		16 | ||||
| #define	INET6_ADDRSTRLEN	46 | ||||
|  | ||||
| #ifndef _UINT16_T_DECLARED | ||||
| typedef	__uint16_t	uint16_t; | ||||
| #define	_UINT16_T_DECLARED | ||||
| #endif | ||||
|  | ||||
| #ifndef _UINT32_T_DECLARED | ||||
| typedef	__uint32_t	uint32_t; | ||||
| #define	_UINT32_T_DECLARED | ||||
| #endif | ||||
|  | ||||
| #ifndef	_IN_ADDR_T_DECLARED | ||||
| typedef	uint32_t	in_addr_t; | ||||
| #define	_IN_ADDR_T_DECLARED | ||||
| #endif | ||||
|  | ||||
| #ifndef	_IN_PORT_T_DECLARED | ||||
| typedef	uint16_t	in_port_t; | ||||
| #define	_IN_PORT_T_DECLARED | ||||
| #endif | ||||
|  | ||||
| #ifndef _POSIX_SOURCE | ||||
| #ifdef	_BSD_SIZE_T_ | ||||
| typedef	_BSD_SIZE_T_	size_t; | ||||
| #undef	_BSD_SIZE_T_ | ||||
| #endif | ||||
| #endif /* !_POSIX_SOURCE */ | ||||
|  | ||||
| /* | ||||
|  * XXX socklen_t is used by a POSIX.1-2001 interface, but not required by | ||||
|  * POSIX.1-2001. | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #ifndef __socklen_t_defined | ||||
| typedef unsigned int socklen_t; | ||||
| #define __socklen_t_defined 1 | ||||
| #endif | ||||
|  | ||||
| #ifdef	_BSD_SOCKLEN_T_ | ||||
| typedef	_BSD_SOCKLEN_T_	socklen_t; | ||||
| #undef	_BSD_SOCKLEN_T_ | ||||
| #endif | ||||
|  | ||||
| #ifndef _STRUCT_IN_ADDR_DECLARED | ||||
| struct in_addr { | ||||
| 	in_addr_t s_addr; | ||||
| }; | ||||
| #define	_STRUCT_IN_ADDR_DECLARED | ||||
| #endif | ||||
|  | ||||
| #define	inet_addr	__inet_addr | ||||
| #define	inet_aton	__inet_aton | ||||
| #define	inet_lnaof	__inet_lnaof | ||||
| #define	inet_makeaddr	__inet_makeaddr | ||||
| #define	inet_neta	__inet_neta | ||||
| #define	inet_netof	__inet_netof | ||||
| #define	inet_network	__inet_network | ||||
| #define	inet_net_ntop	__inet_net_ntop | ||||
| #define	inet_net_pton	__inet_net_pton | ||||
| #define	inet_ntoa	__inet_ntoa | ||||
| #define	inet_pton	__inet_pton | ||||
| #define	inet_ntop	__inet_ntop | ||||
| #define	inet_nsap_addr	__inet_nsap_addr | ||||
| #define	inet_nsap_ntoa	__inet_nsap_ntoa | ||||
|  | ||||
| __BEGIN_DECLS | ||||
| in_addr_t	 inet_addr(const char *); | ||||
| char		*inet_ntoa(struct in_addr); | ||||
| const char	*inet_ntop(int, const void *, char *, socklen_t); | ||||
| int		 inet_pton(int, const char *, void *); | ||||
|  | ||||
| int		 ascii2addr(int, const char *, void *); | ||||
| char		*addr2ascii(int, const void *, int, char *); | ||||
| int		 inet_aton(const char *, struct in_addr *); | ||||
| in_addr_t	 inet_lnaof(struct in_addr); | ||||
| struct in_addr	 inet_makeaddr(in_addr_t, in_addr_t); | ||||
| char *		 inet_neta(in_addr_t, char *, size_t); | ||||
| in_addr_t	 inet_netof(struct in_addr); | ||||
| in_addr_t	 inet_network(const char *); | ||||
| char		*inet_net_ntop(int, const void *, int, char *, size_t); | ||||
| int		 inet_net_pton(int, const char *, void *, size_t); | ||||
| unsigned	 inet_nsap_addr(const char *, unsigned char *, int); | ||||
| char		*inet_nsap_ntoa(int, const unsigned char *, char *); | ||||
| __END_DECLS | ||||
|  | ||||
| #endif /* !_ARPA_INET_H_ */ | ||||
							
								
								
									
										449
									
								
								newlib/libc/sys/linux/include/arpa/nameser.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										449
									
								
								newlib/libc/sys/linux/include/arpa/nameser.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,449 @@ | ||||
| /* | ||||
|  * Copyright (c) 1983, 1989, 1993 | ||||
|  *    The Regents of the University of California.  All rights reserved. | ||||
|  *  | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * 3. All advertising materials mentioning features or use of this software | ||||
|  *    must display the following acknowledgement: | ||||
|  * 	This product includes software developed by the University of | ||||
|  * 	California, Berkeley and its contributors. | ||||
|  * 4. Neither the name of the University nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  *  | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  * Copyright (c) 1996 by Internet Software Consortium. | ||||
|  * | ||||
|  * Permission to use, copy, modify, and distribute this software for any | ||||
|  * purpose with or without fee is hereby granted, provided that the above | ||||
|  * copyright notice and this permission notice appear in all copies. | ||||
|  * | ||||
|  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS | ||||
|  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | ||||
|  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE | ||||
|  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | ||||
|  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | ||||
|  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | ||||
|  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | ||||
|  * SOFTWARE. | ||||
|  */ | ||||
|  | ||||
| /* | ||||
|  *	From: Id: nameser.h,v 8.16 1998/02/06 00:35:58 halley Exp | ||||
|  * $FreeBSD: src/include/arpa/nameser.h,v 1.16 2002/03/23 17:24:55 imp Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef _ARPA_NAMESER_H_ | ||||
| #define _ARPA_NAMESER_H_ | ||||
|  | ||||
| #define BIND_4_COMPAT | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <sys/cdefs.h> | ||||
|  | ||||
| /* | ||||
|  * revision information.  this is the release date in YYYYMMDD format. | ||||
|  * it can change every day so the right thing to do with it is use it | ||||
|  * in preprocessor commands such as "#if (__NAMESER > 19931104)".  do not | ||||
|  * compare for equality; rather, use it to determine whether your libnameser.a | ||||
|  * is new enough to contain a certain feature. | ||||
|  */ | ||||
|  | ||||
| /* XXXRTH I made this bigger than __BIND in 4.9.5 T6B */ | ||||
| #define __NAMESER	19961001	/* New interface version stamp. */ | ||||
|  | ||||
| /* | ||||
|  * Define constants based on RFC 883, RFC 1034, RFC 1035 | ||||
|  */ | ||||
| #define NS_PACKETSZ	512	/* maximum packet size */ | ||||
| #define NS_MAXDNAME	1025	/* maximum domain name */ | ||||
| #define NS_MAXCDNAME	255	/* maximum compressed domain name */ | ||||
| #define NS_MAXLABEL	63	/* maximum length of domain label */ | ||||
| #define NS_HFIXEDSZ	12	/* #/bytes of fixed data in header */ | ||||
| #define NS_QFIXEDSZ	4	/* #/bytes of fixed data in query */ | ||||
| #define NS_RRFIXEDSZ	10	/* #/bytes of fixed data in r record */ | ||||
| #define NS_INT32SZ	4	/* #/bytes of data in a u_int32_t */ | ||||
| #define NS_INT16SZ	2	/* #/bytes of data in a u_int16_t */ | ||||
| #define NS_INT8SZ	1	/* #/bytes of data in a u_int8_t */ | ||||
| #define NS_INADDRSZ	4	/* IPv4 T_A */ | ||||
| #define NS_IN6ADDRSZ	16	/* IPv6 T_AAAA */ | ||||
| #define NS_CMPRSFLGS	0xc0	/* Flag bits indicating name compression. */ | ||||
| #define NS_DEFAULTPORT	53	/* For both TCP and UDP. */ | ||||
|  | ||||
| /* | ||||
|  * These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord() | ||||
|  * in synch with it. | ||||
|  */ | ||||
| typedef enum __ns_sect { | ||||
| 	ns_s_qd = 0,		/* Query: Question. */ | ||||
| 	ns_s_zn = 0,		/* Update: Zone. */ | ||||
| 	ns_s_an = 1,		/* Query: Answer. */ | ||||
| 	ns_s_pr = 1,		/* Update: Prerequisites. */ | ||||
| 	ns_s_ns = 2,		/* Query: Name servers. */ | ||||
| 	ns_s_ud = 2,		/* Update: Update. */ | ||||
| 	ns_s_ar = 3,		/* Query|Update: Additional records. */ | ||||
| 	ns_s_max = 4 | ||||
| } ns_sect; | ||||
|  | ||||
| /* | ||||
|  * This is a message handle.  It is caller allocated and has no dynamic data. | ||||
|  * This structure is intended to be opaque to all but ns_parse.c, thus the | ||||
|  * leading _'s on the member names.  Use the accessor functions, not the _'s. | ||||
|  */ | ||||
| typedef struct __ns_msg { | ||||
| 	const u_char	*_msg, *_eom; | ||||
| 	u_int16_t	_id, _flags, _counts[ns_s_max]; | ||||
| 	const u_char	*_sections[ns_s_max]; | ||||
| 	ns_sect		_sect; | ||||
| 	int		_rrnum; | ||||
| 	const u_char	*_ptr; | ||||
| } ns_msg; | ||||
|  | ||||
| /* Private data structure - do not use from outside library. */ | ||||
| struct _ns_flagdata {  int mask, shift;  }; | ||||
| extern struct _ns_flagdata _ns_flagdata[]; | ||||
|  | ||||
| /* Accessor macros - this is part of the public interface. */ | ||||
| #define ns_msg_getflag(handle, flag) ( \ | ||||
| 			((handle)._flags & _ns_flagdata[flag].mask) \ | ||||
| 			 >> _ns_flagdata[flag].shift \ | ||||
| 			) | ||||
| #define ns_msg_id(handle) ((handle)._id + 0) | ||||
| #define ns_msg_base(handle) ((handle)._msg + 0) | ||||
| #define ns_msg_end(handle) ((handle)._eom + 0) | ||||
| #define ns_msg_size(handle) ((handle)._eom - (handle)._msg) | ||||
| #define ns_msg_count(handle, section) ((handle)._counts[section] + 0) | ||||
|  | ||||
| /* | ||||
|  * This is a parsed record.  It is caller allocated and has no dynamic data. | ||||
|  */ | ||||
| typedef	struct __ns_rr { | ||||
| 	char		name[NS_MAXDNAME];	/* XXX need to malloc */ | ||||
| 	u_int16_t	type; | ||||
| 	u_int16_t	rr_class; | ||||
| 	u_int32_t	ttl; | ||||
| 	u_int16_t	rdlength; | ||||
| 	const u_char	*rdata; | ||||
| } ns_rr; | ||||
|  | ||||
| /* Accessor macros - this is part of the public interface. */ | ||||
| #define ns_rr_name(rr)	(((rr).name[0] != '\0') ? (rr).name : ".") | ||||
| #define ns_rr_type(rr)	((rr).type + 0) | ||||
| #define ns_rr_class(rr)	((rr).rr_class + 0) | ||||
| #define ns_rr_ttl(rr)	((rr).ttl + 0) | ||||
| #define ns_rr_rdlen(rr)	((rr).rdlength + 0) | ||||
| #define ns_rr_rdata(rr)	((rr).rdata + 0) | ||||
|  | ||||
| /* | ||||
|  * These don't have to be in the same order as in the packet flags word, | ||||
|  * and they can even overlap in some cases, but they will need to be kept | ||||
|  * in synch with ns_parse.c:ns_flagdata[]. | ||||
|  */ | ||||
| typedef enum __ns_flag { | ||||
| 	ns_f_qr,		/* Question/Response. */ | ||||
| 	ns_f_opcode,		/* Operation code. */ | ||||
| 	ns_f_aa,		/* Authoritative Answer. */ | ||||
| 	ns_f_tc,		/* Truncation occurred. */ | ||||
| 	ns_f_rd,		/* Recursion Desired. */ | ||||
| 	ns_f_ra,		/* Recursion Available. */ | ||||
| 	ns_f_z,			/* MBZ. */ | ||||
| 	ns_f_ad,		/* Authentic Data (DNSSEC). */ | ||||
| 	ns_f_cd,		/* Checking Disabled (DNSSEC). */ | ||||
| 	ns_f_rcode,		/* Response code. */ | ||||
| 	ns_f_max | ||||
| } ns_flag; | ||||
|  | ||||
| /* | ||||
|  * Currently defined opcodes. | ||||
|  */ | ||||
| typedef enum __ns_opcode { | ||||
| 	ns_o_query = 0,		/* Standard query. */ | ||||
| 	ns_o_iquery = 1,	/* Inverse query (deprecated/unsupported). */ | ||||
| 	ns_o_status = 2,	/* Name server status query (unsupported). */ | ||||
| 				/* Opcode 3 is undefined/reserved. */ | ||||
| 	ns_o_notify = 4,	/* Zone change notification. */ | ||||
| 	ns_o_update = 5,	/* Zone update message. */ | ||||
| 	ns_o_max = 6 | ||||
| } ns_opcode; | ||||
|  | ||||
| /* | ||||
|  * Currently defined response codes. | ||||
|  */ | ||||
| typedef	enum __ns_rcode { | ||||
| 	ns_r_noerror = 0,	/* No error occurred. */ | ||||
| 	ns_r_formerr = 1,	/* Format error. */ | ||||
| 	ns_r_servfail = 2,	/* Server failure. */ | ||||
| 	ns_r_nxdomain = 3,	/* Name error. */ | ||||
| 	ns_r_notimpl = 4,	/* Unimplemented. */ | ||||
| 	ns_r_refused = 5,	/* Operation refused. */ | ||||
| 	/* these are for BIND_UPDATE */ | ||||
| 	ns_r_yxdomain = 6,	/* Name exists */ | ||||
| 	ns_r_yxrrset = 7,	/* RRset exists */ | ||||
| 	ns_r_nxrrset = 8,	/* RRset does not exist */ | ||||
| 	ns_r_notauth = 9,	/* Not authoritative for zone */ | ||||
| 	ns_r_notzone = 10,	/* Zone of record different from zone section */ | ||||
| 	ns_r_max = 11 | ||||
| } ns_rcode; | ||||
|  | ||||
| /* BIND_UPDATE */ | ||||
| typedef enum __ns_update_operation { | ||||
| 	ns_uop_delete = 0, | ||||
| 	ns_uop_add = 1, | ||||
| 	ns_uop_max = 2 | ||||
| } ns_update_operation; | ||||
|  | ||||
| /* | ||||
|  * This RR-like structure is particular to UPDATE. | ||||
|  */ | ||||
| struct ns_updrec { | ||||
| 	struct ns_updrec *r_prev;	/* prev record */ | ||||
| 	struct ns_updrec *r_next;	/* next record */ | ||||
| 	u_int8_t	r_section;	/* ZONE/PREREQUISITE/UPDATE */ | ||||
| 	char *		r_dname;	/* owner of the RR */ | ||||
| 	u_int16_t	r_class;	/* class number */ | ||||
| 	u_int16_t	r_type;		/* type number */ | ||||
| 	u_int32_t	r_ttl;		/* time to live */ | ||||
| 	u_char *	r_data;		/* rdata fields as text string */ | ||||
| 	u_int16_t	r_size;		/* size of r_data field */ | ||||
| 	int		r_opcode;	/* type of operation */ | ||||
| 	/* following fields for private use by the resolver/server routines */ | ||||
| 	struct ns_updrec *r_grpnext;	/* next record when grouped */ | ||||
| 	struct databuf *r_dp;		/* databuf to process */ | ||||
| 	struct databuf *r_deldp;	/* databuf's deleted/overwritten */ | ||||
| 	u_int16_t	r_zone;		/* zone number on server */ | ||||
| }; | ||||
| typedef struct ns_updrec ns_updrec; | ||||
|  | ||||
| /* | ||||
|  * Currently defined type values for resources and queries. | ||||
|  */ | ||||
| typedef enum __ns_type { | ||||
| 	ns_t_a = 1,		/* Host address. */ | ||||
| 	ns_t_ns = 2,		/* Authoritative server. */ | ||||
| 	ns_t_md = 3,		/* Mail destination. */ | ||||
| 	ns_t_mf = 4,		/* Mail forwarder. */ | ||||
| 	ns_t_cname = 5,		/* Canonical name. */ | ||||
| 	ns_t_soa = 6,		/* Start of authority zone. */ | ||||
| 	ns_t_mb = 7,		/* Mailbox domain name. */ | ||||
| 	ns_t_mg = 8,		/* Mail group member. */ | ||||
| 	ns_t_mr = 9,		/* Mail rename name. */ | ||||
| 	ns_t_null = 10,		/* Null resource record. */ | ||||
| 	ns_t_wks = 11,		/* Well known service. */ | ||||
| 	ns_t_ptr = 12,		/* Domain name pointer. */ | ||||
| 	ns_t_hinfo = 13,	/* Host information. */ | ||||
| 	ns_t_minfo = 14,	/* Mailbox information. */ | ||||
| 	ns_t_mx = 15,		/* Mail routing information. */ | ||||
| 	ns_t_txt = 16,		/* Text strings. */ | ||||
| 	ns_t_rp = 17,		/* Responsible person. */ | ||||
| 	ns_t_afsdb = 18,	/* AFS cell database. */ | ||||
| 	ns_t_x25 = 19,		/* X_25 calling address. */ | ||||
| 	ns_t_isdn = 20,		/* ISDN calling address. */ | ||||
| 	ns_t_rt = 21,		/* Router. */ | ||||
| 	ns_t_nsap = 22,		/* NSAP address. */ | ||||
| 	ns_t_nsap_ptr = 23,	/* Reverse NSAP lookup (deprecated). */ | ||||
| 	ns_t_sig = 24,		/* Security signature. */ | ||||
| 	ns_t_key = 25,		/* Security key. */ | ||||
| 	ns_t_px = 26,		/* X.400 mail mapping. */ | ||||
| 	ns_t_gpos = 27,		/* Geographical position (withdrawn). */ | ||||
| 	ns_t_aaaa = 28,		/* Ip6 Address. */ | ||||
| 	ns_t_loc = 29,		/* Location Information. */ | ||||
| 	ns_t_nxt = 30,		/* Next domain (security). */ | ||||
| 	ns_t_eid = 31,		/* Endpoint identifier. */ | ||||
| 	ns_t_nimloc = 32,	/* Nimrod Locator. */ | ||||
| 	ns_t_srv = 33,		/* Server Selection. */ | ||||
| 	ns_t_atma = 34,		/* ATM Address */ | ||||
| 	ns_t_naptr = 35,	/* Naming Authority PoinTeR */ | ||||
| 	ns_t_opt = 41,		/* OPT pseudo-RR, RFC2761 */ | ||||
| 	/* Query type values which do not appear in resource records. */ | ||||
| 	ns_t_ixfr = 251,	/* Incremental zone transfer. */ | ||||
| 	ns_t_axfr = 252,	/* Transfer zone of authority. */ | ||||
| 	ns_t_mailb = 253,	/* Transfer mailbox records. */ | ||||
| 	ns_t_maila = 254,	/* Transfer mail agent records. */ | ||||
| 	ns_t_any = 255,		/* Wildcard match. */ | ||||
| 	ns_t_max = 65536 | ||||
| } ns_type; | ||||
|  | ||||
| /* | ||||
|  * Values for class field | ||||
|  */ | ||||
| typedef enum __ns_class { | ||||
| 	ns_c_in = 1,		/* Internet. */ | ||||
| 				/* Class 2 unallocated/unsupported. */ | ||||
| 	ns_c_chaos = 3,		/* MIT Chaos-net. */ | ||||
| 	ns_c_hs = 4,		/* MIT Hesiod. */ | ||||
| 	/* Query class values which do not appear in resource records */ | ||||
| 	ns_c_none = 254,	/* for prereq. sections in update requests */ | ||||
| 	ns_c_any = 255,		/* Wildcard match. */ | ||||
| 	ns_c_max = 65536 | ||||
| } ns_class; | ||||
|  | ||||
| /* | ||||
|  * Flags field of the KEY RR rdata | ||||
|  */ | ||||
| #define	NS_KEY_TYPEMASK		0xC000	/* Mask for "type" bits */ | ||||
| #define	NS_KEY_TYPE_AUTH_CONF	0x0000	/* Key usable for both */ | ||||
| #define	NS_KEY_TYPE_CONF_ONLY	0x8000	/* Key usable for confidentiality */ | ||||
| #define	NS_KEY_TYPE_AUTH_ONLY	0x4000	/* Key usable for authentication */ | ||||
| #define	NS_KEY_TYPE_NO_KEY	0xC000	/* No key usable for either; no key */ | ||||
| /* The type bits can also be interpreted independently, as single bits: */ | ||||
| #define	NS_KEY_NO_AUTH		0x8000	/* Key unusable for authentication */ | ||||
| #define	NS_KEY_NO_CONF		0x4000	/* Key unusable for confidentiality */ | ||||
| #define	NS_KEY_EXPERIMENTAL	0x2000	/* Security is *mandatory* if bit=0 */ | ||||
| #define	NS_KEY_RESERVED3	0x1000  /* reserved - must be zero */ | ||||
| #define	NS_KEY_RESERVED4	0x0800  /* reserved - must be zero */ | ||||
| #define	NS_KEY_USERACCOUNT	0x0400	/* key is assoc. with a user acct */ | ||||
| #define	NS_KEY_ENTITY		0x0200	/* key is assoc. with entity eg host */ | ||||
| #define	NS_KEY_ZONEKEY		0x0100	/* key is zone key */ | ||||
| #define	NS_KEY_IPSEC		0x0080  /* key is for IPSEC (host or user)*/ | ||||
| #define	NS_KEY_EMAIL		0x0040  /* key is for email (MIME security) */ | ||||
| #define	NS_KEY_RESERVED10	0x0020  /* reserved - must be zero */ | ||||
| #define	NS_KEY_RESERVED11	0x0010  /* reserved - must be zero */ | ||||
| #define	NS_KEY_SIGNATORYMASK	0x000F	/* key can sign RR's of same name */ | ||||
|  | ||||
| #define	NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED3 | \ | ||||
| 				  NS_KEY_RESERVED4 | \ | ||||
| 				  NS_KEY_RESERVED10 | \ | ||||
| 				  NS_KEY_RESERVED11 ) | ||||
|  | ||||
| /* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */ | ||||
| #define	NS_ALG_MD5RSA		1	/* MD5 with RSA */ | ||||
| #define	NS_ALG_EXPIRE_ONLY	253	/* No alg, no security */ | ||||
| #define	NS_ALG_PRIVATE_OID	254	/* Key begins with OID giving alg */ | ||||
|  | ||||
| /* Signatures */ | ||||
| #define	NS_MD5RSA_MIN_BITS	 512	/* Size of a mod or exp in bits */ | ||||
| #define	NS_MD5RSA_MAX_BITS	2552 | ||||
| 	/* Total of binary mod and exp */ | ||||
| #define	NS_MD5RSA_MAX_BYTES	((NS_MD5RSA_MAX_BITS+7/8)*2+3) | ||||
| 	/* Max length of text sig block */ | ||||
| #define	NS_MD5RSA_MAX_BASE64	(((NS_MD5RSA_MAX_BYTES+2)/3)*4) | ||||
|  | ||||
| /* Offsets into SIG record rdata to find various values */ | ||||
| #define	NS_SIG_TYPE	0	/* Type flags */ | ||||
| #define	NS_SIG_ALG	2	/* Algorithm */ | ||||
| #define	NS_SIG_LABELS	3	/* How many labels in name */ | ||||
| #define	NS_SIG_OTTL	4	/* Original TTL */ | ||||
| #define	NS_SIG_EXPIR	8	/* Expiration time */ | ||||
| #define	NS_SIG_SIGNED	12	/* Signature time */ | ||||
| #define	NS_SIG_FOOT	16	/* Key footprint */ | ||||
| #define	NS_SIG_SIGNER	18	/* Domain name of who signed it */ | ||||
|  | ||||
| /* How RR types are represented as bit-flags in NXT records */ | ||||
| #define	NS_NXT_BITS 8 | ||||
| #define	NS_NXT_BIT_SET(  n,p) (p[(n)/NS_NXT_BITS] |=  (0x80>>((n)%NS_NXT_BITS))) | ||||
| #define	NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS))) | ||||
| #define	NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] &   (0x80>>((n)%NS_NXT_BITS))) | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Inline versions of get/put short/long.  Pointer is advanced. | ||||
|  */ | ||||
| #define NS_GET16(s, cp) { \ | ||||
| 	register u_char *t_cp = (u_char *)(cp); \ | ||||
| 	(s) = ((u_int16_t)t_cp[0] << 8) \ | ||||
| 	    | ((u_int16_t)t_cp[1]) \ | ||||
| 	    ; \ | ||||
| 	(cp) += NS_INT16SZ; \ | ||||
| } | ||||
|  | ||||
| #define NS_GET32(l, cp) { \ | ||||
| 	register u_char *t_cp = (u_char *)(cp); \ | ||||
| 	(l) = ((u_int32_t)t_cp[0] << 24) \ | ||||
| 	    | ((u_int32_t)t_cp[1] << 16) \ | ||||
| 	    | ((u_int32_t)t_cp[2] << 8) \ | ||||
| 	    | ((u_int32_t)t_cp[3]) \ | ||||
| 	    ; \ | ||||
| 	(cp) += NS_INT32SZ; \ | ||||
| } | ||||
|  | ||||
| #define NS_PUT16(s, cp) { \ | ||||
| 	register u_int16_t t_s = (u_int16_t)(s); \ | ||||
| 	register u_char *t_cp = (u_char *)(cp); \ | ||||
| 	*t_cp++ = t_s >> 8; \ | ||||
| 	*t_cp   = t_s; \ | ||||
| 	(cp) += NS_INT16SZ; \ | ||||
| } | ||||
|  | ||||
| #define NS_PUT32(l, cp) { \ | ||||
| 	register u_int32_t t_l = (u_int32_t)(l); \ | ||||
| 	register u_char *t_cp = (u_char *)(cp); \ | ||||
| 	*t_cp++ = t_l >> 24; \ | ||||
| 	*t_cp++ = t_l >> 16; \ | ||||
| 	*t_cp++ = t_l >> 8; \ | ||||
| 	*t_cp   = t_l; \ | ||||
| 	(cp) += NS_INT32SZ; \ | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * ANSI C identifier hiding. | ||||
|  */ | ||||
| #define ns_get16		__ns_get16 | ||||
| #define ns_get32		__ns_get32 | ||||
| #define ns_put16		__ns_put16 | ||||
| #define ns_put32		__ns_put32 | ||||
| #define ns_initparse		__ns_initparse | ||||
| #define ns_parserr		__ns_parserr | ||||
| #define	ns_sprintrr		__ns_sprintrr | ||||
| #define	ns_sprintrrf		__ns_sprintrrf | ||||
| #define	ns_format_ttl		__ns_format_ttl | ||||
| #define	ns_parse_ttl		__ns_parse_ttl | ||||
| #define	ns_name_ntop		__ns_name_ntop | ||||
| #define	ns_name_pton		__ns_name_pton | ||||
| #define	ns_name_unpack		__ns_name_unpack | ||||
| #define	ns_name_pack		__ns_name_pack | ||||
| #define	ns_name_compress	__ns_name_compress | ||||
| #define	ns_name_uncompress	__ns_name_uncompress | ||||
|  | ||||
| __BEGIN_DECLS | ||||
| u_int		ns_get16(const u_char *); | ||||
| u_long		ns_get32(const u_char *); | ||||
| void		ns_put16(u_int, u_char *); | ||||
| void		ns_put32(u_long, u_char *); | ||||
| int		ns_initparse(const u_char *, int, ns_msg *); | ||||
| int		ns_parserr(ns_msg *, ns_sect, int, ns_rr *); | ||||
| int		ns_sprintrr(const ns_msg *, const ns_rr *, | ||||
| 			    const char *, const char *, char *, size_t); | ||||
| int		ns_sprintrrf(const u_char *, size_t, const char *, | ||||
| 			     ns_class, ns_type, u_long, const u_char *, | ||||
| 			     size_t, const char *, const char *, | ||||
| 			     char *, size_t); | ||||
| int		ns_format_ttl(u_long, char *, size_t); | ||||
| int		ns_parse_ttl(const char *, u_long *); | ||||
| int		ns_name_ntop(const u_char *, char *, size_t); | ||||
| int		ns_name_pton(const char *, u_char *, size_t); | ||||
| int		ns_name_unpack(const u_char *, const u_char *, | ||||
| 			       const u_char *, u_char *, size_t); | ||||
| int		ns_name_pack(const u_char *, u_char *, int, | ||||
| 			     const u_char **, const u_char **); | ||||
| int		ns_name_uncompress(const u_char *, const u_char *, | ||||
| 				   const u_char *, char *, size_t); | ||||
| int		ns_name_compress(const char *, u_char *, size_t, | ||||
| 				 const u_char **, const u_char **); | ||||
| int		ns_name_skip(const u_char **, const u_char *); | ||||
| __END_DECLS | ||||
|  | ||||
| #ifdef BIND_4_COMPAT | ||||
| #include <arpa/nameser_compat.h> | ||||
| #endif | ||||
|  | ||||
| #endif /* !_ARPA_NAMESER_H_ */ | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user