You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2746 lines
61 KiB

Added all changes from old 4.0 version: PSTACK, libmysqld and MySQL filesystem UPDATE ... ORDER BY DELETE ... ORDER BY New faster fulltext handling Faster compressed keys Makefile.am: Added support for pstack and libmysqld_dir acconfig.h: MySQL filesystem and PSTACK acinclude.m4: MySQL File system client/mysql.cc: Support for --xml configure.in: Pstack, MySQL FS and libmysqld_dir include/ft_global.h: Faster fulltext include/my_pthread.h: Made c++ safe include/myisam.h: Update for faster fulltext include/mysql_com.h: new my_net_read() include/violite.h: libmysqld libmysql/net.c: New protocol that supports big packets myisam/Makefile.am: Faster fulltext myisam/ft_parser.c: Faster fulltext myisam/ft_search.c: Faster fulltext myisam/ft_update.c: Faster fulltext myisam/ftdefs.h: Faster fulltext myisam/mi_check.c: Faster fulltext myisam/mi_open.c: Faster compressed keys myisam/mi_search.c: Faster compressed keys myisam/mi_update.c: Faster compressed keys myisam/myisamdef.h: Faster compressed keys myisam/sort.c: Faster compressed keys mysql-test/mysql-test-run.sh: --skip-innobase and --skip-bdb sql/ChangeLog: Changelog sql/Makefile.am: PSTACK sql/mysql_priv.h: New ORDER BY options and libmysqld sql/mysqld.cc: PSTACK sql/net_serv.cc: New protocol that supports big packets sql/share/estonian/errmsg.txt: New error messages sql/sql_base.cc: Better list_open_tabels sql/sql_delete.cc: ORDER BY for delete sql/sql_lex.cc: Added language convertation of all strings sql/sql_parse.cc: Changes for libmysqld Use new ORDER BY options sql/sql_show.cc: Character set convertations Use new list_open_tables function. sql/sql_update.cc: UPDATE ... ORDER BY sql/sql_yacc.yy: Clean up symbol definitions DELETE .. ORDER BY UPDATE .. ORDER BY sql/table.h: new OPEN_TABLE_LIST structure BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted
25 years ago
Update copyright Fixed memory leak on shutdown (Affects the embedded version & MyODBC) client/client_priv.h: Update copyright client/completion_hash.cc: Update copyright client/completion_hash.h: Update copyright client/connect_test.c: Update copyright client/errmsg.c: Update copyright client/get_password.c: Update copyright client/insert_test.c: Update copyright client/list_test.c: Update copyright client/my_readline.h: Update copyright client/mysql.cc: Update copyright client/mysqladmin.c: Update copyright client/mysqlbinlog.cc: Update copyright client/mysqlcheck.c: Update copyright client/mysqldump.c: Update copyright client/mysqlimport.c: Update copyright client/mysqlmanager-pwgen.c: Update copyright client/mysqlmanagerc.c: Update copyright client/mysqlshow.c: Update copyright client/mysqltest.c: Update copyright client/password.c: Update copyright client/readline.cc: Update copyright client/select_test.c: Update copyright client/showdb_test.c: Update copyright client/sql_string.cc: Update copyright client/sql_string.h: Update copyright client/ssl_test.c: Update copyright client/thimble.cc: Update copyright client/thread_test.c: Update copyright div/deadlock_test.c: Update copyright extra/comp_err.c: Update copyright extra/my_print_defaults.c: Update copyright extra/perror.c: Update copyright extra/replace.c: Update copyright extra/resolve_stack_dump.c: Update copyright extra/resolveip.c: Update copyright fs/database.c: Update copyright fs/libmysqlfs.c: Update copyright fs/mysqlcorbafs.c: Update copyright fs/mysqlcorbafs.h: Update copyright fs/mysqlcorbafs_test.c: Update copyright heap/_check.c: Update copyright heap/_rectest.c: Update copyright heap/heapdef.h: Update copyright heap/hp_block.c: Update copyright heap/hp_clear.c: Update copyright heap/hp_close.c: Update copyright heap/hp_create.c: Update copyright heap/hp_delete.c: Update copyright heap/hp_extra.c: Update copyright heap/hp_hash.c: Update copyright heap/hp_info.c: Update copyright heap/hp_open.c: Update copyright heap/hp_panic.c: Update copyright heap/hp_rename.c: Update copyright heap/hp_rfirst.c: Update copyright heap/hp_rkey.c: Update copyright heap/hp_rlast.c: Update copyright heap/hp_rnext.c: Update copyright heap/hp_rprev.c: Update copyright heap/hp_rrnd.c: Update copyright heap/hp_rsame.c: Update copyright heap/hp_scan.c: Update copyright heap/hp_static.c: Update copyright heap/hp_test1.c: Update copyright heap/hp_test2.c: Update copyright heap/hp_update.c: Update copyright heap/hp_write.c: Update copyright include/config-win.h: Update copyright include/dbug.h: Update copyright include/errmsg.h: Update copyright include/ft_global.h: Update copyright include/getopt.h: Update copyright include/hash.h: Update copyright include/heap.h: Update copyright include/m_ctype.h: Update copyright include/m_string.h: Update copyright include/md5.h: Update copyright include/merge.h: Update copyright include/my_alarm.h: Update copyright include/my_base.h: Update copyright include/my_bitmap.h: Update copyright include/my_dir.h: Update copyright include/my_global.h: Update copyright include/my_list.h: Update copyright include/my_net.h: Update copyright include/my_no_pthread.h: Update copyright include/my_nosys.h: Update copyright include/my_pthread.h: Update copyright include/my_sys.h: Update copyright include/my_tree.h: Update copyright include/myisam.h: Update copyright include/myisammrg.h: Update copyright include/myisampack.h: Update copyright include/mysql.h: Update copyright include/mysql_com.h: Update copyright include/mysql_embed.h: Update copyright include/mysqld_error.h: Update copyright include/mysys_err.h: Update copyright include/nisam.h: Update copyright include/queues.h: Update copyright include/raid.h: Update copyright include/sslopt-case.h: Update copyright include/sslopt-longopts.h: Update copyright include/sslopt-usage.h: Update copyright include/sslopt-vars.h: Update copyright include/t_ctype.h: Update copyright include/thr_alarm.h: Update copyright include/thr_lock.h: Update copyright include/violite.h: Update copyright isam/_cache.c: Update copyright isam/_dbug.c: Update copyright isam/_key.c: Update copyright isam/_locking.c: Update copyright isam/_packrec.c: Update copyright isam/_page.c: Update copyright isam/_search.c: Update copyright isam/_statrec.c: Update copyright isam/changed.c: Update copyright isam/close.c: Update copyright isam/create.c: Update copyright isam/delete.c: Update copyright isam/extra.c: Update copyright isam/info.c: Update copyright isam/isamchk.c: Update copyright isam/isamdef.h: Update copyright isam/log.c: Update copyright isam/open.c: Update copyright isam/panic.c: Update copyright isam/range.c: Update copyright isam/rfirst.c: Update copyright isam/rkey.c: Update copyright isam/rlast.c: Update copyright isam/rnext.c: Update copyright isam/rprev.c: Update copyright isam/rrnd.c: Update copyright isam/rsame.c: Update copyright isam/rsamepos.c: Update copyright isam/sort.c: Update copyright isam/static.c: Update copyright isam/test1.c: Update copyright isam/test2.c: Update copyright isam/test3.c: Update copyright isam/update.c: Update copyright isam/write.c: Update copyright libmysql/conf_to_src.c: Update copyright libmysql/dll.c: Update copyright libmysql/errmsg.c: Update copyright libmysql/get_password.c: Update copyright libmysql/libmysql.c: Update copyright libmysql/manager.c: Update copyright libmysql/net.c: Update copyright libmysql/password.c: Update copyright libmysqld/lib_sql.cc: Update copyright libmysqld/lib_vio.c: Update copyright libmysqld/libmysqld.c: Update copyright merge/mrg_close.c: Update copyright merge/mrg_create.c: Update copyright merge/mrg_def.h: Update copyright merge/mrg_delete.c: Update copyright merge/mrg_extra.c: Update copyright merge/mrg_info.c: Update copyright merge/mrg_locking.c: Update copyright merge/mrg_open.c: Update copyright merge/mrg_panic.c: Update copyright merge/mrg_rrnd.c: Update copyright merge/mrg_rsame.c: Update copyright merge/mrg_static.c: Update copyright merge/mrg_update.c: Update copyright myisam/ft_boolean_search.c: Update copyright myisam/ft_dump.c: Update copyright myisam/ft_eval.h: Update copyright myisam/ft_static.c: Update copyright myisam/ft_stem.c: Update copyright myisam/ft_stopwords.c: Update copyright myisam/ft_test1.h: Update copyright myisam/mi_cache.c: Update copyright myisam/mi_changed.c: Update copyright myisam/mi_check.c: Update copyright myisam/mi_checksum.c: Update copyright myisam/mi_close.c: Update copyright myisam/mi_create.c: Update copyright myisam/mi_dbug.c: Update copyright myisam/mi_delete.c: Update copyright myisam/mi_delete_all.c: Update copyright myisam/mi_delete_table.c: Update copyright myisam/mi_dynrec.c: Update copyright myisam/mi_extra.c: Update copyright myisam/mi_info.c: Update copyright myisam/mi_key.c: Update copyright myisam/mi_locking.c: Update copyright myisam/mi_log.c: Update copyright myisam/mi_open.c: Update copyright myisam/mi_packrec.c: Update copyright myisam/mi_page.c: Update copyright myisam/mi_panic.c: Update copyright myisam/mi_range.c: Update copyright myisam/mi_rename.c: Update copyright myisam/mi_rfirst.c: Update copyright myisam/mi_rlast.c: Update copyright myisam/mi_rnext_same.c: Update copyright myisam/mi_rrnd.c: Update copyright myisam/mi_rsame.c: Update copyright myisam/mi_rsamepos.c: Update copyright myisam/mi_scan.c: Update copyright myisam/mi_search.c: Update copyright myisam/mi_static.c: Update copyright myisam/mi_statrec.c: Update copyright myisam/mi_test1.c: Update copyright myisam/mi_test2.c: Update copyright myisam/mi_test3.c: Update copyright myisam/mi_unique.c: Update copyright myisam/mi_update.c: Update copyright myisam/mi_write.c: Update copyright myisam/myisamchk.c: Update copyright myisam/myisampack.c: Update copyright myisammrg/myrg_close.c: Update copyright myisammrg/myrg_create.c: Update copyright myisammrg/myrg_def.h: Update copyright myisammrg/myrg_delete.c: Update copyright myisammrg/myrg_locking.c: Update copyright myisammrg/myrg_open.c: Update copyright myisammrg/myrg_panic.c: Update copyright myisammrg/myrg_rsame.c: Update copyright myisammrg/myrg_static.c: Update copyright myisammrg/myrg_update.c: Update copyright myisammrg/myrg_write.c: Update copyright mysql-test/r/gcc296.result: Update of benchmark results mysql-test/r/innodb.result: Update of benchmark results mysql-test/r/join_outer.result: Update of benchmark results mysql-test/r/myisam.result: Update of benchmark results mysys/array.c: Update copyright mysys/charset.c: Fix for restart of character sets mysys/checksum.c: Update copyright mysys/default.c: Update copyright mysys/errors.c: Update copyright mysys/getopt.c: Cleanup mysys/getvar.c: Update copyright mysys/hash.c: Update copyright mysys/list.c: Update copyright mysys/make-conf.c: Update copyright mysys/md5.c: Update copyright mysys/mf_brkhant.c: Update copyright mysys/mf_cache.c: Update copyright mysys/mf_casecnv.c: Update copyright mysys/mf_dirname.c: Update copyright mysys/mf_fn_ext.c: Update copyright mysys/mf_format.c: Update copyright mysys/mf_getdate.c: Update copyright mysys/mf_iocache.c: Update copyright mysys/mf_iocache2.c: Update copyright mysys/mf_keycache.c: Update copyright mysys/mf_loadpath.c: Update copyright mysys/mf_pack.c: Update copyright mysys/mf_path.c: Update copyright mysys/mf_qsort.c: Update copyright mysys/mf_qsort2.c: Update copyright mysys/mf_radix.c: Update copyright mysys/mf_same.c: Update copyright mysys/mf_sleep.c: Update copyright mysys/mf_sort.c: Update copyright mysys/mf_soundex.c: Update copyright mysys/mf_stripp.c: Update copyright mysys/mf_tempfile.c: Update copyright mysys/mf_unixpath.c: Update copyright mysys/mf_util.c: Update copyright mysys/mf_wcomp.c: Update copyright mysys/mf_wfile.c: Update copyright mysys/mulalloc.c: Update copyright mysys/my_alarm.c: Update copyright mysys/my_alloc.c: Update copyright mysys/my_append.c: Update copyright mysys/my_bit.c: Update copyright mysys/my_bitmap.c: Update copyright mysys/my_chsize.c: Update copyright mysys/my_clock.c: Update copyright mysys/my_compress.c: Update copyright mysys/my_copy.c: Update copyright mysys/my_create.c: Update copyright mysys/my_delete.c: Update copyright mysys/my_div.c: Update copyright mysys/my_dup.c: Update copyright mysys/my_error.c: Update copyright mysys/my_fopen.c: Update copyright mysys/my_fstream.c: Update copyright mysys/my_getwd.c: Update copyright mysys/my_init.c: Free 'once_alloc' memory at shutdown. mysys/my_lib.c: Update copyright mysys/my_lock.c: Update copyright mysys/my_lockmem.c: Update copyright mysys/my_lread.c: Update copyright mysys/my_lwrite.c: Update copyright mysys/my_malloc.c: Update copyright mysys/my_messnc.c: Update copyright mysys/my_mkdir.c: Update copyright mysys/my_net.c: Update copyright mysys/my_once.c: Update copyright mysys/my_open.c: Update copyright mysys/my_pread.c: Update copyright mysys/my_pthread.c: Update copyright mysys/my_quick.c: Update copyright mysys/my_read.c: Update copyright mysys/my_realloc.c: Update copyright mysys/my_redel.c: Update copyright mysys/my_rename.c: Update copyright mysys/my_seek.c: Update copyright mysys/my_static.c: Update copyright mysys/my_static.h: Update copyright mysys/my_symlink.c: Update copyright mysys/my_symlink2.c: Update copyright mysys/my_tempnam.c: Update copyright mysys/my_thr_init.c: Update copyright mysys/my_vsnprintf.c: Update copyright mysys/my_wincond.c: Update copyright mysys/my_winthread.c: Update copyright mysys/my_write.c: Update copyright mysys/mysys_priv.h: Update copyright mysys/ptr_cmp.c: Update copyright mysys/queues.c: Update copyright mysys/raid.cc: Update copyright mysys/safemalloc.c: Update copyright mysys/string.c: Update copyright mysys/test_charset.c: Update copyright mysys/test_dir.c: Update copyright mysys/test_fn.c: Update copyright mysys/testhash.c: Update copyright mysys/thr_alarm.c: Update copyright mysys/thr_lock.c: Update copyright mysys/thr_mutex.c: Update copyright mysys/thr_rwlock.c: Update copyright mysys/tree.c: Update copyright mysys/typelib.c: Update copyright pstack/debug.c: Update copyright pstack/debug.h: Update copyright pstack/demangle.h: Update copyright pstack/ieee.c: Update copyright pstack/ieee.h: Update copyright pstack/pstack.c: Update copyright readline/bind.c: Cleanup empty lines readline/complete.c: Cleanup empty lines readline/display.c: Cleanup empty lines readline/funmap.c: Cleanup empty lines readline/histexpand.c: Cleanup empty lines readline/histfile.c: Cleanup empty lines readline/history.c: Cleanup empty lines readline/history.h: Cleanup empty lines readline/input.c: Cleanup empty lines readline/kill.c: Cleanup empty lines readline/readline.c: Cleanup empty lines readline/readline.h: Cleanup empty lines readline/vi_mode.c: Cleanup empty lines sql/cache_manager.cc: Update copyright sql/cache_manager.h: Update copyright sql/convert.cc: Update copyright sql/custom_conf.h: Update copyright sql/derror.cc: Update copyright sql/field.cc: Update copyright sql/field.h: Update copyright sql/field_conv.cc: Update copyright sql/filesort.cc: Update copyright sql/frm_crypt.cc: Update copyright sql/ha_berkeley.cc: Update copyright sql/ha_heap.cc: Update copyright sql/ha_heap.h: Update copyright sql/ha_innobase.cc: Update copyright sql/ha_isam.cc: Update copyright sql/ha_isam.h: Update copyright sql/ha_isammrg.cc: Update copyright sql/ha_isammrg.h: Update copyright sql/ha_myisam.cc: Update copyright sql/handler.cc: Update copyright sql/hash_filo.cc: Update copyright sql/hash_filo.h: Update copyright sql/hostname.cc: Update copyright sql/init.cc: Update copyright sql/item.cc: Update copyright sql/item.h: Update copyright sql/item_buff.cc: Update copyright sql/item_cmpfunc.cc: Update copyright sql/item_cmpfunc.h: Update copyright sql/item_create.cc: Update copyright sql/item_create.h: Update copyright sql/item_func.cc: Update copyright sql/item_strfunc.cc: Update copyright sql/item_sum.cc: Update copyright sql/item_sum.h: Update copyright sql/item_timefunc.cc: Update copyright sql/item_timefunc.h: Update copyright sql/item_uniq.cc: Update copyright sql/item_uniq.h: Update copyright sql/key.cc: Update copyright sql/lex_symbol.h: Update copyright sql/lock.cc: Update copyright sql/log.cc: Update copyright sql/log_event.cc: Update copyright sql/log_event.h: Update copyright sql/matherr.c: Update copyright sql/mf_iocache.cc: Update copyright sql/mini_client.cc: Update copyright sql/mini_client.h: Update copyright sql/my_lock.c: Update copyright sql/mysqld.cc: Update copyright sql/net_pkg.cc: Update copyright sql/net_serv.cc: Update copyright sql/opt_sum.cc: Update copyright sql/password.c: Update copyright sql/procedure.cc: Update copyright sql/procedure.h: Update copyright sql/records.cc: Update copyright sql/repl_failsafe.cc: Update copyright sql/slave.cc: Update copyright sql/slave.h: Update copyright sql/sql_acl.cc: Update copyright sql/sql_acl.h: Update copyright sql/sql_analyse.cc: Update copyright sql/sql_analyse.h: Update copyright sql/sql_base.cc: Update copyright sql/sql_cache.cc: Update copyright sql/sql_class.cc: Update copyright sql/sql_class.h: Update copyright sql/sql_crypt.cc: Update copyright sql/sql_crypt.h: Update copyright sql/sql_db.cc: Update copyright sql/sql_delete.cc: Update copyright sql/sql_handler.cc: Update copyright sql/sql_insert.cc: Update copyright sql/sql_lex.cc: Update copyright sql/sql_lex.h: Update copyright sql/sql_list.cc: Update copyright sql/sql_list.h: Update copyright sql/sql_load.cc: Update copyright sql/sql_map.cc: Update copyright sql/sql_map.h: Update copyright sql/sql_parse.cc: Update copyright sql/sql_rename.cc: Update copyright sql/sql_repl.cc: Update copyright sql/sql_select.h: Update copyright sql/sql_string.cc: Update copyright sql/sql_string.h: Update copyright sql/sql_table.cc: Update copyright sql/sql_test.cc: Update copyright sql/sql_udf.cc: Update copyright sql/sql_udf.h: Update copyright sql/stacktrace.c: Update copyright sql/structs.h: Update copyright sql/table.cc: Update copyright sql/table.h: Update copyright sql/thr_malloc.cc: Update copyright sql/time.cc: Update copyright sql/udf_example.cc: Update copyright sql/uniques.cc: Update copyright sql/unireg.cc: Update copyright sql/unireg.h: Update copyright strings/atof.c: Update copyright strings/bchange.c: Update copyright strings/bcmp.c: Update copyright strings/bcopy-duff.c: Update copyright strings/bfill.c: Update copyright strings/bmove.c: Update copyright strings/bmove512.c: Update copyright strings/bmove_upp.c: Update copyright strings/bzero.c: Update copyright strings/conf_to_src.c: Update copyright strings/ctype-big5.c: Update copyright strings/ctype-czech.c: Update copyright strings/ctype-euc_kr.c: Update copyright strings/ctype-gb2312.c: Update copyright strings/ctype-gbk.c: Update copyright strings/ctype-latin1_de.c: Update copyright strings/ctype-sjis.c: Update copyright strings/ctype-tis620.c: Update copyright strings/ctype-ujis.c: Update copyright strings/ctype.c: Update copyright strings/do_ctype.c: Update copyright strings/int2str.c: Update copyright strings/is_prefix.c: Update copyright strings/llstr.c: Update copyright strings/longlong2str.c: Update copyright strings/memcmp.c: Update copyright strings/memcpy.c: Update copyright strings/memset.c: Update copyright strings/r_strinstr.c: Update copyright strings/str2int.c: Update copyright strings/str_test.c: Update copyright strings/strappend.c: Update copyright strings/strcat.c: Update copyright strings/strcend.c: Update copyright strings/strchr.c: Update copyright strings/strcmp.c: Update copyright strings/strcont.c: Update copyright strings/strend.c: Update copyright strings/strfill.c: Update copyright strings/strings-not-used.h: Update copyright strings/strinstr.c: Update copyright strings/strlen.c: Update copyright strings/strmake.c: Update copyright strings/strmov.c: Update copyright strings/strnlen.c: Update copyright strings/strnmov.c: Update copyright strings/strrchr.c: Update copyright strings/strstr.c: Update copyright strings/strto.c: Update copyright strings/strtol.c: Update copyright strings/strtoll.c: Update copyright strings/strtoul.c: Update copyright strings/strtoull.c: Update copyright strings/strxmov.c: Update copyright strings/strxnmov.c: Update copyright strings/t_ctype.h: Update copyright strings/udiv.c: Update copyright tools/mysqlmanager.c: Update copyright vio/test-ssl.c: Update copyright vio/test-sslclient.c: Update copyright vio/test-sslserver.c: Update copyright vio/vio.c: Update copyright vio/viosocket.c: Update copyright vio/viossl.c: Update copyright vio/viosslfactories.c: Update copyright vio/viotest-ssl.c: Update copyright
24 years ago
Added all changes from old 4.0 version: PSTACK, libmysqld and MySQL filesystem UPDATE ... ORDER BY DELETE ... ORDER BY New faster fulltext handling Faster compressed keys Makefile.am: Added support for pstack and libmysqld_dir acconfig.h: MySQL filesystem and PSTACK acinclude.m4: MySQL File system client/mysql.cc: Support for --xml configure.in: Pstack, MySQL FS and libmysqld_dir include/ft_global.h: Faster fulltext include/my_pthread.h: Made c++ safe include/myisam.h: Update for faster fulltext include/mysql_com.h: new my_net_read() include/violite.h: libmysqld libmysql/net.c: New protocol that supports big packets myisam/Makefile.am: Faster fulltext myisam/ft_parser.c: Faster fulltext myisam/ft_search.c: Faster fulltext myisam/ft_update.c: Faster fulltext myisam/ftdefs.h: Faster fulltext myisam/mi_check.c: Faster fulltext myisam/mi_open.c: Faster compressed keys myisam/mi_search.c: Faster compressed keys myisam/mi_update.c: Faster compressed keys myisam/myisamdef.h: Faster compressed keys myisam/sort.c: Faster compressed keys mysql-test/mysql-test-run.sh: --skip-innobase and --skip-bdb sql/ChangeLog: Changelog sql/Makefile.am: PSTACK sql/mysql_priv.h: New ORDER BY options and libmysqld sql/mysqld.cc: PSTACK sql/net_serv.cc: New protocol that supports big packets sql/share/estonian/errmsg.txt: New error messages sql/sql_base.cc: Better list_open_tabels sql/sql_delete.cc: ORDER BY for delete sql/sql_lex.cc: Added language convertation of all strings sql/sql_parse.cc: Changes for libmysqld Use new ORDER BY options sql/sql_show.cc: Character set convertations Use new list_open_tables function. sql/sql_update.cc: UPDATE ... ORDER BY sql/sql_yacc.yy: Clean up symbol definitions DELETE .. ORDER BY UPDATE .. ORDER BY sql/table.h: new OPEN_TABLE_LIST structure BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted
25 years ago
Update copyright Fixed memory leak on shutdown (Affects the embedded version & MyODBC) client/client_priv.h: Update copyright client/completion_hash.cc: Update copyright client/completion_hash.h: Update copyright client/connect_test.c: Update copyright client/errmsg.c: Update copyright client/get_password.c: Update copyright client/insert_test.c: Update copyright client/list_test.c: Update copyright client/my_readline.h: Update copyright client/mysql.cc: Update copyright client/mysqladmin.c: Update copyright client/mysqlbinlog.cc: Update copyright client/mysqlcheck.c: Update copyright client/mysqldump.c: Update copyright client/mysqlimport.c: Update copyright client/mysqlmanager-pwgen.c: Update copyright client/mysqlmanagerc.c: Update copyright client/mysqlshow.c: Update copyright client/mysqltest.c: Update copyright client/password.c: Update copyright client/readline.cc: Update copyright client/select_test.c: Update copyright client/showdb_test.c: Update copyright client/sql_string.cc: Update copyright client/sql_string.h: Update copyright client/ssl_test.c: Update copyright client/thimble.cc: Update copyright client/thread_test.c: Update copyright div/deadlock_test.c: Update copyright extra/comp_err.c: Update copyright extra/my_print_defaults.c: Update copyright extra/perror.c: Update copyright extra/replace.c: Update copyright extra/resolve_stack_dump.c: Update copyright extra/resolveip.c: Update copyright fs/database.c: Update copyright fs/libmysqlfs.c: Update copyright fs/mysqlcorbafs.c: Update copyright fs/mysqlcorbafs.h: Update copyright fs/mysqlcorbafs_test.c: Update copyright heap/_check.c: Update copyright heap/_rectest.c: Update copyright heap/heapdef.h: Update copyright heap/hp_block.c: Update copyright heap/hp_clear.c: Update copyright heap/hp_close.c: Update copyright heap/hp_create.c: Update copyright heap/hp_delete.c: Update copyright heap/hp_extra.c: Update copyright heap/hp_hash.c: Update copyright heap/hp_info.c: Update copyright heap/hp_open.c: Update copyright heap/hp_panic.c: Update copyright heap/hp_rename.c: Update copyright heap/hp_rfirst.c: Update copyright heap/hp_rkey.c: Update copyright heap/hp_rlast.c: Update copyright heap/hp_rnext.c: Update copyright heap/hp_rprev.c: Update copyright heap/hp_rrnd.c: Update copyright heap/hp_rsame.c: Update copyright heap/hp_scan.c: Update copyright heap/hp_static.c: Update copyright heap/hp_test1.c: Update copyright heap/hp_test2.c: Update copyright heap/hp_update.c: Update copyright heap/hp_write.c: Update copyright include/config-win.h: Update copyright include/dbug.h: Update copyright include/errmsg.h: Update copyright include/ft_global.h: Update copyright include/getopt.h: Update copyright include/hash.h: Update copyright include/heap.h: Update copyright include/m_ctype.h: Update copyright include/m_string.h: Update copyright include/md5.h: Update copyright include/merge.h: Update copyright include/my_alarm.h: Update copyright include/my_base.h: Update copyright include/my_bitmap.h: Update copyright include/my_dir.h: Update copyright include/my_global.h: Update copyright include/my_list.h: Update copyright include/my_net.h: Update copyright include/my_no_pthread.h: Update copyright include/my_nosys.h: Update copyright include/my_pthread.h: Update copyright include/my_sys.h: Update copyright include/my_tree.h: Update copyright include/myisam.h: Update copyright include/myisammrg.h: Update copyright include/myisampack.h: Update copyright include/mysql.h: Update copyright include/mysql_com.h: Update copyright include/mysql_embed.h: Update copyright include/mysqld_error.h: Update copyright include/mysys_err.h: Update copyright include/nisam.h: Update copyright include/queues.h: Update copyright include/raid.h: Update copyright include/sslopt-case.h: Update copyright include/sslopt-longopts.h: Update copyright include/sslopt-usage.h: Update copyright include/sslopt-vars.h: Update copyright include/t_ctype.h: Update copyright include/thr_alarm.h: Update copyright include/thr_lock.h: Update copyright include/violite.h: Update copyright isam/_cache.c: Update copyright isam/_dbug.c: Update copyright isam/_key.c: Update copyright isam/_locking.c: Update copyright isam/_packrec.c: Update copyright isam/_page.c: Update copyright isam/_search.c: Update copyright isam/_statrec.c: Update copyright isam/changed.c: Update copyright isam/close.c: Update copyright isam/create.c: Update copyright isam/delete.c: Update copyright isam/extra.c: Update copyright isam/info.c: Update copyright isam/isamchk.c: Update copyright isam/isamdef.h: Update copyright isam/log.c: Update copyright isam/open.c: Update copyright isam/panic.c: Update copyright isam/range.c: Update copyright isam/rfirst.c: Update copyright isam/rkey.c: Update copyright isam/rlast.c: Update copyright isam/rnext.c: Update copyright isam/rprev.c: Update copyright isam/rrnd.c: Update copyright isam/rsame.c: Update copyright isam/rsamepos.c: Update copyright isam/sort.c: Update copyright isam/static.c: Update copyright isam/test1.c: Update copyright isam/test2.c: Update copyright isam/test3.c: Update copyright isam/update.c: Update copyright isam/write.c: Update copyright libmysql/conf_to_src.c: Update copyright libmysql/dll.c: Update copyright libmysql/errmsg.c: Update copyright libmysql/get_password.c: Update copyright libmysql/libmysql.c: Update copyright libmysql/manager.c: Update copyright libmysql/net.c: Update copyright libmysql/password.c: Update copyright libmysqld/lib_sql.cc: Update copyright libmysqld/lib_vio.c: Update copyright libmysqld/libmysqld.c: Update copyright merge/mrg_close.c: Update copyright merge/mrg_create.c: Update copyright merge/mrg_def.h: Update copyright merge/mrg_delete.c: Update copyright merge/mrg_extra.c: Update copyright merge/mrg_info.c: Update copyright merge/mrg_locking.c: Update copyright merge/mrg_open.c: Update copyright merge/mrg_panic.c: Update copyright merge/mrg_rrnd.c: Update copyright merge/mrg_rsame.c: Update copyright merge/mrg_static.c: Update copyright merge/mrg_update.c: Update copyright myisam/ft_boolean_search.c: Update copyright myisam/ft_dump.c: Update copyright myisam/ft_eval.h: Update copyright myisam/ft_static.c: Update copyright myisam/ft_stem.c: Update copyright myisam/ft_stopwords.c: Update copyright myisam/ft_test1.h: Update copyright myisam/mi_cache.c: Update copyright myisam/mi_changed.c: Update copyright myisam/mi_check.c: Update copyright myisam/mi_checksum.c: Update copyright myisam/mi_close.c: Update copyright myisam/mi_create.c: Update copyright myisam/mi_dbug.c: Update copyright myisam/mi_delete.c: Update copyright myisam/mi_delete_all.c: Update copyright myisam/mi_delete_table.c: Update copyright myisam/mi_dynrec.c: Update copyright myisam/mi_extra.c: Update copyright myisam/mi_info.c: Update copyright myisam/mi_key.c: Update copyright myisam/mi_locking.c: Update copyright myisam/mi_log.c: Update copyright myisam/mi_open.c: Update copyright myisam/mi_packrec.c: Update copyright myisam/mi_page.c: Update copyright myisam/mi_panic.c: Update copyright myisam/mi_range.c: Update copyright myisam/mi_rename.c: Update copyright myisam/mi_rfirst.c: Update copyright myisam/mi_rlast.c: Update copyright myisam/mi_rnext_same.c: Update copyright myisam/mi_rrnd.c: Update copyright myisam/mi_rsame.c: Update copyright myisam/mi_rsamepos.c: Update copyright myisam/mi_scan.c: Update copyright myisam/mi_search.c: Update copyright myisam/mi_static.c: Update copyright myisam/mi_statrec.c: Update copyright myisam/mi_test1.c: Update copyright myisam/mi_test2.c: Update copyright myisam/mi_test3.c: Update copyright myisam/mi_unique.c: Update copyright myisam/mi_update.c: Update copyright myisam/mi_write.c: Update copyright myisam/myisamchk.c: Update copyright myisam/myisampack.c: Update copyright myisammrg/myrg_close.c: Update copyright myisammrg/myrg_create.c: Update copyright myisammrg/myrg_def.h: Update copyright myisammrg/myrg_delete.c: Update copyright myisammrg/myrg_locking.c: Update copyright myisammrg/myrg_open.c: Update copyright myisammrg/myrg_panic.c: Update copyright myisammrg/myrg_rsame.c: Update copyright myisammrg/myrg_static.c: Update copyright myisammrg/myrg_update.c: Update copyright myisammrg/myrg_write.c: Update copyright mysql-test/r/gcc296.result: Update of benchmark results mysql-test/r/innodb.result: Update of benchmark results mysql-test/r/join_outer.result: Update of benchmark results mysql-test/r/myisam.result: Update of benchmark results mysys/array.c: Update copyright mysys/charset.c: Fix for restart of character sets mysys/checksum.c: Update copyright mysys/default.c: Update copyright mysys/errors.c: Update copyright mysys/getopt.c: Cleanup mysys/getvar.c: Update copyright mysys/hash.c: Update copyright mysys/list.c: Update copyright mysys/make-conf.c: Update copyright mysys/md5.c: Update copyright mysys/mf_brkhant.c: Update copyright mysys/mf_cache.c: Update copyright mysys/mf_casecnv.c: Update copyright mysys/mf_dirname.c: Update copyright mysys/mf_fn_ext.c: Update copyright mysys/mf_format.c: Update copyright mysys/mf_getdate.c: Update copyright mysys/mf_iocache.c: Update copyright mysys/mf_iocache2.c: Update copyright mysys/mf_keycache.c: Update copyright mysys/mf_loadpath.c: Update copyright mysys/mf_pack.c: Update copyright mysys/mf_path.c: Update copyright mysys/mf_qsort.c: Update copyright mysys/mf_qsort2.c: Update copyright mysys/mf_radix.c: Update copyright mysys/mf_same.c: Update copyright mysys/mf_sleep.c: Update copyright mysys/mf_sort.c: Update copyright mysys/mf_soundex.c: Update copyright mysys/mf_stripp.c: Update copyright mysys/mf_tempfile.c: Update copyright mysys/mf_unixpath.c: Update copyright mysys/mf_util.c: Update copyright mysys/mf_wcomp.c: Update copyright mysys/mf_wfile.c: Update copyright mysys/mulalloc.c: Update copyright mysys/my_alarm.c: Update copyright mysys/my_alloc.c: Update copyright mysys/my_append.c: Update copyright mysys/my_bit.c: Update copyright mysys/my_bitmap.c: Update copyright mysys/my_chsize.c: Update copyright mysys/my_clock.c: Update copyright mysys/my_compress.c: Update copyright mysys/my_copy.c: Update copyright mysys/my_create.c: Update copyright mysys/my_delete.c: Update copyright mysys/my_div.c: Update copyright mysys/my_dup.c: Update copyright mysys/my_error.c: Update copyright mysys/my_fopen.c: Update copyright mysys/my_fstream.c: Update copyright mysys/my_getwd.c: Update copyright mysys/my_init.c: Free 'once_alloc' memory at shutdown. mysys/my_lib.c: Update copyright mysys/my_lock.c: Update copyright mysys/my_lockmem.c: Update copyright mysys/my_lread.c: Update copyright mysys/my_lwrite.c: Update copyright mysys/my_malloc.c: Update copyright mysys/my_messnc.c: Update copyright mysys/my_mkdir.c: Update copyright mysys/my_net.c: Update copyright mysys/my_once.c: Update copyright mysys/my_open.c: Update copyright mysys/my_pread.c: Update copyright mysys/my_pthread.c: Update copyright mysys/my_quick.c: Update copyright mysys/my_read.c: Update copyright mysys/my_realloc.c: Update copyright mysys/my_redel.c: Update copyright mysys/my_rename.c: Update copyright mysys/my_seek.c: Update copyright mysys/my_static.c: Update copyright mysys/my_static.h: Update copyright mysys/my_symlink.c: Update copyright mysys/my_symlink2.c: Update copyright mysys/my_tempnam.c: Update copyright mysys/my_thr_init.c: Update copyright mysys/my_vsnprintf.c: Update copyright mysys/my_wincond.c: Update copyright mysys/my_winthread.c: Update copyright mysys/my_write.c: Update copyright mysys/mysys_priv.h: Update copyright mysys/ptr_cmp.c: Update copyright mysys/queues.c: Update copyright mysys/raid.cc: Update copyright mysys/safemalloc.c: Update copyright mysys/string.c: Update copyright mysys/test_charset.c: Update copyright mysys/test_dir.c: Update copyright mysys/test_fn.c: Update copyright mysys/testhash.c: Update copyright mysys/thr_alarm.c: Update copyright mysys/thr_lock.c: Update copyright mysys/thr_mutex.c: Update copyright mysys/thr_rwlock.c: Update copyright mysys/tree.c: Update copyright mysys/typelib.c: Update copyright pstack/debug.c: Update copyright pstack/debug.h: Update copyright pstack/demangle.h: Update copyright pstack/ieee.c: Update copyright pstack/ieee.h: Update copyright pstack/pstack.c: Update copyright readline/bind.c: Cleanup empty lines readline/complete.c: Cleanup empty lines readline/display.c: Cleanup empty lines readline/funmap.c: Cleanup empty lines readline/histexpand.c: Cleanup empty lines readline/histfile.c: Cleanup empty lines readline/history.c: Cleanup empty lines readline/history.h: Cleanup empty lines readline/input.c: Cleanup empty lines readline/kill.c: Cleanup empty lines readline/readline.c: Cleanup empty lines readline/readline.h: Cleanup empty lines readline/vi_mode.c: Cleanup empty lines sql/cache_manager.cc: Update copyright sql/cache_manager.h: Update copyright sql/convert.cc: Update copyright sql/custom_conf.h: Update copyright sql/derror.cc: Update copyright sql/field.cc: Update copyright sql/field.h: Update copyright sql/field_conv.cc: Update copyright sql/filesort.cc: Update copyright sql/frm_crypt.cc: Update copyright sql/ha_berkeley.cc: Update copyright sql/ha_heap.cc: Update copyright sql/ha_heap.h: Update copyright sql/ha_innobase.cc: Update copyright sql/ha_isam.cc: Update copyright sql/ha_isam.h: Update copyright sql/ha_isammrg.cc: Update copyright sql/ha_isammrg.h: Update copyright sql/ha_myisam.cc: Update copyright sql/handler.cc: Update copyright sql/hash_filo.cc: Update copyright sql/hash_filo.h: Update copyright sql/hostname.cc: Update copyright sql/init.cc: Update copyright sql/item.cc: Update copyright sql/item.h: Update copyright sql/item_buff.cc: Update copyright sql/item_cmpfunc.cc: Update copyright sql/item_cmpfunc.h: Update copyright sql/item_create.cc: Update copyright sql/item_create.h: Update copyright sql/item_func.cc: Update copyright sql/item_strfunc.cc: Update copyright sql/item_sum.cc: Update copyright sql/item_sum.h: Update copyright sql/item_timefunc.cc: Update copyright sql/item_timefunc.h: Update copyright sql/item_uniq.cc: Update copyright sql/item_uniq.h: Update copyright sql/key.cc: Update copyright sql/lex_symbol.h: Update copyright sql/lock.cc: Update copyright sql/log.cc: Update copyright sql/log_event.cc: Update copyright sql/log_event.h: Update copyright sql/matherr.c: Update copyright sql/mf_iocache.cc: Update copyright sql/mini_client.cc: Update copyright sql/mini_client.h: Update copyright sql/my_lock.c: Update copyright sql/mysqld.cc: Update copyright sql/net_pkg.cc: Update copyright sql/net_serv.cc: Update copyright sql/opt_sum.cc: Update copyright sql/password.c: Update copyright sql/procedure.cc: Update copyright sql/procedure.h: Update copyright sql/records.cc: Update copyright sql/repl_failsafe.cc: Update copyright sql/slave.cc: Update copyright sql/slave.h: Update copyright sql/sql_acl.cc: Update copyright sql/sql_acl.h: Update copyright sql/sql_analyse.cc: Update copyright sql/sql_analyse.h: Update copyright sql/sql_base.cc: Update copyright sql/sql_cache.cc: Update copyright sql/sql_class.cc: Update copyright sql/sql_class.h: Update copyright sql/sql_crypt.cc: Update copyright sql/sql_crypt.h: Update copyright sql/sql_db.cc: Update copyright sql/sql_delete.cc: Update copyright sql/sql_handler.cc: Update copyright sql/sql_insert.cc: Update copyright sql/sql_lex.cc: Update copyright sql/sql_lex.h: Update copyright sql/sql_list.cc: Update copyright sql/sql_list.h: Update copyright sql/sql_load.cc: Update copyright sql/sql_map.cc: Update copyright sql/sql_map.h: Update copyright sql/sql_parse.cc: Update copyright sql/sql_rename.cc: Update copyright sql/sql_repl.cc: Update copyright sql/sql_select.h: Update copyright sql/sql_string.cc: Update copyright sql/sql_string.h: Update copyright sql/sql_table.cc: Update copyright sql/sql_test.cc: Update copyright sql/sql_udf.cc: Update copyright sql/sql_udf.h: Update copyright sql/stacktrace.c: Update copyright sql/structs.h: Update copyright sql/table.cc: Update copyright sql/table.h: Update copyright sql/thr_malloc.cc: Update copyright sql/time.cc: Update copyright sql/udf_example.cc: Update copyright sql/uniques.cc: Update copyright sql/unireg.cc: Update copyright sql/unireg.h: Update copyright strings/atof.c: Update copyright strings/bchange.c: Update copyright strings/bcmp.c: Update copyright strings/bcopy-duff.c: Update copyright strings/bfill.c: Update copyright strings/bmove.c: Update copyright strings/bmove512.c: Update copyright strings/bmove_upp.c: Update copyright strings/bzero.c: Update copyright strings/conf_to_src.c: Update copyright strings/ctype-big5.c: Update copyright strings/ctype-czech.c: Update copyright strings/ctype-euc_kr.c: Update copyright strings/ctype-gb2312.c: Update copyright strings/ctype-gbk.c: Update copyright strings/ctype-latin1_de.c: Update copyright strings/ctype-sjis.c: Update copyright strings/ctype-tis620.c: Update copyright strings/ctype-ujis.c: Update copyright strings/ctype.c: Update copyright strings/do_ctype.c: Update copyright strings/int2str.c: Update copyright strings/is_prefix.c: Update copyright strings/llstr.c: Update copyright strings/longlong2str.c: Update copyright strings/memcmp.c: Update copyright strings/memcpy.c: Update copyright strings/memset.c: Update copyright strings/r_strinstr.c: Update copyright strings/str2int.c: Update copyright strings/str_test.c: Update copyright strings/strappend.c: Update copyright strings/strcat.c: Update copyright strings/strcend.c: Update copyright strings/strchr.c: Update copyright strings/strcmp.c: Update copyright strings/strcont.c: Update copyright strings/strend.c: Update copyright strings/strfill.c: Update copyright strings/strings-not-used.h: Update copyright strings/strinstr.c: Update copyright strings/strlen.c: Update copyright strings/strmake.c: Update copyright strings/strmov.c: Update copyright strings/strnlen.c: Update copyright strings/strnmov.c: Update copyright strings/strrchr.c: Update copyright strings/strstr.c: Update copyright strings/strto.c: Update copyright strings/strtol.c: Update copyright strings/strtoll.c: Update copyright strings/strtoul.c: Update copyright strings/strtoull.c: Update copyright strings/strxmov.c: Update copyright strings/strxnmov.c: Update copyright strings/t_ctype.h: Update copyright strings/udiv.c: Update copyright tools/mysqlmanager.c: Update copyright vio/test-ssl.c: Update copyright vio/test-sslclient.c: Update copyright vio/test-sslserver.c: Update copyright vio/vio.c: Update copyright vio/viosocket.c: Update copyright vio/viossl.c: Update copyright vio/viosslfactories.c: Update copyright vio/viotest-ssl.c: Update copyright
24 years ago
Added all changes from old 4.0 version: PSTACK, libmysqld and MySQL filesystem UPDATE ... ORDER BY DELETE ... ORDER BY New faster fulltext handling Faster compressed keys Makefile.am: Added support for pstack and libmysqld_dir acconfig.h: MySQL filesystem and PSTACK acinclude.m4: MySQL File system client/mysql.cc: Support for --xml configure.in: Pstack, MySQL FS and libmysqld_dir include/ft_global.h: Faster fulltext include/my_pthread.h: Made c++ safe include/myisam.h: Update for faster fulltext include/mysql_com.h: new my_net_read() include/violite.h: libmysqld libmysql/net.c: New protocol that supports big packets myisam/Makefile.am: Faster fulltext myisam/ft_parser.c: Faster fulltext myisam/ft_search.c: Faster fulltext myisam/ft_update.c: Faster fulltext myisam/ftdefs.h: Faster fulltext myisam/mi_check.c: Faster fulltext myisam/mi_open.c: Faster compressed keys myisam/mi_search.c: Faster compressed keys myisam/mi_update.c: Faster compressed keys myisam/myisamdef.h: Faster compressed keys myisam/sort.c: Faster compressed keys mysql-test/mysql-test-run.sh: --skip-innobase and --skip-bdb sql/ChangeLog: Changelog sql/Makefile.am: PSTACK sql/mysql_priv.h: New ORDER BY options and libmysqld sql/mysqld.cc: PSTACK sql/net_serv.cc: New protocol that supports big packets sql/share/estonian/errmsg.txt: New error messages sql/sql_base.cc: Better list_open_tabels sql/sql_delete.cc: ORDER BY for delete sql/sql_lex.cc: Added language convertation of all strings sql/sql_parse.cc: Changes for libmysqld Use new ORDER BY options sql/sql_show.cc: Character set convertations Use new list_open_tables function. sql/sql_update.cc: UPDATE ... ORDER BY sql/sql_yacc.yy: Clean up symbol definitions DELETE .. ORDER BY UPDATE .. ORDER BY sql/table.h: new OPEN_TABLE_LIST structure BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted
25 years ago
Added all changes from old 4.0 version: PSTACK, libmysqld and MySQL filesystem UPDATE ... ORDER BY DELETE ... ORDER BY New faster fulltext handling Faster compressed keys Makefile.am: Added support for pstack and libmysqld_dir acconfig.h: MySQL filesystem and PSTACK acinclude.m4: MySQL File system client/mysql.cc: Support for --xml configure.in: Pstack, MySQL FS and libmysqld_dir include/ft_global.h: Faster fulltext include/my_pthread.h: Made c++ safe include/myisam.h: Update for faster fulltext include/mysql_com.h: new my_net_read() include/violite.h: libmysqld libmysql/net.c: New protocol that supports big packets myisam/Makefile.am: Faster fulltext myisam/ft_parser.c: Faster fulltext myisam/ft_search.c: Faster fulltext myisam/ft_update.c: Faster fulltext myisam/ftdefs.h: Faster fulltext myisam/mi_check.c: Faster fulltext myisam/mi_open.c: Faster compressed keys myisam/mi_search.c: Faster compressed keys myisam/mi_update.c: Faster compressed keys myisam/myisamdef.h: Faster compressed keys myisam/sort.c: Faster compressed keys mysql-test/mysql-test-run.sh: --skip-innobase and --skip-bdb sql/ChangeLog: Changelog sql/Makefile.am: PSTACK sql/mysql_priv.h: New ORDER BY options and libmysqld sql/mysqld.cc: PSTACK sql/net_serv.cc: New protocol that supports big packets sql/share/estonian/errmsg.txt: New error messages sql/sql_base.cc: Better list_open_tabels sql/sql_delete.cc: ORDER BY for delete sql/sql_lex.cc: Added language convertation of all strings sql/sql_parse.cc: Changes for libmysqld Use new ORDER BY options sql/sql_show.cc: Character set convertations Use new list_open_tables function. sql/sql_update.cc: UPDATE ... ORDER BY sql/sql_yacc.yy: Clean up symbol definitions DELETE .. ORDER BY UPDATE .. ORDER BY sql/table.h: new OPEN_TABLE_LIST structure BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted
25 years ago
Added all changes from old 4.0 version: PSTACK, libmysqld and MySQL filesystem UPDATE ... ORDER BY DELETE ... ORDER BY New faster fulltext handling Faster compressed keys Makefile.am: Added support for pstack and libmysqld_dir acconfig.h: MySQL filesystem and PSTACK acinclude.m4: MySQL File system client/mysql.cc: Support for --xml configure.in: Pstack, MySQL FS and libmysqld_dir include/ft_global.h: Faster fulltext include/my_pthread.h: Made c++ safe include/myisam.h: Update for faster fulltext include/mysql_com.h: new my_net_read() include/violite.h: libmysqld libmysql/net.c: New protocol that supports big packets myisam/Makefile.am: Faster fulltext myisam/ft_parser.c: Faster fulltext myisam/ft_search.c: Faster fulltext myisam/ft_update.c: Faster fulltext myisam/ftdefs.h: Faster fulltext myisam/mi_check.c: Faster fulltext myisam/mi_open.c: Faster compressed keys myisam/mi_search.c: Faster compressed keys myisam/mi_update.c: Faster compressed keys myisam/myisamdef.h: Faster compressed keys myisam/sort.c: Faster compressed keys mysql-test/mysql-test-run.sh: --skip-innobase and --skip-bdb sql/ChangeLog: Changelog sql/Makefile.am: PSTACK sql/mysql_priv.h: New ORDER BY options and libmysqld sql/mysqld.cc: PSTACK sql/net_serv.cc: New protocol that supports big packets sql/share/estonian/errmsg.txt: New error messages sql/sql_base.cc: Better list_open_tabels sql/sql_delete.cc: ORDER BY for delete sql/sql_lex.cc: Added language convertation of all strings sql/sql_parse.cc: Changes for libmysqld Use new ORDER BY options sql/sql_show.cc: Character set convertations Use new list_open_tables function. sql/sql_update.cc: UPDATE ... ORDER BY sql/sql_yacc.yy: Clean up symbol definitions DELETE .. ORDER BY UPDATE .. ORDER BY sql/table.h: new OPEN_TABLE_LIST structure BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted
25 years ago
  1. /*
  2. pstack.c -- asynchronous stack trace of a running process
  3. Copyright (c) 1999 Ross Thompson
  4. Author: Ross Thompson <ross@whatsis.com>
  5. Critical bug fix: Tim Waugh
  6. */
  7. /*
  8. This file is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. */
  20. /* RESTRICTIONS:
  21. pstack currently works only on Linux, only on an x86 machine running
  22. 32 bit ELF binaries (64 bit not supported). Also, for symbolic
  23. information, you need to use a GNU compiler to generate your
  24. program, and you can't strip symbols from the binaries. For thread
  25. information to be dumped, you have to use the debug-aware version
  26. of libpthread.so. (To check, run 'nm' on your libpthread.so, and
  27. make sure that the symbol "__pthread_threads_debug" is defined.)
  28. The details of pulling stuff out of ELF files and running through
  29. program images is very platform specific, and I don't want to
  30. try to support modes or machine types I can't test in or on.
  31. If someone wants to generalize this to other architectures, I would
  32. be happy to help and coordinate the activity. Please send me whatever
  33. changes you make to support these machines, so that I can own the
  34. central font of all truth (at least as regards this program).
  35. Thanks
  36. */
  37. #include <sys/types.h>
  38. #include <sys/stat.h>
  39. #include <sys/wait.h>
  40. #include <sys/ptrace.h>
  41. #include <asm/ptrace.h>
  42. #include <assert.h>
  43. #include <fcntl.h>
  44. #include <link.h>
  45. #include <malloc.h>
  46. #include <string.h>
  47. #include <stdarg.h>
  48. #include <unistd.h>
  49. #include <stdlib.h>
  50. #include <stdio.h>
  51. #include <errno.h>
  52. #include <signal.h>
  53. #include <pthread.h>
  54. #include <limits.h> /* PTHREAD_THREADS_MAX */
  55. #include <bfd.h>
  56. #include "libiberty.h"
  57. #include "pstack.h" /* just one function */
  58. #include "budbg.h" /* binutils stuff related to debugging symbols. */
  59. #include "bucomm.h" /* some common stuff */
  60. #include "debug.h" /* and more binutils stuff... */
  61. #include "budbg.h"
  62. #include "linuxthreads.h" /* LinuxThreads specific stuff... */
  63. /*
  64. * fprintf for file descriptors :) NOTE: we have to use fixed-size buffer :)(
  65. * due to malloc's unavalaibility.
  66. */
  67. int
  68. fdprintf( int fd,
  69. const char* fmt,...)
  70. {
  71. char xbuf[2048];// FIXME: enough?
  72. va_list ap;
  73. int r;
  74. if (fd<0)
  75. return -1;
  76. va_start(ap, fmt);
  77. r = vsnprintf(xbuf, sizeof(xbuf), fmt, ap);
  78. va_end(ap);
  79. return write(fd, xbuf, r);
  80. }
  81. int
  82. fdputc( char c,
  83. int fd)
  84. {
  85. if (fd<0)
  86. return -1;
  87. return write(fd, &c, sizeof(c));
  88. }
  89. int
  90. fdputs( const char* s,
  91. int fd)
  92. {
  93. if (fd<0)
  94. return -1;
  95. return write(fd, s, strlen(s));
  96. }
  97. /*
  98. * Use this function to open log file.
  99. * Flags: truncate on opening.
  100. */
  101. static const char* path_format = "stack-trace-on-segv-%d.txt";
  102. static int
  103. open_log_file( const pthread_t tid,
  104. const pid_t pid)
  105. {
  106. char fname[PATH_MAX];
  107. int r;
  108. snprintf(fname, sizeof(fname), path_format, tid, pid);
  109. r = open(fname, O_WRONLY|O_CREAT|O_TRUNC,
  110. S_IRUSR|S_IWUSR);
  111. if (r<0)
  112. perror("open");
  113. return r;
  114. }
  115. /*
  116. * Add additional debugging information for functions.
  117. */
  118. /*
  119. * Lineno
  120. */
  121. typedef struct {
  122. int lineno;
  123. bfd_vma addr;
  124. } debug_lineno_t;
  125. /*
  126. * Block - a {} pair.
  127. */
  128. typedef struct debug_block_st {
  129. bfd_vma begin_addr; /* where did it start */
  130. bfd_vma end_addr; /* where did it end */
  131. struct debug_block_st* parent;
  132. struct debug_block_st* childs;
  133. int childs_count;
  134. } debug_block_t;
  135. /*
  136. * Function parameter.
  137. */
  138. typedef struct {
  139. bfd_vma offset; /* Offset in the stack */
  140. const char* name; /* And name. */
  141. } debug_parameter_t;
  142. /*
  143. * Extra information about functions.
  144. */
  145. typedef struct {
  146. asymbol* symbol; /* mangled function name, addr */
  147. debug_lineno_t* lines;
  148. int lines_count;
  149. int max_lines_count;
  150. const char* name;
  151. const char* filename;/* a file name it occured in... */
  152. debug_block_t* block; /* each function has a block, or not, you know */
  153. debug_parameter_t* argv; /* argument types. */
  154. int argc;
  155. int max_argc;
  156. } debug_function_t;
  157. /* This is the structure we use as a handle for these routines. */
  158. struct pr_handle
  159. {
  160. /* File to print information to. */
  161. FILE *f;
  162. /* Current indentation level. */
  163. unsigned int indent;
  164. /* Type stack. */
  165. struct pr_stack *stack;
  166. /* Parameter number we are about to output. */
  167. int parameter;
  168. debug_block_t* block; /* current block */
  169. debug_function_t* function; /* current function */
  170. debug_function_t* functions; /* all functions */
  171. int functions_size; /* current size */
  172. int functions_maxsize; /* maximum size */
  173. };
  174. /* The type stack. */
  175. struct pr_stack
  176. {
  177. /* Next element on the stack. */
  178. struct pr_stack *next;
  179. /* This element. */
  180. char *type;
  181. /* Current visibility of fields if this is a class. */
  182. enum debug_visibility visibility;
  183. /* Name of the current method we are handling. */
  184. const char *method;
  185. };
  186. static void indent PARAMS ((struct pr_handle *));
  187. static boolean push_type PARAMS ((struct pr_handle *, const char *));
  188. static boolean prepend_type PARAMS ((struct pr_handle *, const char *));
  189. static boolean append_type PARAMS ((struct pr_handle *, const char *));
  190. static boolean substitute_type PARAMS ((struct pr_handle *, const char *));
  191. static boolean indent_type PARAMS ((struct pr_handle *));
  192. static char *pop_type PARAMS ((struct pr_handle *));
  193. static void print_vma PARAMS ((bfd_vma, char *, boolean, boolean));
  194. static boolean pr_fix_visibility
  195. PARAMS ((struct pr_handle *, enum debug_visibility));
  196. static boolean pr_start_compilation_unit PARAMS ((PTR, const char *));
  197. static boolean pr_start_source PARAMS ((PTR, const char *));
  198. static boolean pr_empty_type PARAMS ((PTR));
  199. static boolean pr_void_type PARAMS ((PTR));
  200. static boolean pr_int_type PARAMS ((PTR, unsigned int, boolean));
  201. static boolean pr_float_type PARAMS ((PTR, unsigned int));
  202. static boolean pr_complex_type PARAMS ((PTR, unsigned int));
  203. static boolean pr_bool_type PARAMS ((PTR, unsigned int));
  204. static boolean pr_enum_type
  205. PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
  206. static boolean pr_pointer_type PARAMS ((PTR));
  207. static boolean pr_function_type PARAMS ((PTR, int, boolean));
  208. static boolean pr_reference_type PARAMS ((PTR));
  209. static boolean pr_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
  210. static boolean pr_array_type
  211. PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
  212. static boolean pr_set_type PARAMS ((PTR, boolean));
  213. static boolean pr_offset_type PARAMS ((PTR));
  214. static boolean pr_method_type PARAMS ((PTR, boolean, int, boolean));
  215. static boolean pr_const_type PARAMS ((PTR));
  216. static boolean pr_volatile_type PARAMS ((PTR));
  217. static boolean pr_start_struct_type
  218. PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int));
  219. static boolean pr_struct_field
  220. PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
  221. static boolean pr_end_struct_type PARAMS ((PTR));
  222. static boolean pr_start_class_type
  223. PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean,
  224. boolean));
  225. static boolean pr_class_static_member
  226. PARAMS ((PTR, const char *, const char *, enum debug_visibility));
  227. static boolean pr_class_baseclass
  228. PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility));
  229. static boolean pr_class_start_method PARAMS ((PTR, const char *));
  230. static boolean pr_class_method_variant
  231. PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean,
  232. bfd_vma, boolean));
  233. static boolean pr_class_static_method_variant
  234. PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean));
  235. static boolean pr_class_end_method PARAMS ((PTR));
  236. static boolean pr_end_class_type PARAMS ((PTR));
  237. static boolean pr_typedef_type PARAMS ((PTR, const char *));
  238. static boolean pr_tag_type
  239. PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
  240. static boolean pr_typdef PARAMS ((PTR, const char *));
  241. static boolean pr_tag PARAMS ((PTR, const char *));
  242. static boolean pr_int_constant PARAMS ((PTR, const char *, bfd_vma));
  243. static boolean pr_float_constant PARAMS ((PTR, const char *, double));
  244. static boolean pr_typed_constant PARAMS ((PTR, const char *, bfd_vma));
  245. static boolean pr_variable
  246. PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
  247. static boolean pr_start_function PARAMS ((PTR, const char *, boolean));
  248. static boolean pr_function_parameter
  249. PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
  250. static boolean pr_start_block PARAMS ((PTR, bfd_vma));
  251. static boolean pr_end_block PARAMS ((PTR, bfd_vma));
  252. static boolean pr_end_function PARAMS ((PTR));
  253. static boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma));
  254. static const struct debug_write_fns pr_fns =
  255. {
  256. pr_start_compilation_unit,
  257. pr_start_source,
  258. pr_empty_type,
  259. pr_void_type,
  260. pr_int_type,
  261. pr_float_type,
  262. pr_complex_type,
  263. pr_bool_type,
  264. pr_enum_type,
  265. pr_pointer_type,
  266. pr_function_type,
  267. pr_reference_type,
  268. pr_range_type,
  269. pr_array_type,
  270. pr_set_type,
  271. pr_offset_type,
  272. pr_method_type,
  273. pr_const_type,
  274. pr_volatile_type,
  275. pr_start_struct_type,
  276. pr_struct_field,
  277. pr_end_struct_type,
  278. pr_start_class_type,
  279. pr_class_static_member,
  280. pr_class_baseclass,
  281. pr_class_start_method,
  282. pr_class_method_variant,
  283. pr_class_static_method_variant,
  284. pr_class_end_method,
  285. pr_end_class_type,
  286. pr_typedef_type,
  287. pr_tag_type,
  288. pr_typdef,
  289. pr_tag,
  290. pr_int_constant,
  291. pr_float_constant,
  292. pr_typed_constant,
  293. pr_variable,
  294. pr_start_function,
  295. pr_function_parameter,
  296. pr_start_block,
  297. pr_end_block,
  298. pr_end_function,
  299. pr_lineno
  300. };
  301. /* Indent to the current indentation level. */
  302. static void
  303. indent (info)
  304. struct pr_handle *info;
  305. {
  306. unsigned int i;
  307. for (i = 0; i < info->indent; i++)
  308. TRACE_PUTC ((' ', info->f));
  309. }
  310. /* Push a type on the type stack. */
  311. static boolean
  312. push_type (info, type)
  313. struct pr_handle *info;
  314. const char *type;
  315. {
  316. struct pr_stack *n;
  317. if (type == NULL)
  318. return false;
  319. n = (struct pr_stack *) xmalloc (sizeof *n);
  320. memset (n, 0, sizeof *n);
  321. n->type = xstrdup (type);
  322. n->visibility = DEBUG_VISIBILITY_IGNORE;
  323. n->method = NULL;
  324. n->next = info->stack;
  325. info->stack = n;
  326. return true;
  327. }
  328. /* Prepend a string onto the type on the top of the type stack. */
  329. static boolean
  330. prepend_type (info, s)
  331. struct pr_handle *info;
  332. const char *s;
  333. {
  334. char *n;
  335. assert (info->stack != NULL);
  336. n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1);
  337. sprintf (n, "%s%s", s, info->stack->type);
  338. free (info->stack->type);
  339. info->stack->type = n;
  340. return true;
  341. }
  342. /* Append a string to the type on the top of the type stack. */
  343. static boolean
  344. append_type (info, s)
  345. struct pr_handle *info;
  346. const char *s;
  347. {
  348. unsigned int len;
  349. if (s == NULL)
  350. return false;
  351. assert (info->stack != NULL);
  352. len = strlen (info->stack->type);
  353. info->stack->type = (char *) xrealloc (info->stack->type,
  354. len + strlen (s) + 1);
  355. strcpy (info->stack->type + len, s);
  356. return true;
  357. }
  358. /* We use an underscore to indicate where the name should go in a type
  359. string. This function substitutes a string for the underscore. If
  360. there is no underscore, the name follows the type. */
  361. static boolean
  362. substitute_type (info, s)
  363. struct pr_handle *info;
  364. const char *s;
  365. {
  366. char *u;
  367. assert (info->stack != NULL);
  368. u = strchr (info->stack->type, '|');
  369. if (u != NULL)
  370. {
  371. char *n;
  372. n = (char *) xmalloc (strlen (info->stack->type) + strlen (s));
  373. memcpy (n, info->stack->type, u - info->stack->type);
  374. strcpy (n + (u - info->stack->type), s);
  375. strcat (n, u + 1);
  376. free (info->stack->type);
  377. info->stack->type = n;
  378. return true;
  379. }
  380. if (strchr (s, '|') != NULL
  381. && (strchr (info->stack->type, '{') != NULL
  382. || strchr (info->stack->type, '(') != NULL))
  383. {
  384. if (! prepend_type (info, "(")
  385. || ! append_type (info, ")"))
  386. return false;
  387. }
  388. if (*s == '\0')
  389. return true;
  390. return (append_type (info, " ")
  391. && append_type (info, s));
  392. }
  393. /* Indent the type at the top of the stack by appending spaces. */
  394. static boolean
  395. indent_type (info)
  396. struct pr_handle *info;
  397. {
  398. unsigned int i;
  399. for (i = 0; i < info->indent; i++)
  400. {
  401. if (! append_type (info, " "))
  402. return false;
  403. }
  404. return true;
  405. }
  406. /* Pop a type from the type stack. */
  407. static char *
  408. pop_type (info)
  409. struct pr_handle *info;
  410. {
  411. struct pr_stack *o;
  412. char *ret;
  413. assert (info->stack != NULL);
  414. o = info->stack;
  415. info->stack = o->next;
  416. ret = o->type;
  417. free (o);
  418. return ret;
  419. }
  420. /* Print a VMA value into a string. */
  421. static void
  422. print_vma (vma, buf, unsignedp, hexp)
  423. bfd_vma vma;
  424. char *buf;
  425. boolean unsignedp;
  426. boolean hexp;
  427. {
  428. if (sizeof (vma) <= sizeof (unsigned long))
  429. {
  430. if (hexp)
  431. sprintf (buf, "0x%lx", (unsigned long) vma);
  432. else if (unsignedp)
  433. sprintf (buf, "%lu", (unsigned long) vma);
  434. else
  435. sprintf (buf, "%ld", (long) vma);
  436. }
  437. else
  438. {
  439. buf[0] = '0';
  440. buf[1] = 'x';
  441. sprintf_vma (buf + 2, vma);
  442. }
  443. }
  444. /* Start a new compilation unit. */
  445. static boolean
  446. pr_start_compilation_unit (p, filename)
  447. PTR p;
  448. const char *filename;
  449. {
  450. struct pr_handle *info = (struct pr_handle *) p;
  451. assert (info->indent == 0);
  452. /*
  453. TRACE_FPRINTF( (info->f, "%s:\n", filename));
  454. */
  455. return true;
  456. }
  457. /* Start a source file within a compilation unit. */
  458. static boolean
  459. pr_start_source (p, filename)
  460. PTR p;
  461. const char *filename;
  462. {
  463. struct pr_handle *info = (struct pr_handle *) p;
  464. assert (info->indent == 0);
  465. /*
  466. TRACE_FPRINTF( (info->f, " %s:\n", filename));
  467. */
  468. return true;
  469. }
  470. /* Push an empty type onto the type stack. */
  471. static boolean
  472. pr_empty_type (p)
  473. PTR p;
  474. {
  475. struct pr_handle *info = (struct pr_handle *) p;
  476. return push_type (info, "<undefined>");
  477. }
  478. /* Push a void type onto the type stack. */
  479. static boolean
  480. pr_void_type (p)
  481. PTR p;
  482. {
  483. struct pr_handle *info = (struct pr_handle *) p;
  484. return push_type (info, "void");
  485. }
  486. /* Push an integer type onto the type stack. */
  487. static boolean
  488. pr_int_type (p, size, unsignedp)
  489. PTR p;
  490. unsigned int size;
  491. boolean unsignedp;
  492. {
  493. struct pr_handle *info = (struct pr_handle *) p;
  494. char ab[10];
  495. sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8);
  496. return push_type (info, ab);
  497. }
  498. /* Push a floating type onto the type stack. */
  499. static boolean
  500. pr_float_type (p, size)
  501. PTR p;
  502. unsigned int size;
  503. {
  504. struct pr_handle *info = (struct pr_handle *) p;
  505. char ab[10];
  506. if (size == 4)
  507. return push_type (info, "float");
  508. else if (size == 8)
  509. return push_type (info, "double");
  510. sprintf (ab, "float%d", size * 8);
  511. return push_type (info, ab);
  512. }
  513. /* Push a complex type onto the type stack. */
  514. static boolean
  515. pr_complex_type (p, size)
  516. PTR p;
  517. unsigned int size;
  518. {
  519. struct pr_handle *info = (struct pr_handle *) p;
  520. if (! pr_float_type (p, size))
  521. return false;
  522. return prepend_type (info, "complex ");
  523. }
  524. /* Push a boolean type onto the type stack. */
  525. static boolean
  526. pr_bool_type (p, size)
  527. PTR p;
  528. unsigned int size;
  529. {
  530. struct pr_handle *info = (struct pr_handle *) p;
  531. char ab[10];
  532. sprintf (ab, "bool%d", size * 8);
  533. return push_type (info, ab);
  534. }
  535. /* Push an enum type onto the type stack. */
  536. static boolean
  537. pr_enum_type (p, tag, names, values)
  538. PTR p;
  539. const char *tag;
  540. const char **names;
  541. bfd_signed_vma *values;
  542. {
  543. struct pr_handle *info = (struct pr_handle *) p;
  544. unsigned int i;
  545. bfd_signed_vma val;
  546. if (! push_type (info, "enum "))
  547. return false;
  548. if (tag != NULL)
  549. {
  550. if (! append_type (info, tag)
  551. || ! append_type (info, " "))
  552. return false;
  553. }
  554. if (! append_type (info, "{ "))
  555. return false;
  556. if (names == NULL)
  557. {
  558. if (! append_type (info, "/* undefined */"))
  559. return false;
  560. }
  561. else
  562. {
  563. val = 0;
  564. for (i = 0; names[i] != NULL; i++)
  565. {
  566. if (i > 0)
  567. {
  568. if (! append_type (info, ", "))
  569. return false;
  570. }
  571. if (! append_type (info, names[i]))
  572. return false;
  573. if (values[i] != val)
  574. {
  575. char ab[20];
  576. print_vma (values[i], ab, false, false);
  577. if (! append_type (info, " = ")
  578. || ! append_type (info, ab))
  579. return false;
  580. val = values[i];
  581. }
  582. ++val;
  583. }
  584. }
  585. return append_type (info, " }");
  586. }
  587. /* Turn the top type on the stack into a pointer. */
  588. static boolean
  589. pr_pointer_type (p)
  590. PTR p;
  591. {
  592. struct pr_handle *info = (struct pr_handle *) p;
  593. char *s;
  594. assert (info->stack != NULL);
  595. s = strchr (info->stack->type, '|');
  596. if (s != NULL && s[1] == '[')
  597. return substitute_type (info, "(*|)");
  598. return substitute_type (info, "*|");
  599. }
  600. /* Turn the top type on the stack into a function returning that type. */
  601. static boolean
  602. pr_function_type (p, argcount, varargs)
  603. PTR p;
  604. int argcount;
  605. boolean varargs;
  606. {
  607. struct pr_handle *info = (struct pr_handle *) p;
  608. char **arg_types;
  609. unsigned int len;
  610. char *s;
  611. assert (info->stack != NULL);
  612. len = 10;
  613. if (argcount <= 0)
  614. {
  615. arg_types = NULL;
  616. len += 15;
  617. }
  618. else
  619. {
  620. int i;
  621. arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
  622. for (i = argcount - 1; i >= 0; i--)
  623. {
  624. if (! substitute_type (info, ""))
  625. return false;
  626. arg_types[i] = pop_type (info);
  627. if (arg_types[i] == NULL)
  628. return false;
  629. len += strlen (arg_types[i]) + 2;
  630. }
  631. if (varargs)
  632. len += 5;
  633. }
  634. /* Now the return type is on the top of the stack. */
  635. s = (char *) xmalloc (len);
  636. strcpy (s, "(|) (");
  637. if (argcount < 0)
  638. {
  639. #if 0
  640. /* Turn off unknown arguments. */
  641. strcat (s, "/* unknown */");
  642. #endif
  643. }
  644. else
  645. {
  646. int i;
  647. for (i = 0; i < argcount; i++)
  648. {
  649. if (i > 0)
  650. strcat (s, ", ");
  651. strcat (s, arg_types[i]);
  652. }
  653. if (varargs)
  654. {
  655. if (i > 0)
  656. strcat (s, ", ");
  657. strcat (s, "...");
  658. }
  659. if (argcount > 0)
  660. free (arg_types);
  661. }
  662. strcat (s, ")");
  663. if (! substitute_type (info, s))
  664. return false;
  665. free (s);
  666. return true;
  667. }
  668. /* Turn the top type on the stack into a reference to that type. */
  669. static boolean
  670. pr_reference_type (p)
  671. PTR p;
  672. {
  673. struct pr_handle *info = (struct pr_handle *) p;
  674. assert (info->stack != NULL);
  675. return substitute_type (info, "&|");
  676. }
  677. /* Make a range type. */
  678. static boolean
  679. pr_range_type (p, lower, upper)
  680. PTR p;
  681. bfd_signed_vma lower;
  682. bfd_signed_vma upper;
  683. {
  684. struct pr_handle *info = (struct pr_handle *) p;
  685. char abl[20], abu[20];
  686. assert (info->stack != NULL);
  687. if (! substitute_type (info, ""))
  688. return false;
  689. print_vma (lower, abl, false, false);
  690. print_vma (upper, abu, false, false);
  691. return (prepend_type (info, "range (")
  692. && append_type (info, "):")
  693. && append_type (info, abl)
  694. && append_type (info, ":")
  695. && append_type (info, abu));
  696. }
  697. /* Make an array type. */
  698. /*ARGSUSED*/
  699. static boolean
  700. pr_array_type (p, lower, upper, stringp)
  701. PTR p;
  702. bfd_signed_vma lower;
  703. bfd_signed_vma upper;
  704. boolean stringp;
  705. {
  706. struct pr_handle *info = (struct pr_handle *) p;
  707. char *range_type;
  708. char abl[20], abu[20], ab[50];
  709. range_type = pop_type (info);
  710. if (range_type == NULL)
  711. return false;
  712. if (lower == 0)
  713. {
  714. if (upper == -1)
  715. sprintf (ab, "|[]");
  716. else
  717. {
  718. print_vma (upper + 1, abu, false, false);
  719. sprintf (ab, "|[%s]", abu);
  720. }
  721. }
  722. else
  723. {
  724. print_vma (lower, abl, false, false);
  725. print_vma (upper, abu, false, false);
  726. sprintf (ab, "|[%s:%s]", abl, abu);
  727. }
  728. if (! substitute_type (info, ab))
  729. return false;
  730. if (strcmp (range_type, "int") != 0)
  731. {
  732. if (! append_type (info, ":")
  733. || ! append_type (info, range_type))
  734. return false;
  735. }
  736. if (stringp)
  737. {
  738. if (! append_type (info, " /* string */"))
  739. return false;
  740. }
  741. return true;
  742. }
  743. /* Make a set type. */
  744. /*ARGSUSED*/
  745. static boolean
  746. pr_set_type (p, bitstringp)
  747. PTR p;
  748. boolean bitstringp;
  749. {
  750. struct pr_handle *info = (struct pr_handle *) p;
  751. if (! substitute_type (info, ""))
  752. return false;
  753. if (! prepend_type (info, "set { ")
  754. || ! append_type (info, " }"))
  755. return false;
  756. if (bitstringp)
  757. {
  758. if (! append_type (info, "/* bitstring */"))
  759. return false;
  760. }
  761. return true;
  762. }
  763. /* Make an offset type. */
  764. static boolean
  765. pr_offset_type (p)
  766. PTR p;
  767. {
  768. struct pr_handle *info = (struct pr_handle *) p;
  769. char *t;
  770. if (! substitute_type (info, ""))
  771. return false;
  772. t = pop_type (info);
  773. if (t == NULL)
  774. return false;
  775. return (substitute_type (info, "")
  776. && prepend_type (info, " ")
  777. && prepend_type (info, t)
  778. && append_type (info, "::|"));
  779. }
  780. /* Make a method type. */
  781. static boolean
  782. pr_method_type (p, domain, argcount, varargs)
  783. PTR p;
  784. boolean domain;
  785. int argcount;
  786. boolean varargs;
  787. {
  788. struct pr_handle *info = (struct pr_handle *) p;
  789. unsigned int len;
  790. char *domain_type;
  791. char **arg_types;
  792. char *s;
  793. len = 10;
  794. if (! domain)
  795. domain_type = NULL;
  796. else
  797. {
  798. if (! substitute_type (info, ""))
  799. return false;
  800. domain_type = pop_type (info);
  801. if (domain_type == NULL)
  802. return false;
  803. if (strncmp (domain_type, "class ", sizeof "class " - 1) == 0
  804. && strchr (domain_type + sizeof "class " - 1, ' ') == NULL)
  805. domain_type += sizeof "class " - 1;
  806. else if (strncmp (domain_type, "union class ",
  807. sizeof "union class ") == 0
  808. && (strchr (domain_type + sizeof "union class " - 1, ' ')
  809. == NULL))
  810. domain_type += sizeof "union class " - 1;
  811. len += strlen (domain_type);
  812. }
  813. if (argcount <= 0)
  814. {
  815. arg_types = NULL;
  816. len += 15;
  817. }
  818. else
  819. {
  820. int i;
  821. arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
  822. for (i = argcount - 1; i >= 0; i--)
  823. {
  824. if (! substitute_type (info, ""))
  825. return false;
  826. arg_types[i] = pop_type (info);
  827. if (arg_types[i] == NULL)
  828. return false;
  829. len += strlen (arg_types[i]) + 2;
  830. }
  831. if (varargs)
  832. len += 5;
  833. }
  834. /* Now the return type is on the top of the stack. */
  835. s = (char *) xmalloc (len);
  836. if (! domain)
  837. *s = '\0';
  838. else
  839. strcpy (s, domain_type);
  840. strcat (s, "::| (");
  841. if (argcount < 0)
  842. strcat (s, "/* unknown */");
  843. else
  844. {
  845. int i;
  846. for (i = 0; i < argcount; i++)
  847. {
  848. if (i > 0)
  849. strcat (s, ", ");
  850. strcat (s, arg_types[i]);
  851. }
  852. if (varargs)
  853. {
  854. if (i > 0)
  855. strcat (s, ", ");
  856. strcat (s, "...");
  857. }
  858. if (argcount > 0)
  859. free (arg_types);
  860. }
  861. strcat (s, ")");
  862. if (! substitute_type (info, s))
  863. return false;
  864. free (s);
  865. return true;
  866. }
  867. /* Make a const qualified type. */
  868. static boolean
  869. pr_const_type (p)
  870. PTR p;
  871. {
  872. struct pr_handle *info = (struct pr_handle *) p;
  873. return substitute_type (info, "const |");
  874. }
  875. /* Make a volatile qualified type. */
  876. static boolean
  877. pr_volatile_type (p)
  878. PTR p;
  879. {
  880. struct pr_handle *info = (struct pr_handle *) p;
  881. return substitute_type (info, "volatile |");
  882. }
  883. /* Start accumulating a struct type. */
  884. static boolean
  885. pr_start_struct_type (p, tag, id, structp, size)
  886. PTR p;
  887. const char *tag;
  888. unsigned int id;
  889. boolean structp;
  890. unsigned int size;
  891. {
  892. struct pr_handle *info = (struct pr_handle *) p;
  893. info->indent += 2;
  894. if (! push_type (info, structp ? "struct " : "union "))
  895. return false;
  896. if (tag != NULL)
  897. {
  898. if (! append_type (info, tag))
  899. return false;
  900. }
  901. else
  902. {
  903. char idbuf[20];
  904. sprintf (idbuf, "%%anon%u", id);
  905. if (! append_type (info, idbuf))
  906. return false;
  907. }
  908. if (! append_type (info, " {"))
  909. return false;
  910. if (size != 0 || tag != NULL)
  911. {
  912. char ab[30];
  913. if (! append_type (info, " /*"))
  914. return false;
  915. if (size != 0)
  916. {
  917. sprintf (ab, " size %u", size);
  918. if (! append_type (info, ab))
  919. return false;
  920. }
  921. if (tag != NULL)
  922. {
  923. sprintf (ab, " id %u", id);
  924. if (! append_type (info, ab))
  925. return false;
  926. }
  927. if (! append_type (info, " */"))
  928. return false;
  929. }
  930. if (! append_type (info, "\n"))
  931. return false;
  932. info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
  933. return indent_type (info);
  934. }
  935. /* Output the visibility of a field in a struct. */
  936. static boolean
  937. pr_fix_visibility (info, visibility)
  938. struct pr_handle *info;
  939. enum debug_visibility visibility;
  940. {
  941. const char *s;
  942. char *t;
  943. unsigned int len;
  944. assert (info->stack != NULL);
  945. if (info->stack->visibility == visibility)
  946. return true;
  947. assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE);
  948. switch (visibility)
  949. {
  950. case DEBUG_VISIBILITY_PUBLIC:
  951. s = "public";
  952. break;
  953. case DEBUG_VISIBILITY_PRIVATE:
  954. s = "private";
  955. break;
  956. case DEBUG_VISIBILITY_PROTECTED:
  957. s = "protected";
  958. break;
  959. case DEBUG_VISIBILITY_IGNORE:
  960. s = "/* ignore */";
  961. break;
  962. default:
  963. abort ();
  964. return false;
  965. }
  966. /* Trim off a trailing space in the struct string, to make the
  967. output look a bit better, then stick on the visibility string. */
  968. t = info->stack->type;
  969. len = strlen (t);
  970. assert (t[len - 1] == ' ');
  971. t[len - 1] = '\0';
  972. if (! append_type (info, s)
  973. || ! append_type (info, ":\n")
  974. || ! indent_type (info))
  975. return false;
  976. info->stack->visibility = visibility;
  977. return true;
  978. }
  979. /* Add a field to a struct type. */
  980. static boolean
  981. pr_struct_field (p, name, bitpos, bitsize, visibility)
  982. PTR p;
  983. const char *name;
  984. bfd_vma bitpos;
  985. bfd_vma bitsize;
  986. enum debug_visibility visibility;
  987. {
  988. struct pr_handle *info = (struct pr_handle *) p;
  989. char ab[20];
  990. char *t;
  991. if (! substitute_type (info, name))
  992. return false;
  993. if (! append_type (info, "; /* "))
  994. return false;
  995. if (bitsize != 0)
  996. {
  997. print_vma (bitsize, ab, true, false);
  998. if (! append_type (info, "bitsize ")
  999. || ! append_type (info, ab)
  1000. || ! append_type (info, ", "))
  1001. return false;
  1002. }
  1003. print_vma (bitpos, ab, true, false);
  1004. if (! append_type (info, "bitpos ")
  1005. || ! append_type (info, ab)
  1006. || ! append_type (info, " */\n")
  1007. || ! indent_type (info))
  1008. return false;
  1009. t = pop_type (info);
  1010. if (t == NULL)
  1011. return false;
  1012. if (! pr_fix_visibility (info, visibility))
  1013. return false;
  1014. return append_type (info, t);
  1015. }
  1016. /* Finish a struct type. */
  1017. static boolean
  1018. pr_end_struct_type (p)
  1019. PTR p;
  1020. {
  1021. struct pr_handle *info = (struct pr_handle *) p;
  1022. char *s;
  1023. assert (info->stack != NULL);
  1024. assert (info->indent >= 2);
  1025. info->indent -= 2;
  1026. /* Change the trailing indentation to have a close brace. */
  1027. s = info->stack->type + strlen (info->stack->type) - 2;
  1028. assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0');
  1029. *s++ = '}';
  1030. *s = '\0';
  1031. return true;
  1032. }
  1033. /* Start a class type. */
  1034. static boolean
  1035. pr_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
  1036. PTR p;
  1037. const char *tag;
  1038. unsigned int id;
  1039. boolean structp;
  1040. unsigned int size;
  1041. boolean vptr;
  1042. boolean ownvptr;
  1043. {
  1044. struct pr_handle *info = (struct pr_handle *) p;
  1045. char *tv = NULL;
  1046. info->indent += 2;
  1047. if (vptr && ! ownvptr)
  1048. {
  1049. tv = pop_type (info);
  1050. if (tv == NULL)
  1051. return false;
  1052. }
  1053. if (! push_type (info, structp ? "class " : "union class "))
  1054. return false;
  1055. if (tag != NULL)
  1056. {
  1057. if (! append_type (info, tag))
  1058. return false;
  1059. }
  1060. else
  1061. {
  1062. char idbuf[20];
  1063. sprintf (idbuf, "%%anon%u", id);
  1064. if (! append_type (info, idbuf))
  1065. return false;
  1066. }
  1067. if (! append_type (info, " {"))
  1068. return false;
  1069. if (size != 0 || vptr || ownvptr || tag != NULL)
  1070. {
  1071. if (! append_type (info, " /*"))
  1072. return false;
  1073. if (size != 0)
  1074. {
  1075. char ab[20];
  1076. sprintf (ab, "%u", size);
  1077. if (! append_type (info, " size ")
  1078. || ! append_type (info, ab))
  1079. return false;
  1080. }
  1081. if (vptr)
  1082. {
  1083. if (! append_type (info, " vtable "))
  1084. return false;
  1085. if (ownvptr)
  1086. {
  1087. if (! append_type (info, "self "))
  1088. return false;
  1089. }
  1090. else
  1091. {
  1092. if (! append_type (info, tv)
  1093. || ! append_type (info, " "))
  1094. return false;
  1095. }
  1096. }
  1097. if (tag != NULL)
  1098. {
  1099. char ab[30];
  1100. sprintf (ab, " id %u", id);
  1101. if (! append_type (info, ab))
  1102. return false;
  1103. }
  1104. if (! append_type (info, " */"))
  1105. return false;
  1106. }
  1107. info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
  1108. return (append_type (info, "\n")
  1109. && indent_type (info));
  1110. }
  1111. /* Add a static member to a class. */
  1112. static boolean
  1113. pr_class_static_member (p, name, physname, visibility)
  1114. PTR p;
  1115. const char *name;
  1116. const char *physname;
  1117. enum debug_visibility visibility;
  1118. {
  1119. struct pr_handle *info = (struct pr_handle *) p;
  1120. char *t;
  1121. if (! substitute_type (info, name))
  1122. return false;
  1123. if (! prepend_type (info, "static ")
  1124. || ! append_type (info, "; /* ")
  1125. || ! append_type (info, physname)
  1126. || ! append_type (info, " */\n")
  1127. || ! indent_type (info))
  1128. return false;
  1129. t = pop_type (info);
  1130. if (t == NULL)
  1131. return false;
  1132. if (! pr_fix_visibility (info, visibility))
  1133. return false;
  1134. return append_type (info, t);
  1135. }
  1136. /* Add a base class to a class. */
  1137. static boolean
  1138. pr_class_baseclass (p, bitpos, virtual, visibility)
  1139. PTR p;
  1140. bfd_vma bitpos;
  1141. boolean virtual;
  1142. enum debug_visibility visibility;
  1143. {
  1144. struct pr_handle *info = (struct pr_handle *) p;
  1145. char *t;
  1146. const char *prefix;
  1147. char ab[20];
  1148. char *s, *l, *n;
  1149. assert (info->stack != NULL && info->stack->next != NULL);
  1150. if (! substitute_type (info, ""))
  1151. return false;
  1152. t = pop_type (info);
  1153. if (t == NULL)
  1154. return false;
  1155. if (strncmp (t, "class ", sizeof "class " - 1) == 0)
  1156. t += sizeof "class " - 1;
  1157. /* Push it back on to take advantage of the prepend_type and
  1158. append_type routines. */
  1159. if (! push_type (info, t))
  1160. return false;
  1161. if (virtual)
  1162. {
  1163. if (! prepend_type (info, "virtual "))
  1164. return false;
  1165. }
  1166. switch (visibility)
  1167. {
  1168. case DEBUG_VISIBILITY_PUBLIC:
  1169. prefix = "public ";
  1170. break;
  1171. case DEBUG_VISIBILITY_PROTECTED:
  1172. prefix = "protected ";
  1173. break;
  1174. case DEBUG_VISIBILITY_PRIVATE:
  1175. prefix = "private ";
  1176. break;
  1177. default:
  1178. prefix = "/* unknown visibility */ ";
  1179. break;
  1180. }
  1181. if (! prepend_type (info, prefix))
  1182. return false;
  1183. if (bitpos != 0)
  1184. {
  1185. print_vma (bitpos, ab, true, false);
  1186. if (! append_type (info, " /* bitpos ")
  1187. || ! append_type (info, ab)
  1188. || ! append_type (info, " */"))
  1189. return false;
  1190. }
  1191. /* Now the top of the stack is something like "public A / * bitpos
  1192. 10 * /". The next element on the stack is something like "class
  1193. xx { / * size 8 * /\n...". We want to substitute the top of the
  1194. stack in before the {. */
  1195. s = strchr (info->stack->next->type, '{');
  1196. assert (s != NULL);
  1197. --s;
  1198. /* If there is already a ':', then we already have a baseclass, and
  1199. we must append this one after a comma. */
  1200. for (l = info->stack->next->type; l != s; l++)
  1201. if (*l == ':')
  1202. break;
  1203. if (! prepend_type (info, l == s ? " : " : ", "))
  1204. return false;
  1205. t = pop_type (info);
  1206. if (t == NULL)
  1207. return false;
  1208. n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1);
  1209. memcpy (n, info->stack->type, s - info->stack->type);
  1210. strcpy (n + (s - info->stack->type), t);
  1211. strcat (n, s);
  1212. free (info->stack->type);
  1213. info->stack->type = n;
  1214. free (t);
  1215. return true;
  1216. }
  1217. /* Start adding a method to a class. */
  1218. static boolean
  1219. pr_class_start_method (p, name)
  1220. PTR p;
  1221. const char *name;
  1222. {
  1223. struct pr_handle *info = (struct pr_handle *) p;
  1224. assert (info->stack != NULL);
  1225. info->stack->method = name;
  1226. return true;
  1227. }
  1228. /* Add a variant to a method. */
  1229. static boolean
  1230. pr_class_method_variant (p, physname, visibility, constp, volatilep, voffset,
  1231. context)
  1232. PTR p;
  1233. const char *physname;
  1234. enum debug_visibility visibility;
  1235. boolean constp;
  1236. boolean volatilep;
  1237. bfd_vma voffset;
  1238. boolean context;
  1239. {
  1240. struct pr_handle *info = (struct pr_handle *) p;
  1241. char *method_type;
  1242. char *context_type;
  1243. assert (info->stack != NULL);
  1244. assert (info->stack->next != NULL);
  1245. /* Put the const and volatile qualifiers on the type. */
  1246. if (volatilep)
  1247. {
  1248. if (! append_type (info, " volatile"))
  1249. return false;
  1250. }
  1251. if (constp)
  1252. {
  1253. if (! append_type (info, " const"))
  1254. return false;
  1255. }
  1256. /* Stick the name of the method into its type. */
  1257. if (! substitute_type (info,
  1258. (context
  1259. ? info->stack->next->next->method
  1260. : info->stack->next->method)))
  1261. return false;
  1262. /* Get the type. */
  1263. method_type = pop_type (info);
  1264. if (method_type == NULL)
  1265. return false;
  1266. /* Pull off the context type if there is one. */
  1267. if (! context)
  1268. context_type = NULL;
  1269. else
  1270. {
  1271. context_type = pop_type (info);
  1272. if (context_type == NULL)
  1273. return false;
  1274. }
  1275. /* Now the top of the stack is the class. */
  1276. if (! pr_fix_visibility (info, visibility))
  1277. return false;
  1278. if (! append_type (info, method_type)
  1279. || ! append_type (info, " /* ")
  1280. || ! append_type (info, physname)
  1281. || ! append_type (info, " "))
  1282. return false;
  1283. if (context || voffset != 0)
  1284. {
  1285. char ab[20];
  1286. if (context)
  1287. {
  1288. if (! append_type (info, "context ")
  1289. || ! append_type (info, context_type)
  1290. || ! append_type (info, " "))
  1291. return false;
  1292. }
  1293. print_vma (voffset, ab, true, false);
  1294. if (! append_type (info, "voffset ")
  1295. || ! append_type (info, ab))
  1296. return false;
  1297. }
  1298. return (append_type (info, " */;\n")
  1299. && indent_type (info));
  1300. }
  1301. /* Add a static variant to a method. */
  1302. static boolean
  1303. pr_class_static_method_variant (p, physname, visibility, constp, volatilep)
  1304. PTR p;
  1305. const char *physname;
  1306. enum debug_visibility visibility;
  1307. boolean constp;
  1308. boolean volatilep;
  1309. {
  1310. struct pr_handle *info = (struct pr_handle *) p;
  1311. char *method_type;
  1312. assert (info->stack != NULL);
  1313. assert (info->stack->next != NULL);
  1314. assert (info->stack->next->method != NULL);
  1315. /* Put the const and volatile qualifiers on the type. */
  1316. if (volatilep)
  1317. {
  1318. if (! append_type (info, " volatile"))
  1319. return false;
  1320. }
  1321. if (constp)
  1322. {
  1323. if (! append_type (info, " const"))
  1324. return false;
  1325. }
  1326. /* Mark it as static. */
  1327. if (! prepend_type (info, "static "))
  1328. return false;
  1329. /* Stick the name of the method into its type. */
  1330. if (! substitute_type (info, info->stack->next->method))
  1331. return false;
  1332. /* Get the type. */
  1333. method_type = pop_type (info);
  1334. if (method_type == NULL)
  1335. return false;
  1336. /* Now the top of the stack is the class. */
  1337. if (! pr_fix_visibility (info, visibility))
  1338. return false;
  1339. return (append_type (info, method_type)
  1340. && append_type (info, " /* ")
  1341. && append_type (info, physname)
  1342. && append_type (info, " */;\n")
  1343. && indent_type (info));
  1344. }
  1345. /* Finish up a method. */
  1346. static boolean
  1347. pr_class_end_method (p)
  1348. PTR p;
  1349. {
  1350. struct pr_handle *info = (struct pr_handle *) p;
  1351. info->stack->method = NULL;
  1352. return true;
  1353. }
  1354. /* Finish up a class. */
  1355. static boolean
  1356. pr_end_class_type (p)
  1357. PTR p;
  1358. {
  1359. return pr_end_struct_type (p);
  1360. }
  1361. /* Push a type on the stack using a typedef name. */
  1362. static boolean
  1363. pr_typedef_type (p, name)
  1364. PTR p;
  1365. const char *name;
  1366. {
  1367. struct pr_handle *info = (struct pr_handle *) p;
  1368. return push_type (info, name);
  1369. }
  1370. /* Push a type on the stack using a tag name. */
  1371. static boolean
  1372. pr_tag_type (p, name, id, kind)
  1373. PTR p;
  1374. const char *name;
  1375. unsigned int id;
  1376. enum debug_type_kind kind;
  1377. {
  1378. struct pr_handle *info = (struct pr_handle *) p;
  1379. const char *t, *tag;
  1380. char idbuf[30];
  1381. switch (kind)
  1382. {
  1383. case DEBUG_KIND_STRUCT:
  1384. t = "struct ";
  1385. break;
  1386. case DEBUG_KIND_UNION:
  1387. t = "union ";
  1388. break;
  1389. case DEBUG_KIND_ENUM:
  1390. t = "enum ";
  1391. break;
  1392. case DEBUG_KIND_CLASS:
  1393. t = "class ";
  1394. break;
  1395. case DEBUG_KIND_UNION_CLASS:
  1396. t = "union class ";
  1397. break;
  1398. default:
  1399. abort ();
  1400. return false;
  1401. }
  1402. if (! push_type (info, t))
  1403. return false;
  1404. if (name != NULL)
  1405. tag = name;
  1406. else
  1407. {
  1408. sprintf (idbuf, "%%anon%u", id);
  1409. tag = idbuf;
  1410. }
  1411. if (! append_type (info, tag))
  1412. return false;
  1413. if (name != NULL && kind != DEBUG_KIND_ENUM)
  1414. {
  1415. sprintf (idbuf, " /* id %u */", id);
  1416. if (! append_type (info, idbuf))
  1417. return false;
  1418. }
  1419. return true;
  1420. }
  1421. /* Output a typedef. */
  1422. static boolean
  1423. pr_typdef (p, name)
  1424. PTR p;
  1425. const char *name;
  1426. {
  1427. struct pr_handle *info = (struct pr_handle *) p;
  1428. char *s;
  1429. if (! substitute_type (info, name))
  1430. return false;
  1431. s = pop_type (info);
  1432. if (s == NULL)
  1433. return false;
  1434. /*
  1435. indent (info);
  1436. TRACE_FPRINTF( (info->f, "typedef %s;\n", s));
  1437. */
  1438. free (s);
  1439. return true;
  1440. }
  1441. /* Output a tag. The tag should already be in the string on the
  1442. stack, so all we have to do here is print it out. */
  1443. /*ARGSUSED*/
  1444. static boolean
  1445. pr_tag (p, name)
  1446. PTR p;
  1447. const char *name;
  1448. {
  1449. struct pr_handle *info = (struct pr_handle *) p;
  1450. char *t;
  1451. t = pop_type (info);
  1452. if (t == NULL)
  1453. return false;
  1454. /*
  1455. indent (info);
  1456. TRACE_FPRINTF( (info->f, "%s;\n", t));
  1457. */
  1458. free (t);
  1459. return true;
  1460. }
  1461. /* Output an integer constant. */
  1462. static boolean
  1463. pr_int_constant (p, name, val)
  1464. PTR p;
  1465. const char *name;
  1466. bfd_vma val;
  1467. {
  1468. /*
  1469. struct pr_handle *info = (struct pr_handle *) p;
  1470. char ab[20];
  1471. indent (info);
  1472. print_vma (val, ab, false, false);
  1473. TRACE_FPRINTF( (info->f, "const int %s = %s;\n", name, ab));
  1474. */
  1475. return true;
  1476. }
  1477. /* Output a floating point constant. */
  1478. static boolean
  1479. pr_float_constant (p, name, val)
  1480. PTR p;
  1481. const char *name;
  1482. double val;
  1483. {
  1484. /*
  1485. struct pr_handle *info = (struct pr_handle *) p;
  1486. indent (info);
  1487. TRACE_FPRINTF( (info->f, "const double %s = %g;\n", name, val));
  1488. */
  1489. return true;
  1490. }
  1491. /* Output a typed constant. */
  1492. static boolean
  1493. pr_typed_constant (p, name, val)
  1494. PTR p;
  1495. const char *name;
  1496. bfd_vma val;
  1497. {
  1498. struct pr_handle *info = (struct pr_handle *) p;
  1499. char *t;
  1500. t = pop_type (info);
  1501. if (t == NULL)
  1502. return false;
  1503. /*
  1504. char ab[20];
  1505. indent (info);
  1506. print_vma (val, ab, false, false);
  1507. TRACE_FPRINTF( (info->f, "const %s %s = %s;\n", t, name, ab));
  1508. */
  1509. free (t);
  1510. return true;
  1511. }
  1512. /* Output a variable. */
  1513. static boolean
  1514. pr_variable (p, name, kind, val)
  1515. PTR p;
  1516. const char *name;
  1517. enum debug_var_kind kind;
  1518. bfd_vma val;
  1519. {
  1520. struct pr_handle *info = (struct pr_handle *) p;
  1521. char *t;
  1522. char ab[20];
  1523. (void)ab;
  1524. if (! substitute_type (info, name))
  1525. return false;
  1526. t = pop_type (info);
  1527. if (t == NULL)
  1528. return false;
  1529. #if 0
  1530. indent (info);
  1531. switch (kind)
  1532. {
  1533. case DEBUG_STATIC:
  1534. case DEBUG_LOCAL_STATIC:
  1535. TRACE_FPRINTF( (info->f, "static "));
  1536. break;
  1537. case DEBUG_REGISTER:
  1538. TRACE_FPRINTF( (info->f, "register "));
  1539. break;
  1540. default:
  1541. break;
  1542. }
  1543. print_vma (val, ab, true, true);
  1544. TRACE_FPRINTF( (info->f, "%s /* %s */;\n", t, ab));
  1545. #else /* 0 */
  1546. #if 0
  1547. if (kind==DEBUG_STATIC || kind==DEBUG_LOCAL_STATIC) {
  1548. print_vma (val, ab, true, true);
  1549. TRACE_FPRINTF( (info->f, "STATIC_VAR: %s /* %s */;\n", t, ab));
  1550. }
  1551. #endif /* 0 */
  1552. #endif /* !0 */
  1553. free (t);
  1554. return true;
  1555. }
  1556. /* Start outputting a function. */
  1557. static boolean
  1558. pr_start_function (p, name, global)
  1559. PTR p;
  1560. const char *name;
  1561. boolean global;
  1562. {
  1563. struct pr_handle *info = (struct pr_handle *) p;
  1564. char *t;
  1565. if (! substitute_type (info, name))
  1566. return false;
  1567. t = pop_type (info);
  1568. if (t == NULL)
  1569. return false;
  1570. #if 0
  1571. indent (info);
  1572. if (! global)
  1573. TRACE_FPRINTF( (info->f, "static "));
  1574. TRACE_FPRINTF( (info->f, "%s (", t));
  1575. info->parameter = 1;
  1576. #else /* 0 */
  1577. if (info->functions_size==info->functions_maxsize) {
  1578. info->functions_maxsize *= 2;
  1579. info->functions = xrealloc(info->functions,
  1580. info->functions_maxsize*sizeof(debug_function_t));
  1581. assert(info->functions!=0);
  1582. }
  1583. /* info->functions[info->functions_size] = xmalloc(sizeof(debug_function_t)); */
  1584. info->function = &info->functions[info->functions_size];
  1585. ++info->functions_size;
  1586. info->function->symbol = NULL;
  1587. info->function->lines = NULL;
  1588. info->function->lines_count = 0;
  1589. info->function->max_lines_count = 0;
  1590. info->function->name = t;
  1591. info->function->filename = NULL;
  1592. info->function->block = NULL;
  1593. info->function->argv = NULL;
  1594. info->function->argc = 0;
  1595. info->function->max_argc = 0;
  1596. #endif /* !0 */
  1597. return true;
  1598. }
  1599. /* Output a function parameter. */
  1600. static boolean
  1601. pr_function_parameter (p, name, kind, val)
  1602. PTR p;
  1603. const char *name;
  1604. enum debug_parm_kind kind;
  1605. bfd_vma val;
  1606. {
  1607. struct pr_handle *info = (struct pr_handle *) p;
  1608. debug_function_t* f = info->function;
  1609. char *t;
  1610. char ab[20];
  1611. (void)ab;
  1612. if (kind == DEBUG_PARM_REFERENCE
  1613. || kind == DEBUG_PARM_REF_REG)
  1614. {
  1615. if (! pr_reference_type (p))
  1616. return false;
  1617. }
  1618. if (! substitute_type (info, name))
  1619. return false;
  1620. t = pop_type (info);
  1621. if (t == NULL)
  1622. return false;
  1623. #if 0
  1624. if (info->parameter != 1)
  1625. TRACE_FPRINTF( (info->f, ", "));
  1626. if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
  1627. TRACE_FPRINTF( (info->f, "register "));
  1628. print_vma (val, ab, true, true);
  1629. TRACE_FPRINTF( (info->f, "%s /* %s */", t, ab));
  1630. free (t);
  1631. ++info->parameter;
  1632. #else /* 0 */
  1633. assert(f!=NULL);
  1634. if (f->argv==NULL) {
  1635. f->max_argc = 7; /* rarely anyone has more than that many args... */
  1636. f->argv = xmalloc(sizeof(debug_parameter_t)*f->max_argc);
  1637. } else if (f->argc==f->max_argc) {
  1638. f->max_argc *= 2;
  1639. f->argv = realloc(f->argv,sizeof(debug_parameter_t)*f->max_argc);
  1640. }
  1641. f->argv[f->argc].offset = val;
  1642. f->argv[f->argc].name = t;
  1643. ++f->argc;
  1644. #endif /* !0 */
  1645. return true;
  1646. }
  1647. /* Start writing out a block. */
  1648. static boolean
  1649. pr_start_block (p, addr)
  1650. PTR p;
  1651. bfd_vma addr;
  1652. {
  1653. struct pr_handle *info = (struct pr_handle *) p;
  1654. char ab[20];
  1655. debug_block_t* block = 0;
  1656. (void)ab;
  1657. #if 0
  1658. if (info->parameter > 0)
  1659. {
  1660. TRACE_FPRINTF( (info->f, ")\n"));
  1661. info->parameter = 0;
  1662. }
  1663. indent (info);
  1664. print_vma (addr, ab, true, true);
  1665. TRACE_FPRINTF( (info->f, "{ /* %s */\n", ab));
  1666. info->indent += 2;
  1667. #else
  1668. if (info->block) {
  1669. if (info->block->childs_count==0)
  1670. info->block->childs = xmalloc(sizeof(debug_block_t));
  1671. else
  1672. info->block->childs = xrealloc(info->block->childs,
  1673. info->block->childs_count*sizeof(debug_block_t));
  1674. block = &info->block->childs[info->block->childs_count];
  1675. } else {
  1676. block = xmalloc(sizeof(debug_block_t));
  1677. info->function->block = block;
  1678. }
  1679. block->begin_addr = addr;
  1680. block->end_addr = 0;
  1681. block->parent = info->block;
  1682. block->childs = NULL;
  1683. block->childs_count = 0;
  1684. info->block = block;
  1685. #endif
  1686. return true;
  1687. }
  1688. /* Write out line number information. */
  1689. static boolean
  1690. pr_lineno (p, filename, lineno, addr)
  1691. PTR p;
  1692. const char *filename;
  1693. unsigned long lineno;
  1694. bfd_vma addr;
  1695. {
  1696. struct pr_handle *info = (struct pr_handle *) p;
  1697. char ab[20];
  1698. debug_function_t* f = info->function;
  1699. (void)ab;
  1700. #if 0
  1701. indent (info);
  1702. print_vma (addr, ab, true, true);
  1703. TRACE_FPRINTF( (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab));
  1704. #else /* 0 */
  1705. if (f==NULL) /* FIXME: skips junk silently. */
  1706. return true;
  1707. /* assert(f!=NULL); */
  1708. if (f->filename==NULL) {
  1709. f->filename = filename;
  1710. assert(f->lines==0);
  1711. f->max_lines_count = 4;
  1712. f->lines = xmalloc(sizeof(debug_lineno_t)*f->max_lines_count);
  1713. }
  1714. if (f->lines_count==f->max_lines_count) {
  1715. f->max_lines_count *= 2;
  1716. f->lines = xrealloc(f->lines, sizeof(debug_lineno_t)*f->max_lines_count);
  1717. }
  1718. f->lines[f->lines_count].lineno = lineno;
  1719. f->lines[f->lines_count].addr = addr;
  1720. ++f->lines_count;
  1721. #endif /* !0 */
  1722. return true;
  1723. }
  1724. /* Finish writing out a block. */
  1725. static boolean
  1726. pr_end_block (p, addr)
  1727. PTR p;
  1728. bfd_vma addr;
  1729. {
  1730. struct pr_handle *info = (struct pr_handle *) p;
  1731. #if 0
  1732. char ab[20];
  1733. info->indent -= 2;
  1734. indent (info);
  1735. print_vma (addr, ab, true, true);
  1736. TRACE_FPRINTF( (info->f, "} /* %s */\n", ab));
  1737. #else /* 0 */
  1738. assert(info->block!=0);
  1739. info->block->end_addr = addr;
  1740. info->block = info->block->parent;
  1741. #endif /* !0 */
  1742. return true;
  1743. }
  1744. /* Finish writing out a function. */
  1745. /*ARGSUSED*/
  1746. static boolean
  1747. pr_end_function (p)
  1748. PTR p;
  1749. {
  1750. struct pr_handle *info = (struct pr_handle *) p;
  1751. assert(info->block==0);
  1752. info->function = NULL;
  1753. return true;
  1754. }
  1755. /* third parameter to segv_action. */
  1756. /* Got it after a bit of head scratching and stack dumping. */
  1757. typedef struct {
  1758. u_int32_t foo1; /* +0x00 */
  1759. u_int32_t foo2;
  1760. u_int32_t foo3;
  1761. u_int32_t foo4; /* usually 2 */
  1762. u_int32_t foo5; /* +0x10 */
  1763. u_int32_t xgs; /* always zero */
  1764. u_int32_t xfs; /* always zero */
  1765. u_int32_t xes; /* always es=ds=ss */
  1766. u_int32_t xds; /* +0x20 */
  1767. u_int32_t edi;
  1768. u_int32_t esi;
  1769. u_int32_t ebp;
  1770. u_int32_t esp; /* +0x30 */
  1771. u_int32_t ebx;
  1772. u_int32_t edx;
  1773. u_int32_t ecx;
  1774. u_int32_t eax; /* +0x40 */
  1775. u_int32_t foo11; /* usually 0xe */
  1776. u_int32_t foo12; /* usually 0x6 */
  1777. u_int32_t eip; /* instruction pointer */
  1778. u_int32_t xcs; /* +0x50 */
  1779. u_int32_t foo21; /* usually 0x2 */
  1780. u_int32_t foo22; /* second stack pointer?! Probably. */
  1781. u_int32_t xss;
  1782. u_int32_t foo31; /* +0x60 */ /* usually 0x0 */
  1783. u_int32_t foo32; /* usually 0x2 */
  1784. u_int32_t fault_addr; /* Address which caused a fault */
  1785. u_int32_t foo41; /* usually 0x2 */
  1786. } signal_regs_t;
  1787. signal_regs_t* ptrace_regs = 0; /* Tells my_ptrace to "ptrace" current process" */
  1788. /*
  1789. * my_ptrace: small wrapper around ptrace.
  1790. * Act as normal ptrace if ptrace_regs==0.
  1791. * Read data from current process if ptrace_regs!=0.
  1792. */
  1793. static int
  1794. my_ptrace( int request,
  1795. int pid,
  1796. int addr,
  1797. int data)
  1798. {
  1799. if (ptrace_regs==0)
  1800. return ptrace(request, pid, addr, data);
  1801. /* we are tracing ourselves! */
  1802. switch (request) {
  1803. case PTRACE_ATTACH: return 0;
  1804. case PTRACE_CONT: return 0;
  1805. case PTRACE_DETACH: return 0;
  1806. case PTRACE_PEEKUSER:
  1807. switch (addr / 4) {
  1808. case EIP: return ptrace_regs->eip;
  1809. case EBP: return ptrace_regs->ebp;
  1810. default: assert(0);
  1811. }
  1812. case PTRACE_PEEKTEXT: /* FALLTHROUGH */
  1813. case PTRACE_PEEKDATA: return *(int*)(addr);
  1814. default: assert(0);
  1815. }
  1816. errno = 1; /* what to do here? */
  1817. return 1; /* failed?! */
  1818. }
  1819. #define MAXARGS 6
  1820. /*
  1821. * To minimize the number of parameters.
  1822. */
  1823. typedef struct {
  1824. asymbol** syms; /* Sorted! */
  1825. int symcount;
  1826. debug_function_t** functions;
  1827. int functions_size;
  1828. } symbol_data_t;
  1829. /*
  1830. * Perform a search. A binary search for a symbol.
  1831. */
  1832. static void
  1833. decode_symbol( symbol_data_t* symbol_data,
  1834. const unsigned long addr,
  1835. char* buf,
  1836. const int bufsize)
  1837. {
  1838. asymbol** syms = symbol_data->syms;
  1839. const int symcount = symbol_data->symcount;
  1840. int bottom = 0;
  1841. int top = symcount - 1;
  1842. int i;
  1843. if (symcount==0) {
  1844. sprintf(buf, "????");
  1845. return;
  1846. }
  1847. while (top>bottom+1) {
  1848. i = (top+bottom) / 2;
  1849. if (bfd_asymbol_value(syms[i])==addr) {
  1850. sprintf(buf, "%s", syms[i]->name);
  1851. return;
  1852. } else if (bfd_asymbol_value(syms[i]) > addr)
  1853. top = i;
  1854. else
  1855. bottom = i;
  1856. }
  1857. i = bottom;
  1858. if (addr<bfd_asymbol_value(syms[i]) || addr>(syms[i]->section->vma+syms[i]->section->_cooked_size))
  1859. sprintf(buf, "????");
  1860. else
  1861. sprintf(buf, "%s + 0x%lx", syms[i]->name, addr-bfd_asymbol_value(syms[i]));
  1862. }
  1863. /*
  1864. * 1. Perform a binary search for an debug_function_t.
  1865. * 2. Fill buf/bufsize with name, parameters and lineno, if found
  1866. * Or with '????' otherwise.
  1867. */
  1868. static debug_function_t*
  1869. find_debug_function_t( symbol_data_t* symbol_data,
  1870. const pid_t pid,
  1871. const unsigned long fp, /* frame pointer */
  1872. const unsigned long addr,
  1873. char* buf, /* string buffer */
  1874. const int bufsize)/* FIXME: not used! */
  1875. {
  1876. debug_function_t** syms = symbol_data->functions;
  1877. debug_function_t* f = NULL;
  1878. debug_block_t* block = NULL;
  1879. debug_lineno_t* lineno = NULL;
  1880. const int symcount = symbol_data->functions_size;
  1881. int bottom = 0;
  1882. int top = symcount - 1;
  1883. int i;
  1884. char* bufptr = buf;
  1885. if (symcount==0) {
  1886. sprintf(buf, "????");
  1887. return NULL;
  1888. }
  1889. while (top>bottom+1) {
  1890. i = (top+bottom) / 2;
  1891. if (syms[i]->block->begin_addr==addr) {
  1892. f = syms[i];
  1893. break;
  1894. } else if (syms[i]->block->begin_addr > addr)
  1895. top = i;
  1896. else
  1897. if (syms[i]->block->end_addr >= addr) {
  1898. f = syms[i];
  1899. break;
  1900. } else
  1901. bottom = i;
  1902. }
  1903. i = bottom;
  1904. if (f!=0)
  1905. block = f->block;
  1906. else {
  1907. block = syms[i]->block;
  1908. if (block->begin_addr>=addr && block->end_addr<=addr)
  1909. f = syms[i];
  1910. }
  1911. if (f==0)
  1912. sprintf(buf, "????");
  1913. else {
  1914. /*
  1915. * Do the backtrace the GDB way...
  1916. */
  1917. unsigned long arg;
  1918. /* assert(f->lines_count>0); */
  1919. if (f->lines_count>0) {
  1920. lineno = &f->lines[f->lines_count-1];
  1921. for (i=1; i<f->lines_count; ++i)
  1922. if (f->lines[i].addr>addr) {
  1923. lineno = &f->lines[i-1];
  1924. break;
  1925. }
  1926. }
  1927. bufptr[0] = 0;
  1928. bufptr += sprintf(bufptr, "%s+0x%lx (", f->name, addr-block->begin_addr);
  1929. for (i=0; i<f->argc; ++i) {
  1930. bufptr += sprintf(bufptr, "%s = ", f->argv[i].name);
  1931. /* FIXME: better parameter printing */
  1932. errno = 0;
  1933. arg = my_ptrace(PTRACE_PEEKDATA, pid, fp+f->argv[i].offset, 0);
  1934. assert(errno==0);
  1935. bufptr += sprintf(bufptr, "0x%x", arg);
  1936. if (i!=f->argc-1)
  1937. bufptr += sprintf(bufptr, ", ");
  1938. }
  1939. if (lineno!=0)
  1940. bufptr += sprintf(bufptr, ") at %s:%d", f->filename, lineno->lineno);
  1941. }
  1942. return f;
  1943. }
  1944. /*
  1945. * Advance through the stacks and display frames as needed.
  1946. */
  1947. static int
  1948. my_crawl( int pid,
  1949. symbol_data_t* symbol_data,
  1950. int fout)
  1951. {
  1952. unsigned long pc = 0;
  1953. unsigned long fp = 0;
  1954. unsigned long nextfp;
  1955. unsigned long nargs;
  1956. unsigned long i;
  1957. unsigned long arg;
  1958. char buf[8096]; // FIXME: enough?
  1959. debug_function_t* f = 0;
  1960. errno = 0;
  1961. pc = my_ptrace(PTRACE_PEEKUSER, pid, EIP * 4, 0);
  1962. if (!errno)
  1963. fp = my_ptrace(PTRACE_PEEKUSER, pid, EBP * 4, 0);
  1964. if (!errno) {
  1965. #if 1
  1966. f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf));
  1967. fdprintf(fout,"0x%08lx: %s", pc, buf);
  1968. for ( ; !errno && fp; ) {
  1969. nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0);
  1970. if (errno)
  1971. break;
  1972. if (f==0) {
  1973. nargs = (nextfp - fp - 8) / 4;
  1974. if (nargs > MAXARGS)
  1975. nargs = MAXARGS;
  1976. if (nargs > 0) {
  1977. fdputs(" (", fout);
  1978. for (i = 1; i <= nargs; i++) {
  1979. arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0);
  1980. if (errno)
  1981. break;
  1982. fdprintf(fout,"%lx", arg);
  1983. if (i < nargs)
  1984. fdputs(", ", fout);
  1985. }
  1986. fdputc(')', fout);
  1987. nargs = nextfp - fp - 8 - (4 * nargs);
  1988. if (!errno && nargs > 0)
  1989. fdprintf(fout," + %lx\n", nargs);
  1990. else
  1991. fdputc('\n', fout);
  1992. } else
  1993. fdputc('\n', fout);
  1994. } else
  1995. fdputc('\n', fout);
  1996. if (errno || !nextfp)
  1997. break;
  1998. pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0);
  1999. fp = nextfp;
  2000. if (errno)
  2001. break;
  2002. f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf));
  2003. fdprintf(fout,"0x%08lx: %s", pc, buf);
  2004. }
  2005. #else /* 1 */
  2006. decode_symbol(symbol_data, pc, buf, sizeof(buf));
  2007. fdprintf(fout,"0x%08lx: %s", pc, buf);
  2008. for ( ; !errno && fp; ) {
  2009. nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0);
  2010. if (errno)
  2011. break;
  2012. nargs = (nextfp - fp - 8) / 4;
  2013. if (nargs > MAXARGS)
  2014. nargs = MAXARGS;
  2015. if (nargs > 0) {
  2016. fputs(" (", fout);
  2017. for (i = 1; i <= nargs; i++) {
  2018. arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0);
  2019. if (errno)
  2020. break;
  2021. fdprintf(fout,"%lx", arg);
  2022. if (i < nargs)
  2023. fputs(", ", fout);
  2024. }
  2025. fdputc(')', fout);
  2026. nargs = nextfp - fp - 8 - (4 * nargs);
  2027. if (!errno && nargs > 0)
  2028. fdprintf(fout," + %lx\n", nargs);
  2029. else
  2030. fdputc('\n', fout);
  2031. } else
  2032. fdputc('\n', fout);
  2033. if (errno || !nextfp)
  2034. break;
  2035. pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0);
  2036. fp = nextfp;
  2037. if (errno)
  2038. break;
  2039. decode_symbol(symbol_data, pc, buf, sizeof(buf));
  2040. fdprintf(fout,"0x%08lx: %s", pc, buf);
  2041. }
  2042. #endif /* !1 */
  2043. }
  2044. if (errno)
  2045. perror("my_crawl");
  2046. return errno;
  2047. }
  2048. /* layout from /usr/src/linux/arch/i386/kernel/process.c */
  2049. static void
  2050. show_regs( signal_regs_t* regs,
  2051. int fd)
  2052. {
  2053. /* long cr0 = 0L, cr2 = 0L, cr3 = 0L; */
  2054. fdprintf(fd,"\n");
  2055. fdprintf(fd,"FAULT ADDR: %08x\n", regs->fault_addr);
  2056. fdprintf(fd,"EIP: %04x:[<%08x>]",0xffff & regs->xcs,regs->eip);
  2057. if (regs->xcs & 3)
  2058. fdprintf(fd," ESP: %04x:%08x",0xffff & regs->xss,regs->esp);
  2059. /*fdprintf(fd," EFLAGS: %08lx\n",regs->eflags); */
  2060. fdprintf(fd, "\n");
  2061. fdprintf(fd,"EAX: %08x EBX: %08x ECX: %08x EDX: %08x\n",
  2062. regs->eax,regs->ebx,regs->ecx,regs->edx);
  2063. fdprintf(fd,"ESI: %08x EDI: %08x EBP: %08x",
  2064. regs->esi, regs->edi, regs->ebp);
  2065. fdprintf(fd," DS: %04x ES: %04x\n",
  2066. 0xffff & regs->xds,0xffff & regs->xes);
  2067. /*
  2068. __asm__("movl %%cr0, %0": "=r" (cr0));
  2069. __asm__("movl %%cr2, %0": "=r" (cr2));
  2070. __asm__("movl %%cr3, %0": "=r" (cr3));
  2071. fprintf(stderr,"CR0: %08lx CR2: %08lx CR3: %08lx\n", cr0, cr2, cr3); */
  2072. }
  2073. /*
  2074. * Load a BFD for an executable based on PID. Return 0 on failure.
  2075. */
  2076. static bfd*
  2077. load_bfd( const int pid)
  2078. {
  2079. char filename[512];
  2080. bfd* abfd = 0;
  2081. /* Get the contents from procfs. */
  2082. #if 1
  2083. sprintf(filename, "/proc/%d/exe", pid);
  2084. #else
  2085. sprintf(filename, "crashing");
  2086. #endif
  2087. if ((abfd = bfd_openr (filename, 0))== NULL)
  2088. bfd_nonfatal (filename);
  2089. else {
  2090. char** matching;
  2091. assert(bfd_check_format(abfd, bfd_archive)!=true);
  2092. /*
  2093. * There is no indication in BFD documentation that it should be done.
  2094. * God knows why...
  2095. */
  2096. if (!bfd_check_format_matches (abfd, bfd_object, &matching)) {
  2097. bfd_nonfatal (bfd_get_filename (abfd));
  2098. if (bfd_get_error () == bfd_error_file_ambiguously_recognized) {
  2099. list_matching_formats (matching);
  2100. free (matching);
  2101. }
  2102. }
  2103. }
  2104. return abfd;
  2105. }
  2106. /*
  2107. * Those are for qsort. We need only function addresses, so all the others don't count.
  2108. */
  2109. /*
  2110. * Compare two BFD::asymbol-s.
  2111. */
  2112. static int
  2113. compare_symbols(const void* ap,
  2114. const void* bp)
  2115. {
  2116. const asymbol *a = *(const asymbol **)ap;
  2117. const asymbol *b = *(const asymbol **)bp;
  2118. if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
  2119. return 1;
  2120. else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
  2121. return -1;
  2122. return 0;
  2123. }
  2124. /*
  2125. * Compare two debug_asymbol_t-s.
  2126. */
  2127. static int
  2128. compare_debug_function_t(const void* ap,
  2129. const void* bp)
  2130. {
  2131. const debug_function_t *a = *(const debug_function_t **)ap;
  2132. const debug_function_t *b = *(const debug_function_t **)bp;
  2133. assert(a->block!=0);
  2134. assert(b->block!=0);
  2135. {
  2136. const bfd_vma addr1 = a->block->begin_addr;
  2137. const bfd_vma addr2 = b->block->begin_addr;
  2138. if (addr1 > addr2)
  2139. return 1;
  2140. else if (addr2 > addr1)
  2141. return -1;
  2142. }
  2143. return 0;
  2144. }
  2145. /*
  2146. * Filter out (in place) symbols that are useless for stack tracing.
  2147. * COUNT is the number of elements in SYMBOLS.
  2148. * Return the number of useful symbols.
  2149. */
  2150. static long
  2151. remove_useless_symbols( asymbol** symbols,
  2152. long count)
  2153. {
  2154. asymbol** in_ptr = symbols;
  2155. asymbol** out_ptr = symbols;
  2156. while (--count >= 0) {
  2157. asymbol *sym = *in_ptr++;
  2158. if (sym->name == NULL || sym->name[0] == '\0' || sym->value==0)
  2159. continue;
  2160. if (sym->flags & (BSF_DEBUGGING))
  2161. continue;
  2162. if (bfd_is_und_section (sym->section) || bfd_is_com_section (sym->section))
  2163. continue;
  2164. *out_ptr++ = sym;
  2165. }
  2166. return out_ptr - symbols;
  2167. }
  2168. /*
  2169. * Debugging information.
  2170. */
  2171. static bfd* abfd = 0;
  2172. static PTR dhandle = 0;
  2173. static asymbol** syms = 0;
  2174. static long symcount = 0;
  2175. static asymbol** sorted_syms = 0;
  2176. static long sorted_symcount = 0;
  2177. static debug_function_t** functions = 0;
  2178. static int functions_size = 0;
  2179. static int sigreport = SIGUSR1;
  2180. static pthread_t segv_tid; /* What thread did SEGV? */
  2181. static pid_t segv_pid;
  2182. /*
  2183. * We'll get here after a SIGSEGV. But you can install it on other signals, too :)
  2184. * Because we are in the middle of the SIGSEGV, we are on our own. We can't do
  2185. * any malloc(), any fopen(), nothing. The last is actually a sin. We event can't
  2186. * fprintf(stderr,...)!!!
  2187. */
  2188. static void
  2189. segv_action(int signo, siginfo_t* siginfo, void* ptr)
  2190. {
  2191. symbol_data_t symbol_data;
  2192. int fd = -1;
  2193. segv_pid = getpid();
  2194. segv_tid = pthread_self();
  2195. fd = open_log_file(segv_tid, segv_pid);
  2196. /* signal(SIGSEGV, SIG_DFL); */
  2197. ptrace_regs = (signal_regs_t*)ptr;
  2198. assert(ptrace_regs!=0);
  2199. /* Show user how guilty we are. */
  2200. fdprintf(fd,"--------- SEGV in PROCESS %d, THREAD %d ---------------\n", segv_pid, pthread_self());
  2201. show_regs(ptrace_regs, fd);
  2202. /* Some form of stack trace, too. */
  2203. fdprintf(fd, "STACK TRACE:\n");
  2204. symbol_data.syms = sorted_syms;
  2205. symbol_data.symcount = sorted_symcount;
  2206. symbol_data.functions = functions;
  2207. symbol_data.functions_size = functions_size;
  2208. my_crawl(segv_pid, &symbol_data, fd);
  2209. //fflush(stdout);
  2210. close(fd);
  2211. linuxthreads_notify_others(sigreport);
  2212. }
  2213. static void
  2214. report_action(int signo, siginfo_t* siginfo, void* ptr)
  2215. {
  2216. const int pid = getpid();
  2217. pthread_t tid = pthread_self();
  2218. symbol_data_t symbol_data;
  2219. int fd;
  2220. if (pthread_equal(tid, segv_tid)) {
  2221. /* We have already printed our stack trace... */
  2222. return;
  2223. }
  2224. fd = open_log_file(tid, pid);
  2225. fdprintf(fd, "REPORT: CURRENT PROCESS:%d, THREAD:%d\n", getpid(), pthread_self());
  2226. /* signal(SIGSEGV, SIG_DFL); */
  2227. ptrace_regs = (signal_regs_t*)ptr;
  2228. assert(ptrace_regs!=0);
  2229. /* Show user how guilty we are. */
  2230. fdprintf(fd,"--------- STACK TRACE FOR PROCESS %d, THREAD %d ---------------\n", pid, pthread_self());
  2231. show_regs(ptrace_regs, fd);
  2232. /* Some form of stack trace, too. */
  2233. fdprintf(fd, "STACK TRACE:\n");
  2234. symbol_data.syms = sorted_syms;
  2235. symbol_data.symcount = sorted_symcount;
  2236. symbol_data.functions = functions;
  2237. symbol_data.functions_size = functions_size;
  2238. my_crawl(pid, &symbol_data, fd);
  2239. //fflush(stdout);
  2240. close(fd);
  2241. /* Tell segv_thread to proceed after pause(). */
  2242. /*pthread_kill(segv_tid, sigreport);
  2243. kill(segv_pid, sigreport);
  2244. pthread_cancel(tid); */
  2245. }
  2246. /*
  2247. * Main library routine. Just call it on your program.
  2248. */
  2249. int
  2250. pstack_install_segv_action( const char* path_format_)
  2251. {
  2252. const int pid = getpid();
  2253. struct sigaction act;
  2254. /* Store what we have to for later usage. */
  2255. path_format = path_format_;
  2256. /* We need a signal action for SIGSEGV and sigreport ! */
  2257. sigreport = SIGUSR1;
  2258. act.sa_handler = 0;
  2259. sigemptyset(&act.sa_mask);
  2260. act.sa_flags = SA_SIGINFO|SA_ONESHOT; /* Just one SIGSEGV. */
  2261. act.sa_sigaction = segv_action;
  2262. act.sa_restorer = NULL;
  2263. if (sigaction(SIGSEGV, &act, NULL)!=0) {
  2264. perror("sigaction");
  2265. return 1;
  2266. }
  2267. act.sa_sigaction = report_action;
  2268. act.sa_flags = SA_SIGINFO; /* But many sigreports. */
  2269. if (sigaction(sigreport, &act, NULL)!=0) {
  2270. perror("sigaction");
  2271. return 1;
  2272. }
  2273. /* And a little setup for libiberty. */
  2274. program_name = "crashing";
  2275. xmalloc_set_program_name (program_name);
  2276. /* Umm, and initialize BFD, too */
  2277. bfd_init();
  2278. #if 0
  2279. list_supported_targets(0, stdout);
  2280. set_default_bfd_target();
  2281. #endif /* 0 */
  2282. if ((abfd = load_bfd(pid))==0)
  2283. fprintf(stderr, "BFD load failed..\n");
  2284. else {
  2285. long storage_needed= (bfd_get_file_flags(abfd) & HAS_SYMS) ?
  2286. bfd_get_symtab_upper_bound (abfd) : 0;
  2287. long i;
  2288. (void)i;
  2289. if (storage_needed < 0)
  2290. fprintf(stderr, "Symbol table size estimation failure.\n");
  2291. else if (storage_needed > 0) {
  2292. syms = (asymbol **) xmalloc (storage_needed);
  2293. symcount = bfd_canonicalize_symtab (abfd, syms);
  2294. TRACE_FPRINTF((stderr, "TOTAL: %ld SYMBOLS.\n", symcount));
  2295. /* We need debugging info, too! */
  2296. if (symcount==0 || (dhandle = read_debugging_info (abfd, syms, symcount))==0)
  2297. fprintf(stderr, "NO DEBUGGING INFORMATION FOUND.\n");
  2298. /* We make a copy of syms to sort. We don't want to sort syms
  2299. because that will screw up the relocs. */
  2300. sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
  2301. memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));
  2302. #if 0
  2303. for (i=0; i<symcount; ++i)
  2304. if (syms[i]->name!=0 && strlen(syms[i]->name)>0 && syms[i]->value!=0)
  2305. printf("%08lx T %s\n", syms[i]->section->vma + syms[i]->value, syms[i]->name);
  2306. #endif
  2307. sorted_symcount = remove_useless_symbols (sorted_syms, symcount);
  2308. TRACE_FPRINTF((stderr, "SORTED: %ld SYMBOLS.\n", sorted_symcount));
  2309. /* Sort the symbols into section and symbol order */
  2310. qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
  2311. #if 0
  2312. for (i=0; i<sorted_symcount; ++i)
  2313. if (sorted_syms[i]->name!=0 && strlen(sorted_syms[i]->name)>0 && sorted_syms[i]->value!=0)
  2314. printf("%08lx T %s\n", sorted_syms[i]->section->vma + sorted_syms[i]->value, sorted_syms[i]->name);
  2315. #endif
  2316. /* We have symbols, we need debugging info somehow sorted out. */
  2317. if (dhandle==0) {
  2318. fprintf(stderr, "STACK TRACE WILL BE UNCOMFORTABLE.\n");
  2319. } else {
  2320. /* Start collecting the debugging information.... */
  2321. struct pr_handle info;
  2322. info.f = stdout;
  2323. info.indent = 0;
  2324. info.stack = NULL;
  2325. info.parameter = 0;
  2326. info.block = NULL;
  2327. info.function = NULL;
  2328. info.functions_size = 0;
  2329. info.functions_maxsize = 1000;
  2330. info.functions = (debug_function_t*)xmalloc(sizeof(debug_function_t)*info.functions_maxsize);
  2331. debug_write (dhandle, &pr_fns, (PTR) &info);
  2332. TRACE_FPRINTF((stdout, "\n%d DEBUG SYMBOLS\n", info.functions_size));
  2333. assert(info.functions_size!=0);
  2334. functions = xmalloc(sizeof(debug_function_t*)*info.functions_size);
  2335. functions_size = info.functions_size;
  2336. for (i=0; i<functions_size; ++i)
  2337. functions[i] = &info.functions[i];
  2338. /* Sort the symbols into section and symbol order */
  2339. qsort (functions, functions_size, sizeof(debug_function_t*),
  2340. compare_debug_function_t);
  2341. #if 0
  2342. for (i=0; i<info.functions_size; ++i)
  2343. fprintf(stdout, "%08lx T %s\n", info.functions[i].block->begin_addr, info.functions[i].name);
  2344. #endif
  2345. fflush(stdout);
  2346. }
  2347. } else /* storage_needed == 0 */
  2348. fprintf(stderr, "NO SYMBOLS FOUND.\n");
  2349. }
  2350. return 0;
  2351. }
  2352. /*********************************************************************/
  2353. /*********************************************************************/
  2354. /*********************************************************************/