Please consider a donation to the Higher Intellect project. See https://preterhuman.net/donate.php or the Donate to Higher Intellect page for more info. |
Dsolist.shar
Jump to navigation
Jump to search
#! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # Makefile # main.c # dsolist.h # dsolist.c # myfunc.h # myfunc.c # myfunc2.h # myfunc2.c # README # This archive created: Tue May 28 15:53:59 1996 export PATH; PATH=/bin:$PATH if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else sed 's/^X//' << \SHAR_EOF > 'Makefile' X X Xall: dsolist X XMODEL = -32 XCFLAGS = $(MODEL) X# X#intentionally trying to generate a dso addr conflict with some dso X# X# so we create 2 at same address XDSOADDR = -T 4000000 -D 400b000 X Xdsolist: main.o dsolist.o myfunc.so myfunc2.so X $(CC) $(CFLAGS) main.o dsolist.o -lelf -lm myfunc.so myfunc2.so -o dsolist X X Xmyfunc.so: myfunc.c myfunc.h X $(CC) $(CFLAGS) -g -c myfunc.c X ld $(MODEL) -shared $(DSOADDR) myfunc.o -soname \ X ./myfunc.so -o myfunc.so Xmyfunc2.so: myfunc2.c myfunc2.h X $(CC) $(CFLAGS) -g -c myfunc2.c X ld $(MODEL) -shared $(DSOADDR) myfunc2.o -soname \ X ./myfunc2.so -o myfunc2.so X Xmain.o: main.c dsolist.h X $(CC) -g -c $(CFLAGS) main.c X Xdsolist.o: dsolist.c dsolist.h X $(CC) -g -c $(CFLAGS) dsolist.c X Xclobber: X -rm -f dsolist X -rm -f *.o a.out junk X -rm -f *.so X -rm -f so_locations Xshar: X shar -p X Makefile main.c dsolist.h dsolist.c \ X myfunc.h myfunc.c myfunc2.h myfunc2.c \ X README \ X >/d2/public/dsolist.shar SHAR_EOF fi # end of overwriting check if test -f 'main.c' then echo shar: will not over-write existing file "'main.c'" else sed 's/^X//' << \SHAR_EOF > 'main.c' X X/* X test driver: print my own dso list X X $Revision: 1.2 $ X X*/ X#include <stdio.h> X#include <math.h> X#include "dsolist.h" X#include "myfunc2.h" X#include "myfunc.h" X Xint main() X{ X X double sval = sin(27.333); X int i = myfunc() + myfunc2(); X X dsolist_print(); X X return i; X X} SHAR_EOF fi # end of overwriting check if test -f 'dsolist.h' then echo shar: will not over-write existing file "'dsolist.h'" else sed 's/^X//' << \SHAR_EOF > 'dsolist.h' X#ifndef DSOLIST_H X#define DSOLIST_H X/* X X$Revision: 1.2 $ X*/ X X Xvoid dsolist_print(void); X X#endif X X SHAR_EOF fi # end of overwriting check if test -f 'dsolist.c' then echo shar: will not over-write existing file "'dsolist.c'" else sed 's/^X//' << \SHAR_EOF > 'dsolist.c' X/* X X$Revision: 1.3 $ X XThis routine is intended to print the dso list of the program Xit is linked into. X XSince it can only be one ABI (chosen at compile time) Xit uses compiler predefines to determine which routine is Xapplicable. X XIt is provided in the hope it may be useful. X XThere is no guarantee that this will work in any given release. X XIt was tested with IRIX6.2 X XDavid Anderson May, 1996 X X*/ X X X X#include <elf.h> X#include <libelf.h> X#include <objlist.h> X#include <obj_list.h> X#include <obj.h> X#include <alloca.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <fcntl.h> X#include <sgidefs.h> X X/* this is the pointer to the list */ Xextern long * __rld_obj_head; X X#define INCRPHDR(x,sz) (((char *)(x)) + (sz)) X Xstatic void Xprint64_one_phdr(Elf64_Phdr * phdr, unsigned long base_addr, Xunsigned long new_addr) X{ X unsigned long newa; X newa = phdr->p_vaddr + (new_addr - base_addr); X printf("\toriginal vaddr 0x%lx memory size 0x%lx (%ld)\n", X (long)phdr->p_vaddr, (long)phdr->p_memsz, X (long)phdr->p_memsz); X printf("\tin-mem vaddr 0x%lx \n", X (long)newa); X X if(phdr->p_flags & PF_X) { X printf("\tTEXT\n"); X } else if(phdr->p_flags & PF_W) { X printf("\tDATA\n"); X } else if (phdr->p_flags & PF_R) { X printf("\tREAD_ONLY DATA\n"); X } else { X printf("\tUnknown category\n"); X } X printf("\n"); X} X Xstatic void Xprint32_one_phdr(Elf32_Phdr * phdr, unsigned long base_addr, Xunsigned long new_addr) X{ X unsigned int newa; X newa = phdr->p_vaddr + (new_addr - base_addr); X printf("\toriginal vaddr 0x%x memory size 0x%x (%d)\n", X phdr->p_vaddr, phdr->p_memsz, X phdr->p_memsz); X printf("\tin-mem vaddr 0x%x \n", X (int)newa); X X if(phdr->p_flags & PF_X) { X printf("\tTEXT\n"); X } else if(phdr->p_flags & PF_W) { X printf("\tDATA\n"); X } else if (phdr->p_flags & PF_R) { X printf("\tREAD_ONLY DATA\n"); X } else { X printf("\tUnknown category\n"); X } X printf("\n"); X} Xstatic void Xdo_one_elf32( Elf32_Ehdr * ehdrp, Elf *elf_in, unsigned long X base_addr, unsigned long new_addr, char *name) X{ X Elf32_Phdr * phdr; X int i; X int hdrsize = ehdrp->e_phentsize; X X phdr = elf32_getphdr(elf_in); X X if (phdr == 0) { X printf("No program headers or error\n"); X return; X } X X for(i = 0; X i < ehdrp->e_phnum ; X ++i, phdr = ( Elf32_Phdr *) INCRPHDR(phdr,hdrsize)) { X if((phdr->p_type == PT_LOAD)) { X printf("\tprogram header entry PT_LOAD %d\n",i); X print32_one_phdr(phdr,base_addr, new_addr); X X } else if (phdr->p_type == PT_DYNAMIC) { X printf("\tprogram header entry PT_DYNAMIC %d\n",i); X print32_one_phdr(phdr,base_addr, new_addr); X } X } X} Xstatic void Xdo_one_elf64( Elf64_Ehdr * ehdrp, Elf *elf_in, Xunsigned long base_addr, unsigned long new_addr,char *name) X{ X Elf64_Phdr * phdr; X int i; X int hdrsize = ehdrp->e_phentsize; X X phdr = elf64_getphdr(elf_in); X X if (phdr == 0) { X printf("No program headers or error\n"); X return; X } X X for(i = 0; X i < ehdrp->e_phnum ; X ++i, phdr = ( Elf64_Phdr *) INCRPHDR(phdr,hdrsize)) { X if((phdr->p_type == PT_LOAD)) { X printf("\tprogram header entry PT_LOAD %d\n",i); X print64_one_phdr(phdr,base_addr, new_addr); X X } else if (phdr->p_type == PT_DYNAMIC) { X printf("\tprogram header entry PT_DYNAMIC %d\n",i); X print64_one_phdr(phdr,base_addr, new_addr); X } X } X} X Xstatic void Xprint_text_and_data_info( unsigned long base_addr, X unsigned long new_addr, char *dsoname) X{ X Elf * elf_in = 0; X Elf_Cmd cmd; X int ourfd; X Elf_Kind kind; X int res; X Elf32_Ehdr *lcl32ehdr; X Elf64_Ehdr *lcl64ehdr; X unsigned version; X X cmd = ELF_C_READ; X X X ourfd = open(dsoname,O_RDONLY); X X if(ourfd < 0) { X (void)printf("%s: Could not open %s\n",dsoname); X return; X } X version = elf_version(EV_CURRENT); X if(version == EV_NONE) { X printf("%s linked with incorrect libelf (elf_version returns EV_NONE). Cannot proceed.\n", X "dsolist"); X exit(1); X } X elf_in = elf_begin(ourfd,cmd,(Elf*)0); X kind = elf_kind(elf_in); X switch(kind) { X default: X printf("Unknown elf kind %d: cannot process %s\n",dsoname); X break; X case ELF_K_ELF: X if((lcl32ehdr = elf32_getehdr(elf_in)) != 0) { X do_one_elf32(lcl32ehdr,elf_in,base_addr, X new_addr,dsoname); X } else if (( lcl64ehdr = elf64_getehdr(elf_in)) != 0) { X do_one_elf64(lcl64ehdr,elf_in,base_addr, X new_addr,dsoname); X } else { X printf("Unable to get elf header\n"); X } X break; X } X elf_end(elf_in); X close(ourfd); X X return; X X} X X X#if _MIPS_SIM == _MIPS_SIM_ABI32 X Xstatic void Xprint_single_32_entry(long v,struct obj * ostr) X{ X printf("Dso %ld\n",v); X printf("\toriginal addr 0x%x\n",ostr->o_base_address); X printf("\tcurrent addr 0x%x\n",ostr->o_praw); X printf("\tPath at 0x%x\n",ostr->o_path); X printf("\tname %s\n",(char *)ostr->o_path); X print_text_and_data_info((unsigned long)ostr->o_base_address,(unsigned long)ostr->o_praw,ostr->o_path); X} X X/* by definition, nextentry->data is NOT 0xffffffff */ Xstatic void Xprint_32_obj_list(long *list_base) X{ X struct obj_list *nextentry = (struct obj_list *)list_base; X long v; X X printf(" -32 dso list \n"); X for(v = 0; nextentry ; ++v ) { X print_single_32_entry(v,(struct obj *)nextentry->data); X nextentry = nextentry->next; X } X} X#endif X X#if _MIPS_SIM == _MIPS_SIM_NABI32 Xstatic void Xprint_single_n32_entry(long v,Elf32_Obj_Info *ostr) X{ X printf("Dso %ld\n",v); X if(ostr->oi_magic != -1) { X printf("\tIncorrect oi_magic: 0x%x, should be 0xffffffff\n" , X ostr->oi_magic); X } X printf("\toriginal addr 0x%x\n",ostr->oi_orig_ehdr); X printf("\tcurrent addr 0x%x\n",ostr->oi_ehdr); X printf("\tPath at 0x%x, length %d\n", X ostr->oi_pathname,ostr->oi_pathname_len); X X printf("\tname %s\n",(char *)ostr->oi_pathname); X print_text_and_data_info(ostr->oi_orig_ehdr,ostr->oi_ehdr, X (char *)ostr->oi_pathname); X} X X/* by definition, oi_magic *is* 0xffffffff */ Xstatic void Xprint_n32_obj_list(long *list_base) X{ X Elf32_Obj_Info *nextentry = (Elf32_Obj_Info *)list_base; X long v; X X printf(" n32 dso list \n"); X for(v = 0; nextentry ; ++v ) { X print_single_n32_entry(v,nextentry); X nextentry = (Elf32_Obj_Info *)nextentry->oi_next; X } X} X#endif X X#if _MIPS_SIM == _MIPS_SIM_ABI64 Xstatic void Xprint_single_64_entry(long v, Elf64_Obj_Info * ostr) X{ X printf("Dso %ld ",v); X printf("\toriginal addr 0x%lx\n",ostr->oi_orig_ehdr); X printf("\tcurrent addr 0x%lx\n",ostr->oi_ehdr); X printf("\tPath at 0x%lx, length %ld\n", X (long)ostr->oi_pathname,(long)ostr->oi_pathname_len); X X printf("\tname %s\n",(char *)ostr->oi_pathname); X print_text_and_data_info(ostr->oi_orig_ehdr,ostr->oi_ehdr, X (char *)ostr->oi_pathname); X} Xstatic void Xprint_64_obj_list(long *list_base) X{ X Elf64_Obj_Info *nextentry = (Elf64_Obj_Info *)list_base; X long v; X X printf(" 64 bit dso list \n"); X for(v = 0; nextentry ; ++v ) { X print_single_64_entry(v,nextentry); X nextentry = (Elf64_Obj_Info *)nextentry->oi_next; X } X} X#endif X X X Xvoid Xdsolist_print(void) X{ X#if _MIPS_SIM == _MIPS_SIM_ABI32 Xprint_32_obj_list(__rld_obj_head); X#elif _MIPS_SIM == _MIPS_SIM_NABI32 Xprint_n32_obj_list(__rld_obj_head); X#elif _MIPS_SIM == _MIPS_SIM_ABI64 Xprint_64_obj_list(__rld_obj_head); X#else X#error "incorrect subprogram interface model" X#endif X X} SHAR_EOF fi # end of overwriting check if test -f 'myfunc.h' then echo shar: will not over-write existing file "'myfunc.h'" else sed 's/^X//' << \SHAR_EOF > 'myfunc.h' X Xint myfunc(); X SHAR_EOF fi # end of overwriting check if test -f 'myfunc.c' then echo shar: will not over-write existing file "'myfunc.c'" else sed 's/^X//' << \SHAR_EOF > 'myfunc.c' X X#include "myfunc.h" X Xint myfunc() X{ X return 0; X} SHAR_EOF fi # end of overwriting check if test -f 'myfunc2.h' then echo shar: will not over-write existing file "'myfunc2.h'" else sed 's/^X//' << \SHAR_EOF > 'myfunc2.h' X Xint myfunc2(); X SHAR_EOF fi # end of overwriting check if test -f 'myfunc2.c' then echo shar: will not over-write existing file "'myfunc2.c'" else sed 's/^X//' << \SHAR_EOF > 'myfunc2.c' X X#include "myfunc2.h" X Xint myfunc2() X{ X return 1; X} SHAR_EOF fi # end of overwriting check if test -f 'README' then echo shar: will not over-write existing file "'README'" else sed 's/^X//' << \SHAR_EOF > 'README' X XThis is a tiny example showing how an application can Xprint its own dso list. X XIt's intended to be passed, as source, to anyone needing Xinformation on how to do this. X XFeel free to copy or use this source in any way. X XThe information here is not guaranteed to work across releases. XIt was tested with IRIX6.2. X XTo build and run this, do, in an empty directory, X X # unpack the shar file (you already did that to read this X # README X sh /usr/tmp/dsolist.shar X X #edit Makefile to have the right MODEL (-32, -64 -n32) X # use vi, emacs, whatever. X X # build the sample app, which builds two dso's with X # the same address to show the effect of dso movement. X make X X # run the app, printing its dso list. X ./dsolist X X XDavid Anderson May 1996 [email protected] SHAR_EOF fi # end of overwriting check # End of shell archive exit 0