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

From Higher Intellect Vintage Wiki
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