/* * Copyright (C) 1996-1998 Ilya Ryzhenkov (orangy@inetlab.com) */ #include "dlmstr.h" static void err(char *str) { printf("DUMP FATAL : %s\n",str); exit(1); } static void DumpSection(DLMSCN *sh,char *base,FILE *f) { if (!strncmp(sh->s_name,".aload",8)) fprintf(f," AutoLoad section. File = %s \n",base+sh->s_vaddr); else { fprintf(f," %.8s ",sh->s_name); fprintf(f,"virtual 0x%08lx ",sh->s_vaddr); fprintf(f,"size=0x%08lx ",sh->s_size); fprintf(f,"fileptr=0x%08lx ",sh->s_scnptr); fprintf(f,"FLAGS 0x%04lx\n",sh->s_flags); } } static void DumpReloc(DLMREL *rh,DLMSYM *eh,char *str,char *base,FILE *f) { long val; fprintf(f," Reloc at 0x%08lx ",rh->r_vaddr); switch (rh->r_flags&DLMREL_TYPE) { case DLMREL_REL32 : fprintf(f,"REL32 "); break; case DLMREL_ABS32 : fprintf(f,"ABS32 "); break; default : fprintf(f,"unk "); } val=*((long *)(base+rh->r_vaddr)); if (val>0) fprintf(f," (+"); else { fprintf(f," (-"); val=-val; } fprintf(f,"%08lxh) ",val); fprintf(f,"-> [%5ld] ",rh->r_symndx); eh+=rh->r_symndx; if (eh->e_flags&DLMSYM_IMPORT) fprintf(f,"( Imported ) "); else fprintf(f,"(0x%08lx) ",eh->e_value); if (eh->e_name!=DLMSYM_NONAME) fprintf(f,"%s\n",str+eh->e_name); else fprintf(f,"\n"); } static void DumpSymbol(DLMSYM *eh,char *str,int *seq,DLMSCN *sh,FILE *f) { fprintf(f,"[%5d] ",*seq); fprintf(f,"FLAGS : "); if (eh->e_flags&DLMSYM_COMMON) fprintf(f,"C"); else fprintf(f,"."); if (eh->e_flags&DLMSYM_IMPORT) fprintf(f,"I"); else fprintf(f,"."); if (eh->e_flags&DLMSYM_EXPORT) fprintf(f,"E"); else fprintf(f,"."); if (eh->e_flags&DLMSYM_SECTION) fprintf(f,"S"); else fprintf(f,"."); fprintf(f," 0x%08lx ",eh->e_value); if (eh->e_name!=DLMSYM_NONAME) fprintf(f,"%s\n",str+eh->e_name); else fprintf(f,"\n"); } void DumpDlm(TDlm *dlm,char *name) { int i; FILE *f; f=fopen(name,"w"); if (!f) return; fprintf(f,"\nSection list :\n"); fprintf(f, "==============\n"); for (i=0; iNumSect; i++) DumpSection(dlm->Sections+i,dlm->Base,f); fprintf(f,"\nRelocation list :\n"); fprintf(f, "=================\n"); for (i=0; iNumRel; i++) DumpReloc(dlm->Relocs+i,dlm->Symbols,dlm->Strings, dlm->Base,f); fprintf(f,"\nSymbol list :\n"); fprintf(f,"=============\n"); for (i=0; iNumSym; i++) DumpSymbol(dlm->Symbols+i,dlm->Strings,&i,dlm->Sections,f); fclose(f); } TDlm *LoadDlm(char *fname) { int sz,i,f,max; DLMHDR *fh=(DLMHDR*)malloc(DLMHDRSZ); TDlm *dlm=(TDlm*)malloc(sizeof(TDlm)); if (!fh) err("memory error"); f=open(fname,O_RDWR|O_BINARY); if (f==-1) err("file not found"); sz=read(f,fh,DLMHDRSZ); if (sz!=DLMHDRSZ) err("invalid file"); if (fh->f_magic!=DLM_MAGIC) { printf("This file is not DLM\n"); err("Unsupported file type"); } dlm->NumSect=fh->f_nscns; dlm->NumSym=fh->f_nsyms; dlm->NumRel=fh->f_nreloc; dlm->StrSize=fh->f_strsz; dlm->VSize=fh->f_vsize; free(fh); // allocate memory for section headers dlm->Sections=(DLMSCN*)malloc(DLMSCNSZ*dlm->NumSect); if (!dlm->Sections) err("memory error"); dlm->SectData=(SCNDTA*)malloc(sizeof(SCNDTA)*dlm->NumSect); if (!dlm->SectData) err("memory error"); // allocate memory for reloc data dlm->Relocs=(DLMREL*)malloc(DLMRELSZ*dlm->NumRel); if (!dlm->Relocs) err("memory error"); // allocate memory for symbols dlm->Symbols=(DLMSYM*)malloc(DLMSYMSZ*dlm->NumSym); if (!dlm->Symbols) err("memory error"); // allocate memory for strings dlm->Strings=(char *)malloc(dlm->StrSize); if (!dlm->Strings) err("memory error"); // loading section headers sz=read(f,dlm->Sections,DLMSCNSZ*dlm->NumSect); if (sz!=DLMSCNSZ*dlm->NumSect) err("invalid file"); // loading symbols sz=read(f,dlm->Symbols,DLMSYMSZ*dlm->NumSym); if (sz!=DLMSYMSZ*dlm->NumSym) err("invalid file"); // loading reloc table sz=read(f,dlm->Relocs,DLMRELSZ*dlm->NumRel); if (sz!=DLMRELSZ*dlm->NumRel) err("invalid file"); // loading string table sz=read(f,dlm->Strings,dlm->StrSize); if (sz!=dlm->StrSize) err("invalid file"); // loading section data // allocate memory for sect data dlm->Base=(char *)malloc(dlm->VSize); if (!dlm->Base) err("memory error"); max=0; for (i=0; iNumSect; i++) if (dlm->Sections[i].s_size) { if (dlm->Sections[i].s_scnptr) /* load data for section*/ { sz=lseek(f,dlm->Sections[i].s_scnptr,SEEK_SET); if (sz!=dlm->Sections[i].s_scnptr) err("invalid file"); sz=read(f,dlm->Base+dlm->Sections[i].s_vaddr,dlm->Sections[i].s_size); if (sz!=dlm->Sections[i].s_size) err("invalid file"); if (maxSections[i].s_scnptr+dlm->Sections[i].s_size) max=dlm->Sections[i].s_scnptr+dlm->Sections[i].s_size; if (dlm->Sections[i].s_size) dlm->SectData[i]=dlm->Base+dlm->Sections[i].s_vaddr; else dlm->SectData[i]=0; } else { memset(dlm->Base+dlm->Sections[i].s_vaddr,0,dlm->Sections[i].s_size); dlm->SectData[i]=0; } } dlm->FSize=max; return dlm; }