Readobj.shar

#! /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:
#	readobj.c
#	Makefile
#	readobj64.c
#	readobj.h
#	readobj64.h
# This archive created: Wed Jun 13 09:55:57 2001
export PATH; PATH=/bin:$PATH
if test -f 'readobj.c'
then
	echo shar: will not over-write existing file "'readobj.c'"
else
sed 's/^X//' << \SHAR_EOF > 'readobj.c'
X/* this program attempts to read and print the headers of a MIPS 
X** object or ** a.out.
X**
X** It prints as much as possible as early as possible in case the
X** object is malformed.
X** It does its own i/o in case libmld is ill.
X**
X*/
X
Xchar *Usage = "Usage: readobj <options> file ...\n"
X"Options:\n"
X"-d print the dynamic section (DT_ stuff)\n"
X#ifdef __sgi
X"-g print out all gp tables (IRIX o32 specific)\n"
X"-l print all local symbol tables\n"
X"-p print procedure tables\n"
X#endif
X"-r print relocation entries\n"
X"-t print out all elf symbols\n"
X
X;
X
X
X#include <stdio.h>
X#include <a.out.h>
X#include <malloc.h>
X#include <alloca.h>
X#include <string.h>
X#include <time.h>
X#include "readobj.h"
X#ifdef LINUX
X#include <elf.h>
X#include <unistd.h>
X#else /* !LINUX */
X#ifdef HAS_ELFHDR
X#include <elf_abi.h>
X#include <elf_mips.h>
X#endif
X#include <stdlib.h>
X#endif /* !LINUX */
X
X#include "readobj64.h"
X
X#ifndef IS_ELF
X#define IS_ELF(e) (e.e_ident[0] == 0x7f && \
X		e.e_ident[1]== 'E' && \
X		e.e_ident[2]== 'L' && \
X		e.e_ident[3]== 'F' )
X#endif
X
X#define USHORT unsigned short
X#ifdef __sgi
Xstatic void print_a_proc(int num, unsigned long fileaddr);
Xstatic void print_a_localsymbol(int count, unsigned long loc);
Xstatic void print_procs(void);
Xstatic void print_localsyms(void);
Xstatic void get_local_strings(void);
Xstatic void get_external_strings(void);
Xstatic void do_ifds(void);
Xstatic void print_ifd(unsigned long,unsigned long);
Xint do_opthdr(void);
Xint do_scnhdr(int i);
Xint do_symt(void);
X#endif
X
X
Xstatic void dofile(char *);
X#ifdef HAS_ELFHDR
Xstatic void do_elf_file(char *);
Xstatic void elf_get_sectstrings(unsigned long, unsigned long, unsigned long, unsigned long);
Xstatic void elf_print_progheaders(unsigned long,unsigned long,unsigned long);
Xstatic void elf_print_sectheaders(unsigned long,unsigned long,unsigned long);
Xstatic int elf_print_dynamic32(unsigned long offset,unsigned long size,int link);
Xstatic int elf_print_relocation32(unsigned long offset,unsigned long size,int link);
Xstatic int elf_print_symbols32(unsigned long offset,unsigned long size);
Xstatic char * get_dynstr_string(unsigned long offset, int index);
Xstatic char * get_symstr_string(unsigned long offset);
X
Xstatic void elf_get_dynstr(unsigned long offset,unsigned long entsize,unsigned long count );
Xstatic void elf_get_symstr(unsigned long offset,unsigned long entsize,unsigned long count );
X
X
X#endif
X#ifdef __sgi
Xstatic int do_a_symtab_at(long addr);
X#endif
X
X
X
X#define P printf
X#define F fflush(stdout)
X#define RR(buf,loc,siz)  ((fseek(fin,(long)loc,0)<0) ? -1 : \
X		((fread(buf,(long)siz,1,fin)!=1)?-2:0))
X#define RN(buf,siz)  ((fread(buf,siz,1,fin) != 1) ? -2 : 0)
X#define CURLOC     ( ftell(fin) )
X#define SEEKTO(i)  (fseek(fin,(long)(i),SEEK_SET))
X
X#ifdef __sgi
Xstatic int print_gp_tables = 0;
Xstatic int print_pd_tables = 0;
Xstatic void print_gp_table_data(unsigned fileloc, int cnt);
Xstatic int print_localsym_tables = 0;
X#endif
X
Xint print_dynamic_section = 0;
Xint print_symtab_sections = 0;
Xint print_reloc_sections  = 0;
X
X#ifdef LINUX
Xstruct filehdr { char x[sizeof(Elf32_Ehdr)]; };
Xstatic struct filehdr fhdr;
X#else
Xstatic struct filehdr fhdr;
Xstatic struct aouthdr opthdr;
Xstatic struct scnhdr  shdr;
Xstatic HDRR    symhdr;
Xstatic FDR	symifdrec;
Xstatic PDR 	pdr;
Xstatic SYMR 	symr;
X#endif
X
X#ifdef HAS_ELFHDR
Xstatic Elf32_Ehdr ehdr;
X#endif
X
Xchar *filename;
X
X#ifdef __sgi
Xstatic char *externalstringbase;
Xstatic char *localstringbase;
X#endif
X
Xstatic char *elf_shstrings_data; /* section name strings */
Xstatic unsigned long  elf_shstrings_length; /* length of currentsection. 
X			Might be zero..*/
Xstatic unsigned long  elf_shstrings_max; /* size of malloc-d space */
X
Xstatic char *dynamic_sect_strings;
Xstatic unsigned long dynamic_sect_strings_length;
Xstatic int  dynamic_sect_strings_sect_index;
X
Xstatic char *symbol_sect_strings;
Xstatic unsigned long symbol_sect_strings_length;
X
XFILE *fin;
X
Xint
Xmain(int argc,char **argv)
X{
X	int i;
X
X	if( argc == 1) {
X		printf("%s\n",Usage);
X		exit(1);
X	} else {
X		argv++;
X		for(i =1; i<argc; i++,argv++) {
X#ifdef __sgi
X			if(strcmp(argv[0],"-p") == 0) {
X				print_pd_tables = 1;
X				continue;
X			}
X			if(strcmp(argv[0],"-l") == 0) {
X				print_localsym_tables = 1;
X				continue;
X			}
X			if(strcmp(argv[0],"-g") == 0) {
X				print_gp_tables = 1;
X				continue;
X			}
X#endif
X			if(strcmp(argv[0],"-t") == 0) {
X				print_symtab_sections= 1;
X				continue;
X			}
X			if(strcmp(argv[0],"-r") == 0) {
X				print_reloc_sections= 1;
X				continue;
X			}
X			if(strcmp(argv[0],"-d") == 0) {
X				print_dynamic_section= 1;
X				continue;
X			}
X			fin = fopen(argv[0],"r");
X			if(fin == NULL) {
X				printf("No such file as %s\n",argv[0]);
X				continue;
X			}
X			filename = argv[0];
X			dofile(argv[0]);
X			fclose(fin);
X		}
X	}
X	return 0;
X}
X
X#define MIPSEBMAGIC_2     0x0163
X
Xstatic void
Xdofile(char *s)
X{
X	int res;
X#ifdef __sgi
X	int i;
X#endif
X
X	res = RR(&fhdr,0,sizeof(fhdr));
X	if(res) {
X		P("could not read whole file header of %s\n",filename);
X		return;
X	}
X#ifdef HAS_ELFHDR
X	memcpy((void *)&ehdr,(void *)&fhdr,sizeof(ehdr));
X	if(IS_ELF(ehdr)) {
X		do_elf_file(s);
X		return;
X	}
X#endif
X#ifdef __sgi
X	P("File: %s\n",filename);
X	P("  magic %#x f_nscns %d date %#x syms at %#x symhdr_size %d\n",
X	  fhdr.f_magic, fhdr.f_nscns, fhdr.f_timdat, fhdr.f_symptr,
X	  fhdr.f_nsyms);
X	P("  pthdr_size %d flags %#x",
X		fhdr.f_opthdr,fhdr.f_flags);
X	F;
X	if(fhdr.f_magic == MIPSEBMAGIC)
X		P("  is MIPSEBMAGIC\n");
X	if(fhdr.f_magic == MIPSEBMAGIC_2)
X		P("  is MIPSEBMAGIC_2\n");
X	else
X		P("\n");
X	F;
X	if(do_opthdr())
X		return;
X	for(i = 0; i < fhdr.f_nscns; i++) {
X		if(do_scnhdr(i))
X			return;
X	}
X	if(do_symt())
X		return;
X	P("done\n");
X	F;
X#endif /* __sgi*/
X}
X
X#ifndef LINUX
Xint do_opthdr(void)
X{
X
X	int res;
X	int o;
X	
X	res = RN(&opthdr,sizeof(opthdr));
X	if(res) {
X		P("could not read whole file header of %s\n",filename);
X		return 1;
X	}
X	o = opthdr.magic;
X	P("\n  opthdr magic %#x %s\n",o, (o == OMAGIC) ?"OMAGIC" : (o == ZMAGIC) ?
X			"ZMAGIC" : (o == NMAGIC) ? "NMAGIC" : 
X			(o == LIBMAGIC) ? "LIBMAGIC": "unknownmagic");
X	P("  vstamp %#x tsize %#x dsize %#x bsize %#x entry %#x\n",
X		opthdr.vstamp, opthdr.tsize,opthdr.dsize, opthdr.bsize,opthdr.entry);
X	P("  start text %#x data %#x bss %#x gprmask %#x\n",
X		opthdr.text_start, opthdr.data_start,opthdr.bss_start,
X		opthdr.gprmask);
X	P("  cprmask %#x %#x %#x %#x gp_value %#x\n",
X		opthdr.cprmask[0],
X		opthdr.cprmask[1],
X		opthdr.cprmask[2],
X		opthdr.cprmask[3],
X		opthdr.gp_value);
X	F;
X	return 0;
X}
Xint
Xdo_scnhdr(int i)
X{
X	int res;
X	char lname[10];
X
X	res = RN(&shdr,sizeof(shdr));
X	if(res) {
X		P("could not read whole section %d header of %s\n",i,filename);
X		return 1;
X	}
X	strncpy(lname,shdr.s_name,sizeof(shdr.s_name));
X	lname[8] = 0;
X	P(" Section %d  %s\n",i,lname);
X	P("  paddr %#x vaddr %#x size %#x data at %#x reloc at %#x\n",
X		shdr.s_paddr,
X		shdr.s_vaddr,
X		shdr.s_size,	
X		shdr.s_scnptr,
X		shdr.s_relptr);
X	P("  gp at %#x numreloc %#x",
X		shdr.s_lnnoptr,
X		shdr.s_nreloc);
X	P("  numgp %#x flags %#x\n",
X		shdr.s_nlnno,
X		shdr.s_flags);
X	
X	F;
X	if(print_gp_tables) {
X		print_gp_table_data(shdr.s_lnnoptr,shdr.s_nlnno);
X	}
X	if(strcmp(".lib",lname) == 0) {
X		long oldloc;
X		oldloc = CURLOC;
X		if(shdr.s_size > 0) {
X			struct libscn *ilp;
X			char *curlibp;
X			int i;
X			char *buf = malloc(shdr.s_size);
X
X
X			if(buf == 0) {
X				P("Cannot malloc %d bytes\n",shdr.s_size);
X				exit(2);
X			}
X			SEEKTO(shdr.s_scnptr);
X			i = RN(buf,shdr.s_size);
X			if(i ) {
X				P("could not read shared lib section\n");
X				exit(1);
X			}
X			P("  .lib with %d shared libraries referenced\n",shdr.s_nlib);
X			curlibp = buf;
X			for( i = 0; i < shdr.s_nlib; 
X			    i++, curlibp += ilp->size*sizeof(int)) {
X
X				ilp = (struct libscn *)curlibp;
X				P("  size %d;  offset %d;  tsize %#x",
X					ilp->size,ilp->offset,ilp->tsize);
X				P("  dsize %#x; bsize %#x\n",ilp->dsize,ilp->bsize);
X				P(  "  tstart %#x;",ilp->text_start);
X				P(  "  dstart %#x;",ilp->data_start);
X				P(  "  bstart %#x\n",ilp->bss_start);
X				P("  %s\n", ((char *)ilp)+ ilp->offset*sizeof(int));
X			}
X		}
X		SEEKTO(oldloc);
X	}
X	F;
X	return 0;
X
X}
X
Xint
Xdo_symt(void)
X{
X	long symtaddr = fhdr.f_symptr;
X
X	if(fhdr.f_symptr == 0) {
X		P("  No symbol table\n");
X		return 0;
X	}
X	return do_a_symtab_at(symtaddr);
X}
Xstatic int
Xdo_a_symtab_at(long addr)
X{
X	int res;
X
X	res = RR(&symhdr,addr,sizeof(symhdr));
X	if(res) {
X		P("could not read whole symbol table header at %#x of %s\n",
X			addr,filename);
X		return 1;
X	}
X	P("\n");
X	P("  Symtab magic %#x symtab magic? %s  true magic is %#x\n",
X		symhdr.magic , 
X		(symhdr.magic == magicSym) ? "yes" : "no", magicSym);
X	F;
X	P("  vstamp %#x  ilineMax %ld cbLine %ld\n",
X		 symhdr.vstamp, symhdr.ilineMax,symhdr.cbLine);
X		
X	P("  linetaboffest %#x.  %d dense numbers at %#x\n",
X		symhdr.cbLineOffset,symhdr.idnMax,
X		symhdr.cbDnOffset);
X	P("  %d procedures at %#x,  %d local symbols at %#x\n",
X		symhdr.ipdMax, symhdr.cbPdOffset,
X		symhdr.isymMax, symhdr.cbSymOffset);
X	P("  %d optim ents at %#x,  %d auxes at %#x\n",
X		symhdr.ioptMax,symhdr.cbOptOffset,
X		symhdr.iauxMax, symhdr.cbAuxOffset);
X	P("  %d local string bytes at %#x, %d external string bytes at %#x\n",
X		symhdr.issMax,symhdr.cbSsOffset,
X		symhdr.issExtMax,symhdr.cbSsExtOffset);
X	P("  %d file descriptors at %#x,  %d relative file descriptors at %#x\n",
X		symhdr.ifdMax,symhdr.cbFdOffset,
X		symhdr.crfd, symhdr.cbRfdOffset);
X	P("  %d exernal syms at %#x\n",
X		symhdr.iextMax,symhdr.cbExtOffset);
X	if(print_pd_tables || print_localsym_tables) {
X		get_local_strings();
X		get_external_strings();
X		do_ifds();
X	}
X	return 0;
X}
Xstatic void get_local_strings(void)
X{
X	int res;
X	unsigned long curloc;
X
X	localstringbase = (char *)malloc(symhdr.issMax);
X	if(localstringbase == 0) {
X		P("Could not allocate local strings: %#x bytes of mem\n",symhdr.issMax);
X		exit(1);
X	}
X	curloc = CURLOC;
X	if(curloc == (unsigned long)-1L) {
X		P("\tcurrent loc unknown/error in ftell?\n");
X		return;
X	}
X	res = (int)SEEKTO(symhdr.cbSsOffset);
X	if(res) {
X		P("could not SEEK lclstrings at file loc %lu\n",
X			(unsigned long)symhdr.cbSsOffset);
X		exit(1);
X	}
X	if(symhdr.issMax > 0) {
X 	  res = RN(localstringbase,symhdr.issMax);
X	  if(res) {
X		P("could not read lclstrings at file loc %lu for %lu bytes\n",
X			(unsigned long)symhdr.cbSsOffset,(unsigned long)symhdr.issMax);
X		exit(1);
X	  }
X	}
X	res = (int)SEEKTO(curloc);
X	if(res) {
X		P("could not SEEK back to %lu local strings\n",curloc);
X		exit(1);
X	}
X}
Xstatic void get_external_strings(void)
X{
X	int res;
X	unsigned long curloc;
X
X	externalstringbase = (char *)malloc(symhdr.issExtMax);
X	if(externalstringbase == 0) {
X		P("Could not allocate  external strings: %#x bytes of mem\n",symhdr.issMax);
X		exit(1);
X	}
X	curloc = CURLOC;
X	if(curloc  == (unsigned long)-1L) {
X		P("\tcurrent loc unknown/error in ftell??\n");
X		return;
X	}
X	res = (int)SEEKTO(symhdr.cbSsExtOffset);
X	if(res) {
X		P("could not SEEK external strings at file loc %ul\n",
X			symhdr.cbSsExtOffset);
X		exit(1);
X	}
X	res = RN(externalstringbase,symhdr.issExtMax);
X	if(res) {
X		P("could not read external strings at file loc %ul\n",
X			symhdr.cbSsOffset);
X		exit(1);
X	}
X	res = (int)SEEKTO(curloc);
X	if(res) {
X		P("could not SEEK back to %lu external strings\n",curloc);
X		exit(1);
X	}
X}
Xstatic void do_ifds(void)
X{
X	unsigned long curloc;
X	unsigned  long nextifdloc;
X	unsigned long countifdrecs;
X	unsigned long i;
X	int res;
X
X	curloc = CURLOC;
X	if(curloc  == (unsigned long)-1L) {
X		P("\tcurrent loc unknown/error in ftell???\n");
X		return;
X	}
X	countifdrecs = symhdr.ifdMax;
X	nextifdloc = symhdr.cbFdOffset;
X	for(i = 0; i < countifdrecs; i++, nextifdloc += cbFDR) {
X		res = (int)SEEKTO(nextifdloc);
X		if(res) {
X			P("could not SEEK ifd %ul at file loc %ul\n",i,nextifdloc);
X			exit(1);
X		}
X		res = RN(&symifdrec,cbFDR);
X		if(res) {
X			P("could not read ifd %ul at file loc %ul\n",i,nextifdloc);
X			exit(1);
X		}
X		print_ifd(i,nextifdloc);
X		if(print_pd_tables)
X			print_procs();
X		if(print_localsym_tables)
X			print_localsyms();
X	}	
X	res = (int)SEEKTO(curloc);
X	if(res) {
X		P("could not SEEK back to old loc: %ul\n",curloc);
X		exit(1);
X	}
X}
X
X/* zero and 2 are reversed: print in user terms */
Xstatic int userglevel[] = {
X2,1,0,4};
X
Xstatic void print_ifd(unsigned long count, unsigned long fileaddr)
X{
X	static int overflow;
X
X	if(sizeof(symifdrec.ipdFirst) != sizeof(USHORT)) {
X		P(" ipdFirst not unsigned short! giving up\n");
X		exit(1);
X	}
X	P("  IFD %u fileaddr %#x  file %s\n",count,fileaddr,
X		(symifdrec.cbSs && symifdrec.cbSs > symifdrec.rss)?
X			(localstringbase + symifdrec.issBase
X			+ symifdrec.rss) : "<stripped>");
X	P("      adr %#x  rss %ld  issBase %ld cbSs %ld\n",
X		symifdrec.adr,
X		symifdrec.rss,
X		symifdrec.issBase,
X		symifdrec.cbSs);
X	P("      isymBase %ld csym %ld ilineBase %ld cline %ld ",
X		symifdrec.isymBase,
X		symifdrec.csym,
X		symifdrec.ilineBase,
X		symifdrec.cline);
X	P("  ioptBase %ld copt %d\n",
X		symifdrec.ioptBase,
X		symifdrec.copt);
X	P("      ipdFirst %u %s cpd %u ",
X		(USHORT)symifdrec.ipdFirst,
X		(((USHORT)symifdrec.ipdFirst) > 32767)? "EXCEEDED 32K procedures!":"",
X		(USHORT)symifdrec.cpd);
X	if((overflow == 0) && (((USHORT)symifdrec.ipdFirst) > 32767))  {
X		overflow = 1;
X		fprintf(stderr,"EXCEEDED 32K procedures! in ifd %u\n",count);
X	}
X	P(" iauxBase %ld caux %ld rfdBase %ld crfd %ld\n",
X		symifdrec.iauxBase,
X		symifdrec.caux,
X		symifdrec.rfdBase,
X		symifdrec.crfd);                                      
X	P("      lang %d merge %u fReadin %u fBigend %u glevel %u\n",
X		symifdrec.lang,
X		symifdrec.fMerge,
X		symifdrec.fReadin,
X		symifdrec.fBigendian,
X		userglevel[symifdrec.glevel]
X		);
X	P("      reserved %#x cbLineOffset %ld cbLine %ld\n",
X		symifdrec.reserved,
X		symifdrec.cbLineOffset,
X		symifdrec.cbLine);
X}
Xstatic void print_procs(void)
X{
X	int res;
X	int i;
X	unsigned long curloc;
X
X	if(symifdrec.cpd <= 0)
X		return;
X
X	curloc = CURLOC;
X	if(curloc  == (unsigned long)-1L) {
X		P("\tcurrent loc unknown/error in ftell????\n");
X		return;
X	}
X	res = (int)SEEKTO(symhdr.cbPdOffset + 
X		((USHORT)symifdrec.ipdFirst)*cbPDR);
X	if(res) {
X		P("could not SEEK procedure table at file loc %ul\n",
X			symhdr.cbPdOffset);
X		exit(1);
X	}
X	for(i = 0; i < symifdrec.cpd; i++) {
X		res = RN(&pdr,cbPDR);
X		if(res) {
X			P("could not read procedure table at file loc %ul\n",
X				symhdr.cbPdOffset + 
X				((USHORT)symifdrec.ipdFirst)*cbPDR);
X			exit(1);
X		}
X		print_a_proc(i,(unsigned long)CURLOC);
X	}
X	res = (int)SEEKTO(curloc);
X	if(res) {
X		P("could not SEEK back to %lu local strings\n",curloc);
X		exit(1);
X	}
X}
Xstatic void print_localsyms(void)
X{
X	int res;
X	int i;
X	unsigned long curloc;
X
X	if(symifdrec.csym <= 0)
X		return;
X
X	curloc = CURLOC;
X	res = (int)SEEKTO(symhdr.cbSymOffset + 
X		(symifdrec.isymBase)*cbSYMR);
X	if(res) {
X		P("could not SEEK localsymbol table at file loc %ul\n",
X			symhdr.cbSymOffset);
X		exit(1);
X	}
X	for(i = 0; i < symifdrec.csym; i++) {
X		res = RN(&symr,cbSYMR);
X		if(res) {
X			P("could not read localsymbol table at file loc %ul\n",
X				symhdr.cbSymOffset + 
X				(symifdrec.isymBase)*cbSYMR);
X			exit(1);
X		}
X		print_a_localsymbol(i,(unsigned long)CURLOC);
X	}
X	res = (int)SEEKTO(curloc);
X	if(res) {
X		P("could not SEEK back to %lu local symbols\n",curloc);
X		exit(1);
X	}
X}
Xstatic void print_a_localsymbol(int count, unsigned long loc)
X{
X	P("\tSYMR %u (g %ld) at file loc %#x iss %ld",count,
X		(long)count + (long)symifdrec.isymBase,
X		loc,symr.iss);
X	P(" value %#x %ld",symr.value,symr.value);
X	P("\n");
X	P("\t    st %d sc %d",symr.st,symr.sc);
X	P(" index %x %d", symr.index,symr.index);
X	if(symr.iss > 0) {
X		if(symr.iss >= symifdrec.cbSs) {
X		  P("Error! iss %ld bug cbSs is only %ld",
X			(long)symr.iss,(long)symifdrec.cbSs);
X		} else if((symifdrec.issBase + symr.iss)
X			>= symhdr.issMax) {
X		  P("Error! iss (%ld) + issBase (%ld) >= issMax! (%ld)",
X			(long)symr.iss, 
X			(long)symifdrec.issBase,(long)symhdr.issMax);
X		} else {
X		  P("  %s",localstringbase + symifdrec.issBase + symr.iss);
X		}
X	} 
X	P("\n");
X}
Xstatic void print_a_proc(int count, unsigned long loc)
X{
X	P("\tPDR  %u (g %ld) at file loc %#x isym %ld",count,
X		(long)count + (long)symifdrec.ipdFirst,
X		loc,pdr.isym);
X	if(pdr.isym == isymNil) {
X		P("\n");
X		return;
X	}
X	if(symifdrec.csym) {
X		/* isym is local */
X	} else {
X		P(" (external)");
X		/* isym is global */
X	}
X	P("\n");
X	P("\t    adr  %#x iline %ld regmask %#x regoffset %ld\n",
X		pdr.adr,
X		pdr.iline,
X		pdr.regmask,
X		pdr.regoffset);
X	P("\t    iopt %ld fregmask %#x fregoffset %#x frameoffset"
X		" %ld  framereg %d\n",
X		pdr.iopt,
X		pdr.fregmask,
X		pdr.fregoffset,
X		pdr.frameoffset,
X		pdr.framereg);
X	P("\t    pcreg %d  lnLow %ld  lnHigh %ld cbLineOffset %ld\n",
X		pdr.pcreg,
X		pdr.lnLow,
X		pdr.lnHigh,
X		pdr.cbLineOffset
X		);
X}
X
X
Xstatic void 
Xprint_gp_table_data(unsigned fileloc,int cnt)
X{
X	unsigned curloc;
X	int res;
X	long size;
X	union gp_table *gpdata;
X	int i;
X
X
X	size = (long)sizeof(union gp_table) *(long)cnt;
X	gpdata = (union gp_table *)malloc(size);
X	if(gpdata == 0) {
X		printf("Quit: could not allocate %d bytes for gp table\n",
X			size);
X		exit(1);
X	}
X
X	curloc = CURLOC;
X
X
X	if(fileloc == 0)
X		return;
X	res = RR(gpdata,fileloc,size);
X	if(res ) {
X		printf("could not read the gp data. "
X		"file loc %u, size in bytes: %d, entries %d",
X			(unsigned)fileloc,
X			(int)size,
X			(int)cnt);
X		return;
X	}
X		
X
X
X	P("\tGP table number of entries %d\n",cnt);
X	P("\t\tg_value of compilation: %ld\n",gpdata->header.current_g_value);
X	for(i = 1; i < cnt; i++) {
X		P("\t\t%d: for g_value %5ld,   theoretical gp data size %6ld\n",
X			i,
X			gpdata[i].entry.g_value,
X			gpdata[i].entry.bytes);    
X	}
X
X	SEEKTO(curloc);
X	
X}
X#endif /* !LINUX */
X
X#ifdef HAS_ELFHDR
Xstatic void
Xdo_elf_file(char *s)
X{
X	int i;
X	int res;
X	unsigned char c;
X
X	SEEKTO(0);
X	res = RR(&ehdr,0,sizeof(ehdr));
X	if(res) {
X		P("could not read whole ELF file header of %s\n",filename);
X		return;
X	}
X	c = ehdr.e_ident[EI_CLASS];
X#ifdef HAS_ELFHDR64
X	if (c == ELFCLASS64) {
X		do_elf_file64(s);
X		return;
X	}
X#endif
X	P("Elf object file %s\n",s);
X	P("\tident bytes: ");
X	for(i = 0; i < EI_NIDENT; i++) {
X		c =  ehdr.e_ident[i];
X		P(" %02x",c);
X	}
X	P("\n");
X	c = ehdr.e_ident[EI_CLASS];
X	P("\t\tident[class] %#x   %s\n",c,(c == ELFCLASSNONE)? "ELFCLASSNONE":
X			(c == ELFCLASS32) ? "ELFCLASS32" :
X			(c == ELFCLASS64) ? "ELFCLASS64" :
X			"unknown ");
X	c = ehdr.e_ident[EI_DATA];
X	P("\t\tident[data] %#x   %s\n",c,(c == ELFDATANONE)? "ELFDATANONE":
X			(c == ELFDATA2MSB)? "ELFDATA2MSB":
X			(c == ELFDATA2LSB) ? "ELFDATA2LSB":
X			"unknown");
X	c = ehdr.e_ident[EI_VERSION];
X	P("\t\tident[version] %#x   %s\n",c,(c == EV_CURRENT)? "EV_CURRENT":
X			"unknown");
X	i = ehdr.e_type;
X	P("\ttype %#x	%s\n",i,(i == ET_NONE)? "ET_NONE No file type":
X		(i == ET_REL)? "ET_REL Relocatable file":
X		(i == ET_EXEC)? "ET_EXEC Executable file":
X		(i == ET_DYN)? "ET_DYN Shared object file":
X		(i == ET_CORE) ? "ET_CORE Core file":
X#ifdef ET_IR
X		(i == ET_IR)? "ET_IR intermediate file":
X#endif
X			"unknown");
X	P("\tmachine %#x %s\n",ehdr.e_machine,
X			(ehdr.e_machine == EM_NONE) ? "EM_NONE Invalid machine":
X			(ehdr.e_machine == EM_MIPS) ? "EM_MIPS Mips cpu":
X			(ehdr.e_machine == EM_386) ? "EM_386 x86 cpu":
X			"unknown");
X	P("\tversion %#x %s\n",ehdr.e_version,
X			(ehdr.e_version == EV_NONE) ? "EV_NONE Invalid version":
X			(ehdr.e_version == EV_CURRENT) ? "EV_CURRENT current version":
X			"unknown");
X	P("\tEntry %#x   prog hdr off: %#x   sec hdr off %#x\n",
X		ehdr.e_entry,ehdr.e_phoff,ehdr.e_shoff);
X	P("\tFlags %#x",ehdr.e_flags);
X	if(ehdr.e_flags& EF_MIPS_NOREORDER){
X		P(", .noreorder present(flag EF_MIPS_NOREORDER)");
X	}
X	if(ehdr.e_flags& EF_MIPS_PIC){
X		P(", EF_MIPS_PIC");
X	}
X	if(ehdr.e_flags& EF_MIPS_CPIC){
X		P(", EF_MIPS_CPIC(calls pic)");
X	}
X#ifdef EF_MIPS_XGOT
X        if(ehdr.e_flags& EF_MIPS_XGOT){
X                P(", EF_MIPS_XGOT");
X        }
X#endif
X#ifdef EF_MIPS_UGEN_RESERVED
X        if(ehdr.e_flags& EF_MIPS_UGEN_RESERVED){
X                P(", EF_MIPS_UGEN_RESERVED");
X        }
X#endif
X	P("\n");
X	if(ehdr.e_flags& EF_MIPS_ARCH){
X		int c;
X		c=(int)(ehdr.e_flags& EF_MIPS_ARCH);
X		P("\t    flag mips-arch 0x%x",c);
X		P("  %s", 
X#ifdef EF_MIPS_ARCH_2
X			(c == EF_MIPS_ARCH_2) ? "EF_MIPS_ARCH_2" :
X#endif
X#ifdef EF_MIPS_ARCH_3
X			(c == EF_MIPS_ARCH_3) ? "EF_MIPS_ARCH_3":
X#endif
X#ifdef EF_MIPS_ARCH_4
X			(c == EF_MIPS_ARCH_4) ? "EF_MIPS_ARCH_4":
X#endif
X			(c == 0) ? "mips_1" :
X			"unknownarch");
X		P("\n");
X	}
X	P("\tEhdrsize %3d  Proghdrsize %3d  Sechdrsize %3d\n",
X		ehdr.e_ehsize,ehdr.e_phentsize,ehdr.e_shentsize);
X	P("\t              P-hdrcount  %3d  S-hdrcount %3d\n",
X		ehdr.e_phnum,ehdr.e_shnum);
X	if(ehdr.e_shstrndx == SHN_UNDEF) {
X	  P("\tSection strings are not present e_shstrndx ==SHN_UNDEF\n");
X	} else {
X	  P("\tSection strings are in section %d\n",ehdr.e_shstrndx);
X	}
X
X	if(ehdr.e_shstrndx > ehdr.e_shnum) {
X		P("String section index is wrong: %ld vs only %ld sections. Consider it 0\n",
X			(long)(ehdr.e_shstrndx),(long)(ehdr.e_shnum));
X		ehdr.e_shstrndx = 0;
X	}
X	elf_get_sectstrings(ehdr.e_shoff,ehdr.e_shentsize,ehdr.e_shnum,ehdr.e_shstrndx);
X        if(elf_shstrings_data == 0) {
X		return;
X	}
X
X	elf_get_dynstr(ehdr.e_shoff,ehdr.e_shentsize,ehdr.e_shnum);
X
X	elf_print_progheaders(ehdr.e_phoff,ehdr.e_phentsize,ehdr.e_phnum);
X	elf_print_sectheaders(ehdr.e_shoff,ehdr.e_shentsize,ehdr.e_shnum);
X}
X
X#define SHTYPESTRING(x)  get_shtypestring(x)
X#define SHSTRING(x)  ((elf_shstrings_length > (x)) ? \
X                 (x) + elf_shstrings_data :  \
X                  "Invalid sh_name value")
X/*
X*/
Xstatic void
Xelf_get_dynstr(unsigned long offset,unsigned long entsize,unsigned long count )
X{
X        int i;
X        Elf32_Shdr *psh;
X        Elf32_Shdr *orig_psh;
X	unsigned long curloc;
X	unsigned long seekres;
X	int res;
X
X
X        if(entsize < sizeof(Elf32_Shdr)) {
X                P("Elf Section header too small? %ld vs %ld\n",
X                        entsize,(unsigned long)sizeof(Elf32_Shdr));
X        }
X        if(offset == 0) {
X                P("No section headers\n");
X                return;
X        }
X	curloc = CURLOC;
X	if(curloc  == (unsigned long)-1L) {
X		P("\tcurrent loc unknown/error in ftell?????\n");
X		return;
X	}
X        i =(int)SEEKTO(offset);
X        if(i) {
X                P("Seek to %ld to read section headers failed\n",offset);
X                return;
X        }
X        psh = (Elf32_Shdr *)alloca(count * entsize);
X        if(psh == 0) {
X                P("malloc to %ld bytes of section header space failed\n",count *entsize);
X                return;
X        }
X        orig_psh = psh;
X        i = RN(orig_psh,count*entsize);
X        if(i) {
X                P("Read %lu bytes of section headers failed\n",count*entsize);
X                return;
X        }
X
X
X        for(i = 0; i < count;
X                ++i, psh = (Elf32_Shdr *) ((char *)psh + entsize)) {
X
X	  char *namestr =  SHSTRING(psh->sh_name);
X	  if(0 == strcmp(namestr,".dynstr")) {
X		dynamic_sect_strings_sect_index = i;
X		dynamic_sect_strings_length = psh->sh_size;
X		dynamic_sect_strings = malloc(dynamic_sect_strings_length);
X		res = RR(dynamic_sect_strings,psh->sh_offset,
X			dynamic_sect_strings_length);
X		if(res) {
X		 P("Could not read dynamic section strings at "
X			LONGESTXFMT "\n",
X			(LONGESTUTYPE) psh->sh_offset);
X		 dynamic_sect_strings = 0;
X		  dynamic_sect_strings_length = 0;
X			dynamic_sect_strings_sect_index = 0;
X                  seekres =(int)SEEKTO(curloc);
X                  if(seekres) {
X                          P("Seek back to %ld after reading sect headers failed\n",
X			 	curloc);
X                  }
X		  return;
X		}
X		break;
X           }
X
X
X        }
X        i =(int)SEEKTO(curloc);
X        if(i) {
X                P("Seek to %ld after reading sect headers failed\n",offset);
X                return;
X        }
X}
X
X
Xstatic char *
Xget_dynstr_string(unsigned long offset, int index)
X{
X
X
X   if(index != dynamic_sect_strings_sect_index) {
X
X	P("link is %d, sect found was %d\n",
X		(int)index,
X		(int)dynamic_sect_strings_sect_index);
X	return"dynamic section link does not match section of dynamic strings";
X   }
X   if(offset >= dynamic_sect_strings_length) {
X	return "offset beyond end of dynamic sect strings";
X   }
X   return dynamic_sect_strings + offset;
X}
X
X/*
X*/
Xstatic void
Xelf_get_symstr(unsigned long offset,unsigned long entsize,unsigned long count )
X{
X        int i;
X	unsigned long curloc;
X	int res;
X
X
X        if(offset == 0) {
X                P("No section headers\n");
X                return;
X        }
X	curloc = CURLOC;
X	if(curloc  == (unsigned long)-1L) {
X		P("\tcurrent loc unknown/error in ftell?????\n");
X		return;
X	}
X        i =(int)SEEKTO(offset);
X        if(i) {
X                P("Seek to %ld to read symstring section failed\n",offset);
X                return;
X        }
X	symbol_sect_strings_length = count*entsize;
X	symbol_sect_strings = malloc(symbol_sect_strings_length);
X	if(symbol_sect_strings == 0) {
X	  P("Unable to malloc %u symbol string bytes\n",
X		(unsigned)dynamic_sect_strings_length);
X	  return;
X	}
X	res = RR(symbol_sect_strings,offset,
X			symbol_sect_strings_length);
X	if(res) {
X	    P("Could not read symbol section strings at "
X			LONGESTXFMT "\n",
X			(LONGESTUTYPE) offset);
X	    free(symbol_sect_strings);
X	    symbol_sect_strings = 0;
X	    symbol_sect_strings_length = 0;
X        }
X        i =(int)SEEKTO(curloc);
X        if(i) {
X                P("Seek to %ld after reading strings failed\n",offset);
X                return;
X        }
X}
X
X
Xstatic char *
Xget_symstr_string(unsigned long offset)
X{
X   if(offset >= symbol_sect_strings_length) {
X	return "offset beyond end of symbol sect strings";
X   }
X   return symbol_sect_strings + offset;
X}
Xstatic void 
Xelf_get_sectstrings(unsigned long offset,unsigned long entsize,unsigned long count,unsigned long stringsection)
X{
X	int i;
X	Elf32_Shdr *psh;
X	Elf32_Shdr *orig_psh;
X
X
X	if(count == 0) {
X		P("No section headers\n");
X		return;
X	}
X	elf_shstrings_length = 0;
X	if(entsize < sizeof(Elf32_Shdr)) {
X		P("Elf Section header too small? %ld vs %ld\n",
X			entsize,(unsigned long)sizeof(Elf32_Shdr));
X	}
X
X	i =(int)SEEKTO(offset + entsize*stringsection);
X	if(i) {
X		P("Seek to %ld to read string section header failed\n",offset+
X			entsize*stringsection);
X		return;
X	}
X	psh = (Elf32_Shdr *)malloc( entsize);
X	if(psh == 0) {
X		P("malloc to %ld bytes of section header space failed\n",entsize);
X		return;
X	}
X	orig_psh = psh;
X	i = RN(psh,entsize);
X	if(i) {
X		P("read string section header failed "
X		"( attempted read of %ld bytes ( 0x%lx) "
X		"at offset %ld (0x%lx) \n",
X		  (long)entsize,
X		  (long)entsize,
X		  (long)(offset + (long)entsize*(long)stringsection),
X		  (long)(offset + (long)entsize*(long)stringsection));
X		return;
X	}
X	if(psh->sh_type == SHT_NULL) {
X		P("String section type SHT_NULL!!. No sstring section!\n");
X		return;
X	}
X	P("String section data at %#x length %#x %d\n",
X		psh->sh_offset,psh->sh_size,psh->sh_size);
X	i =(int)SEEKTO(psh->sh_offset);
X	if(i) {
X		P("Seek to %ld string section data failed\n",(long)psh->sh_offset);
X		elf_shstrings_length = 0;
X		return;
X	}
X	if(psh->sh_size > elf_shstrings_max) {
X		if(elf_shstrings_data)
X			free(elf_shstrings_data);
X		elf_shstrings_data = (char *)malloc(psh->sh_size);
X		elf_shstrings_max = psh->sh_size;
X		if(elf_shstrings_data == 0) {
X		  elf_shstrings_max = 0;
X		  P("Unable to malloc %ld bytes for strings\n",
X			(long)psh->sh_size);
X		}
X	}
X	elf_shstrings_length = psh->sh_size;
X	i = RN(elf_shstrings_data,psh->sh_size);
X	if(i) {
X		P("Read  %ld bytes of string section string data failed\n",elf_shstrings_length);
X		elf_shstrings_length = 0;
X		return;
X	}
X	free(orig_psh);
X}
X
Xstatic void 
Xelf_print_interp(long offset, long size)
X{
X	long cloc;
X	long j;
X	long res;
X	char *buf;
X
X	cloc = CURLOC;
X	if(cloc < 0) {
X		P("\tcurrent loc unknown?\n");
X		return;
X	}
X	j = (long)SEEKTO(offset);
X	if(j < 0){
X		P("\tseekto  %lx failed\n",(long)offset);
X	}
X	buf = malloc(size);
X	if(buf == 0) {
X		P("\tmalloc failed\n");
X	}
X	res = RN(buf,size);
X	if(res < 0) {
X		P("\tRead interp string failed\n");
X		SEEKTO(cloc);
X		return;
X	}
X	P("\t%s\n",buf);
X	if(SEEKTO(cloc) != 0) {
X		P("\tseek back to %lx failed\n",(long)cloc);
X	}
X	return;
X}
X
X
Xstatic void 
Xelf_print_progheaders(unsigned long offset,unsigned long entsize,unsigned long count)
X{
X	int i;
X	Elf32_Phdr *pph;
X	Elf32_Phdr *orig_pph;
X
X
X
X	if(count == 0) {
X		P("No program headers\n");
X		return;
X	}
X	if(entsize < sizeof(Elf32_Phdr)) {
X		P("Elf Program header too small? %ld vs %ld\n",
X			entsize,(unsigned long)sizeof(Elf32_Phdr));
X	}
X	i =(int)SEEKTO(offset);
X	if(i) {
X		P("Seek to %ld to read program headers failed\n",offset);
X		return;
X	}
X	pph = (Elf32_Phdr *)malloc(count * entsize);
X	if(pph == 0) {
X		P("malloc to %ld bytes of program header space failed\n",count *entsize);
X		return;
X	}
X	orig_pph = pph;
X	i = RN(pph,count*entsize);
X	if(i) {
X		P("Read  %ld bytes program headers failed\n",count*entsize);
X		return;
X	}
X#ifdef LINUX
X#define PHTYPE(x) (\
X	((x) == PT_NULL) ? "PT_NULL": \
X	((x) == PT_LOAD) ? "PT_LOAD": \
X	((x) == PT_DYNAMIC) ? "PT_DYNAMIC": \
X	((x) == PT_INTERP) ? "PT_INTERP": \
X	((x) == PT_NOTE) ? "PT_NOTE": \
X	((x) == PT_SHLIB) ? "PT_SHLIB": \
X	((x) == PT_PHDR) ? "PT_PHDR": \
X	((x) == PT_MIPS_REGINFO) ? "PT_MIPS_REGINFO": \
X	"unknowntype")
X#else
X#define PHTYPE(x) (\
X	((x) == PT_NULL) ? "PT_NULL": \
X	((x) == PT_LOAD) ? "PT_LOAD": \
X	((x) == PT_DYNAMIC) ? "PT_DYNAMIC": \
X	((x) == PT_INTERP) ? "PT_INTERP": \
X	((x) == PT_NOTE) ? "PT_NOTE": \
X	((x) == PT_SHLIB) ? "PT_SHLIB": \
X	((x) == PT_PHDR) ? "PT_PHDR": \
X	((x) == PT_MIPS_REGINFO) ? "PT_MIPS_REGINFO": \
X	((x) == PT_MIPS_OPTIONS) ? "PT_MIPS_OPTIONS": \
X	((x) == PT_MIPS_RTPROC) ? "PT_MIPS_RTPROC (run time proc tbl)":  \
X		/* run time proc table*/ \
X	"unknowntype")
X#endif
X
X	P("Program header count %ld\n",count);
X	for( i = 0; i < count; 
X		++i,  pph = (Elf32_Phdr *) ((char *)pph + entsize)) {
X	  P("Program header %d",i);
X	  P("  type %s (%lx)",PHTYPE(pph->p_type),(unsigned long)pph->p_type);
X	  P(", offset 0x%lx %ld",(long)pph->p_offset,(long)pph->p_offset);
X	  P("\n");
X	  P("\tvaddr 0x%lx %ld",(long)pph->p_vaddr,(long)pph->p_vaddr);
X	  P(", paddr 0x%lx %ld",(long)pph->p_paddr,(long)pph->p_paddr);
X	  P("\n");
X	  P("\tfilesz 0x%lx %ld",(long)pph->p_filesz,(long)pph->p_filesz);
X	  P("\n");
X	  P("\tmemsz 0x%lx %ld",(long)pph->p_memsz,(long)pph->p_memsz);
X	  P(", flags 0x%lx",(long)pph->p_flags);
X#ifdef PF_MIPS_LOCAL
X	  if(pph->p_flags & PF_MIPS_LOCAL) {
X		P(" PF_MIPS_LOCAL");
X	  }
X#endif
X	  if(pph->p_flags & PF_X) {
X		P(" PF_X");
X	  }
X	  if(pph->p_flags & PF_W) {
X		P(" PF_W");
X	  }
X	  if(pph->p_flags & PF_R) {
X		P(" PF_R");
X	  }
X	  P(", align 0x%lx %ld",(long)pph->p_align,(long)pph->p_align);
X	  P("\n");
X	  if(pph->p_type == PT_INTERP) {
X		elf_print_interp((long)pph->p_offset,
X			(long)pph->p_filesz);
X	  }
X	}
X	free(orig_pph);
X}
X
X
X
X
Xstatic void 
Xelf_print_sectheaders(unsigned long offset,unsigned long entsize,unsigned long count)
X{
X	int i;
X	Elf32_Shdr *psh;
X	Elf32_Shdr *orig_psh;
X	char *namestr;
X
X
X	if(entsize < sizeof(Elf32_Shdr)) {
X		P("Elf Section header too small? %ld vs %ld\n",
X			entsize,(unsigned long)sizeof(Elf32_Shdr));
X	}
X	if(count == 0) {
X		P("No section headers\n");
X		return;
X	}
X	i =(int)SEEKTO(offset);
X	if(i) {
X		P("Seek to %ld to read section headers failed\n",offset);
X		return;
X	}
X	psh = (Elf32_Shdr *)malloc(count * entsize);
X	if(psh == 0) {
X		P("malloc to %ld bytes of section header space failed\n",count *entsize);
X		return;
X	}
X	orig_psh = psh;
X	i = RN(orig_psh,count*entsize);
X	if(i) {
X		P("Read %lu bytes of section headers failed\n",count*entsize);
X		return;
X	}
X
X	P("Section count: %d\n",(int)count);
X	for(i = 0; i < count; 
X		i++, psh = (Elf32_Shdr *) ((char *)psh + entsize)) {
X	  namestr = SHSTRING(psh->sh_name);
X	  P("Section %ld, name %ld %s\n",(long)i,(long)psh->sh_name,
X		namestr);
X	  P("  type 0x%lx %s",(unsigned long)psh->sh_type,
X		SHTYPESTRING((LONGESTUTYPE)psh->sh_type));
X	  if(psh->sh_flags == 0) {
X	    P(", flags 0x%lx",(long)psh->sh_flags);
X	  } else {
X	    P("\n");
X	    P("\tflags 0x%lx",(long)psh->sh_flags);
X	    if(psh->sh_flags & SHF_WRITE) {
X		P(" SHF_WRITE");
X	    }
X	    if(psh->sh_flags & SHF_ALLOC) {
X		P(" SHF_ALLOC");
X	    }
X	    if(psh->sh_flags & SHF_EXECINSTR) {
X		P(" SHF_EXECINSTR");
X	    }
X#ifndef SHF_MIPS_GPREL
X#define SHF_MIPS_GPREL          0x10000000
X#endif
X	    if(psh->sh_flags & SHF_MIPS_GPREL) {
X		P(" SHF_MIPS_GPREL");
X	    }
X#ifndef SHF_MIPS_NOSTRIP
X#define SHF_MIPS_NOSTRIP        0x08000000
X#endif
X	    if(psh->sh_flags & SHF_MIPS_NOSTRIP) {
X		P(" SHF_MIPS_NOSTRIP");
X	    }
X#ifndef SHF_MIPS_MERGE
X#define SHF_MIPS_MERGE          0x20000000
X#endif
X	    if(psh->sh_flags & SHF_MIPS_MERGE) {
X		P(" SHF_MIPS_MERGE");
X	    }
X#ifndef SHF_MIPS_ADDR
X#define SHF_MIPS_ADDR           0x40000000
X#endif
X	    if(psh->sh_flags & SHF_MIPS_ADDR) {
X		P(" SHF_MIPS_ADDR");
X	    }
X#ifndef SHF_MIPS_STRINGS
X#define SHF_MIPS_STRINGS        0x80000000
X#endif
X	    if(psh->sh_flags & SHF_MIPS_STRINGS) {
X		P(" SHF_MIPS_STRINGS");
X	    }
X#ifndef SHF_MIPS_LOCAL
X#define SHF_MIPS_LOCAL          0x04000000
X#endif
X	    if(psh->sh_flags & SHF_MIPS_LOCAL) {
X		P(" SHF_MIPS_LOCAL");
X	    }
X#ifndef SHF_MIPS_NAMES
X#define SHF_MIPS_NAMES          0x02000000
X#endif
X	    if(psh->sh_flags & SHF_MIPS_NAMES) {
X		P(" SHF_MIPS_NAMES");
X	    }
X#ifndef SHF_MIPS_NODUPE
X#define SHF_MIPS_NODUPE         0x01000000
X#endif
X	    if(psh->sh_flags & SHF_MIPS_NODUPE) {
X		P(" SHF_MIPS_NODUPE");
X	    }
X	  }
X	  P("\n");
X	  P("\taddr 0x%lx %ld",(long)psh->sh_addr,(long)psh->sh_addr);
X	  P(" offset 0x%lx %ld",(long)psh->sh_offset,(long)psh->sh_offset);
X	  P(", size %ld",(long)psh->sh_size);
X	  P("\n");
X	  P("\tlink %ld",(long)psh->sh_link);
X	  P(", info %ld",(long)psh->sh_info);
X	  P(", align %ld",(long)psh->sh_addralign);
X	  P(", entsize %ld",(long)psh->sh_entsize);
X	  P("\n");
X
X	  namestr = SHSTRING(psh->sh_name);
X#ifdef __sgi
X	  if(0 == strcmp(namestr,".mdebug")) {
X		do_a_symtab_at((long)psh->sh_offset);
X	  }
X#endif
X	  namestr = SHSTRING(psh->sh_name);
X	  if(print_dynamic_section && 
X		0 == strcmp(namestr,".dynamic")) {
X		if(elf_print_dynamic32(psh->sh_offset,psh->sh_size,
X			(int)psh->sh_link))
X			return;
X	  }
X	  if(print_symtab_sections ) {
X	   if( (0 == strcmp(namestr,".dynsym")) ||
X	      (0 == strcmp(namestr,".symtab"))) {
X	      unsigned link = psh->sh_link;
X	      Elf32_Shdr *strh = orig_psh+link;
X	      if(link >= count) {
X		P("link section %d beyond %d sections\n",
X			(int)link,(int)count);
X                if(symbol_sect_strings)
X   	          free(symbol_sect_strings);
X   	        symbol_sect_strings = 0;
X   	        symbol_sect_strings_length = 0;
X
X	      } else {
X		 elf_get_symstr(strh->sh_offset,strh->sh_size,/*count*/1);
X	      }
X
X	      elf_print_symbols32(psh->sh_offset,psh->sh_size);
X	   }
X	  }
X		
X          if(print_reloc_sections) {
X	   if( 0 == strncmp(namestr,".rel.",5)) {
X		elf_print_relocation32(psh->sh_offset,
X			psh->sh_size,psh->sh_link);
X	   } else if ( 0 == strncmp(namestr,".rela.",6)) {
X	     P("rela not implemented\n");
X	   }
X	  }
X	}
X	free(orig_psh);
X}
X
Xstatic
Xint
Xelf_print_dynamic32(unsigned long offset,unsigned long size, int dynstr_index)
X{
X    long ecount = 0;
X    unsigned long size2 = 0;
X    unsigned long i;
X    Elf32_Dyn *buffer;
X    unsigned long trueoff = offset;
X	int res;
X
X#define PREFIX "\t"
X#define LUFMT "%lu"
X#define UFMT "%u"
X#define DFMT "%d"
X#define XFMT "0x%x"
X
X    ecount = (long)(size/sizeof(Elf32_Dyn));
X    size2 = ecount * sizeof(Elf32_Dyn);
X    if(size != size2) {
X	P("Bogus size of dynamic. %lu not divisible by %lu\n",
X		size,(unsigned long)sizeof(Elf32_Dyn));
X	return 0;
X    }
X
X    buffer = alloca(size);
X    
X    res = RR(buffer,offset,size);
X    if(res) {
X                P("could not read whole dynamic section of %s "
X		  "at offset %lu size %lu\n",
X			filename,
X			offset,size);
X                return 0;
X    }
X
X
X    if(ecount > 0) {
X      P("	offset  name     value\n");
X    }
X    for(i = 0; i < ecount; ++i,++buffer,trueoff += sizeof(Elf32_Dyn)) {
X	switch(buffer->d_tag) {
X	case  DT_NULL : 
X		P(PREFIX LUFMT ": DT_NULL "  LUFMT " end of dynamic array\n",
X			trueoff,(unsigned long)buffer->d_un.d_ptr);
X		break;
X	case  DT_NEEDED       :
X		P(PREFIX LUFMT ": DT_NEEDED " DFMT " lib needed:\n",
X			trueoff,
X			(int)buffer->d_un.d_val);
X		P("\t\t %s\n",
X			get_dynstr_string(buffer->d_un.d_val,dynstr_index));
X		break;
X	case  DT_PLTRELSZ     :
X		P(PREFIX LUFMT ": DT_PLTRELSZ " DFMT " size of reloc ent in proc linkage table:\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_PLTGOT       :
X		P(PREFIX LUFMT ": DT_PLTGOT " XFMT " GOT addr.\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_HASH         :
X		P(PREFIX LUFMT ": DT_HASH " XFMT " HASH addr.\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_STRTAB       :
X		P(PREFIX LUFMT ": DT_STRTAB " XFMT " stringtable addr \n",
X		 		trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_SYMTAB       :
X		P(PREFIX LUFMT ": DT_SYMTAB "
X			XFMT  " hashtable addr\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_RELA         :
X		P(PREFIX LUFMT ": DT_RELA "
X			XFMT " relocation table addr \n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_RELASZ       :
X		P(PREFIX LUFMT ": DT_RELASZ "
X			DFMT " relocation table size in bytes \n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_RELAENT      :
X		P(PREFIX LUFMT ": DT_RELAENT "
X			DFMT " relocation table entry size in bytes \n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_STRSZ        :
X		P(PREFIX LUFMT ": DT_STRSZ "
X			DFMT " string table size in bytes \n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_SYMENT       :
X		P(PREFIX LUFMT ": DT_SYMENT "
X			DFMT " symtab entry size in bytes \n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_INIT         :
X		P(PREFIX LUFMT ": DT_INIT "
X			XFMT " initialization func addr\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_FINI         :
X		P(PREFIX LUFMT ": DT_FINI "
X			XFMT " termination func addr\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_SONAME       :
X		P(PREFIX LUFMT ": DT_SONAME "
X			DFMT " so name offset \n",
X			trueoff,
X			buffer->d_un.d_val);
X		P("\t\t %s\n",
X			get_dynstr_string(buffer->d_un.d_val,dynstr_index));
X		break;
X	case  DT_RPATH        :
X		P(PREFIX LUFMT ": DT_RPATH "
X			DFMT " library search path\n",
X			trueoff,
X			buffer->d_un.d_val);
X		P("\t\t %s\n",
X			get_dynstr_string(buffer->d_un.d_val,dynstr_index));
X		break;
X	case  DT_SYMBOLIC     :
X		P(PREFIX LUFMT ": DT_SYMBOLIC "
X			DFMT " -B symbolic marked\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_REL          :
X		P(PREFIX LUFMT ": DT_REL "
X			XFMT " relocation table address\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_RELSZ        :
X		P(PREFIX LUFMT ": DT_RELSZ "
X			DFMT " relocation table size, bytes\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_RELENT       :
X		P(PREFIX LUFMT ": DT_RELENT "
X			DFMT " relocation table entry size, bytes\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_PLTREL       :
X		P(PREFIX LUFMT ": DT_PLTREL "
X			DFMT " relocation table type\n",
X			trueoff,
X			buffer->d_un.d_val);
X		P("\t\t\t %s is reloc entry type  for plt\n",
X			(buffer->d_un.d_val == DT_REL)? "DT_REL" :
X			(buffer->d_un.d_val == DT_RELA)? "DT_RELA" :
X			"other?");
X		break;
X	case  DT_DEBUG        :
X		P(PREFIX LUFMT ": DT_DEBUG "
X			DFMT " unused.\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_TEXTREL      :
X		P(PREFIX LUFMT ": DT_TEXTREL "
X			DFMT " no relocs in read-only.\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_JMPREL       :
X		P(PREFIX LUFMT ": DT_JMPREL "
X			XFMT " address of proc. linkage table\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X#ifdef DT_VERSYM
X	case DT_VERSYM:
X		P(PREFIX LUFMT ": DT_VERSYM "
X			XFMT " version symbol\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X#endif
X#ifdef DT_VERDEF
X	case DT_VERDEF:
X		P(PREFIX LUFMT ": DT_VERDEF "
X			XFMT " version definition table address\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X#endif
X#ifdef DT_VERDEFNUM
X	case DT_VERDEFNUM:
X		P(PREFIX LUFMT ": DT_VERDEFNUM"
X			DFMT " number of version definition table entries\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X#endif
X#ifdef DT_VERNEED
X	case DT_VERNEED:
X		P(PREFIX LUFMT ": DT_VERNEED"
X			XFMT " address of table with needed versions\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X#endif
X#ifdef DT_VERNEEDNUM
X	case DT_VERNEEDNUM:
X		P(PREFIX LUFMT ": DT_VERNEEDNUM"
X			DFMT " number of needed versions\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X#endif
X#ifdef DT_AUXILIARY
X	case DT_AUXILIARY:
X		P(PREFIX LUFMT ": DT_AUXILIARY"
X			DFMT " shared object to load before self\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X#endif
X#ifdef DT_FILTER
X	case DT_FILTER:
X		P(PREFIX LUFMT ": DT_FILTER"
X			DFMT " shared object to load values from\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X#endif
X	
X	
X#ifdef DT_MIPS_RLD_VERSION
X	case DT_MIPS_RLD_VERSION :/*    0x70000001 */
X		P(PREFIX LUFMT ": DT_MIPS_RLD_VERSION "
X			DFMT " rld version\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X#endif
X#ifdef DT_MIPS_TIME_STAMP
X	case DT_MIPS_TIME_STAMP    :/*  0x70000002 */
X		{
X		time_t t;
X		P(PREFIX LUFMT ": DT_MIPS_TIME_STAMP "
X			XFMT " timestamp\n",
X			trueoff,
X			buffer->d_un.d_val);
X		t = (time_t)buffer->d_un.d_val;
X		P("\t\t %s\n",ctime(&t));
X		}
X		break;
X#endif
X#ifdef DT_MIPS_ICHECKSUM
X	case DT_MIPS_ICHECKSUM       :/*0x70000003 */
X		P(PREFIX LUFMT ": DT_MIPS_ICHECKSUM "
X			DFMT " string + common sum\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X#endif
X#ifdef DT_MIPS_IVERSION
X	case DT_MIPS_IVERSION     :/*   0x70000004 */
X		P(PREFIX LUFMT ": DT_MIPS_IVERSION "
X			DFMT " string + common sum\n",
X			trueoff,
X			buffer->d_un.d_val);
X		if(buffer->d_un.d_val) {
X			P("\t\t %s\n",
X			   get_dynstr_string(buffer->d_un.d_val,dynstr_index));
X		}
X		break;
X#endif
X#ifdef DT_MIPS_FLAGS
X	case DT_MIPS_FLAGS          :/* 0x70000005 */
X		P(PREFIX LUFMT ": DT_MIPS_FLAGS "
X			XFMT " flags\n",
X			trueoff,
X			buffer->d_un.d_val);
X		if(buffer->d_un.d_val) {
X		  long flags = (long)buffer->d_un.d_val;		
X		  if(flags& RHF_QUICKSTART) {
X			P("\t\t0x%x %s\n",RHF_QUICKSTART,"RHF_QUICKSTART");
X		  }
X		  if(flags& RHF_NOTPOT) {
X			P("\t\t0x%x %s\n",RHF_NOTPOT,"RHF_NOTPOT");
X		  }
X#ifdef __sgi
X		  if(flags& RHF_NO_LIBRARY_REPLACEMENT) {
X			P("\t\t0x%x %s\n",RHF_NO_LIBRARY_REPLACEMENT,"RHF_NO_LIBRARY_REPLACEMENT");
X		  }
X		  if(flags& RHF_NO_MOVE) {
X			P("\t\t0x%x %s\n",RHF_NO_MOVE,"RHF_NO_MOVE");
X		  }
X		  if(flags& RHF_SGI_ONLY) {
X			P("\t\t0x%x %s\n",RHF_SGI_ONLY,"RHF_SGI_ONLY");
X		  }
X		  if(flags& RHF_GUARANTEE_INIT) {
X			P("\t\t0x%x %s\n",RHF_GUARANTEE_INIT,"RHF_GUARANTEE_INIT");
X		  }
X		  if(flags& RHF_REQUICKSTART) {
X			P("\t\t0x%x %s\n",RHF_REQUICKSTART,"RHF_REQUICKSTART ok to requickstart");
X		  }
X		  if(flags& RHF_DELTA_C_PLUS_PLUS) {
X			P("\t\t0x%x %s\n",RHF_DELTA_C_PLUS_PLUS,"RHF_DELTA_C_PLUS_PLUS");
X		  }
X		  if(flags& RHF_GUARANTEE_START_INIT) {
X			P("\t\t0x%x %s\n",RHF_GUARANTEE_START_INIT,"RHF_GUARANTEE_START_INIT");
X		  }
X		  if(flags& RHF_PIXIE) {
X			P("\t\t0x%x %s\n",RHF_PIXIE,"RHF_PIXIE");
X		  }
X		  if(flags& RHF_DEFAULT_DELAY_LOAD) {
X			P("\t\t0x%x %s\n",RHF_DEFAULT_DELAY_LOAD,"RHF_DEFAULT_DELAY_LOAD");
X		  }
X		  if(flags& RHF_REQUICKSTARTED) {
X			P("\t\t0x%x %s\n",RHF_REQUICKSTARTED,"RHF_REQUICKSTARTED has been requickstarted");
X		  }
X		  if(flags& RHF_CORD) {
X			P("\t\t0x%x %s\n",RHF_CORD,"RHF_CORD");
X		  }
X		  if(flags& RHF_NO_UNRES_UNDEF) {
X			P("\t\t0x%x %s\n",RHF_NO_UNRES_UNDEF,"RHF_NO_UNRES_UNDEF");
X		  }
X		  if(flags& RHF_RLD_ORDER_SAFE) {
X			P("\t\t0x%x %s\n",RHF_RLD_ORDER_SAFE,"RHF_RLD_ORDER_SAFE");
X		  }
X#endif /* __sgi */
X
X		}
X		break;
X#endif
X#ifdef DT_MIPS_BASE_ADDRESS
X	case DT_MIPS_BASE_ADDRESS:/*   0x70000006 */
X  		P(PREFIX LUFMT ": DT_MIPS_BASE_ADDRESS "
X                        XFMT " static link time/rqs address\n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X#endif
X#ifdef DT_MIPS_MSYM
X	case DT_MIPS_MSYM          : /*  0x70000007 */
X  		P(PREFIX LUFMT ": DT_MIPS_MSYM "
X                        XFMT " \n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X#endif /* DT_MIPS_MSYM */
X#ifdef DT_MIPS_CONFLICT
X	case DT_MIPS_CONFLICT    : /*    0x70000008 */
X  		P(PREFIX LUFMT ": DT_MIPS_MSYM "
X                        XFMT " address of .conflict section \n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X#endif
X#ifdef DT_MIPS_LIBLIST
X	case DT_MIPS_LIBLIST  : /*       0x70000009 */
X  		P(PREFIX LUFMT ": DT_MIPS_LIBLIST "
X                        XFMT " address of .liblist section \n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X#endif
X#ifdef DT_MIPS_LOCAL_GOTNO
X	case DT_MIPS_LOCAL_GOTNO : /*    0x7000000A */
X  		P(PREFIX LUFMT ": DT_MIPS_LOCAL_GOTNO "
X                        DFMT "  number of local got entries\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X#endif
X#ifdef DT_MIPS_CONFLICTNO
X	case DT_MIPS_CONFLICTNO : /*     0x7000000B */
X  		P(PREFIX LUFMT ": DT_MIPS_CONFLICTNO "
X                        DFMT "  number of .conflict section entries\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X#endif
X#ifdef DT_MIPS_LIBLISTNO
X	case DT_MIPS_LIBLISTNO   : /*    0x70000010 */
X  		P(PREFIX LUFMT ": DT_MIPS_LIBLISTNO "
X                        DFMT "  number of .liblist section entries\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X#endif
X#ifdef DT_MIPS_SYMTABNO
X	case DT_MIPS_SYMTABNO  : /*      0x70000011 */
X  		P(PREFIX LUFMT ": DT_MIPS_SYMTABNO "
X                        DFMT "  number of .dynsym section entries\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X#endif
X#ifdef DT_MIPS_UNREFEXTNO
X	case DT_MIPS_UNREFEXTNO   : /*   0x70000012 */
X  		P(PREFIX LUFMT ": DT_MIPS_UNREFEXTNO "
X                        DFMT "  index into .dynsym of first external not in this object\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X#endif
X#ifdef DT_MIPS_GOTSYM
X	case DT_MIPS_GOTSYM    : /*      0x70000013 */
X  		P(PREFIX LUFMT ": DT_MIPS_GOTSYM "
X                        DFMT "  index into .dynsym of first external in GOT\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X#endif
X#ifdef DT_MIPS_HIPAGENO
X	case DT_MIPS_HIPAGENO    :/*    0x70000014 */
X  		P(PREFIX LUFMT ": DT_MIPS_HIPAGENO "
X                        DFMT " number of 64K page entries in GOT \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X#endif
X#ifdef DT_MIPS_RLD_MAP
X	case DT_MIPS_RLD_MAP    :/*     0x70000016 */
X  		P(PREFIX LUFMT ": DT_MIPS_RLD_MAP "
X                        DFMT " \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X#endif
X#ifdef  DT_MIPS_DELTA_CLASS
X	case DT_MIPS_DELTA_CLASS  :/*     0x70000017 */      
X		/* contains Delta C++ class definition */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_CLASS "
X                        DFMT " \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_DELTA_CLASS_NO :/*   0x70000018 */      
X			/* the number of entries in DT_MIPS_DELTA_CLASS */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_CLASS_NO "
X                        DFMT " number of entries in delta class\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_DELTA_INSTANCE  :/*  0x70000019 */      
X		/* contains Delta C++ class instances */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_INSTANCE "
X                        DFMT " \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_DELTA_INSTANCE_NO:/* 0x7000001A */      
X		/* the number of entries in DT_MIPS_DELTA_INSTANCE */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_INSTANCE_NO "
X                        DFMT " number of entries in delta instance\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_DELTA_RELOC  :/*     0x7000001B */      
X		/* contains Delta relocations */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_RELOC "
X                        DFMT " \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_DELTA_RELOC_NO :/*   0x7000001C */      
X		/* the number of entries in DT_M */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_RELOC_NO "
X                        DFMT "  number of delta reloc entries\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_DELTA_SYM
X#define DT_MIPS_DELTA_SYM        0x7000001D
X#endif
X	case DT_MIPS_DELTA_SYM :/*0x7000001D */      
X		/* contains Delta symbols that Delta relocations refer to */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_SYM "
X                        DFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X
X#ifndef DT_MIPS_DELTA_SYM_NO
X#define DT_MIPS_DELTA_SYM_NO     0x7000001E
X#endif
X	case DT_MIPS_DELTA_SYM_NO:/*      0x7000001E */      
X		/* the number of entries in DT_M */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_SYM_NO "
X                        DFMT "  number of delta sym entries\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X
X#ifndef DT_MIPS_DELTA_CLASSSYM
X#define DT_MIPS_DELTA_CLASSSYM 0x70000020
X#endif
X	case DT_MIPS_DELTA_CLASSSYM:/*    0x70000020 */      
X		/* contains Delta symbols that hold the class declaration */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_CLASSSYM "
X                        DFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X#ifndef DT_MIPS_DELTA_CLASSSYM_NO
X#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021
X#endif
X	case DT_MIPS_DELTA_CLASSSYM_NO:/* 0x70000021 */      
X		/* the number of entries in DT_MIPS_DELTA_CLASSSYM */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_CLASSSYM_NO "
X                        DFMT "  number of delta class sym entries\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X#endif /* DT_MIPS_DELTA stuff */
X
X#ifdef __sgi
X#ifndef DT_MIPS_CXX_FLAGS
X#define DT_MIPS_CXX_FLAGS 0x70000022
X#endif
X	case   DT_MIPS_CXX_FLAGS      :/* 0x70000022 */      /* Flags indicating information about C++ flavor */
X  		P(PREFIX LUFMT ": DT_MIPS_CXX_FLAGS "
X                        XFMT "  c++ flags\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_PIXIE_INIT
X#define  DT_MIPS_PIXIE_INIT 0x70000023
X#endif
X	case   DT_MIPS_PIXIE_INIT    :/*  0x70000023 */
X  		P(PREFIX LUFMT ": DT_MIPS_PIXIE_INIT "
X                        XFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_SYMBOL_LIB
X#define  DT_MIPS_SYMBOL_LIB      0x70000024
X#endif
X	case   DT_MIPS_SYMBOL_LIB    :/*  0x70000024 */
X  		P(PREFIX LUFMT ": DT_MIPS_SYMBOL_LIB "
X                        XFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_LOCALPAGE_GOTIDX
X#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
X#endif
X	case DT_MIPS_LOCALPAGE_GOTIDX :/* 0x70000025 */
X  		P(PREFIX LUFMT ": DT_MIPS_LOCALPAGE_GOTIDX "
X                        XFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_LOCAL_GOTIDX
X#define DT_MIPS_LOCAL_GOTIDX     0x70000026
X#endif
X	case DT_MIPS_LOCAL_GOTIDX    :/*  0x70000026 */
X  		P(PREFIX LUFMT ": DT_MIPS_LOCAL_GOTIDX "
X                        XFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_HIDDEN_GOTIDX
X#define DT_MIPS_HIDDEN_GOTIDX    0x70000027
X#endif
X	case DT_MIPS_HIDDEN_GOTIDX   :/*  0x70000027 */
X  		P(PREFIX LUFMT ": DT_MIPS_HIDDEN_GOTIDX "
X                        XFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_PROTECTED_GOTIDX
X#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
X#endif
X	case DT_MIPS_PROTECTED_GOTIDX :/* 0x70000028 */
X  		P(PREFIX LUFMT ": DT_MIPS_PROTECTED_GOTIDX "
X                        XFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_OPTIONS
X#define DT_MIPS_OPTIONS          0x70000029
X#endif
X	case DT_MIPS_OPTIONS          :/* 0x70000029  */     /* Address of .options */
X  		P(PREFIX LUFMT ": DT_MIPS_OPTIONS "
X                        XFMT "  address of .options \n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X
X#ifndef DT_MIPS_INTERFACE
X#define DT_MIPS_INTERFACE        0x7000002a
X#endif
X	case DT_MIPS_INTERFACE :/*0x7000002a */      /* Address of .interface */
X  		P(PREFIX LUFMT ": DT_MIPS_INTERFACE "
X                        XFMT "  address of .interface \n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X
X#ifndef DT_MIPS_DYNSTR_ALIGN
X#define DT_MIPS_DYNSTR_ALIGN     0x7000002b
X#endif
X	case DT_MIPS_DYNSTR_ALIGN :/*     0x7000002b */
X  		P(PREFIX LUFMT ": DT_MIPS_DYNSTR_ALIGN "
X                        DFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_INTERFACE_SIZE
X#define DT_MIPS_INTERFACE_SIZE   0x7000002c
X#endif
X	case DT_MIPS_INTERFACE_SIZE :/*   0x7000002c */      /* size of the .interface sec. */
X  		P(PREFIX LUFMT ": DT_MIPS_INTERFACE_SIZE "
X                        DFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_RLD_TEXT_RESOLVE_ADDR
X#define  DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d 
X#endif
X	case   DT_MIPS_RLD_TEXT_RESOLVE_ADDR:/* 0x7000002d */    /* Address of rld_text_rsolve function stored in the got */
X  		P(PREFIX LUFMT ": DT_MIPS_RLD_TEXT_RESOLVE_ADDR "
X                        XFMT "  address of rld_text_resolve func stored in got\n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X
X#ifndef DT_MIPS_PERF_SUFFIX
X#define  DT_MIPS_PERF_SUFFIX     0x7000002e
X#endif
X	case   DT_MIPS_PERF_SUFFIX  :/*   0x7000002e */      /* Default suffix of dso to be added by */
X  		P(PREFIX LUFMT ": DT_MIPS_PERF_SUFFIX "
X                        DFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_COMPACT_SIZE
X#define DT_MIPS_COMPACT_SIZE     0x7000002f
X#endif
X	case DT_MIPS_COMPACT_SIZE    :/*  0x7000002f */      /* (O32)Size of compact rel scn */
X  		P(PREFIX LUFMT ": DT_MIPS_COMPACT_SIZE "
X                        DFMT "  size of compact rel section\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_GP_VALUE
X#define DT_MIPS_GP_VALUE 0x70000030
X#endif
X	case DT_MIPS_GP_VALUE :/* 0x70000030 */      /* gp value for aux gots */
X  		P(PREFIX LUFMT ": DT_MIPS_GP_VALUE "
X                        XFMT "  gp val for aux gots\n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X
X
X#ifndef  DT_MIPS_AUX_DYNAMIC
X#define DT_MIPS_AUX_DYNAMIC      0x70000031
X#endif
X	case DT_MIPS_AUX_DYNAMIC  :/*     0x70000031 */      /* Address of aux .dynamic */
X  		P(PREFIX LUFMT ": DT_MIPS_AUX_DYNAMIC "
X                        XFMT "  address of aux .dynamic\n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X#endif /* __sgi */
X
X
X	default:
X  		P(PREFIX LUFMT ": unknown tag 0x%lx "
X                        DFMT " \n",
X                        trueoff,
X			(unsigned long)buffer->d_tag,
X                        buffer->d_un.d_val);
X		break;
X	}
X	
X	
X     
X
X    }
X    return 0;
X
X}
X
Xstatic
Xint
Xelf_print_symbols32(unsigned long offset,unsigned long size)
X{
X    long ecount = 0;
X    unsigned long size2 = 0;
X    unsigned long i;
X    Elf32_Sym *buffer;
X    unsigned long trueoff = offset;
X	int res;
X
X#define PREFIX "\t"
X#define LUFMT "%lu"
X#define UFMT "%u"
X#define DFMT "%d"
X#define XFMT "0x%x"
X
X    ecount = (long)(size/sizeof(Elf32_Sym));
X    size2 = ecount * sizeof(Elf32_Sym);
X    if(size != size2) {
X	P("Bogus size of symbols. %lu not divisible by %lu\n",
X		size,(unsigned long)sizeof(Elf32_Sym));
X	return 0;
X    }
X
X    buffer = alloca(size);
X    
X    res = RR(buffer,offset,size);
X    if(res) {
X                P("could not read whole symbol section of %s "
X		  "at offset %lu size %lu\n",
X			filename,
X			offset,size);
X                return 0;
X    }
X
X
X#if 0
X    if(ecount > 0) {
X      P("[Index] Value\tSize\tType              Bind       Other          Shndx   Name\n");
X    }
X#endif
X    for(i = 0; i < ecount; ++i,++buffer,trueoff += sizeof(Elf32_Sym)) {
X	
X	unsigned type;
X	unsigned bind;
X	unsigned shndx;
X	char indxname[50];
X
X	P("[%3d]",(int)i);
X	P("\t st_value 0x%lx", (unsigned long)buffer->st_value);
X	P("\n");
X	P("\t st_size  0x%ld", (long)buffer->st_size);
X	P("\n");
X	P("\t st_info  0x%02lx", (unsigned long)buffer->st_info);
X	P("\n");
X
X	type = ELF32_ST_TYPE(buffer->st_info);
X	bind = ELF32_ST_BIND(buffer->st_info);
X        sprintf(indxname,"STT?(0x%02x)",type);
X	P("\t type     %s",
X		(type ==  STT_NOTYPE )? "STT_NOTYPE ":
X		(type == STT_OBJECT  )? "STT_OBJECT ":
X		(type == STT_FUNC    )? "STT_FUNC   ":
X		(type == STT_SECTION )? "STT_SECTION":
X		(type == STT_FILE    )? "STT_FILE   ":
X			indxname);
X        P("\n");
X
X        sprintf(indxname,"STB?(0x%x)",bind);
X	P("\t bind     %s", 
X		 (bind == STB_LOCAL ) ? "STB_LOCAL ":
X		 (bind == STB_GLOBAL) ? "STB_GLOBAL":
X		 (bind == STB_WEAK  ) ? "STB_WEAK  ":
X			indxname);
X	
X        P("\n");
X	switch(buffer->st_other) {
X#ifdef STO_DEFAULT
X	case STO_DEFAULT :
X	   strcpy(indxname,"STO_DEFAULT");
X	   break;
X#endif
X#ifdef STO_INTERNAL
X	case STO_INTERNAL:
X	   strcpy(indxname,"STO_INTERNAL");
X	   break;
X#endif
X#ifdef STO_HIDDEN
X	case STO_HIDDEN  :
X	   strcpy(indxname,"STO_HIDDEN");
X	   break;
X#endif
X#ifdef STO_PROTECTED
X	case STO_PROTECTED:
X	   strcpy(indxname,"STO_PROTECTED");
X	   break;
X#endif
X	default:
X	   sprintf(indxname,"%d",buffer->st_other);
X	   break;
X	}
X	P("\t st_other (%d)%s",(int)buffer->st_other,indxname);
X        P("\n");
X
X	shndx = buffer->st_shndx;
X	switch(shndx) {
X	case SHN_ABS:
X	     strcpy(indxname,"SHN_ABS");
X	     break;
X	case SHN_COMMON:
X	     strcpy(indxname,"SHN_COMMON");
X	     break;
X#ifdef SHN_MIPS_ACOMMON
X	case SHN_MIPS_ACOMMON:
X	     strcpy(indxname,"SHN_MIPS_ACOMMON");
X	     break;
X#endif
X#ifdef SHN_MIPS_TEXT
X	case SHN_MIPS_TEXT   :
X	     strcpy(indxname,"SHN_MIPS_TEXT");
X	     break;
X#endif
X#ifdef SHN_MIPS_DATA
X	case SHN_MIPS_DATA   :
X	     strcpy(indxname,"SHN_MIPS_DATA");
X	     break;
X#endif
X#ifdef SHN_MIPS_SCOMMON
X	case SHN_MIPS_SCOMMON:
X	     strcpy(indxname,"SHN_SCOMMON");
X	     break;
X#endif
X#ifdef SHN_MIPS_SUNDEFINED
X	case SHN_MIPS_SUNDEFINED:
X	     strcpy(indxname,"SHN_MIPS_SUNDEFINED");
X	     break;
X#endif
X	case SHN_UNDEF:
X		strcpy(indxname,"SHN_UNDEF");
X	     break;
X        default:
X	     sprintf(indxname,"%d", (int)shndx);
X	     break;
X
X	}
X	P("\t st_shndx (0x%02x)%s",(unsigned)shndx,indxname);
X	P("\n");
X	
X
X	P("\t st_name  (%d)%s",buffer->st_name,get_symstr_string(buffer->st_name));
X
X	/* FIX: print string here */
X	P("\n");
X
X    }
X    return 0;
X
X}
Xstatic int 
Xelf_print_relocation32(unsigned long offset,unsigned long size,int link)
X{
X    long          ecount  = 0;
X    unsigned long size2   = 0;
X    int           reclen  = sizeof(Elf32_Rel);
X    unsigned long i;
X    char      *   buffer;
X    unsigned long trueoff = offset;
X    int           res;
X
X#define PREFIX "\t"
X#define LUFMT "%lu"
X#define UFMT "%u"
X#define DFMT "%d"
X#define XFMT "0x%x"
X
X    if(size == 0) {
X	P("Bogus relocation section: offset 0x%lx size 0x%lx\n",
X			offset, size);
X	return 0;
X    }
X    ecount = (long)(size/reclen);
X    size2 = ecount * reclen;
X    if(size != size2) {
X        P("Bogus size of relocations. %lu not divisible by %lu\n",
X                size,(unsigned long)reclen);
X        return 0;
X    }
X
X    buffer = alloca(size);
X
X    res = RR(buffer,offset,size);
X    if(res) {
X                P("could not read whole reloc section of %s "
X                  "at offset %lu size %lu\n",
X                        filename,
X                        offset,size);
X                return 0;
X    }
X
X
X    for(i = 0; i < ecount; ++i,buffer+=reclen,trueoff += reclen){
X	Elf32_Rel *r = (Elf32_Rel *)buffer;
X	P("[%3d] ",i);
X	P(" file offset " XFMT " ",(unsigned)trueoff);
X	P(" targ_offset " XFMT "(" UFMT ") ", 
X		(unsigned)r->r_offset,(unsigned)r->r_offset);
X	P("info " XFMT, (unsigned)r->r_info);
X	P(" sym %d ",ELF32_R_SYM(r->r_info));
X	P(" type %d ",ELF32_R_TYPE(r->r_info));
X	P("\n");
X    }
X    return 1;
X}
X#endif /* HAS_ELFHDR */
SHAR_EOF
fi # end of overwriting check
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
XSHELL = /bin/sh
X
X
X# For IRIX4, do NOT define HAS_ELFHDR here.
X#CFLAGS = -fullwarn -wlint -g -DHAS_ELFHDR -DHAS_ELFHDR64
XCFLAGS = -n32 -fullwarn -g -DHAS_ELFHDR -DHAS_ELFHDR64
X#CFLAGS =  -Wall -pedantic -ansi -g -DLINUX -DPC -DHAS_ELFHDR
X
X#all: readobj wasteobj
Xall: readobj
Xshar:
X	shar -p X readobj.c Makefile readobj64.c readobj.h readobj64.h \
X		>/d2/public/readobj.shar
X	shar -p X whacksyms.c array_alloc.h array_alloc.c Makefile \
X		>/d2/public/whacksyms.shar
X	shar -p X wasteobj.c Makefile >/d2/public/wasteobj.shar
X	
X#makeabs whacksyms
Xwhacksyms:  whacksyms.o array_alloc.o
X	$(CC) $(CFLAGS) -g whacksyms.o array_alloc.o -o whacksyms
Xmakeabs:  makeabs.o
X	$(CC) $(CFLAGS) -g makeabs.o -o makeabs
X
Xreadobj.o: readobj.h readobj64.h readobj.c
Xreadobj64.o: readobj.h readobj64.h readobj64.c
Xreadobj:  readobj.o readobj64.o
X	$(CC) $(CFLAGS) -g readobj.o readobj64.o -o readobj
Xwasteobj:  wasteobj.o
X	$(CC) $(CFLAGS) -g wasteobj.o -o wasteobj
X
Xclobber:
X	-rm *.o 
X	-rm  wasteobj
X	-rm  readobj  makeabs whacksyms
X	-rm core a.out
X
SHAR_EOF
fi # end of overwriting check
if test -f 'readobj64.c'
then
	echo shar: will not over-write existing file "'readobj64.c'"
else
sed 's/^X//' << \SHAR_EOF > 'readobj64.c'
X
X/*
X	readobj64.c
X
X	For handling 64-bit elf objects.
X
X*/
X
X#include <stdio.h>
X#include <a.out.h>
X#include <malloc.h>
X#include <string.h>
X#include <alloca.h>
X#include <time.h>
X#include "readobj.h"
X#ifdef LINUX
X#include <elf.h>
X#else /* !LINUX */
X#include <elf_abi.h>
X#include <elf_mips.h>
X#endif
X#include "readobj64.h"
X
X
X#define USHORT unsigned short
X
X#define P printf
X#define F fflush(stdout)
X#define RR(buf,loc,siz)  ((fseek(fin,(long)(loc),0)<0) ? -1 : \
X		((fread(buf,(long)(siz),1,fin)!=1)?-2:0))
X#define RN(buf,siz)  ((fread(buf,(long)(siz),1,fin) != 1) ? -2 : 0)
X#define CURLOC     ( ftell(fin) )
X#define SEEKTO(i)  (fseek(fin,(long)(i),SEEK_SET))
X
Xtypedef LONGESTUTYPE ULONG64;
Xtypedef LONGESTSTYPE LONG64;
X
X#ifdef __sgi
Xstatic void elf_print_progheaders(ULONG64,ULONG64,ULONG64 );
Xstatic void elf_print_sectheaders(ULONG64,ULONG64,ULONG64 );
Xstatic void elf_get_sectstrings(ULONG64 offset,ULONG64 entsize,ULONG64 count,ULONG64 stringsection);
Xstatic int elf_print_dynamic64(ULONG64 offset,ULONG64 size,int sectnum);
Xstatic char * get_dynstr_string(ULONG64 offset, int index);
Xstatic void elf_get_dynstr(ULONG64 offset, ULONG64 entsize, ULONG64 count);
X#endif
X
X
X
X#ifdef HAS_ELFHDR64
Xstatic Elf64_Ehdr ehdr;
X#endif
X
X
X#ifdef HAS_ELFHDR64
Xextern int print_dynamic_section;
X
Xstatic char *elf_shstrings_data; /* section name strings */
Xstatic long  elf_shstrings_length; /* length of currentsection. Might be zero..*/
Xstatic unsigned long  elf_shstrings_max; /* size of malloc-d space */
Xstatic char *dynamic_sect_strings;
Xstatic long dynamic_sect_strings_length;
Xstatic int  dynamic_sect_strings_sect_index;
X
X
X
Xvoid
Xdo_elf_file64(char *s)
X{
X	int i;
X	int res;
X	unsigned char c;
X
X	P("Elf 64-bit object file %s\n",s);
X	SEEKTO(0);
X	res = RR(&ehdr,0,sizeof(ehdr));
X	if(res) {
X		P("could not read whole ELF file header of %s\n",filename);
X		return;
X	}
X	P("\tident bytes: ");
X	for(i = 0; i < EI_NIDENT; i++) {
X		c =  ehdr.e_ident[i];
X		P(" %02x",c);
X	}
X	P("\n");
X	c = ehdr.e_ident[EI_CLASS];
X	P("\t\tident[class] 0x%x   %s\n",(int)c,
X			(c == ELFCLASSNONE)? "ELFCLASSNONE":
X			(c == ELFCLASS32) ? "ELFCLASS32" :
X			(c == ELFCLASS64) ? "ELFCLASS64" :
X			"unknown ");
X	c = ehdr.e_ident[EI_DATA];
X	P("\t\tident[data] 0x%x   %s\n",(int)c,
X			(c == ELFDATANONE)? "ELFDATANONE":
X			(c == ELFDATA2MSB)? "ELFDATA2MSB":
X			(c == ELFDATA2LSB) ? "ELFDATA2LSB":
X			"unknown");
X	c = ehdr.e_ident[EI_VERSION];
X	P("\t\tident[version] 0x%x   %s\n",(int)c,
X			(c == EV_CURRENT)? "EV_CURRENT":
X			"unknown");
X	i = ehdr.e_type;
X	P("\ttype 0x%x	%s\n",(int)i,(i == ET_NONE)? "ET_NONE No file type":
X		(i == ET_REL)? "ET_REL Relocatable file":
X		(i == ET_EXEC)? "ET_EXEC Executable file":
X		(i == ET_DYN)? "ET_DYN Shared object file":
X		(i == ET_CORE) ? "ET_CORE Core file":
X#ifdef ET_IR
X                (i == ET_IR)? "ET_IR intermediate file":
X#endif
X			"unknown");
X	P("\tmachine 0x%x %s\n",(int)ehdr.e_machine,
X			(ehdr.e_machine == EM_NONE) ? "EM_NONE Invalid machine":
X			(ehdr.e_machine == EM_MIPS) ? "EM_MIPS Mips cpu":
X			"unknown");
X	P("\tversion 0x%x %s\n",(int)ehdr.e_version,
X			(ehdr.e_version == EV_NONE) ? "EV_NONE Invalid version":
X			(ehdr.e_version == EV_CURRENT) ? "EV_CURRENT current version":
X			"unknown");
X	P("\tEntry 0x%llx   prog hdr off: 0x%llx   sec hdr off 0x%llx\n",
X		(ULONG64)ehdr.e_entry,(ULONG64)ehdr.e_phoff,(ULONG64)ehdr.e_shoff);
X	P("\tFlags 0x%llx",(ULONG64)ehdr.e_flags);
X	if(ehdr.e_flags& EF_MIPS_NOREORDER){
X		P(", .noreorder present(flag EF_MIPS_NOREORDER)");
X	}
X	if(ehdr.e_flags& EF_MIPS_PIC){
X		P(", EF_MIPS_PIC");
X	}
X	if(ehdr.e_flags& EF_MIPS_CPIC){
X		P(", EF_MIPS_CPIC(calls pic)");
X	}
X#ifdef EF_MIPS_XGOT
X	if(ehdr.e_flags& EF_MIPS_XGOT){
X		P(", EF_MIPS_XGOT");
X	}
X#endif
X	if(ehdr.e_flags& EF_MIPS_UGEN_RESERVED){
X		P(", EF_MIPS_UGEN_RESERVED");
X	}
X	P("\n");
X	if(ehdr.e_flags& EF_MIPS_ARCH){
X		int c;
X		c=(ehdr.e_flags& EF_MIPS_ARCH);
X		P("\t    flag mips-arch 0x%x",c);
X		P("  %s", (c == EF_MIPS_ARCH_2) ? "EF_MIPS_ARCH_2" :
X			(c == EF_MIPS_ARCH_3) ? "EF_MIPS_ARCH_3":
X			(c == EF_MIPS_ARCH_4) ? "EF_MIPS_ARCH_4":
X			(c == 0) ? "mips_1" :
X			"unknownarch");
X		P("\n");
X	}
X	P("\tEhdrsize %3d  Proghdrsize %3d  Sechdrsize %3d\n",
X		(int)ehdr.e_ehsize,(int)ehdr.e_phentsize,(int)ehdr.e_shentsize);
X	P("\t              P-hdrcount  %3d  S-hdrcount %3d\n",
X		(int)ehdr.e_phnum,(int)ehdr.e_shnum);
X	if(ehdr.e_shstrndx == SHN_UNDEF) {
X	  P("\tSection strings are not present e_shstrndx ==SHN_UNDEF\n");
X	} else {
X	  P("\tSection strings are in section %lld\n",(LONG64)ehdr.e_shstrndx);
X	}
X
X	if(ehdr.e_shstrndx > ehdr.e_shnum) {
X		P("String section index is wrong: %lld vs only %lld sections. Consider it 0\n",
X			(LONG64)(ehdr.e_shstrndx),(LONG64)(ehdr.e_shnum));
X		ehdr.e_shstrndx = 0;
X	}
X	elf_get_sectstrings(ehdr.e_shoff,ehdr.e_shentsize,ehdr.e_shnum,ehdr.e_shstrndx);
X        if(elf_shstrings_data == 0) {
X		return;
X	}
X 	elf_get_dynstr(ehdr.e_shoff,ehdr.e_shentsize,ehdr.e_shnum);
X
X	elf_print_progheaders(ehdr.e_phoff,ehdr.e_phentsize,ehdr.e_phnum);
X	elf_print_sectheaders(ehdr.e_shoff,ehdr.e_shentsize,ehdr.e_shnum);
X}
X
X
Xstatic void 
Xelf_get_sectstrings(ULONG64 offset,ULONG64 entsize,ULONG64 count,ULONG64 stringsection)
X{
X	int i;
X	Elf64_Shdr *psh;
X	Elf64_Shdr *orig_psh;
X
X
X	if(count == 0) {
X		P("No section headers\n");
X		return;
X	}
X	elf_shstrings_length = 0;
X	if(entsize < (ULONG64)sizeof(Elf64_Shdr)) {
X		P("Elf Section header too small? %lld vs %lld\n",
X			(ULONG64)entsize,(ULONG64)sizeof(Elf64_Shdr));
X	}
X
X	i =(int)SEEKTO(offset + entsize*stringsection);
X	if(i) {
X		P("Seek to %lld to read string section header failed\n",
X			(ULONG64)offset+
X			(ULONG64)entsize*stringsection);
X		return;
X	}
X	psh = (Elf64_Shdr *)malloc( entsize);
X	if(psh == 0) {
X		P("malloc to %lld bytes of section header space failed\n"
X			,(LONG64)entsize);
X		return;
X	}
X	orig_psh = psh;
X	i = RN(psh,entsize);
X	if(i) {
X                P("read string section header failed "
X                "( attempted read of %ld bytes ( 0x%lx) "
X                "at offset %ld (0x%lx) \n",
X                  (long)entsize,
X                  (long)entsize,
X                  (long)(offset + (long)entsize*(long)stringsection),
X                  (long)(offset + (long)entsize*(long)stringsection));
X		return;
X	}
X	if(psh->sh_type == SHT_NULL) {
X		P("String section type SHT_NULL!!. No string section!\n");
X		return;
X	}
X	P("String section data at 0x%llx length 0x%llx %llu\n",
X		(ULONG64)psh->sh_offset,(ULONG64)psh->sh_size,(ULONG64)psh->sh_size);
X	i =(int)SEEKTO(psh->sh_offset);
X	if(i) {
X		P("Seek to %llu string section data failed\n",(ULONG64)psh->sh_offset);
X		elf_shstrings_length = 0;
X		return;
X	}
X	if(psh->sh_size > elf_shstrings_max) {
X		if(elf_shstrings_data)
X			free(elf_shstrings_data);
X		elf_shstrings_data = (char *)malloc(psh->sh_size);
X		elf_shstrings_max = (unsigned long)psh->sh_size;
X		if(elf_shstrings_data == 0) {
X                  elf_shstrings_max = 0;
X                  P("Unable to malloc %ld bytes for strings\n",
X                        (long)psh->sh_size);
X                }
X
X	}
X	elf_shstrings_length = (long)psh->sh_size;
X	i = RN(elf_shstrings_data,psh->sh_size);
X	if(i) {
X		P("Read  %llu bytes of string section string data failed\n",
X			(ULONG64)elf_shstrings_length);
X		elf_shstrings_length = 0;
X		return;
X	}
X	free(orig_psh);
X}
X
X#define SHTYPESTRING(x)  get_shtypestring(x)
X#define SHSTRING(x) ((elf_shstrings_length > (x)) ? \
X                 (x) + elf_shstrings_data :  \
X                  "Invalid sh_name value")
Xstatic void
Xelf_get_dynstr(ULONG64 offset, ULONG64 entsize, ULONG64 count)
X{
X        int i;
X        Elf64_Shdr *psh;
X        Elf64_Shdr *orig_psh;
X	ULONG64 curloc;
X	ULONG64 seekres;
X	int res;
X
X
X        if(entsize < sizeof(Elf64_Shdr)) {
X                P("Elf Section header too small? %ld vs %ld\n",
X                        (long)entsize,(long)sizeof(Elf64_Shdr));
X        }
X        if(count == 0) {
X                P("No section headers\n");
X                return;
X        }
X	curloc = CURLOC;
X	if(curloc != (ULONG64)-1LL) {
X		P("\tcurrent loc unknown/error error in ftell?\n");
X		return;
X	}
X        i =(int)SEEKTO(offset);
X        if(i) {
X                P("Seek to %ld to read section headers failed\n",
X			(long)offset);
X                return;
X        }
X        psh = (Elf64_Shdr *)alloca(count * entsize);
X        if(psh == 0) {
X                P("malloc to %ld bytes of section header space failed\n",
X			(long)(count *entsize));
X                return;
X        }
X        orig_psh = psh;
X        i = RN(orig_psh,count*entsize);
X        if(i) {
X                P("Read %lu bytes of section headers failed\n",
X			(unsigned long) (count*entsize));
X                return;
X        }
X
X
X        for(i = 0; i < count;
X                i++, psh = (Elf64_Shdr *) ((char *)psh + entsize)) {
X
X	  if(0 == strcmp(SHSTRING(psh->sh_name),".dynstr")) {
X		dynamic_sect_strings_sect_index = i;
X		dynamic_sect_strings_length = (long)psh->sh_size;
X		dynamic_sect_strings = malloc(dynamic_sect_strings_length);
X		res = RR(dynamic_sect_strings,psh->sh_offset,
X			dynamic_sect_strings_length);
X		if(res) {
X		 P("Could not read dynamic section strings at "
X				LONGESTXFMT "\n",
X			(LONGESTUTYPE) psh->sh_offset);
X		 dynamic_sect_strings = 0;
X		  dynamic_sect_strings_length = 0;
X			dynamic_sect_strings_sect_index = 0;
X                  seekres =(int)SEEKTO(curloc);
X                  if(seekres) {
X                          P("Seek to %ld after reading sect headers failed\n",
X			(long)curloc);
X                  }
X		  return;
X		}
X		break;
X
X          }
X
X        }
X        i =(int)SEEKTO(curloc);
X        if(i) {
X                P("Seek to %ld after reading sect headers failed\n",(long)offset);
X                return;
X        }
X}
Xstatic char *
Xget_dynstr_string(ULONG64 offset, int index)
X{
X
X
X   if(index != dynamic_sect_strings_sect_index) {
X        P("link is %d, sect found was %d\n",
X                (int)index,
X                (int)dynamic_sect_strings_sect_index);
X	return"dynamic section link does not match section of dynamic strings";
X   }
X   if(offset >= dynamic_sect_strings_length) {
X	return "offset beyond end of dynamic sect strings";
X   }
X   return dynamic_sect_strings + offset;
X}
X
X
Xstatic void 
Xelf_print_interp(LONG64 offset, LONG64 size)
X{
X	long cloc;
X	long j;
X	long res;
X	char *buf;
X
X	cloc = CURLOC;
X	if(cloc < 0) {
X		P("\tcurrent loc unknown?\n");
X		return;
X	}
X	j = (int)SEEKTO(offset);
X	if(j != 0){
X		P("\tseekto  0x%llx failed\n",(LONG64)offset);
X	}
X	buf = malloc(size);
X	if(buf == 0) {
X		P("\tmalloc failed\n");
X	}
X	res = RN(buf,size);
X	if(res < 0) {
X		P("\tRead interp string failed\n");
X		SEEKTO(cloc);
X		return;
X	}
X	P("\t%s\n",buf);
X	if(SEEKTO(cloc) != 0) {
X		P("\tseek back to 0x%llx failed\n",(LONG64)cloc);
X	}
X	return;
X}
X
X
Xstatic void 
Xelf_print_progheaders(ULONG64 offset,ULONG64 entsize,ULONG64 count)
X{
X	int i;
X	Elf64_Phdr *pph;
X	Elf64_Phdr *orig_pph;
X
X
X
X	if(count == 0) {
X		P("No program headers\n");
X		return;
X	}
X	if(entsize < sizeof(Elf64_Phdr)) {
X		P("Elf Program header too small? %lld vs %lld\n",
X			(LONG64)entsize,(LONG64)sizeof(Elf64_Phdr));
X	}
X	i =(int)SEEKTO(offset);
X	if(i) {
X		P("Seek to %lld to read program headers failed\n",
X			(LONG64)offset);
X		return;
X	}
X	pph = (Elf64_Phdr *)malloc(count * entsize);
X	if(pph == 0) {
X		P("malloc to %lld bytes of program header space failed\n",
X			(LONG64)count *  (LONG64)entsize);
X		return;
X	}
X	orig_pph = pph;
X	i = RN(pph,count*entsize);
X	if(i) {
X		P("Read  %lld bytes program headers failed\n",count*entsize);
X		return;
X	}
X#define PHTYPE(x) (\
X	((x) == PT_NULL) ? "PT_NULL": \
X	((x) == PT_LOAD) ? "PT_LOAD": \
X	((x) == PT_DYNAMIC) ? "PT_DYNAMIC": \
X	((x) == PT_INTERP) ? "PT_INTERP": \
X	((x) == PT_NOTE) ? "PT_NOTE": \
X	((x) == PT_SHLIB) ? "PT_SHLIB": \
X	((x) == PT_PHDR) ? "PT_PHDR": \
X	((x) == PT_MIPS_REGINFO) ? "PT_MIPS_REGINFO": \
X	((x) == PT_MIPS_OPTIONS) ? "PT_MIPS_OPTIONS": \
X	((x) == PT_MIPS_RTPROC) ? "PT_MIPS_RTPROC (run time proc tbl)":  \
X		/* run time proc table*/ \
X	"unknowntype")
X
X	P("Program header count %lld\n",(LONG64)count);
X	for( i = 0; i < count; 
X		++i,  pph = (Elf64_Phdr *) ((char *)pph + entsize)) {
X	  P("Program header %lld",(LONG64)i);
X	  P("  type %s (%llx)",PHTYPE(pph->p_type),(ULONG64)pph->p_type);
X	  P(", offset 0x%llx %lld",(LONG64)pph->p_offset,(LONG64)pph->p_offset);
X	  P("\n");
X	  P("\tvaddr 0x%llx %lld",(LONG64)pph->p_vaddr,(LONG64)pph->p_vaddr);
X	  P(", paddr 0x%llx %lld",(LONG64)pph->p_paddr,(LONG64)pph->p_paddr);
X	  P("\n");
X	  P("\tfilesz 0x%llx %lld",(LONG64)pph->p_filesz,(LONG64)pph->p_filesz);
X	  P("\n");
X	  P("\tmemsz 0x%llx %lld",(LONG64)pph->p_memsz,(LONG64)pph->p_memsz);
X	  P(", flags %#lx",(long)pph->p_flags);
X#ifdef PF_MIPS_LOCAL
X          if(pph->p_flags & PF_MIPS_LOCAL) {
X                P(" PF_MIPS_LOCAL");
X          }
X#endif
X	  if(pph->p_flags & PF_X) {
X		P(" PF_X");
X	  }
X	  if(pph->p_flags & PF_W) {
X		P(" PF_W");
X	  }
X	  if(pph->p_flags & PF_R) {
X		P(" PF_R");
X	  }
X	  P(", align 0x%llx %lld",(LONG64)pph->p_align,(LONG64)pph->p_align);
X	  P("\n");
X	  if(pph->p_type == PT_INTERP) {
X		elf_print_interp(pph->p_offset,pph->p_filesz);
X	  }
X	}
X	free(orig_pph);
X}
X#endif /* HAS_ELFHDR64 */
X
X
X
X#define TYPEENTRY(x)  { x , #x }
X
Xstatic struct shstring_s {
X	long bits;
X	char *name;
X} shstrings[] = {
X        TYPEENTRY(SHT_NULL),
X        TYPEENTRY(SHT_PROGBITS),
X        TYPEENTRY(SHT_SYMTAB),
X        TYPEENTRY(SHT_STRTAB),
X        TYPEENTRY(SHT_RELA),
X        TYPEENTRY(SHT_HASH),
X        TYPEENTRY(SHT_DYNAMIC),
X        TYPEENTRY(SHT_NOTE),
X        TYPEENTRY(SHT_NOBITS),
X        TYPEENTRY(SHT_REL),
X        TYPEENTRY(SHT_SHLIB),
X        TYPEENTRY(SHT_DYNSYM),
X        TYPEENTRY(SHT_MIPS_LIBLIST),
X        TYPEENTRY(SHT_MIPS_CONFLICT),
X        TYPEENTRY(SHT_MIPS_GPTAB),
X        TYPEENTRY(SHT_MIPS_UCODE),
X        TYPEENTRY(SHT_MIPS_DEBUG),
X#ifdef  SHT_GNU_verdef  /*0x6ffffffd      Version definition section.  */
X	TYPEENTRY(SHT_GNU_verdef),
X#endif
X#ifdef SHT_GNU_verneed /* 0x6ffffffe      Version needs section.  */
X	TYPEENTRY(SHT_GNU_verneed),
X#endif
X#ifdef  SHT_GNU_versym  /* 0x6fffffff    */
X	TYPEENTRY(SHT_GNU_versym),
X#endif
X
X#ifdef  SHT_MIPS_REGINFO
X        TYPEENTRY(SHT_MIPS_REGINFO),
X#endif
X#ifdef SHT_MIPS_MSYM
X        TYPEENTRY(SHT_MIPS_MSYM),
X#endif
X#ifdef SHT_MIPS_RELD
X        TYPEENTRY( SHT_MIPS_RELD),
X#endif
X#ifdef SHT_MIPS_DONTUSE
X         TYPEENTRY(SHT_MIPS_DONTUSE),
X#endif
X#ifdef SHT_MIPS_IFACE
X         TYPEENTRY(SHT_MIPS_IFACE),
X#endif
X#ifdef SHT_MIPS_CONTENT
X         TYPEENTRY(SHT_MIPS_CONTENT),
X#endif
X#ifdef SHT_MIPS_OPTIONS
X         TYPEENTRY(SHT_MIPS_OPTIONS),
X#endif
X#ifdef SHT_MIPS_SHDR
X         TYPEENTRY(SHT_MIPS_SHDR),
X#endif
X#ifdef SHT_MIPS_FDESC
X         TYPEENTRY(SHT_MIPS_FDESC),
X#endif
X#ifdef SHT_MIPS_EXTSYM
X         TYPEENTRY(SHT_MIPS_EXTSYM),
X#endif
X#ifdef SHT_MIPS_DENSE
X         TYPEENTRY(SHT_MIPS_DENSE),
X#endif
X#ifdef SHT_MIPS_PDESC
X         TYPEENTRY(SHT_MIPS_PDESC),
X#endif
X#ifdef SHT_MIPS_LOCSYM
X         TYPEENTRY(SHT_MIPS_LOCSYM),
X#endif
X#ifdef SHT_MIPS_AUXSYM
X         TYPEENTRY(SHT_MIPS_AUXSYM),
X#endif
X#ifdef SHT_MIPS_OPTSYM
X         TYPEENTRY(SHT_MIPS_OPTSYM),
X#endif
X#ifdef SHT_MIPS_LOCSTR
X         TYPEENTRY(SHT_MIPS_LOCSTR),
X#endif
X#ifdef SHT_MIPS_LINE
X         TYPEENTRY(SHT_MIPS_LINE),
X#endif
X#ifdef SHT_MIPS_RFDESC
X         TYPEENTRY(SHT_MIPS_RFDESC),
X#endif
X#ifdef SHT_MIPS_DELTASYM
X TYPEENTRY(SHT_MIPS_DELTASYM),
X#endif
X#ifdef SHT_MIPS_DELTAINST
X TYPEENTRY(SHT_MIPS_DELTAINST),
X#endif
X#ifdef SHT_MIPS_DELTACLASS
X TYPEENTRY(SHT_MIPS_DELTACLASS),
X#endif
X#ifdef SHT_MIPS_DWARF
X TYPEENTRY(SHT_MIPS_DWARF),
X#endif
X#ifdef SHT_MIPS_DELTADECL
X TYPEENTRY(SHT_MIPS_DELTADECL), 
X#endif
X#ifdef SHT_MIPS_SYMBOL_LIB
X TYPEENTRY(SHT_MIPS_SYMBOL_LIB),
X#endif
X#ifdef SHT_MIPS_EVENTS
X TYPEENTRY(SHT_MIPS_EVENTS),
X#endif
X#ifdef SHT_MIPS_TRANSLATE
X TYPEENTRY(SHT_MIPS_TRANSLATE),
X#endif
X#ifdef SHT_MIPS_PIXIE
X TYPEENTRY(SHT_MIPS_PIXIE),
X#endif
X#ifdef SHT_MIPS_XLATE
X TYPEENTRY(SHT_MIPS_XLATE),
X#endif
X#ifdef SHT_MIPS_XLATE_DEBUG
X TYPEENTRY(SHT_MIPS_XLATE_DEBUG),
X#endif
X#ifdef SHT_MIPS_WHIRL
X TYPEENTRY(SHT_MIPS_WHIRL),
X#endif
X};
X
X
X
X
X#ifdef HAS_ELFHDR64
X
Xstatic void 
Xelf_print_sectheaders(ULONG64 offset,ULONG64 entsize,ULONG64 count)
X{
X	int i;
X	Elf64_Shdr *psh;
X	Elf64_Shdr *orig_psh;
X
X
X	if(entsize < sizeof(Elf64_Shdr)) {
X		P("Elf Section header too small? %lld vs %lld\n",
X			(ULONG64) entsize,(ULONG64 )sizeof(Elf64_Shdr));
X	}
X	if(count == 0) {
X		P("No section headers\n");
X		return;
X	}
X	i =(int)SEEKTO(offset);
X	if(i) {
X		P("Seek to %lld to read section headers failed\n",offset);
X		return;
X	}
X	psh = (Elf64_Shdr *)malloc(count * entsize);
X	if(psh == 0) {
X		P("malloc to %lld bytes of section header space failed\n",count *entsize);
X		return;
X	}
X	orig_psh = psh;
X	i = RN(orig_psh,count*entsize);
X	if(i) {
X		P("Read %llu bytes of section headers failed\n",count*entsize);
X		return;
X	}
X
X	P("Section count: %lld\n",(LONG64)count);
X	for(i = 0; i < count; 
X		i++, psh = (Elf64_Shdr *) ((char *)psh + entsize)) {
X	  P("Section %lld, name %lld %s",(LONG64)i,(LONG64)psh->sh_name,
X		SHSTRING(psh->sh_name));
X	  P("  type 0x%llx %s",
X		(LONG64)psh->sh_type,SHTYPESTRING(psh->sh_type));
X	  if(psh->sh_flags == 0) {
X	    P(", flags 0x%llx",(LONG64)psh->sh_flags);
X	  } else {
X	    P("\n");
X	    P("\tflags 0x%llx",(LONG64)psh->sh_flags);
X	    if(psh->sh_flags & SHF_WRITE) {
X		P(" SHF_WRITE");
X	    }
X	    if(psh->sh_flags & SHF_ALLOC) {
X		P(" SHF_ALLOC");
X	    }
X	    if(psh->sh_flags & SHF_EXECINSTR) {
X		P(" SHF_EXECINSTR");
X	    }
X#ifndef SHF_MIPS_GPREL
X#define SHF_MIPS_GPREL          0x10000000
X#endif
X	    if(psh->sh_flags & SHF_MIPS_GPREL) {
X		P(" SHF_MIPS_GPREL");
X	    }
X#ifndef SHF_MIPS_NOSTRIP
X#define SHF_MIPS_NOSTRIP        0x08000000
X#endif
X	    if(psh->sh_flags & SHF_MIPS_NOSTRIP) {
X		P(" SHF_MIPS_NOSTRIP");
X	    }
X#ifndef SHF_MIPS_MERGE
X#define SHF_MIPS_MERGE          0x20000000
X#endif
X	    if(psh->sh_flags & SHF_MIPS_MERGE) {
X		P(" SHF_MIPS_MERGE");
X	    }
X#ifndef SHF_MIPS_ADDR
X#define SHF_MIPS_ADDR           0x40000000
X#endif
X	    if(psh->sh_flags & SHF_MIPS_ADDR) {
X		P(" SHF_MIPS_ADDR");
X	    }
X#ifndef SHF_MIPS_STRINGS
X#define SHF_MIPS_STRINGS        0x80000000
X#endif
X	    if(psh->sh_flags & SHF_MIPS_STRINGS) {
X		P(" SHF_MIPS_STRINGS");
X	    }
X#ifndef SHF_MIPS_LOCAL
X#define SHF_MIPS_LOCAL          0x04000000
X#endif
X	    if(psh->sh_flags & SHF_MIPS_LOCAL) {
X		P(" SHF_MIPS_LOCAL");
X	    }
X#ifndef SHF_MIPS_NAMES
X#define SHF_MIPS_NAMES          0x02000000
X#endif
X	    if(psh->sh_flags & SHF_MIPS_NAMES) {
X		P(" SHF_MIPS_NAMES");
X	    }
X#ifndef SHF_MIPS_NODUPE
X#define SHF_MIPS_NODUPE         0x01000000
X#endif
X            if(psh->sh_flags & SHF_MIPS_NODUPE) {
X                P(" SHF_MIPS_NODUPE");
X            }
X	  }
X	  P("\n");
X	  P("\taddr 0x%llx %lld",(LONG64)psh->sh_addr,(LONG64)psh->sh_addr);
X	  P(" offset 0x%llx %lld",(LONG64)psh->sh_offset,
X			(LONG64)psh->sh_offset);
X	  P(", size %lld",(LONG64)psh->sh_size);
X	  P("\n");
X	  P("\tlink %lld",(LONG64)psh->sh_link);
X	  P(", info %lld",(LONG64)psh->sh_info);
X	  P(", align %lld",(LONG64)psh->sh_addralign);
X	  P(", entsize %lld",(LONG64)psh->sh_entsize);
X	  P("\n");
X          if(print_dynamic_section &&
X                0 == strcmp(SHSTRING(psh->sh_name),".dynamic")) {
X                if(elf_print_dynamic64(psh->sh_offset,psh->sh_size,i))
X                        return;
X          }
X
X
X	}
X	free(orig_psh);
X}
X
Xstatic
Xint
Xelf_print_dynamic64(ULONG64 offset,ULONG64 size, int sectionnum)
X{
X    ULONG64 ecount = 0;
X    ULONG64 size2 = 0;
X    ULONG64 i;
X    Elf64_Dyn *buffer;
X    ULONG64 trueoff = offset;
X	int res;
X
X#define PREFIX "\t"
X#define LUFMT "%llu"
X#define UFMT "%llu"
X#define DFMT "%lld"
X#define XFMT "0x%llx"
X
X    ecount = size/sizeof(Elf64_Dyn);
X    size2 = ecount * sizeof(Elf64_Dyn);
X    if(size != size2) {
X	P("Bogus size of dynamic. %llu not divisible by %llu\n",
X		(ULONG64 )size,(ULONG64 )sizeof(Elf64_Dyn));
X	return 0;
X    }
X
X    buffer = alloca(size);
X    
X    res = RR(buffer,offset,size);
X    if(res) {
X                P("could not read whole dynamic section of %s "
X		  "at offset %llu size %llu\n",
X			filename,
X			(ULONG64 )offset,(ULONG64 )size);
X                return 0;
X    }
X
X    if(ecount > 0) {
X      P("       offset  name     value\n");
X    }
X    for(i = 0; i < ecount; ++i,++buffer,trueoff += sizeof(Elf64_Dyn)) {
X	switch(buffer->d_tag) {
X	case  DT_NULL : 
X		P(PREFIX LUFMT ": DT_NULL "  LUFMT " end of dynamic array\n",
X			trueoff,buffer->d_un.d_ptr);
X		break;
X	case  DT_NEEDED       :
X		P(PREFIX LUFMT ": DT_NEEDED " DFMT " lib needed:\n",
X			trueoff,
X			buffer->d_un.d_val);
X		P("\t\t %s\n",
X			elf_shstrings_data + buffer->d_un.d_val);
X		break;
X	case  DT_PLTRELSZ     :
X		P(PREFIX LUFMT ": DT_PLTRELSZ " DFMT " size of reloc ent in proc linkage table:\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_PLTGOT       :
X		P(PREFIX LUFMT ": DT_PLTGOT " XFMT " GOT addr.\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_HASH         :
X		P(PREFIX LUFMT ": DT_HASH " XFMT " HASH addr.\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_STRTAB       :
X		P(PREFIX LUFMT ": DT_STRTAB " XFMT " stringtable addr \n",
X		 		trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_SYMTAB       :
X		P(PREFIX LUFMT ": DT_SYMTAB "
X			XFMT  " hashtable addr\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_RELA         :
X		P(PREFIX LUFMT ": DT_RELA "
X			XFMT " relocation table addr \n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_RELASZ       :
X		P(PREFIX LUFMT ": DT_RELASZ "
X			DFMT " relocation table size in bytes \n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_RELAENT      :
X		P(PREFIX LUFMT ": DT_RELAENT "
X			DFMT " relocation table entry size in bytes \n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_STRSZ        :
X		P(PREFIX LUFMT ": DT_STRSZ "
X			DFMT " string table size in bytes \n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_SYMENT       :
X		P(PREFIX LUFMT ": DT_SYMENT "
X			DFMT " symtab entry size in bytes \n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_INIT         :
X		P(PREFIX LUFMT ": DT_INIT "
X			XFMT " initialization func addr\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_FINI         :
X		P(PREFIX LUFMT ": DT_FINI "
X			XFMT " termination func addr\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_SONAME       :
X		P(PREFIX LUFMT ": DT_SONAME "
X			DFMT " so name offset \n",
X			trueoff,
X			buffer->d_un.d_val);
X		P("\t\t %s\n",
X			get_dynstr_string (buffer->d_un.d_val,sectionnum));
X		break;
X	case  DT_RPATH        :
X		P(PREFIX LUFMT ": DT_RPATH "
X			DFMT " library search path\n",
X			trueoff,
X			buffer->d_un.d_val);
X		P("\t\t %s\n",
X			get_dynstr_string (buffer->d_un.d_val,sectionnum));
X		break;
X	case  DT_SYMBOLIC     :
X		P(PREFIX LUFMT ": DT_SYMBOLIC "
X			DFMT " -B symbolic marked\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_REL          :
X		P(PREFIX LUFMT ": DT_REL "
X			XFMT " relocation table address\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_RELSZ        :
X		P(PREFIX LUFMT ": DT_RELSZ "
X			DFMT " relocation table size, bytes\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_RELENT       :
X		P(PREFIX LUFMT ": DT_RELENT "
X			DFMT " relocation table entry size, bytes\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case  DT_PLTREL       :
X		P(PREFIX LUFMT ": DT_PLTREL "
X			DFMT " relocation table type\n",
X			trueoff,
X			buffer->d_un.d_val);
X		P("\t\t %s is reloc type used\n",
X			(buffer->d_un.d_val == DT_REL)? "DT_REL" :
X			(buffer->d_un.d_val == DT_RELA)? "DT_RELA" :
X			"other?");
X		break;
X	case  DT_DEBUG        :
X		P(PREFIX LUFMT ": DT_DEBUG "
X			DFMT " unused.\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_TEXTREL      :
X		P(PREFIX LUFMT ": DT_TEXTREL "
X			DFMT " no relocs in read-only.\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case  DT_JMPREL       :
X		P(PREFIX LUFMT ": DT_JMPREL "
X			XFMT " address of proc. linkage table\n",
X			trueoff,
X			buffer->d_un.d_ptr);
X		break;
X	case DT_MIPS_RLD_VERSION :/*    0x70000001 */
X		P(PREFIX LUFMT ": DT_MIPS_RLD_VERSION "
X			DFMT " rld version\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case DT_MIPS_TIME_STAMP    :/*  0x70000002 */
X		{
X		time_t t;
X		P(PREFIX LUFMT ": DT_MIPS_TIME_STAMP "
X			XFMT " timestamp\n",
X			trueoff,
X			buffer->d_un.d_val);
X		t = (time_t)buffer->d_un.d_val;
X		P("\t\t %s\n",ctime(&t));
X		}
X		break;
X	case DT_MIPS_ICHECKSUM       :/*0x70000003 */
X		P(PREFIX LUFMT ": DT_MIPS_ICHECKSUM "
X			DFMT " string + common sum\n",
X			trueoff,
X			buffer->d_un.d_val);
X		break;
X	case DT_MIPS_IVERSION     :/*   0x70000004 */
X		P(PREFIX LUFMT ": DT_MIPS_IVERSION "
X			DFMT " string + common sum\n",
X			trueoff,
X			buffer->d_un.d_val);
X		if(buffer->d_un.d_val) {
X			P("\t\t %s\n",
X			get_dynstr_string (buffer->d_un.d_val,sectionnum));
X		}
X		break;
X	case DT_MIPS_FLAGS          :/* 0x70000005 */
X		P(PREFIX LUFMT ": DT_MIPS_FLAGS "
X			XFMT " flags\n",
X			trueoff,
X			buffer->d_un.d_val);
X		if(buffer->d_un.d_val) {
X		  long flags = (long)buffer->d_un.d_val;		
X		  if(flags& RHF_QUICKSTART) {
X			P("\t\t0x%x %s\n",RHF_QUICKSTART,"RHF_QUICKSTART");
X		  }
X		  if(flags& RHF_NOTPOT) {
X			P("\t\t0x%x %s\n",RHF_NOTPOT,"RHF_NOTPOT");
X		  }
X#ifndef LINUX
X		  if(flags& RHF_NO_LIBRARY_REPLACEMENT) {
X			P("\t\t0x%x %s\n",RHF_NO_LIBRARY_REPLACEMENT,"RHF_NO_LIBRARY_REPLACEMENT");
X		  }
X		  if(flags& RHF_NO_MOVE) {
X			P("\t\t0x%x %s\n",RHF_NO_MOVE,"RHF_NO_MOVE");
X		  }
X		  if(flags& RHF_SGI_ONLY) {
X			P("\t\t0x%x %s\n",RHF_SGI_ONLY,"RHF_SGI_ONLY");
X		  }
X		  if(flags& RHF_GUARANTEE_INIT) {
X			P("\t\t0x%x %s\n",RHF_GUARANTEE_INIT,"RHF_GUARANTEE_INIT");
X		  }
X		  if(flags& RHF_DELTA_C_PLUS_PLUS) {
X			P("\t\t0x%x %s\n",RHF_DELTA_C_PLUS_PLUS,"RHF_DELTA_C_PLUS_PLUS");
X		  }
X		  if(flags& RHF_GUARANTEE_START_INIT) {
X			P("\t\t0x%x %s\n",RHF_GUARANTEE_START_INIT,"RHF_GUARANTEE_START_INIT");
X		  }
X		  if(flags& RHF_PIXIE) {
X			P("\t\t0x%x %s\n",RHF_PIXIE,"RHF_PIXIE");
X		  }
X		  if(flags& RHF_DEFAULT_DELAY_LOAD) {
X			P("\t\t0x%x %s\n",RHF_DEFAULT_DELAY_LOAD,"RHF_DEFAULT_DELAY_LOAD");
X		  }
X		  if(flags& RHF_REQUICKSTART) {
X			P("\t\t0x%x %s\n",RHF_REQUICKSTART,"RHF_REQUICKSTART ok to requickstart");
X		  }
X		  if(flags& RHF_REQUICKSTARTED) {
X			P("\t\t0x%x %s\n",RHF_REQUICKSTARTED,"RHF_REQUICKSTARTED has been requickstarted");
X		  }
X		  if(flags& RHF_CORD) {
X			P("\t\t0x%x %s\n",RHF_CORD,"RHF_CORD");
X		  }
X		  if(flags& RHF_NO_UNRES_UNDEF) {
X			P("\t\t0x%x %s\n",RHF_NO_UNRES_UNDEF,"RHF_NO_UNRES_UNDEF");
X		  }
X		  if(flags& RHF_RLD_ORDER_SAFE) {
X			P("\t\t0x%x %s\n",RHF_RLD_ORDER_SAFE,"RHF_RLD_ORDER_SAFE");
X		  }
X#endif
X
X		}
X		break;
X	case DT_MIPS_BASE_ADDRESS:/*   0x70000006 */
X  		P(PREFIX LUFMT ": DT_MIPS_BASE_ADDRESS "
X                        XFMT " static link time/rqs address\n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X	case DT_MIPS_MSYM          : /*  0x70000007 */
X  		P(PREFIX LUFMT ": DT_MIPS_MSYM "
X                        XFMT " \n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X	case DT_MIPS_CONFLICT    : /*    0x70000008 */
X  		P(PREFIX LUFMT ": DT_MIPS_MSYM "
X                        XFMT " address of .conflict section \n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X	case DT_MIPS_LIBLIST  : /*       0x70000009 */
X  		P(PREFIX LUFMT ": DT_MIPS_LIBLIST "
X                        XFMT " address of .liblist section \n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X	case DT_MIPS_LOCAL_GOTNO : /*    0x7000000A */
X  		P(PREFIX LUFMT ": DT_MIPS_LOCAL_GOTNO "
X                        DFMT "  number of local got entries\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_CONFLICTNO : /*     0x7000000B */
X  		P(PREFIX LUFMT ": DT_MIPS_CONFLICTNO "
X                        DFMT "  number of .conflict section entries\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_LIBLISTNO   : /*    0x70000010 */
X  		P(PREFIX LUFMT ": DT_MIPS_LIBLISTNO "
X                        DFMT "  number of .liblist section entries\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_SYMTABNO  : /*      0x70000011 */
X  		P(PREFIX LUFMT ": DT_MIPS_SYMTABNO "
X                        DFMT "  number of .dynsym section entries\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_UNREFEXTNO   : /*   0x70000012 */
X  		P(PREFIX LUFMT ": DT_MIPS_UNREFEXTNO "
X                        DFMT "  index into .dynsym of first external not in this object\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_GOTSYM    : /*      0x70000013 */
X  		P(PREFIX LUFMT ": DT_MIPS_GOTSYM "
X                        DFMT "  index into .dynsym of first external in GOT\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_HIPAGENO    :/*    0x70000014 */
X  		P(PREFIX LUFMT ": DT_MIPS_HIPAGENO "
X                        DFMT " number of 64K page entries in GOT \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_RLD_MAP    :/*     0x70000016 */
X  		P(PREFIX LUFMT ": DT_MIPS_RLD_MAP "
X                        DFMT " \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X#ifdef DT_MIPS_DELTA_CLASS
X	case DT_MIPS_DELTA_CLASS  :/*     0x70000017 */      /* contains Delta C++ class definition */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_CLASS "
X                        DFMT " \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_DELTA_CLASS_NO :/*   0x70000018 */      /* the number of entries in DT_MIPS_DELTA_CLASS */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_CLASS_NO "
X                        DFMT " number of entries in delta class\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_DELTA_INSTANCE  :/*  0x70000019 */      /* contains Delta C++ class instances */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_INSTANCE "
X                        DFMT " \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_DELTA_INSTANCE_NO:/* 0x7000001A */      /* the number of entries in DT_MIPS_DELTA_INSTANCE */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_INSTANCE_NO "
X                        DFMT " number of entries in delta instance\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_DELTA_RELOC  :/*     0x7000001B */      /* contains Delta relocations */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_RELOC "
X                        DFMT " \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X	case DT_MIPS_DELTA_RELOC_NO :/*   0x7000001C */      /* the number of entries in DT_M */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_RELOC_NO "
X                        DFMT "  number of delta reloc entries\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X#endif /* DT_MIPS_DELTA_CLASS */
X
X#ifndef DT_MIPS_DELTA_SYM
X#define DT_MIPS_DELTA_SYM        0x7000001D
X#endif
X	case DT_MIPS_DELTA_SYM :/*0x7000001D */      /* contains Delta symbols that Delta relocations refer to */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_SYM "
X                        DFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X
X#ifndef DT_MIPS_DELTA_SYM_NO
X#define DT_MIPS_DELTA_SYM_NO     0x7000001E
X#endif
X	case DT_MIPS_DELTA_SYM_NO:/*      0x7000001E */      /* the number of entries in DT_M */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_SYM_NO "
X                        DFMT "  number of delta sym entries\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X
X#ifndef DT_MIPS_DELTA_CLASSSYM
X#define DT_MIPS_DELTA_CLASSSYM 0x70000020
X#endif
X	case DT_MIPS_DELTA_CLASSSYM:/*    0x70000020 */      /* contains Delta symbols that hold the class declaration */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_CLASSSYM "
X                        DFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X#ifndef DT_MIPS_DELTA_CLASSSYM_NO
X#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021
X#endif
X	case DT_MIPS_DELTA_CLASSSYM_NO:/* 0x70000021 */      /* the number of entries in DT_MIPS_DELTA_CLASSSYM */
X  		P(PREFIX LUFMT ": DT_MIPS_DELTA_CLASSSYM_NO "
X                        DFMT "  number of delta class sym entries\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_CXX_FLAGS
X#define DT_MIPS_CXX_FLAGS 0x70000022
X#endif
X	case   DT_MIPS_CXX_FLAGS      :/* 0x70000022 */      /* Flags indicating information about C++ flavor */
X  		P(PREFIX LUFMT ": DT_MIPS_CXX_FLAGS "
X                        XFMT "  c++ flags\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_PIXIE_INIT
X#define  DT_MIPS_PIXIE_INIT 0x70000023
X#endif
X	case   DT_MIPS_PIXIE_INIT    :/*  0x70000023 */
X  		P(PREFIX LUFMT ": DT_MIPS_PIXIE_INIT "
X                        XFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_SYMBOL_LIB
X#define  DT_MIPS_SYMBOL_LIB      0x70000024
X#endif
X	case   DT_MIPS_SYMBOL_LIB    :/*  0x70000024 */
X  		P(PREFIX LUFMT ": DT_MIPS_SYMBOL_LIB "
X                        XFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_LOCALPAGE_GOTIDX
X#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
X#endif
X	case DT_MIPS_LOCALPAGE_GOTIDX :/* 0x70000025 */
X  		P(PREFIX LUFMT ": DT_MIPS_LOCALPAGE_GOTIDX "
X                        XFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_LOCAL_GOTIDX
X#define DT_MIPS_LOCAL_GOTIDX     0x70000026
X#endif
X	case DT_MIPS_LOCAL_GOTIDX    :/*  0x70000026 */
X  		P(PREFIX LUFMT ": DT_MIPS_LOCAL_GOTIDX "
X                        XFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_HIDDEN_GOTIDX
X#define DT_MIPS_HIDDEN_GOTIDX    0x70000027
X#endif
X	case DT_MIPS_HIDDEN_GOTIDX   :/*  0x70000027 */
X  		P(PREFIX LUFMT ": DT_MIPS_HIDDEN_GOTIDX "
X                        XFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_PROTECTED_GOTIDX
X#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
X#endif
X	case DT_MIPS_PROTECTED_GOTIDX :/* 0x70000028 */
X  		P(PREFIX LUFMT ": DT_MIPS_PROTECTED_GOTIDX "
X                        XFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_OPTIONS
X#define DT_MIPS_OPTIONS          0x70000029
X#endif
X	case DT_MIPS_OPTIONS          :/* 0x70000029  */     /* Address of .options */
X  		P(PREFIX LUFMT ": DT_MIPS_OPTIONS "
X                        XFMT "  address of .options \n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X
X#ifndef DT_MIPS_INTERFACE
X#define DT_MIPS_INTERFACE        0x7000002a
X#endif
X	case DT_MIPS_INTERFACE :/*0x7000002a */      /* Address of .interface */
X  		P(PREFIX LUFMT ":  DT_MIPS_INTERFACE "
X                        XFMT "  address of .interface \n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X
X#ifndef DT_MIPS_DYNSTR_ALIGN
X#define DT_MIPS_DYNSTR_ALIGN     0x7000002b
X#endif
X	case DT_MIPS_DYNSTR_ALIGN :/*     0x7000002b */
X  		P(PREFIX LUFMT ":  DT_MIPS_DYNSTR_ALIGN "
X                        DFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_INTERFACE_SIZE
X#define DT_MIPS_INTERFACE_SIZE   0x7000002c
X#endif
X	case DT_MIPS_INTERFACE_SIZE :/*   0x7000002c */      /* size of the .interface sec. */
X  		P(PREFIX LUFMT ":  DT_MIPS_INTERFACE_SIZE "
X                        DFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_RLD_TEXT_RESOLVE_ADDR
X#define  DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d 
X#endif
X	case   DT_MIPS_RLD_TEXT_RESOLVE_ADDR:/* 0x7000002d */    /* Address of rld_text_rsolve function stored in the got */
X  		P(PREFIX LUFMT ":  DT_MIPS_RLD_TEXT_RESOLVE_ADDR "
X                        XFMT "  address of rld_text_resolve func stored in got\n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X
X#ifndef DT_MIPS_PERF_SUFFIX
X#define  DT_MIPS_PERF_SUFFIX     0x7000002e
X#endif
X	case   DT_MIPS_PERF_SUFFIX  :/*   0x7000002e */      /* Default suffix of dso to be added by */
X  		P(PREFIX LUFMT ":  DT_MIPS_PERF_SUFFIX "
X                        DFMT "  \n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_COMPACT_SIZE
X#define DT_MIPS_COMPACT_SIZE     0x7000002f
X#endif
X	case DT_MIPS_COMPACT_SIZE    :/*  0x7000002f */      /* (O32)Size of compact rel scn */
X  		P(PREFIX LUFMT ":  DT_MIPS_COMPACT_SIZE "
X                        DFMT "  size of compact rel section\n",
X                        trueoff,
X                        buffer->d_un.d_val);
X		break;
X
X#ifndef DT_MIPS_GP_VALUE
X#define DT_MIPS_GP_VALUE 0x70000030
X#endif
X	case DT_MIPS_GP_VALUE :/* 0x70000030 */      /* gp value for aux gots */
X  		P(PREFIX LUFMT ":  DT_MIPS_GP_VALUE "
X                        XFMT "  gp val for aux gots\n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X
X
X#ifndef  DT_MIPS_AUX_DYNAMIC
X#define DT_MIPS_AUX_DYNAMIC  0x70000031
X#endif
X	case DT_MIPS_AUX_DYNAMIC  :/*     0x70000031 */      /* Address of aux .dynamic */
X  		P(PREFIX LUFMT ":  DT_MIPS_AUX_DYNAMIC "
X                        XFMT "  address of aux .dynamic\n",
X                        trueoff,
X                        buffer->d_un.d_ptr);
X		break;
X
X
X	default:
X  		P(PREFIX LUFMT ": unknown tag 0x%lx "
X                        DFMT " \n",
X                        trueoff,
X			(unsigned long)buffer->d_tag,
X                        buffer->d_un.d_val);
X		break;
X	}
X	
X	
X     
X
X    }
X
X    return 0;
X}
X
X#endif /* HAS_ELFHDR64 */
Xchar *get_shtypestring(LONGESTUTYPE x)
X{
X	int lim = sizeof(shstrings)/sizeof(shstrings[0]);
X	int i;
X
X	for(i = 0; i < lim; i++) {
X	   if(shstrings[i].bits == x) {
X		return shstrings[i].name;
X	   }
X	}
X	return( "<unknowntype>");
X}
X
SHAR_EOF
fi # end of overwriting check
if test -f 'readobj.h'
then
	echo shar: will not over-write existing file "'readobj.h'"
else
sed 's/^X//' << \SHAR_EOF > 'readobj.h'
X/*
X
X	readobj.h
X
X*/
X#ifdef __sgi
X#define LONGESTXFMT "0x%llx"
X#define LONGESTUTYPE unsigned long long
X#define LONGESTSTYPE long long
X#else
X#define LONGESTXFMT "0x%lx"
X#define LONGESTUTYPE unsigned long
X#define LONGESTSTYPE long
X#endif
X
Xextern char *filename;
Xextern FILE *fin;
Xextern char *getshstring(LONGESTUTYPE sectype);
SHAR_EOF
fi # end of overwriting check
if test -f 'readobj64.h'
then
	echo shar: will not over-write existing file "'readobj64.h'"
else
sed 's/^X//' << \SHAR_EOF > 'readobj64.h'
X/*
X
X	readobj64.h
X
X
X*/
X
X
X#ifdef HAS_ELFHDR64
Xvoid do_elf_file64(char *s);
X#endif
X
Xchar *get_shtypestring(LONGESTUTYPE x);
X
X
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0