⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 syms.c

📁 汇编源码大全 有各种汇编源码 希望对你有所帮助
💻 C
📖 第 1 页 / 共 2 页
字号:
/* This file is SYMS.C
**
** changed Rainer Schnitker
*/

/*
** Copyright (C) 1993 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
**
** This file is distributed under the terms listed in the document
** "copying.dj", available from DJ Delorie at the address above.
** A copy of "copying.dj" should accompany this file; if not, a copy
** should be available from where this file was obtained.  This file
** may not be distributed without a verbatim copy of "copying.dj".
**
** This file is distributed WITHOUT ANY WARRANTY; without even the implied
** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include <io.h>
#include <memory.h>
#include <malloc.h>

#ifndef __GO32__
#include <sys/reg.h>
#else
#include <sys/_reg.h>
#endif

typedef unsigned char	   word8;
typedef unsigned short	   word16;
typedef unsigned long	   word32;
typedef short		   int16;

#include "coff.h"
#include "syms.h"
#include "stab.h"

extern int ptrace_get_register(int);

int undefined_symbol = 0;

struct reg_names {
    char *name;
    int size;
    int ofs;
};

struct reg_names regs[] =
{
  { "%eip", 4, EIP },
  { "%eflags", 4, EFL },
  { "%eax", 4, EAX },
  { "%ebx", 4, EBX },
  { "%ecx", 4, ECX },
  { "%edx", 4, EDX },
  { "%esp", 4, ESP },
  { "%ebp", 4, EBP },
  { "%esi", 4, ESI },
  { "%edi", 4, EDI },
  { "%ax", 2, EAX },
  { "%bx", 2, EBX },
  { "%cx", 2, ECX },
  { "%dx", 2, EDX },
  { "%ah", 0, EAX },
  { "%bh", 0, EBX },
  { "%ch", 0, ECX },
  { "%dh", 0, EDX },
  { "%al", 1, EAX },
  { "%bl", 1, EBX },
  { "%cl", 1, ECX },
  { "%dl", 1, EDX },
  { 0, 0, 0 }
};

typedef struct SYM_ENTRY {
  word32 string_off;
  word8 type;
  word8 other;
  word16 desc;
  word32 val;
} SYM_ENTRY;

static FILHDR f_fh;
static AOUTHDR f_ah;
static SCNHDR *f_sh;
static SYMENT *f_symtab;
static SYM_ENTRY *f_aoutsyms;
static AUXENT *f_aux;
static LINENO **f_lnno;
static char *f_string_table;
static char *f_types;

/* built internally */

typedef struct {
  char *filename;
  word32 first_address;
  word32 last_address;
  LINENO *lines;
  int num_lines;
} FileNode;

static FileNode *files;
static int num_files;

typedef struct SymNode {
  char *name;
  word32 address;
  char type_c;
} SymNode;

static SymNode *syms;
static SymNode *syms_byname;
static int num_syms;

static int syms_sort_bn(const void *a, const void *b)
{
  SymNode *sa = (SymNode *)a;
  SymNode *sb = (SymNode *)b;
  return strcmp(sa->name, sb->name);
}

static int syms_sort_bv(const void *a, const void *b)
{
  SymNode *sa = (SymNode *)a;
  SymNode *sb = (SymNode *)b;
  return sa->address - sb->address;
}

static char *symndup(char *s, int len)
{
  char c = s[len], *rv;
  s[len] = 0;
  rv = strdup(s);
  s[len] = c;
  return rv;
}

static int valid_symbol(int i)
{
  char *sn;
  if (f_symtab[i].e.e.e_zeroes)
    sn = f_symtab[i].e.e_name;
  else
    sn = f_string_table + f_symtab[i].e.e.e_offset;
  if (sn[0] != '_')
    return 0;
  if (strncmp(sn, "___gnu_compiled", 15) == 0)
    return 0;
  if (strcmp(sn, "__DYNAMIC") == 0)
    return 0;
  return 1;
}

static void * xmalloc(int size)
{
    void *p;
    if ((p = malloc(size)) == NULL) {
	printf("malloc %d failed", size);
	exit(1);
    }
    memset (p, 0, size);
    return p;
}

