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

📄 elf.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
  bfd_map_over_sections(abfd, elf_make_sections, &est);  /* dump out the one symtab */  {    int symcount = bfd_get_symcount (abfd);    asymbol ** syms = bfd_get_outsymbols (abfd);    struct strtab * stt = bfd_new_strtab (abfd);    Elf_Internal_Shdr *symtab_hdr;    Elf_Internal_Shdr *symstrtab_hdr;    int symstrtab_section;    Elf_External_Sym *outbound_syms;    int idx;    symtab_hdr = &i_shdrp[est.symtab_section];    symtab_hdr->sh_type = SHT_SYMTAB;    symtab_hdr->sh_entsize = sizeof (Elf_External_Sym);    symtab_hdr->sh_size = symtab_hdr->sh_entsize * symcount;    /* see assert in elf_fake_sections that supports this: */    symstrtab_section = est.symtab_section+1;    symstrtab_hdr = &i_shdrp[symstrtab_section];    symtab_hdr->sh_link = symstrtab_section;    symstrtab_hdr->sh_type = SHT_STRTAB;    outbound_syms = (Elf_External_Sym*)      bfd_alloc(abfd, (1+symcount) * sizeof(Elf_External_Sym));    /* now generate the data (for "contents") */    for (idx = 0; idx < symcount; idx++)      {	Elf_Internal_Sym sym;	sym.st_name = bfd_add_to_strtab (abfd, stt, syms[idx]->name);	sym.st_value = syms[idx]->value;	sym.st_size =  0; /* we should recover this (FIXME) */	if (syms[idx]->flags & BSF_WEAK)	  sym.st_info = ELF_ST_INFO(STB_WEAK, STT_OBJECT);	else if (syms[idx]->flags & BSF_LOCAL)	  sym.st_info = ELF_ST_INFO(STB_LOCAL, STT_OBJECT);	else if (syms[idx]->flags & BSF_GLOBAL)	  sym.st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT);	else if (syms[idx]->flags & BSF_SECTION_SYM)	  sym.st_info = ELF_ST_INFO(STB_LOCAL, STT_SECTION);	else if (syms[idx]->flags & BSF_FILE)	  sym.st_info = ELF_ST_INFO(STB_LOCAL, STT_FILE);	sym.st_other = 0;	if (syms[idx]->section) 	  sym.st_shndx =	    elf_section_from_bfd_section(abfd,					 syms[idx]->section->output_section);	else	  sym.st_shndx = SHN_UNDEF;	elf_swap_symbol_out (abfd, &sym, outbound_syms+idx+1);      }    {      /* fill in 0th symbol */      Elf_Internal_Sym sym;      sym.st_name = 0;      sym.st_value = 0;      sym.st_size = 0;      sym.st_info = 0;      sym.st_other = 0;      sym.st_shndx = SHN_UNDEF;      elf_swap_symbol_out (abfd, &sym, outbound_syms);    }    symtab_hdr->contents = (void*)outbound_syms;    symstrtab_hdr->contents = (void*)stt->tab;    symstrtab_hdr->sh_size = stt->length;  }  /* put the strtab out too... */  {    Elf_Internal_Shdr *this_hdr;    int this_section;    this_section = i_ehdrp->e_shnum++;    i_ehdrp->e_shstrndx = this_section;    this_hdr = &i_shdrp[this_section];    this_hdr->sh_name = bfd_add_to_strtab (abfd, shstrtab, ".shstrtab");    this_hdr->sh_size = shstrtab->length;    this_hdr->contents = (void*)shstrtab->tab;  }  outbase = i_ehdrp->e_ehsize;  /* swap the header before spitting it out... */  elf_swap_ehdr_out (abfd, i_ehdrp, &x_ehdr);  bfd_seek (abfd, (file_ptr) 0, SEEK_SET);  bfd_write ((PTR) &x_ehdr, sizeof(x_ehdr), 1, abfd);  outbase += i_ehdrp->e_shentsize * i_ehdrp->e_shnum;  /* now we fix up the offsets... */  for (count = 0; count < i_ehdrp->e_shnum; count ++)    {      i_shdrp[count].sh_offset = outbase;      outbase += i_shdrp[count].sh_size;    }  /* at this point we've concocted all the ELF sections... */  x_shdrp = (Elf_External_Shdr *)    bfd_alloc (abfd, sizeof (*x_shdrp) * (i_ehdrp->e_shnum));  if (! x_shdrp)    {      bfd_error = no_memory;      return (false);    }  for (count = 0; count < i_ehdrp->e_shnum; count ++)    {      elf_swap_shdr_out (abfd, i_shdrp+count, x_shdrp+count);    }  bfd_write ((PTR) x_shdrp, sizeof(*x_shdrp), i_ehdrp->e_shnum, abfd);  /* need to dump the string table too... */    /* after writing the headers, we need to write the sections too... */  nsect = abfd->sections;  for (count = 0; count < i_ehdrp->e_shnum; count ++)    {      if(i_shdrp[count].contents)	{	  bfd_seek (abfd, i_shdrp[count].sh_offset, SEEK_SET);	  bfd_write (i_shdrp[count].contents, i_shdrp[count].sh_size, 1, abfd);	}    }    /* sample use of bfd:   * bfd_seek (abfd, (file_ptr) 0, SEEK_SET);   * bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd);   * if (bfd_seek(abfd, scn_base, SEEK_SET) != 0)   * return false;   * old = bfd_tell(abfd);   */  return true;  }/* Given an index of a section, retrieve a pointer to it.  Note   that for our purposes, sections are indexed by {1, 2, ...} with   0 being an illegal index. *//* In the original, each ELF section went into exactly one BFD   section. This doesn't really make sense, so we need a real mapping.   The mapping has to hide in the Elf_Internal_Shdr since asection   doesn't have anything like a tdata field... */   static struct sec *DEFUN (section_from_elf_index, (abfd, index),       bfd            *abfd AND       int             index){  Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd);  Elf_Internal_Shdr *hdr = i_shdrp + index;  switch (hdr->sh_type)    {      /* ELF sections that map to BFD sections */    case SHT_PROGBITS:    case SHT_NOBITS:      if (! hdr->rawdata)	bfd_section_from_shdr (abfd, index);      return (struct sec *)hdr->rawdata;      break;    default:      return (struct sec *)&bfd_abs_section;    }}/* given a section, search the header to find them... */static intDEFUN (elf_section_from_bfd_section, (abfd, asect),       bfd		*abfd AND       struct sec	*asect){  Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd);  int index;  Elf_Internal_Shdr *hdr;  int maxindex = elf_elfheader (abfd)->e_shnum;    for(index = 0; index < maxindex; index++) {    hdr = &i_shdrp[index];    switch (hdr->sh_type)      {	/* ELF sections that map to BFD sections */      case SHT_PROGBITS:      case SHT_NOBITS:	if (hdr->rawdata) 	  {	    if (((struct sec *)(hdr->rawdata)) == asect)	      return index;	  }	break;      default:	break;      }  }  return 0;}static booleanDEFUN (elf_slurp_symbol_table, (abfd, symptrs),       bfd		*abfd AND       asymbol		**symptrs)	/* Buffer for generated bfd symbols */{  Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd);  Elf_Internal_Shdr *hdr = i_shdrp + elf_onesymtab (abfd);  int symcount;		/* Number of external ELF symbols */  int i;  asymbol *sym;		/* Pointer to current bfd symbol */  asymbol *symbase;	/* Buffer for generated bfd symbols */  Elf_Internal_Sym i_sym;  Elf_External_Sym *x_symp;  /* this is only valid because there is only one symtab... */  /* FIXME:  This is incorrect, there may also be a dynamic symbol     table which is a subset of the full symbol table.  We either need     to be prepared to read both (and merge them) or ensure that we     only read the full symbol table.  Currently we only get called to     read the full symbol table.  -fnf */  if (bfd_get_outsymbols (abfd) != NULL)    {      return (true);    }  /* Read each raw ELF symbol, converting from external ELF form to     internal ELF form, and then using the information to create a     canonical bfd symbol table entry.     Note that we allocate the initial bfd canonical symbol buffer     based on a one-to-one mapping of the ELF symbols to canonical     symbols.  We actually use all the ELF symbols, so there will be no     space left over at the end.  When we have all the symbols, we     build the caller's pointer vector. */  if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1)    {      bfd_error = system_call_error;      return (false);    }  symcount = hdr->sh_size / sizeof (Elf_External_Sym);  symbase = (asymbol *) bfd_zalloc (abfd, symcount * sizeof (asymbol));  sym = symbase;  /* Temporarily allocate room for the raw ELF symbols.  */  x_symp = (Elf_External_Sym *) malloc (symcount * sizeof (Elf_External_Sym));  if (bfd_read ((PTR) x_symp, sizeof (Elf_External_Sym), symcount, abfd)       != symcount * sizeof (Elf_External_Sym))    {      free ((PTR)x_symp);      bfd_error = system_call_error;      return (false);    }  /* Skip first symbol, which is a null dummy.  */  for (i = 1; i < symcount; i++)    {      elf_swap_symbol_in (abfd, x_symp + i, &i_sym);      sym -> the_bfd = abfd;      if (i_sym.st_name > 0)	sym -> name = elf_string_from_elf_section(abfd, hdr->sh_link,						i_sym.st_name);      else	sym -> name = "unnamed"; /* perhaps should include the number? */      sym -> value = i_sym.st_value;/* FIXME -- this is almost certainly bogus.  It's from Pace Willisson'shasty Solaris support, to pass the sizes of object files or functionsdown into GDB via the back door, to circumvent some other kludge inhow Sun hacked stabs.   -- gnu@cygnus.com  */      sym -> udata = (PTR)i_sym.st_size;/* FIXME -- end of bogosity.  */      if (i_sym.st_shndx > 0 && i_sym.st_shndx < SHN_LORESERV)	{	  sym -> section = section_from_elf_index (abfd, i_sym.st_shndx);	}      else if (i_sym.st_shndx == SHN_ABS)	{	  sym -> section = &bfd_abs_section;	}      else if (i_sym.st_shndx == SHN_COMMON)	{	  sym -> section = &bfd_com_section;	}      else if (i_sym.st_shndx == SHN_UNDEF)	{	  sym -> section = &bfd_und_section;	}      else	sym -> section = &bfd_abs_section;            switch (ELF_ST_BIND (i_sym.st_info))	{	  case STB_LOCAL:	    sym -> flags |= BSF_LOCAL;	    break;	  case STB_GLOBAL:	    sym -> flags |= (BSF_GLOBAL | BSF_EXPORT);	    break;	  case STB_WEAK:	    sym -> flags |= BSF_WEAK;	    break;	}      switch (ELF_ST_TYPE (i_sym.st_info))	{	  case STT_SECTION:	    sym->flags |= BSF_SECTION_SYM | BSF_DEBUGGING;	    break;	  case STT_FILE:	    sym->flags |= BSF_FILE | BSF_DEBUGGING;	    break;	}      sym++;    }  /* We rely on the zalloc to clear out the final symbol entry.  */  /* We're now done with the raw symbols.  */  free ((PTR)x_symp);  bfd_get_symcount(abfd) = symcount = sym - symbase;    /* Fill in the user's symbol pointer vector if needed.  */  if (symptrs)    {      sym = symbase;      while (symcount-- > 0)	{	  *symptrs++ = sym++;	}      *symptrs = 0;			/* Final null pointer */    }  return (true);}/* Return the number of bytes required to hold the symtab vector.   Note that we base it on the count plus 1, since we will null terminate   the vector allocated based on this size.  However, the ELF symbol table   always has a dummy entry as symbol #0, so it ends up even.  */static unsigned intDEFUN (elf_get_symtab_upper_bound, (abfd), bfd *abfd){  unsigned int symcount;  unsigned int symtab_size;  Elf_Internal_Shdr *i_shdrp = elf_elfsections (abfd);  Elf_Internal_Shdr *hdr = i_shdrp + elf_onesymtab (abfd);  symcount = hdr->sh_size / sizeof (Elf_External_Sym);  symtab_size = (symcount - 1 + 1) * (sizeof (asymbol));  return (symtab_size);}/*	This function return the number of bytes required to store the	relocation information associated with section <<sect>>	attached to bfd <<abfd>>*/static unsigned intelf_get_reloc_upper_bound (abfd, asect)bfd            *abfd;sec_ptr         asect;{  if (asect->flags & SEC_RELOC)    {      /* either rel or rela */      return asect->_raw_size;    }  else    return (0);}/* FIXME!!! sparc howto should go into elf-32-sparc.c */#ifdef sparcenum reloc_type  {    R_SPARC_NONE = 0,    R_SPARC_8,		R_SPARC_16,		R_SPARC_32,     R_SPARC_DISP8,	R_SPARC_DISP16,		R_SPARC_DISP32,     R_SPARC_WDISP30,	R_SPARC_WDISP22,    R_SPARC_HI22,	R_SPARC_22,    R_SPARC_13,		R_SPARC_LO10,    R_SPARC_GOT10,	R_SPARC_GOT13,		R_SPARC_GOT22,    R_SPARC_PC10,	R_SPARC_PC22,    R_SPARC_WPLT30,    R_SPARC_COPY,    R_SPARC_GLOB_DAT,	R_SPARC_JMP_SLOT,    R_SPARC_RELATIVE,    R_SPARC_UA32,    };#define	RELOC_TYPE_NAMES	\    "R_SPARC_NONE",		\    "R_SPARC_8",	"R_SPARC_16",		"R_SPARC_32",		\    "R_SPARC_DISP8",	"R_SPARC_DISP16",	"R_SPARC_DISP32",	\    "R_SPARC_WDISP30",	"R_SPARC_WDISP22",	\    "R_SPARC_HI22",	"R_SPARC_22",		\    "R_SPARC_13",	"R_SPARC_LO10",		\    "R_SPARC_GOT10",	"R_SPARC_GOT13",	"R_SPARC_GOT22",	\    "R_SPARC_PC10",	"R_SPARC_PC22",		\    "R_SPARC_WPLT30",		\    "R_SPARC_COPY",		\    "R_SPARC_GLOB_DAT",	"R_SPARC_JMP_SLOT",	\    "R_SPARC_RELATIVE",		\    "R_SPARC_UA32"static reloc_howto_type elf_howto_table[] = {  HOWTO(R_SPARC_NONE,   0,0, 0,false,0,false,false, 0,"R_SPARC_NONE",   false,0,0x00000000,false),  HOWTO(R_SPARC_8,      0,0, 8,false,0,true,  true, 0,"R_SPARC_8",      false,0,0x000000ff,false),  HOWTO(R_SPARC_16,     0,1,16,false,0,true,  true, 0,"R_SPARC_16",     false,0,0x0000ffff,false),  HOWTO(R_SPARC_32,     0,2,32,false,0,true,  true, 0,"R_SPARC_32",     false,0,0xffffffff,false),  HOWTO(R_SPARC_DISP8,  0,0, 8,true, 0,false, true, 0,"R_SPARC_DISP8",  false,0,0x000000ff,false),  HOWTO(R_SPARC_DISP16, 0,1,16,true, 0,false, true, 0,"R_SPARC_DISP16", false,0,0x0000ffff,false),  HOWTO(R_SPARC_DISP32, 0,2,32,true, 0,false, true, 0,"R_SPARC_DISP32", false,0,0x00ffffff,false),  HOWTO(R_SPARC_WDISP30,2,2,30,true, 0,false, true, 0,"R_SPARC_WDISP30",false,0,0x3fffffff,false),  HOWTO(R_SPARC_WDISP22,2,2,22,true, 0,false, true, 0,"R_SPARC_WDISP22",false,0,0x003fffff,false),  HOWTO(R_SPARC_HI22,  10,2,22,false,0,true, false, 0,"R_SPARC_HI22",   false,0,0x003fffff,false),  HOWTO(R_SPARC_22,     0,2,22,false,0,true,  true, 0,"R_SPARC_22",     false,0,0x003fffff,false),  HOWTO(R_SPARC_13,     0,1,13,false,0,true,  true, 0,"R_SPARC

⌨️ 快捷键说明

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