diff options
| author | Michele Calgaro <michele.calgaro@yahoo.it> | 2026-01-08 17:57:04 +0900 |
|---|---|---|
| committer | Michele Calgaro <michele.calgaro@yahoo.it> | 2026-01-08 17:57:04 +0900 |
| commit | 19b03cd019433591a6bfb375b5d68a4e9abd28e7 (patch) | |
| tree | df7eba1d02d14a3998637b53170dd1cfcce3e9aa | |
| parent | f175a58c4136914a53430c3184f38f2b564f48ab (diff) | |
| download | kvirc-19b03cd019433591a6bfb375b5d68a4e9abd28e7.tar.gz kvirc-19b03cd019433591a6bfb375b5d68a4e9abd28e7.zip | |
Remove object prelink logic
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
| -rw-r--r-- | INSTALL | 13 | ||||
| -rw-r--r-- | admin/Makefile.am | 6 | ||||
| -rw-r--r-- | admin/acinclude.m4.in | 87 | ||||
| -rw-r--r-- | admin/objprelink.c | 530 |
4 files changed, 1 insertions, 635 deletions
@@ -373,19 +373,6 @@ General notes for the installation of the 3.4.0 release of KVIrc Explicitly add the specified include search path Example: --with-other-idirs="-I/home/pippo/include/ -I/tmp/inc/" - --enable-objprelink - This is an experimental support for object prelinking that improves - significantly the executable startup time. In order to use it you - need to have the "objprelink" program in the PATH. The objprelink - program is included in the distribution in the admin directory. - In order to use it, you will need to: - - # cd admin - # make objprelink - # cp objprelink /somewhere_on_your_path - - All this AFTER running ./configure and BEFORE running make. - --with-no-pthread-check Do not check if the pthread stuff works. If configure fails in the pthread library check , you might want to diff --git a/admin/Makefile.am b/admin/Makefile.am index fa91a48..cbce7d7 100644 --- a/admin/Makefile.am +++ b/admin/Makefile.am @@ -1,5 +1 @@ -EXTRA_DIST = acinclude.m4.in libtool.m4.in gendoc.pl gensrc.pl objprelink.c - -objprelink: objprelink.c - $(CC) -o $@ -O2 $< /usr/lib/libbfd.a /usr/lib/libiberty.a - +EXTRA_DIST = acinclude.m4.in libtool.m4.in gendoc.pl gensrc.pl diff --git a/admin/acinclude.m4.in b/admin/acinclude.m4.in index 745dd93..7584d20 100644 --- a/admin/acinclude.m4.in +++ b/admin/acinclude.m4.in @@ -2349,94 +2349,7 @@ dnl just a wrapper to clean up configure.in AC_DEFUN([KVIRC_PROG_LIBTOOL], [ AM_PROG_LIBTOOL - LIBTOOL_SHELL="/bin/sh ./libtool" - # LIBTOOL="$LIBTOOL --silent" - - AC_ARG_ENABLE(objprelink, [ --enable-objprelink prelink apps (experimental, needs objprelink in path)], - kvirc_use_objprelink=$enableval, kvirc_use_objprelink=no) - if test "x$kvirc_use_objprelink" = "xyes"; then - echo Patching libtool to run objprelink. - mv libtool libtool.orig - cat > libtool <<\EOF -#! /bin/sh - -ALREADYPRELINKED="" - -for n -do - case $n in - *.o) k=$n - if test -r $k; then - ISELF=`file $k | grep ELF` - if test -n "$ISELF"; then - ALREADY=`echo $ALREADYPRELINKED | grep "!!!$k"` - if test -z "$ALREADY"; then - echo objprelink $k - objprelink $k - ALREADYPRELINKED="$ALREADYPRELINKED !!!$k" - fi - fi - fi - ;; - *.lo) k=$n - if test -r $k; then - ISELF=`file $k | grep ELF` - if test -n "$ISELF"; then - ALREADY=`echo $ALREADYPRELINKED | grep "!!!$k"` - if test -z "$ALREADY"; then - echo objprelink $k - objprelink $k - ALREADYPRELINKED="$ALREADYPRELINKED !!!$k" - fi - fi - fi - ASHORTNAME=`echo $n | sed -e 's/\.lo$//'` - k=".libs/$ASHORTNAME.o" - if test -r $k; then - ISELF=`file $k | grep ELF` - if test -n "$ISELF"; then - ALREADY=`echo $ALREADYPRELINKED | grep "!!!$k"` - if test -z "$ALREADY"; then - echo objprelink $k - objprelink $k - ALREADYPRELINKED="$ALREADYPRELINKED !!!$k" - fi - fi - fi - k=".libs/$ASHORTNAME.lo" - if test -r $k; then - ISELF=`file $k | grep ELF` - if test -n "$ISELF"; then - ALREADY=`echo $ALREADYPRELINKED | grep "!!!$k"` - if test -z "$ALREADY"; then - echo objprelink $k - objprelink $k - ALREADYPRELINKED="$ALREADYPRELINKED !!!$k" - fi - fi - fi - k="$ASHORTNAME.o" - if test -r $k; then - ISELF=`file $k | grep ELF` - if test -n "$ISELF"; then - ALREADY=`echo $ALREADYPRELINKED | grep "!!!$k"` - if test -z "$ALREADY"; then - echo objprelink $k - objprelink $k - ALREADYPRELINKED="$ALREADYPRELINKED !!!$k" - fi - fi - fi - ;; - esac -done - -EOF - cat >> libtool libtool.orig - rm libtool.orig - chmod a+x libtool - fi ]) # =========================================================================== diff --git a/admin/objprelink.c b/admin/objprelink.c deleted file mode 100644 index 319bd68..0000000 --- a/admin/objprelink.c +++ /dev/null @@ -1,530 +0,0 @@ -/* objprelink -- prelinks c++ files for producing a more efficient dynlink. - Copyright 2001, Leon Bottou - - This program is free software; you can redistribute it and/or modify ait - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) - any later version. - - Compile with: - gcc -O2 -o objprelink objprelink.c /usr/lib/libbfd.a /usr/lib/libiberty.a - - This is i386 only. - There is very experimental PPC support (totally unproven). -*/ - -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include <sys/stat.h> -#include <stdarg.h> -#include "bfd.h" - -static int verbose = 0; -static int replace = 1; -static const char *target = 0; -static const char *program_name = "objprelink"; -static const char *enomem = "out of memory"; -static const char *eassert = "assertion failed"; - -static void -fatal(const char *fname, int lineno, const char *msg) -{ - if (program_name) - fprintf(stderr,"%s ", program_name); - if (fname) - fprintf(stderr,"(%s:%d) ", fname, lineno); - if (program_name || fname) - fprintf(stderr," : "); - if (bfd_get_error() != bfd_error_no_error) - bfd_perror(msg); - else if (errno) - perror(msg); - else - fprintf(stderr,"%s\n", msg); - exit(5); -} - -#define FATAL(s) \ - do{fatal(__FILE__,__LINE__,s);}while(0) -#define ASSERT(x,s) \ - do{if(!(x))fatal(__FILE__,__LINE__,s);}while(0) -#define CLEARERR() \ - do{errno=0;bfd_set_error(bfd_error_no_error);}while(0) - -static const char * -M(const char *format, ...) -{ - static char buffer[256*256]; - va_list ap; - va_start(ap, format); - vsprintf(buffer, format, ap); - va_end(ap); - return buffer; -} - -static void -usage(FILE *stream, int status) -{ - fprintf(stream, - "Usage: %s [-v] [-n] <objectfiles>\n" - "-- \"prelink\" c++ virtual tables\n" - "\n" - "This program massages object files in order to accelerate the loading\n" - "of shared object files (.so files) created by linking these object files.\n" - "This is intel specific at the moment\n" - "\n" - "The program scans the specified object file for linkonce sections\n" - "containing virtual tables with 32 bit absolute relocations (R_386_32)\n" - "to undefined procedures. For each such procedure, it creates a linkonce\n" - "text section containing a relay jump. All absolute relocations to this\n" - "procedure are then redirected to the single relay jump.\n" - "\n" - "Program objprelink should be called on all object files before linking.\n" - "\n" - "Option -v selects verbose mode\n" - "Option -n does not change the object files but generates a new object\n" - "whose name is composed by appending \".new\" to the original filename.\n", - program_name); - exit(status); -} - - -/* ---------------- MACHINE DEPENDENT PART ---- */ - -static char *stub; -static int stub_size; -static int stub_alignment; -static void (*stub_install)(bfd*, asection*, asymbol**); - -static reloc_howto_type *howto_32; - - -/* I386 */ - -static char stub_i386[] = { - 0xb8, 0, 0, 0, 0, /* mov $0,%eax */ - 0xff, 0xe0 /* jmp *(%eax) */ -}; - -static void -stub_install_i386(bfd *obfd, asection *p, asymbol **jumpto) -{ - int status; - int relcount = 1; - arelent **reloc = (arelent**)bfd_alloc(obfd, sizeof(arelent*)*relcount); - arelent *relent = (arelent*)bfd_alloc(obfd, sizeof(arelent)*relcount); - ASSERT(reloc, enomem); - ASSERT(relent, enomem); - reloc[0] = &relent[0]; - reloc[0]->sym_ptr_ptr = jumpto; - reloc[0]->address = 1; - reloc[0]->addend = 0; - reloc[0]->howto = howto_32; - bfd_set_reloc(obfd, p, reloc, relcount); - status = bfd_set_section_contents(obfd, p, stub, (file_ptr) 0, stub_size); - ASSERT(status, eassert); -} - -/* PPC */ - -static char stub_ppc[] = { - 0x48, 0, 0, 0 -}; - -static reloc_howto_type *howto_ppc_pltrel24; -static reloc_howto_type *howto_ppc_rel24; - -static void -stub_install_ppc(bfd *obfd, asection *p, asymbol **jumpto) -{ - int status; - int relcount = 1; - arelent **reloc = (arelent**)bfd_alloc(obfd, sizeof(arelent*)*relcount); - arelent *relent = (arelent*)bfd_alloc(obfd, sizeof(arelent)*relcount); - ASSERT(reloc, enomem); - ASSERT(relent, enomem); - reloc[0] = &relent[0]; - reloc[0]->sym_ptr_ptr = jumpto; - reloc[0]->address = 0; - reloc[0]->addend = 0; - reloc[0]->howto = howto_ppc_pltrel24; /* Second choice: howto_ppc_rel24 */ - bfd_set_reloc(obfd, p, reloc, relcount); - status = bfd_set_section_contents(obfd, p, stub, (file_ptr) 0, stub_size); - ASSERT(status, eassert); -} - -/* ALPHA */ - -/* ALL */ - -static void -prepare_stub_data(bfd *obfd, asymbol **syms, int symcount) -{ - switch (bfd_get_arch(obfd)) - { - case bfd_arch_i386: - stub = stub_i386; - stub_size = sizeof(stub_i386); - stub_install = stub_install_i386; - stub_alignment = 1; - break; - - case bfd_arch_powerpc: - fprintf(stderr,"Warning: PPC support is experimental\n"); - howto_ppc_pltrel24 = bfd_reloc_type_lookup(obfd, BFD_RELOC_24_PLT_PCREL); - howto_ppc_rel24 = bfd_reloc_type_lookup(obfd, BFD_RELOC_PPC_B26); - ASSERT(howto_ppc_pltrel24, eassert); - ASSERT(howto_ppc_rel24, eassert); - stub = stub_ppc; - stub_size = sizeof(stub_ppc); - stub_install = stub_install_ppc; - stub_alignment = 2; - break; - - default: - FATAL("This cpu architecture is not supported (yet)"); - break; - } - howto_32 = bfd_reloc_type_lookup(obfd, BFD_RELOC_32); - ASSERT(howto_32, eassert); -} - - -/* ---------- END OF MACHINE DEPENDENT PART ---- */ - - - -/* Symbol hash table */ - -typedef struct symbol_entry_s { - struct bfd_hash_entry root; - struct symbol_entry_s *next; - asection *relay; - asymbol *sym; -} symbol_entry; - -static struct bfd_hash_entry * -init_symbol_entry(struct bfd_hash_entry *entry, - struct bfd_hash_table *table, - const char *string) -{ - symbol_entry *ret = (symbol_entry*)entry; - if (! ret) - ret = (symbol_entry*)bfd_hash_allocate(table, sizeof(symbol_entry)); - ASSERT(ret,eassert); - memset(ret, 0, sizeof(symbol_entry)); - return bfd_hash_newfunc((struct bfd_hash_entry*)ret, table, string); -} - -static symbol_entry * -lookup_symbol(struct bfd_hash_table *table, const char *id, boolean create) -{ - return (symbol_entry*) bfd_hash_lookup(table, id, create, true); -} - -/* Cached relocations stored - in section userdata field */ - -struct section_userdata { - int relcount; - arelent **reloc; -}; - -/* Check if section is a virtual table */ - -static const char * -is_vt_section(bfd *abfd, asection *p) -{ - const char *name = bfd_section_name(abfd, p); - static const char prefix[] = ".gnu.linkonce.d.__vt_"; - static flagword w = (SEC_ALLOC|SEC_LOAD|SEC_RELOC|SEC_DATA|SEC_LINK_ONCE); - flagword f = bfd_get_section_flags (abfd, p); - if (f & w == w) - if (!strncmp(name, prefix, sizeof(prefix)-1)) - return name + sizeof(prefix)-6; - return false; -} - -/* Process one object file. - Returns true if a new file has been successfully created. */ - -static boolean -process(char *iname, char *oname) -{ - - bfd *ibfd = 0; - bfd *obfd = 0; - int isymcount = 0; - asymbol **isyms = 0; - struct bfd_hash_table vtsymtab; - symbol_entry *vtsyms = 0; - int vtcount = 0; - - int relcount; - arelent **reloc; - asection *p; - symbol_entry *hsym; - int storage_needed; - int status; - int i; - - if (verbose) - printf("processing file %s\n", iname); - - /* --- open bfds */ - ibfd = bfd_openr (iname, target); - ASSERT(ibfd, M("cannot read file \"%s\"", iname)); - if (! bfd_check_format(ibfd, bfd_object)) - FATAL(M("file \"%s\" is not a regular object file", iname)); - CLEARERR(); - - /* --- get input symbols */ - storage_needed = bfd_get_symtab_upper_bound(ibfd); - ASSERT(storage_needed>=0, eassert); - isyms = (asymbol**) bfd_alloc(ibfd, storage_needed); - ASSERT(isyms, enomem); - isymcount = bfd_canonicalize_symtab(ibfd, isyms); - ASSERT(isymcount>=0, eassert); - CLEARERR(); - - /* --- prepare variables required for stub generation */ - prepare_stub_data(ibfd, isyms, isymcount); - - /* --- cache all relocation entries */ - for (p=ibfd->sections; p; p=p->next) - { - const char *name = bfd_section_name(ibfd, p); - if (! strncmp(name, ".gnu.linkonce.t.stub.", 21)) - { - if (verbose) - printf(" file has already been processed\n"); - bfd_close(ibfd); - return false; - } - p->userdata = 0; - storage_needed = bfd_get_reloc_upper_bound(ibfd, p); - if (storage_needed > 0) - { - struct section_userdata *u = (void*)bfd_alloc(ibfd, sizeof(*u)); - ASSERT(u, enomem); - memset(u, 0, sizeof(*u)); - reloc = (arelent**)bfd_alloc(ibfd, storage_needed); - ASSERT(reloc, enomem); - relcount = bfd_canonicalize_reloc(ibfd, p, reloc, isyms); - ASSERT(relcount>=0, M("Problem with relocations for section %s in file %s", - bfd_section_name(ibfd,p), bfd_get_filename(ibfd))); - u->relcount = relcount; - u->reloc = reloc; - p->userdata = u; - } - } - - /* --- construct hash table of vt undefined symbols */ - memset(&vtsymtab, 0, sizeof(vtsymtab)); - status = bfd_hash_table_init(&vtsymtab, init_symbol_entry); - ASSERT(status, eassert); - for (p=ibfd->sections; p; p=p->next) - { - const char *vtname = is_vt_section(ibfd, p); - if (vtname) - { - if (verbose) - printf(" scanning section \"%s\"\n", vtname); - reloc = (p->userdata) ? ((struct section_userdata*)p->userdata)->reloc : 0; - relcount = (p->userdata) ? ((struct section_userdata*)p->userdata)->relcount : 0; - for (i=0; i<relcount; i++) - { - arelent *rel = reloc[i]; - asymbol *sym = (rel->sym_ptr_ptr ? *rel->sym_ptr_ptr : 0); - if (sym && - rel->howto->type == howto_32->type && - !lookup_symbol(&vtsymtab, sym->name, false)) - { - hsym = lookup_symbol(&vtsymtab, sym->name, true); - ASSERT(hsym, eassert); - hsym->next = vtsyms; - hsym->sym = sym; - vtsyms = hsym; - vtcount += 1; - } - } - } - } - if (verbose) - printf(" found %d symbols in need for a stub\n", vtcount); - if (! vtcount) - { - bfd_hash_table_free(&vtsymtab); - bfd_close(ibfd); - return false; - } - - /* --- create output bfd */ - obfd = bfd_openw (oname, bfd_get_target (ibfd)); - ASSERT(obfd, M("cannot create file \"%s\"", iname)); - bfd_set_format (obfd, bfd_get_format (ibfd)); - bfd_set_start_address (obfd, bfd_get_start_address(ibfd)); - bfd_set_file_flags (obfd, (bfd_get_file_flags (ibfd) & bfd_applicable_file_flags (obfd))); - bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd)); - - /* --- create copied sections */ - for (p=ibfd->sections; p; p=p->next) - { - const char *err = M("cannot replicate section %s from file %s", - bfd_section_name (ibfd, p), iname); - asection *isection = p; - asection *osection = bfd_make_section_anyway (obfd, bfd_section_name (ibfd, isection)); - ASSERT(osection, err); - status = bfd_set_section_size (obfd, osection, bfd_section_size (ibfd, isection)); - ASSERT(status, err); - status = bfd_set_section_vma (obfd, osection, bfd_section_vma (ibfd, isection)); - ASSERT(status, err); - osection->lma = isection->lma; - status = bfd_set_section_alignment(obfd, osection, bfd_section_alignment (ibfd, isection)); - ASSERT(status, err); - status = bfd_set_section_flags(obfd, osection, bfd_get_section_flags (ibfd, isection)); - ASSERT(status, err); - isection->output_section = osection; - isection->output_offset = 0; - status = bfd_copy_private_section_data (ibfd, isection, obfd, osection); - ASSERT(status, err); - } - - /* --- create stub sections */ - if (verbose) - printf(" defining stub sections\n"); - for (hsym=vtsyms; hsym; hsym=hsym->next) - { - asection *osection; - asymbol *sym; - char *name; - /* new section */ - name = (char*)bfd_alloc(obfd, strlen(hsym->sym->name) + 28); - ASSERT(name, enomem); - strcpy(name,".gnu.linkonce.t.stub."); - strcat(name,hsym->sym->name); - hsym->relay = osection = bfd_make_section_anyway (obfd, name); - ASSERT(osection, enomem); - bfd_set_section_size(obfd, osection, stub_size); - bfd_set_section_alignment(obfd, osection, stub_alignment); - bfd_set_section_flags(obfd, osection, - SEC_HAS_CONTENTS|SEC_ALLOC|SEC_LOAD| - SEC_RELOC|SEC_READONLY|SEC_CODE|SEC_LINK_ONCE); - } - - /* --- copy symbols */ - bfd_set_symtab (obfd, isyms, isymcount); - - /* --- copy section relocs and data */ - if (verbose) - printf(" copying section data from %s\n", iname); - for (p=ibfd->sections; p; p=p->next) - { - const char *sname; - const char *err = M("cannot copy data from section %s in file %s", - bfd_section_name (ibfd, p), iname); - asection *isection = p; - asection *osection = p->output_section; - bfd_size_type size = bfd_get_section_size_before_reloc (isection); - /* copy relocs */ - reloc = (p->userdata) ? ((struct section_userdata*)isection->userdata)->reloc : 0; - relcount = (p->userdata) ? ((struct section_userdata*)isection->userdata)->relcount : 0; - sname = is_vt_section(ibfd, isection); - if (sname) - { - if (verbose) - printf(" patching relocs for %s\n", sname); - for (i=0; i<relcount; i++) - { - arelent *rel = reloc[i]; - asymbol *sym = (rel->sym_ptr_ptr ? *rel->sym_ptr_ptr : 0); - ASSERT(sym, eassert); - hsym = lookup_symbol(&vtsymtab, sym->name, false); - if (hsym) - rel->sym_ptr_ptr = hsym->relay->symbol_ptr_ptr; - } - } - bfd_set_reloc(obfd, osection, (relcount) ? reloc : 0, relcount); - /* copy data */ - if (bfd_get_section_flags (ibfd, isection) & SEC_HAS_CONTENTS) - { - void *memchunk = malloc(size); - ASSERT(memchunk, enomem); - status = bfd_get_section_contents (ibfd, isection, memchunk, (file_ptr) 0, size); - ASSERT(status, eassert); - status = bfd_set_section_contents(obfd, osection, memchunk, (file_ptr) 0, size); - ASSERT(status, eassert); - free(memchunk); - } - } - - /* --- generate relocs and data for stub sections */ - for (hsym=vtsyms; hsym; hsym=hsym->next) - { - asection *osection = hsym->relay; - (*stub_install)(obfd, osection, &hsym->sym); - } - - /* --- copy private data */ - status = bfd_copy_private_bfd_data (ibfd, obfd); - ASSERT(status, M("error copying private data for %s", iname)); - - /* --- close bfds */ - if (verbose) - printf(" finishing %s\n", iname); - status = bfd_close(obfd); - ASSERT(status, M("error while writing %s", oname)); - bfd_close(ibfd); - - /* --- cleanup */ - bfd_hash_table_free(&vtsymtab); - return true; -} - - - -/* Main */ - -int -main(int argc, char **argv) -{ - int i; - int status = 0; - program_name = strrchr(argv[0],'/'); - program_name = (program_name) ? program_name + 1 : argv[0]; - if (argc < 2) - usage(stderr, 5); - bfd_init(); - bfd_set_error_program_name(program_name); - for (i=1; i<argc; i++) - { - if (!strcmp(argv[i], "-v")) - verbose = 1; - else if (!strcmp(argv[i], "-n")) - replace = 0; - else if (!strncmp(argv[i], "--target=", 9)) - target = argv[i] + 9; - else - { - char *name = argv[i]; - char *newname = malloc(strlen(name) + 8); - ASSERT(newname,enomem); - strcpy(newname, name); - strcat(newname, ".new"); - if (process(name, newname) && replace) - { - unlink(name); - link(newname, name); - unlink(newname); - } - free(newname); - } - } - /* Finished */ - return status; -} - - |