static void process_coff(FILE *fd, long ofs)
{
  int i, f, s, f_pending;
  LINENO *l;
  int l_pending;
  word32 strsize;
  char *name;

  fseek(fd, ofs, 0);
  fread(&f_fh, 1, FILHSZ, fd);
  fread(&f_ah, 1, AOUTSZ, fd);

  printf("COFF HEADER\n");
  printf("text   = %08lX\n", f_ah.tsize);
  printf("data   = %08lX\n", f_ah.dsize);
  printf("bss    = %08lX\n", f_ah.bsize);
  printf("entry  = %08lX\n", f_ah.entry);

  f_sh = (SCNHDR *)xmalloc(f_fh.f_nscns * SCNHSZ);
  f_types = (char *)xmalloc(f_fh.f_nscns);
  f_lnno = (LINENO **)xmalloc(f_fh.f_nscns * sizeof(LINENO *));
  fread(f_sh, f_fh.f_nscns, SCNHSZ, fd);

  for (i=0; i<f_fh.f_nscns; i++)
  {
    if (f_sh[i].s_flags & STYP_TEXT)
      f_types[i] = 'T';
    if (f_sh[i].s_flags & STYP_DATA)
      f_types[i] = 'D';
    if (f_sh[i].s_flags & STYP_BSS)
      f_types[i] = 'B';
    if (f_sh[i].s_nlnno)
    {
      fseek(fd, ofs + f_sh[i].s_lnnoptr, 0L);
      f_lnno[i] = (LINENO *)xmalloc(f_sh[i].s_nlnno * LINESZ);
      fread(f_lnno[i], LINESZ, f_sh[i].s_nlnno, fd);
    }
    else
      f_lnno[i] = 0;
  }

  fseek(fd, ofs + f_fh.f_symptr + f_fh.f_nsyms * SYMESZ, 0);
  fread(&strsize, 1, 4, fd);
  f_string_table = (char *)xmalloc(strsize);
  fread(f_string_table+4, 1, strsize-4, fd);
  f_string_table[0] = 0;

  fseek(fd, ofs+f_fh.f_symptr, 0);
  f_symtab = (SYMENT *)xmalloc(f_fh.f_nsyms * SYMESZ);
  fread(f_symtab, SYMESZ, f_fh.f_nsyms, fd);
  f_aux = (AUXENT *)f_symtab;

  num_syms = num_files = 0;
  for (i=0; i<f_fh.f_nsyms; i++)
  {
    switch (f_symtab[i].e_sclass)
    {
      case C_FILE:
	num_files++;
	break;
      case C_EXT:
      case C_STAT:
	if (!valid_symbol(i))
	  break;
	num_syms++;
	break;
    }
    i += f_symtab[i].e_numaux;
  }

  files = (FileNode *)xmalloc(num_files * sizeof(FileNode));

  syms = (SymNode *)xmalloc(num_syms * sizeof(SymNode));

  f = s = f_pending = l_pending = 0;
  for (i=0; i<f_fh.f_nsyms; i++)
  {
    switch (f_symtab[i].e_sclass)
    {
      case C_FILE:
	if (f_aux[i+1].x_file.x_n.x_zeroes)
	  files[f].filename = symndup(f_aux[i+1].x_file.x_fname, 16);
	else
	  files[f].filename = f_string_table + f_aux[i+1].x_file.x_n.x_offset;
	files[f].lines = 0;
	f_pending = 1;
	f++;
	break;
      case C_EXT:
      case C_STAT:

	if (f_symtab[i].e.e.e_zeroes)
	  name = f_symtab[i].e.e_name;
	else
	  name = f_string_table + f_symtab[i].e.e.e_offset;

	if (f_pending && strcmp(name, ".text") == 0)
	{
	  files[f-1].first_address = f_symtab[i].e_value;
	  files[f-1].last_address = f_symtab[i].e_value + f_aux[i+1].x_scn.x_scnlen - 1;
	  files[f-1].num_lines = f_aux[i+1].x_scn.x_nlinno;
	  f_pending = 0;
	}

	if (ISFCN(f_symtab[i].e_type))
	{
	  int scn = f_symtab[i].e_scnum - 1;
	  l = f_lnno[scn] + ((f_aux[i+1].x_sym.x_fcnary.x_fcn.x_lnnoptr - f_sh[scn].s_lnnoptr)/LINESZ);
	  l_pending = 1;
	  l->l_addr.l_paddr = f_symtab[i].e_value;
	}

	if (!valid_symbol(i))
	  break;

	syms[s].address = f_symtab[i].e_value;
	if (f_symtab[i].e.e.e_zeroes)
	  syms[s].name = symndup(f_symtab[i].e.e_name, 8);
	else
	  syms[s].name = f_string_table + f_symtab[i].e.e.e_offset;

	switch (f_symtab[i].e_scnum)
	{
	  case 1 ... 10:
	    syms[s].type_c = f_types[f_symtab[i].e_scnum-1];
	    break;
	  case N_UNDEF:
	    syms[s].type_c = 'U';
	    break;
	  case N_ABS:
	    syms[s].type_c = 'A';
	    break;
	  case N_DEBUG:
	    syms[s].type_c = 'D';
	    break;
	}
	if (f_symtab[i].e_sclass == C_STAT)
	  syms[s].type_c += 'a' - 'A';

	s++;
	break;
      case C_FCN:
	if (f_pending && files[f-1].lines == 0)
	{
	  files[f-1].lines = l;
	}
	if (l_pending)
	{
	  int lbase = f_aux[i+1].x_sym.x_misc.x_lnsz.x_lnno - 1;
	  int i2;
	  l->l_lnno = lbase;
	  l++;
	  for (i2=0; l[i2].l_lnno; i2++)
	    l[i2].l_lnno += lbase;
	  l_pending = 0;
	}
	break;
    }
    i += f_symtab[i].e_numaux;
  }
}

