Please consider a donation to the Higher Intellect project. See https://preterhuman.net/donate.php or the Donate to Higher Intellect page for more info. |
Optionalsym.shar
Jump to navigation
Jump to search
#! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # optionalsym.c # Makefile # optionalsym64.c # optionalsym.h # optionalsym64.h # This archive created: Wed Feb 16 10:47:23 2000 export PATH; PATH=/bin:$PATH if test -f 'optionalsym.c' then echo shar: will not over-write existing file "'optionalsym.c'" else sed 's/^X//' << \SHAR_EOF > 'optionalsym.c' X X/* X This program both reports on and sets X the st_other field in symbols. X It focuses on the STO_OPTIONAL flag of the st_other field. X X X Usage: X optionalsym [-v <selectname>] X [-p] X [-u <updateto>] X [-y symname [ -y symname]] X file ... X X If -u supplied, selected symbols have their X st_other field updated to contain the -u value. X For example: X -u STO_OPTIONAL X Legal values for the <updateto> X are STO_DEFAULT STO_INTERNAL STO_HIDDEN X STO_PROTECTED STO_OPTIONAL X If multiple -u are supplied the last is actually used. X X X If -p supplied, selected symbols are printed X (if -u also suppled, the symbol X is printed before updating) X If -u is not supplied, -p is assumed. X X -v <selectname> X selects symbols with st_other having that value. X optionalsymbol -v STO_OPTIONAL -p t.o X prints all symbols marked STO_OPTIONAL. X The <selectname> may be any of the STO* mentioned above. X If multiple -v are supplied the last is actually used. X X -y symname X selects a symbol with the name "symname". X If multiple -y options are given each name in X the set of names is selected. X X If both -u and -y are given, symbols must have X BOTH the <selectname> and any one of the X symbol names to be selected. X X XWritten March 1997 by David B. Anderson Silicon Graphics. X [email protected] X XFor general distribution to anyone who is interested. X XIt's a hack :-) X X*/ X X X X#include <stdio.h> X#include <stdlib.h> X#include <a.out.h> X#include <malloc.h> X#include <alloca.h> X#include <string.h> X#include <time.h> X#include "optionalsym.h" X#include <elf_abi.h> X#include <elf_mips.h> X#include <elf.h> X#include "optionalsym64.h" X X X#define USHORT unsigned short Xstatic void dofile(char *); Xstatic void do_elf_file(char *); Xstatic void elf_get_section_table_strings(unsigned long, X unsigned long, unsigned long, unsigned long); Xstatic char * get_dynstr_string(unsigned long offset, int index); Xstatic void elf_get_symstrings(unsigned long offset, X unsigned long entsize,unsigned long count , X unsigned stringsecnum); Xstatic void elf_ck_dynsym(unsigned long offset,unsigned X long size, int symstr_index); Xstatic int get_symtab_section(unsigned long offset, X unsigned long entsize, X unsigned long count); X Xint symbol_header_printed; X X Xstatic void add_desired_symbol(char *name); X X Xchar *Usage = X"Usage: optionalsym -v <selectname> -p -u <updateto> -y <symname> file ..."; X X#define P printf X#define F fflush(stdout) X#define RR(buf,loc,siz) ((fseek(fin,loc,0)<0) ? -1 : \ X ((fread(buf,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,i,SEEK_SET)) X X Xstatic struct filehdr fhdr; X Xstatic Elf32_Ehdr ehdr; X Xchar *filename; X X Xstatic char *elf_shstrings_data; /* section name strings */ Xstatic long elf_shstrings_length; X /* length of currentsection. Might be zero..*/ X Xstatic long elf_shstrings_max; /* size of malloc-d space */ X Xstatic char *dynamic_sect_strings; Xstatic long dynamic_sect_strings_length; Xstatic int dynamic_sect_strings_sect_index; X Xstruct a_desired_symbol *ds_array; Xlong ds_next_to_use; X /* ds_next_to_use is the count of the number of names X supplied with -y flags X */ Xlong ds_allocated_count; X /* ds_allocated_count is the number of structs X malloc-d X */ X X/* the -v value, as a name and an integer. X name 0 unless -v supplied. X*/ Xint value_search; Xchar *value_search_name; X X/* The -u value, as a name and an integer. X Name 0 unless -u supplied. X*/ Xint new_value; Xchar * new_value_name; X Xint printsymbols; Xstatic int saw_dash_p; X XFILE *fin; X Xstruct sto_xlate_s X{ X char *sx_name; X int sx_val; X} sto_xlate_data[] = { X{"STO_DEFAULT",STO_DEFAULT}, X{"STO_INTERNAL",STO_INTERNAL}, X{"STO_HIDDEN",STO_HIDDEN}, X{"STO_PROTECTED",STO_PROTECTED}, X{"STO_OPTIONAL",STO_OPTIONAL}, X{0,0} X}; X Xstatic int Xst_other_to_int(char *option,char *name) X{ X int i; X for( i = 0 ; sto_xlate_data[i].sx_name; ++i) { X if(streq(sto_xlate_data[i].sx_name,name)) { X return sto_xlate_data[i].sx_val; X } X } X fprintf(stderr," \"%s\" not valid in \"%s %s\"\n", X name,option,name); X exit(1); X /*NOTREACHED*/ X} X Xint Xmain(int argc,char **argv) X{ X int i; X int turn_off_options = 0; X X if( argc == 1) { X printf("%s\n",Usage); X exit(1); X } else { X argv++; X for(i =1;turn_off_options == 0 && i<argc; i++,argv++) { X if(strcmp(argv[0],"--") == 0) { X turn_off_options = 1; X continue; X } X if(strcmp(argv[0],"-p") == 0) { X printsymbols = 1; X saw_dash_p = 1; X continue; X } X if(strcmp(argv[0],"-v") == 0) { X i++; X argv++; X if(i >= argc) { X fprintf(stderr, X "-v cannot be the last option!\n"); X exit(1); X X } X value_search_name = argv[0]; X value_search = st_other_to_int("-v", X value_search_name); X continue; X } X if(strcmp(argv[0],"-u") == 0) { X i++; X argv++; X if(i >= argc) { X fprintf(stderr, X "-u cannot be the last option!\n"); X exit(1); X X } X new_value_name = argv[0]; X new_value = st_other_to_int("-u", X new_value_name); X X continue; X } X if(strcmp(argv[0],"-y") == 0) { X i++; X argv++; X if(i >= argc) { X fprintf(stderr, X "-y cannot be the last option!\n"); X exit(1); X X } X add_desired_symbol(argv[0]); X X continue; X } X /* The rest must be file names */ X break; X } X X /* print if -p or if not updating. X */ X if(saw_dash_p) { X printsymbols=1; X } else if (!new_value_name) { X printsymbols=1; X } X for( ; i<argc; i++,argv++) { X char *opentype = "r"; X if(new_value_name) X opentype = "r+b"; X fin = fopen(argv[0],opentype); X if(fin == NULL) { X printf( X "No such file as %s or cannot open read-only\n", X argv[0]); X continue; X } X filename = argv[0]; X printf("%s:\n",filename); 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 X res = RR(&fhdr,0,sizeof(fhdr)); X if(res) { X P("could not read whole file header of %s\n", X filename); X return; X } X memcpy((void *)&ehdr,(void *)&fhdr,sizeof(ehdr)); X if(IS_ELF(ehdr)) { X do_elf_file(s); X return; X } X P("We don't do COFF files\n"); X F; X} X Xstatic void Xdo_elf_file(char *s) X{ 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", X 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 X elf_get_section_table_strings(ehdr.e_shoff, X ehdr.e_shentsize,ehdr.e_shnum,ehdr.e_shstrndx); X if(elf_shstrings_data == 0) { X return; X } X X get_symtab_section(ehdr.e_shoff,ehdr.e_shentsize,ehdr.e_shnum); X X X return; 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_symstrings(unsigned long offset, X unsigned long entsize,unsigned long count, X unsigned stringsecnum ) X{ X int i; X Elf32_Shdr *psh; X Elf32_Shdr *orig_psh; X 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 < 0) { X P("\tcurrent loc unknown/error in ftell?????\n"); X return; X } X i =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", X 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 count*entsize); X return; X } X X X i = stringsecnum; X psh = (Elf32_Shdr *)((char *)psh + (entsize*stringsecnum)); X dynamic_sect_strings_sect_index = i; X dynamic_sect_strings_length = psh->sh_size; X if(dynamic_sect_strings) { X free(dynamic_sect_strings); X } 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 section %ld strings at %llx\n", X (long)stringsecnum, X (long long)psh->sh_offset); X dynamic_sect_strings = 0; X dynamic_sect_strings_length = 0; X dynamic_sect_strings_sect_index = 0; X seekres =SEEKTO(curloc); X if(seekres) { X P("Seek back to %ld after reading sect headers failed\n", X curloc); X } X return; X } X i =SEEKTO(curloc); X if(i) { X P("Seek to %ld after reading sect headers failed\n",offset); X return; X } X} Xstatic char * Xget_dynstr_string(unsigned long offset, int index) X{ X char *retval; 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 retval ="dynamic section link does not match" X " section of dynamic strings"; X return retval; 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 Xstatic void Xelf_get_section_table_strings(unsigned long offset, X unsigned long entsize, X unsigned long count, X 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 =SEEKTO(offset + entsize*stringsection); X if(i) { X P("Seek to %ld to read string section header failed\n", X 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", X entsize); X return; X } X orig_psh = psh; X i = RN(psh,entsize); X if(i) { X P("read string section header failed\n"); 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 i =SEEKTO(psh->sh_offset); X if(i) { X P("Seek to %ld string section data failed\n", X 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 of string space!\n", X (long)psh->sh_size); X return; 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", X elf_shstrings_length); X elf_shstrings_length = 0; X return; X } X free(orig_psh); X} X X Xstatic int Xget_symtab_section(unsigned long offset, X unsigned long entsize,unsigned long count) X{ 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 return 0; X } X if(count == 0) { X P("No section headers\n"); X return 0; X } X i =SEEKTO(offset); X if(i) { X P("Seek to %ld to read section headers failed\n",offset); X return 0; X } X psh = (Elf32_Shdr *)malloc(count * entsize); X if(psh == 0) { X P("malloc to %ld bytes of section header space failed\n", X count *entsize); X return 0; 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 count*entsize); X return 0; X } X X for(i = 0; i < count; X i++, psh = (Elf32_Shdr *) ((char *)psh + entsize)) { X namestr = SHSTRING(psh->sh_name); X if( 0 == strcmp(namestr,".dynsym")) { X symbol_header_printed = 0; X elf_get_symstrings(ehdr.e_shoff,ehdr.e_shentsize, X ehdr.e_shnum, X psh->sh_link); X elf_ck_dynsym(psh->sh_offset,psh->sh_size,psh->sh_link); X continue; X } X if( 0 == strcmp(namestr,".symtab")) { X symbol_header_printed = 0; X elf_get_symstrings(ehdr.e_shoff,ehdr.e_shentsize, X ehdr.e_shnum, X psh->sh_link); X elf_ck_dynsym(psh->sh_offset,psh->sh_size,psh->sh_link); X continue; X } X } X free(orig_psh); X return 0; X} X Xvoid Xprint_a_symbol(unsigned int nameindex, X unsigned long long value, X unsigned long long size, X unsigned char info, X unsigned char other, X unsigned short shndx, X char * symname) X{ X if(!symbol_header_printed) { X P("nameindx :value :size :info bind type :other :sectindex :name\n"); X symbol_header_printed = 1; X } X P("%6d ",nameindex); X P(":0x%-8llx ",(unsigned long long)value); X P(":0x%-4llx ",(unsigned long long)size); X P(":0x%02x ",info); X P("0x%02x ",ELF64_ST_BIND(info)); X if(ELF64_ST_BIND(info) == STB_LOCAL) { X P("STB_LOCAL "); X } else if(ELF64_ST_BIND(info) == STB_GLOBAL) { X P("STB_GLOBAL "); X } else if(ELF64_ST_BIND(info) == STB_WEAK) { X P("STB_WEAK "); X } X P("0x%02x ",ELF64_ST_TYPE(info)); X if(ELF64_ST_TYPE(info) == STT_NOTYPE) { X P("STT_NOTYPE "); X } else if(ELF64_ST_TYPE(info) == STT_OBJECT) { X P("STT_OBJECT "); X } else if(ELF64_ST_TYPE(info) == STT_FUNC) { X P("STT_FUNC "); X } else if(ELF64_ST_TYPE(info) == STT_SECTION) { X P("STT_SECTION "); X } else if(ELF64_ST_TYPE(info) == STT_FILE) { X P("STT_FILE "); X } X P(":0x%02x ",other); X if(other == STO_DEFAULT) X P("STO_DEFAULT "); X if(other == STO_INTERNAL) X P("STO_INTERNAL "); X if(other == STO_HIDDEN) X P("STO_HIDDEN "); X if(other == STO_PROTECTED) X P("STO_PROTECTED "); X if(other == STO_OPTIONAL) X P("STO_OPTIONAL "); X P(":%-4d ",shndx); X if(shndx == SHN_UNDEF) { X P("SHN_UNDEF "); X } X if(shndx == SHN_ABS) { X P("SHN_ABS "); X } X if(shndx == SHN_COMMON) { X P("SHN_COMMON "); X } X if(shndx == SHN_MIPS_ACOMMON) { X P("SHN_MIPS_ACOMMON "); X } X if(shndx == SHN_MIPS_TEXT) { X P("SHN_MIPS_TEXT "); X } X if(shndx == SHN_MIPS_DATA) { X P("SHN_MIPS_DATA "); X } X if(shndx == SHN_MIPS_SCOMMON) { X P("SHN_MIPS_SCOMMON "); X } X if(shndx == SHN_MIPS_SUNDEFINED) { X P("SHN_MIPS_SUNDEFINED "); X } X P(":%s",symname); X P("\n"); X} X X/* X Handle one symbol. X*/ X/*ARGSUSED*/ Xstatic void Xhandle_one_symbol(Elf32_Sym *symp,long symindx, X int symstr_index,long *modify_count) X{ X char *symname; X X symname = get_dynstr_string(symp->st_name,symstr_index); X X if(value_search_name) { X if (value_search != symp->st_other) { X return; X } X if(ds_next_to_use > 0) { X if(!interesting_name(symname)) { X return; X } X } X } else { X if(ds_next_to_use > 0) { X if(!interesting_name(symname)) { X return; X } X } else { X /* nothing asked for! */ X return; X } X } X X /* we have not discarded the entry so do something with/to it X */ X if(printsymbols) { X print_a_symbol(symp->st_name, X symp->st_value, X symp->st_size, X symp->st_info, X symp->st_other, X symp->st_shndx, X symname); X } X if(new_value_name) { X symp->st_other = new_value; X *modify_count += 1; X } X X} Xstatic void Xelf_ck_dynsym(unsigned long offset,unsigned X long size, int symstr_index) X X{ X long ecount = 0; X unsigned long size2 = 0; X unsigned long i; X Elf32_Sym *origbuffer; X Elf32_Sym *buffer; X int res; X long modify_count = 0; X X ecount = 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 ; 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 ; X } X origbuffer = buffer; X X X for(i = 0; i < ecount; ++i,++buffer) { X handle_one_symbol(buffer,i,symstr_index,&modify_count); X } X if(modify_count > 0) { X size_t res; X res =SEEKTO(offset); X if(res) { X P("Seek to %ld to prepare write section failed\n", X offset); X return; X } X res =fwrite(origbuffer,size,1,fin); X if(res != 1) { X P("Unable to write back section: fwrite returned %d\n",res); X return; X } X fflush(fin); X } X X X return ; X} X Xstatic void Xadd_desired_symbol(char *name) X{ X if(ds_array == 0) { X ds_allocated_count = DS_INITIAL_ALLOC; X ds_array = malloc(sizeof(struct a_desired_symbol)* X ds_allocated_count); X if(ds_array == 0) { X fprintf(stderr, X "Unable to malloc %ld bytes for desired symbol array\n", X (long)sizeof(struct a_desired_symbol)* X ds_allocated_count); X exit(1); X } X } X if(ds_next_to_use >= ds_allocated_count) { X struct a_desired_symbol * ds_arrayl; X ds_allocated_count += DS_ADDITIONAL_ALLOC; X ds_arrayl = realloc(ds_array,sizeof(struct a_desired_symbol)* X ds_allocated_count); X if(ds_arrayl == 0) { X fprintf(stderr, X "Unable to realloc %ld bytes for desired symbol array\n", X (long)sizeof(struct a_desired_symbol)* X ds_allocated_count); X exit(1); X } X ds_array = ds_arrayl; X } X ds_array[ds_next_to_use].ds_name = name; X ++ds_next_to_use; X} X X X/* XReturn 1 if the name is in the list of names as -y options. XReturn 0 otherwise. X*/ Xint Xinteresting_name(char *name) X{ X long i; X X for (i = 0; i < ds_next_to_use; ++i) { X if(streq(ds_array[i].ds_name,name)) { X return 1; X } X } X return 0; X X} 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# Add -fullwarn for full checking XCFLAGS = -g -DHAS_ELFHDR64 X Xall: optionalsym Xshar: X shar -p X optionalsym.c Makefile optionalsym64.c \ X optionalsym.h optionalsym64.h \ X >/d2/public/optionalsym.shar X X Xoptionalsym: optionalsym.o optionalsym64.o X $(CC) $(CFLAGS) -g optionalsym.o optionalsym64.o -o optionalsym Xclobber: X -rm *.o X -rm optionalsym X -rm core a.out X SHAR_EOF fi # end of overwriting check if test -f 'optionalsym64.c' then echo shar: will not over-write existing file "'optionalsym64.c'" else sed 's/^X//' << \SHAR_EOF > 'optionalsym64.c' X X/* X optionalsym64.c X X For handling 64-bit elf objects. X X*/ X X#include <stdio.h> X#include <stdlib.h> X#include <a.out.h> X#include <malloc.h> X#include <string.h> X#include <alloca.h> X#include "optionalsym.h" X#ifdef HAS_ELFHDR64 X#include <elf_abi.h> X#include <elf_mips.h> X#endif X#include <elf.h> X#include "optionalsym64.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,loc,0)<0) ? -1 : \ X ((fread(buf,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,i,SEEK_SET)) X Xtypedef unsigned long long ULONG64; Xtypedef long long LONG64; X Xstatic void elf_get_section_table_strings(ULONG64 offset, X ULONG64 entsize,ULONG64 count,ULONG64 stringsection); Xstatic char * get_dynstr_string(ULONG64 offset, int index); Xstatic void elf_get_symstrings(ULONG64 offset, ULONG64 entsize, ULONG64 count, X unsigned sec_strings_index); Xstatic void elf_ck_dynsym64(unsigned long offset,unsigned X long size, int symstr_index); Xstatic int get_symtab_section(unsigned long offset, X unsigned long entsize,unsigned long count); X X X#ifdef HAS_ELFHDR64 Xstatic Elf64_Ehdr ehdr; Xstatic void handle_one_symbol(Elf64_Sym *symp,long symindx, X int symstr_index,long *modify_count); X#endif X X X Xstatic char *elf_shstrings_data; /* section name strings */ Xstatic long elf_shstrings_length; /* length of currentsection. Might be zero..*/ Xstatic 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 X#ifdef HAS_ELFHDR64 Xvoid Xdo_elf_file64(char *s) X{ X int res; 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 elf_get_section_table_strings(ehdr.e_shoff, X ehdr.e_shentsize,ehdr.e_shnum,ehdr.e_shstrndx); X if(elf_shstrings_data == 0) { X return; X } X get_symtab_section(ehdr.e_shoff,ehdr.e_shentsize,ehdr.e_shnum); X} X X Xstatic void Xelf_get_section_table_strings(ULONG64 offset,ULONG64 entsize, X 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 =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\n"); 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 i =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 = psh->sh_size; X if(elf_shstrings_data == 0) { X elf_shstrings_max = 0; X P("Unable to malloc %ld bytes of string space!\n", X (long)psh->sh_size); X return; X } X X } X elf_shstrings_length = 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 SHSTRING(x) ((elf_shstrings_length > (x)) ? \ X (x) + elf_shstrings_data : \ X "Invalid sh_name value") Xstatic void Xelf_get_symstrings(ULONG64 offset, ULONG64 entsize, ULONG64 count, X unsigned stringsecnum) X{ X int i; X Elf64_Shdr *psh; X Elf64_Shdr *orig_psh; X long 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 < 0) { X P("\tcurrent loc unknown/error error in ftell?\n"); X return; X } X i =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 i = stringsecnum; X psh = (Elf64_Shdr *)((char *)psh + (entsize*stringsecnum)); X dynamic_sect_strings_sect_index = i; X dynamic_sect_strings_length = psh->sh_size; X if(dynamic_sect_strings) { X free(dynamic_sect_strings); X } 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 section %ld strings at %llx\n", X (long)stringsecnum, X (long long)psh->sh_offset); X dynamic_sect_strings = 0; X dynamic_sect_strings_length = 0; X dynamic_sect_strings_sect_index = 0; X seekres =SEEKTO(curloc); X if(seekres) { X P("Seek back to %ld after reading sect headers failed\n", X (long)curloc); X } X return; X } X i =SEEKTO(curloc); X if(i) { X P("Seek to %ld after reading sect headers failed\n", X (long)offset); X return; X } X 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 X X Xstatic int Xget_symtab_section(unsigned long offset,unsigned long entsize,unsigned long count) X{ X X int i; X Elf64_Shdr *psh; X Elf64_Shdr *orig_psh; X char *namestr; X X X if(entsize < sizeof(Elf64_Shdr)) { X P("Elf Section header too small? %ld vs %ld\n", X entsize,(unsigned long)sizeof(Elf64_Shdr)); X return 0; X } X if(count == 0) { X P("No section headers\n"); X return 0; X } X i =SEEKTO(offset); X if(i) { X P("Seek to %ld to read section headers failed\n",offset); X return 0; X } X psh = (Elf64_Shdr *)malloc(count * entsize); X if(psh == 0) { X P("malloc to %ld bytes of section header space failed\n",count *entsize); X return 0; 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 0; X } X X for(i = 0; i < count; X i++, psh = (Elf64_Shdr *) ((char *)psh + entsize)) { X namestr = SHSTRING(psh->sh_name); X if( 0 == strcmp(namestr,".dynsym")) { X elf_get_symstrings(ehdr.e_shoff,ehdr.e_shentsize, X ehdr.e_shnum, X psh->sh_link); X elf_ck_dynsym64(psh->sh_offset,psh->sh_size,psh->sh_link); X continue; X } X if( 0 == strcmp(namestr,".symtab")) { X elf_get_symstrings(ehdr.e_shoff,ehdr.e_shentsize, X ehdr.e_shnum, X psh->sh_link); X elf_ck_dynsym64(psh->sh_offset,psh->sh_size,psh->sh_link); X continue; X } X } X free(orig_psh); X return 0; X} X Xstatic void Xelf_ck_dynsym64(unsigned long offset,unsigned X long size, int symstr_index) X X{ X long ecount = 0; X unsigned long size2 = 0; X unsigned long i; X Elf64_Sym *origbuffer; X Elf64_Sym *buffer; X int res; X long modify_count = 0; X X ecount = size/sizeof(Elf64_Sym); X size2 = ecount * sizeof(Elf64_Sym); X if(size != size2) { X P("Bogus size of symbols. %lu not divisible by %lu\n", X size,(unsigned long)sizeof(Elf64_Sym)); X return ; X } X X buffer = alloca(size); X X res = RR(buffer,offset,size); X if(res) { X P("could not read whole dynsym section of %s " X "at offset %lu size %lu\n", X filename, X offset,size); X return ; X } X origbuffer = buffer; X X for(i = 0; i < ecount; ++i,++buffer) { X handle_one_symbol(buffer,i,symstr_index,&modify_count); X } X if(modify_count > 0) { X size_t res; X res =SEEKTO(offset); X if(res) { X P("Seek to %ld to prepare write section failed\n", X offset); X return; X } X res =fwrite(origbuffer,size,1,fin); X if(res != 1) { X P("Unable to write back section: fwrite returned %d\n",res); X return; X } X fflush(fin); X } X X X return; X} X X/* X Handle one symbol. X*/ X/*ARGSUSED*/ Xstatic void Xhandle_one_symbol(Elf64_Sym *symp,long symindx, X int symstr_index,long *modify_count) X{ X char *symname; X X symname = get_dynstr_string(symp->st_name,symstr_index); X X if(value_search_name) { X if (value_search != symp->st_other) { X return; X } X if(ds_next_to_use > 0) { X if(!interesting_name(symname)) { X return; X } X } X } else { X if(ds_next_to_use > 0) { X if(!interesting_name(symname)) { X return; X } X } else { X /* nothing asked for! */ X return; X } X } X X /* we have not discarded the entry so do something with/to it X */ X if(printsymbols) { X print_a_symbol(symp->st_name, X symp->st_value, X symp->st_size, X symp->st_info, X symp->st_other, X symp->st_shndx, X symname); X } X if(new_value_name) { X symp->st_other = new_value; X *modify_count += 1; X } X X} X#endif /* HAS_ELFHDR64 */ SHAR_EOF fi # end of overwriting check if test -f 'optionalsym.h' then echo shar: will not over-write existing file "'optionalsym.h'" else sed 's/^X//' << \SHAR_EOF > 'optionalsym.h' X/* X X optionalsym.h X X*/ Xextern char *filename; Xextern FILE *fin; Xextern char *getshstring(long long sectype); Xextern int printsymbols; Xextern void print_a_symbol(unsigned int nameindex, X unsigned long long value, X unsigned long long size, X unsigned char info, X unsigned char other, X unsigned short shndx, X char * symname); Xint interesting_name(char *name); X#define streq(_a,_b) (strcmp(_a,_b) == 0) X X/* the following is mostly for the X -ya -yb etc X list of symbols-to-select X*/ Xtypedef struct a_desired_symbol X{ X char * ds_name; X} a_desired_symbol; X X/* X We'll build an array, each entry a X struct a_desired_symbol X*/ Xextern struct a_desired_symbol *ds_array; Xextern long ds_next_to_use; X /* ds_next_to_use is the count of the number of names X supplied with -y flags X */ Xextern long ds_allocated_count; X /* ds_allocated_count is the number of structs X malloc-d X */ X#define DS_INITIAL_ALLOC 10 X#define DS_ADDITIONAL_ALLOC 10 X X/* the -v value, as a name and an integer. X name 0 unless -v supplied. X*/ Xextern int value_search; Xextern char *value_search_name; X X/* The -u value, as a name and an integer. X Name 0 unless -u supplied. X*/ Xextern int new_value; Xextern char * new_value_name; X X#ifndef STO_OPTIONAL X#define STO_OPTIONAL 4 X#endif SHAR_EOF fi # end of overwriting check if test -f 'optionalsym64.h' then echo shar: will not over-write existing file "'optionalsym64.h'" else sed 's/^X//' << \SHAR_EOF > 'optionalsym64.h' X/* X X optionalsym64.h X X X*/ X X X#ifdef HAS_ELFHDR64 Xvoid do_elf_file64(char *s); X#endif X Xchar *get_shtypestring(long long x); X X SHAR_EOF fi # end of overwriting check # End of shell archive exit 0