home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <powerpc/powerpc.h>
- #include <proto/powerpc.h>
- #include "elf/external.h"
- #include "elf/common.h"
- #include "symbols.h"
- #include "error.h"
-
- void print_symbols(PElfObject *);
-
- int add_symbol_sect(PElfObject *obj,unsigned long i)
- {
- int n;
- int symbolsnum=obj->sections[i].size/sizeof(Elf32_External_Sym);
- Elf32_External_Sym *symtab=(Elf32_External_Sym *)obj->sections[i].elfadr;
- char *strings=obj->sections[obj->sections[i].link].elfadr;
- int undefnum=0,absnum=0,commonnum=0,normalnum=0;
- size_t commonsize=0;
-
- if(!(obj->symbols))
- {
- if(!(obj->symbols=calloc(symbolsnum,sizeof(PSymbol))))
- {
- error_printf("No mem for Symbol Table !");
- return 0L;
- }
- }else{
- error_printf("More than one symbol section ?");
- error_printf("%s",obj->sections[i].name);
- return 0L;
- }
-
- obj->symbolscnt=symbolsnum;
-
- info_printf("Collecting %i Symbols!\n",symbolsnum);
- for(n=1;n<symbolsnum;n++)
- {
- obj->symbols[n].name=strings+symtab[n].st_name;
- obj->symbols[n].value=symtab[n].st_value;
- obj->symbols[n].size=symtab[n].st_size;
- obj->symbols[n].type=symtab[n].st_info;
- obj->symbols[n].sectionindex=symtab[n].st_shndx;
- if(ELF_ST_TYPE(obj->symbols[n].type)==STT_SECTION)
- obj->symbols[n].name=obj->sections[obj->symbols[n].sectionindex].name;
- switch(obj->symbols[n].sectionindex)
- {
- case SHN_UNDEF :
- error_printf("Undefined Symbol: %s",obj->symbols[n].name);
- undefnum++;
- break;
-
- case SHN_ABS :
- absnum++;
- break;
-
- case SHN_COMMON :
- {
- unsigned int tempalign=obj->symbols[n].value-1;
- unsigned int tempsize=obj->symbols[n].size;
- obj->symbols[n].value=(commonsize+tempalign)&(~tempalign);
- commonsize=obj->symbols[n].value+tempsize;
- obj->symbols[n].size=tempsize;
- }
- commonnum++;
- break;
-
- default:
- if(obj->symbols[n].sectionindex>obj->sectcnt)
- {
- error_printf("Unknown Sectionindex for Symbol: %s !",obj->symbols[n].name);
- return 0L;
- }
- obj->symbols[n].value+=(unsigned long)obj->sections[obj->symbols[n].sectionindex].virtadr;
- normalnum++;
- }
- }
-
- if(undefnum>0)
- {
- return 0L;
- }
-
- info_printf("Collected Symbols:\n");
- info_printf("%i undefined\n",undefnum);
- info_printf("%i absolute\n",absnum);
- info_printf("%i common ",commonnum);
- info_printf("Size: %li\n",commonsize);
- info_printf("%i normal\n",normalnum);
-
- //Create Common Section
-
- if(commonsize)
- {
- if(!(obj->sections[0].virtadr=AllocVec32(commonsize,0L))) // Probably should use AllocMem32 here
- {
- error_printf("No mem for common section !");
- return 0L;
- }
- memset(obj->sections[0].virtadr,0,commonsize);
- }
-
- obj->sections[0].name=".common";
- obj->sections[0].elfadr=0L;
- obj->sections[0].size=commonsize;
- obj->sections[0].type=SHT_NOBITS;
- obj->sections[0].flags=SHF_ALLOC;
-
- for(i=1;i<symbolsnum;i++)
- if(obj->symbols[i].sectionindex==SHN_COMMON)
- {
- obj->symbols[i].sectionindex=0;
- obj->symbols[i].value+=(unsigned long)obj->sections[0].virtadr;
- }
-
- //print_symbols(obj);
-
- return 1L;
- }
-
- void print_symbols(PElfObject *obj)
- {
- int i;
- for(i=1;i<obj->symbolscnt;i++)
- {
- info_printf("%-30s: %8lx\n",obj->symbols[i].name,obj->symbols[i].value);
- }
- }
-
- unsigned long get_symbol_by_name(PElfObject *obj,char *name)
- {
- int i;
- for(i=1;i<obj->symbolscnt;i++)
- if(strcmp(name,obj->symbols[i].name)==0)
- return obj->symbols[i].value;
- return -1L;
- }
-