#define _N_HDROFF(x)	_n_hdroff
#define N_TXTOFF(x)	( _N_HDROFF((x)) + sizeof (GNU_AOUT))
#define N_DATOFF(x)	(N_TXTOFF(x)  + (x).tsize)
#define N_TRELOFF(x)	(N_DATOFF(x)  + (x).dsize)
#define N_DRELOFF(x)	(N_TRELOFF(x) + (x).txrel)
#define N_SYMOFF(x)	(N_DRELOFF(x) + (x).dtrel)
#define N_STROFF(x)	(N_SYMOFF(x)  + (x).symsize)

static void process_aout(FILE *fd, long ofs)
{
  GNU_AOUT header;
  word32 string_table_length;
  DWORD _n_hdroff;
  int nsyms, i, f, s, l;

  fseek(fd, ofs, 0);
  fread(&header, 1, sizeof(header), fd);

  if (header.entry == 0x10000)
    _n_hdroff = (1024 - sizeof(GNU_AOUT));
  else if (header.entry == 0x1020)
    _n_hdroff = 0;
  else {
    printf("Not supported a.out file type\n");
    return;
  }

  printf("GNUAOUT HEADER\n");
  printf("text   = %08lX\n", header.tsize);
  printf("data   = %08lX\n", header.dsize);
  printf("bss    = %08lX\n", header.bsize);
  printf("entry  = %08lX\n", header.entry);
  printf("syms   = %08lX\n", header.symsize);

  fseek(fd, ofs + N_SYMOFF(header),0);
  nsyms = header.symsize / sizeof(SYM_ENTRY);
  f_aoutsyms = (SYM_ENTRY *)xmalloc(header.symsize);
  fread(f_aoutsyms, 1, header.symsize, fd);

  fread(&string_table_length, 1, 4, fd);
  f_string_table = (char *)xmalloc(string_table_length);
  fread(f_string_table+4, 1, string_table_length-4, fd);
  f_string_table[0] = 0;

  num_files = num_syms = 0;
  for (i=0; i<nsyms; i++)
  {
    char *symn = f_string_table + f_aoutsyms[i].string_off;
    char *cp;
    switch (f_aoutsyms[i].type & ~N_EXT)
    {
      case N_SO:
	if (symn[strlen(symn)-1] == '/')
	  break;
	num_files++;
	break;
      case N_TEXT:
	cp = symn + strlen(symn) - 2;
	if (strncmp(symn, "___gnu", 6) == 0 ||
	    strcmp(cp, "d.") == 0 /* as in gcc_compiled. */ ||
	    strcmp(cp, ".o") == 0)
	  break;
      case N_DATA:
      case N_ABS:
      case N_BSS:
      case N_FN:
      case N_SETV:
      case N_SETA:
      case N_SETT:
      case N_SETD:
      case N_SETB:
      case N_INDR:
	num_syms ++;
	break;
    }
  }

  syms = (SymNode *)xmalloc(num_syms * sizeof(SymNode));
  memset(syms, num_syms * sizeof(SymNode), 0);
  files = (FileNode *)xmalloc(num_files * sizeof(FileNode));
  memset(files, num_files * sizeof(FileNode), 0);

  f = s = 0;
  for (i=0; i<nsyms; i++)
  {
    char c, *cp;
    char *symn = f_string_table + f_aoutsyms[i].string_off;
    switch (f_aoutsyms[i].type & ~N_EXT)
    {
      case N_SO:
	if (symn[strlen(symn)-1] == '/')
	  break;
	if (f && files[f-1].last_address == 0)
	  files[f-1].last_address = f_aoutsyms[i].val - 1;
	files[f].filename = symn;
	files[f].first_address = f_aoutsyms[i].val;
	f ++;
	break;
      case N_SLINE:
	files[f-1].num_lines++;
	break;
      case N_TEXT:
	cp = symn + strlen(symn) - 2;
	if (strncmp(symn, "___gnu", 6) == 0 ||

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -