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

📄 elf.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
    }  /* Switch xvec to match the specified byte order.  */  switch (x_ehdr.e_ident[EI_DATA])    {    case ELFDATA2MSB:		/* Big-endian */       abfd->xvec = &elf_big_vec;      break;    case ELFDATA2LSB:		/* Little-endian */      abfd->xvec = &elf_little_vec;      break;    case ELFDATANONE:		/* No data encoding specified */    default:			/* Unknown data encoding specified */      goto wrong;    }    /* Allocate an instance of the elf_obj_tdata structure and hook it up to     the tdata pointer in the bfd. */  elf_tdata (abfd) =    (struct elf_obj_tdata *) bfd_zalloc (abfd, sizeof (struct elf_obj_tdata));  if (elf_tdata (abfd) == NULL)    {      bfd_error = no_memory;      return (NULL);    }  /* FIXME, `wrong' returns from this point onward, leak memory.  */  /* Now that we know the byte order, swap in the rest of the header */  i_ehdrp = elf_elfheader (abfd);  elf_swap_ehdr_in (abfd, &x_ehdr, i_ehdrp);  /* If there is no program header, or the type is not a core file, then     we are hosed. */  if (i_ehdrp->e_phoff == 0 || i_ehdrp->e_type != ET_CORE)    goto wrong;  /* Allocate space for a copy of the program header table in      internal form, seek to the program header table in the file,     read it in, and convert it to internal form.  As a simple sanity     check, verify that the what BFD thinks is the size of each program     header table entry actually matches the size recorded in the file. */  if (i_ehdrp->e_phentsize != sizeof (x_phdr))    goto wrong;  i_phdrp = (Elf_Internal_Phdr *)    bfd_alloc (abfd, sizeof (*i_phdrp) * i_ehdrp->e_phnum);  if (! i_phdrp)    {      bfd_error = no_memory;      return (NULL);    }  if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) == -1)    {      bfd_error = system_call_error;      return (NULL);    }  for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++)    {      if (bfd_read ((PTR) &x_phdr, sizeof (x_phdr), 1, abfd)	  != sizeof (x_phdr))	{	  bfd_error = system_call_error;	  return (NULL);	}      elf_swap_phdr_in (abfd, &x_phdr, i_phdrp + phindex);    }  /* Once all of the program headers have been read and converted, we     can start processing them. */  for (phindex = 0; phindex < i_ehdrp->e_phnum; phindex++)    {      bfd_section_from_phdr (abfd, i_phdrp + phindex, phindex);      if ((i_phdrp + phindex) -> p_type == PT_NOTE)	{	  elf_corefile_note (abfd, i_phdrp + phindex);	}    }  /* Remember the entry point specified in the ELF file header. */  bfd_get_start_address (abfd) = i_ehdrp->e_entry;  return (abfd->xvec);}static booleanDEFUN (elf_mkobject, (abfd), bfd *abfd){  /* this just does initialization */  /* coff_mkobject zalloc's space for tdata.coff_obj_data ... */  elf_tdata(abfd) = (struct elf_obj_tdata *)    bfd_zalloc (abfd, sizeof(struct elf_obj_tdata));  if (elf_tdata(abfd) == 0) {    bfd_error = no_memory;    return false;  }  /* since everything is done at close time, do we need any     initialization? */    return (true);}/*  Create ELF output from BFD sections.    Essentially, just create the section header and forget about the program  header for now.     *//* lacking nested functions and nested types, set up for mapping over   BFD sections to produce ELF sections */typedef struct {  Elf_Internal_Ehdr	*i_ehdr;  Elf_Internal_Shdr	*i_shdrp;  struct strtab		*shstrtab;  int			symtab_section;} elf_sect_thunk;static voidDEFUN (elf_make_sections, (abfd, asect, obj),       bfd		*abfd AND       asection		*asect AND       PTR		obj){  elf_sect_thunk *thunk = (elf_sect_thunk*)obj;  /* most of what is in bfd_shdr_from_section goes in here... */  /* and all of these sections generate at *least* one ELF section. */  int this_section;  int idx;    /* check if we're making a PROGBITS section... */  /* if ((asect->flags & SEC_ALLOC) && (asect->flags & SEC_LOAD)) */  /* this was too strict... what *do* we want to check here? */  if(1)    {      Elf_Internal_Shdr *this_hdr;      this_section = elf_section_from_bfd_section (abfd, asect);      this_hdr = &thunk->i_shdrp[this_section];      this_hdr->sh_addr = asect->vma;      this_hdr->sh_size = asect->_raw_size;      /* contents already set by elf_set_section_contents */      if (asect->flags & SEC_RELOC)	{	  /* emit a reloc section, and thus strtab and symtab... */	  Elf_Internal_Shdr *rela_hdr;	  Elf_Internal_Shdr *symtab_hdr;	  Elf_Internal_Shdr *symstrtab_hdr;	  Elf_External_Rela *outbound_relocs;	  Elf_External_Sym *outbound_syms;	  int rela_section;	  int symstrtab_section;	  	  symtab_hdr = &thunk->i_shdrp[thunk->symtab_section];	  if (thunk->symtab_section == this_section + 1)	    rela_section = thunk->symtab_section + 2; /* symtab + symstrtab */	  else	    rela_section = this_section + 1;	  rela_hdr = &thunk->i_shdrp[rela_section];	  rela_hdr->sh_type = SHT_RELA;	  rela_hdr->sh_link = thunk->symtab_section;	  rela_hdr->sh_info = this_section;	  rela_hdr->sh_entsize = sizeof (Elf_External_Rela);	  /* orelocation has the data, reloc_count has the count... */	  rela_hdr->sh_size = rela_hdr->sh_entsize * asect->reloc_count;	  outbound_relocs = (Elf_External_Rela *)	    bfd_alloc(abfd, asect->reloc_count * sizeof(Elf_External_Rela));	  for (idx = 0; idx < asect->reloc_count; idx++)	    {	      Elf_Internal_Rela dst;	      arelent        *ptr;	      Elf_External_Rela  *src;	      	      ptr = asect->orelocation[idx];	      src = outbound_relocs + idx;	      if (asect->flags & SEC_RELOC)		dst.r_offset = ptr->address - asect->vma;	      else		dst.r_offset = ptr->address;	      dst.r_info = ELF_R_INFO(1 /*ptr->sym_ptr_ptr*/, /* needs index into symtab (FIXME) */				      ptr->howto->type);	      dst.r_addend = ptr->addend;	      elf_swap_reloca_out(abfd, &dst, src);	    }	  rela_hdr->contents = (void*)outbound_relocs;	}    }}static voidDEFUN (elf_fake_sections, (abfd, asect, obj),       bfd		*abfd AND       asection		*asect AND       PTR		obj){  elf_sect_thunk *thunk = (elf_sect_thunk*)obj;  /* most of what is in bfd_shdr_from_section goes in here... */  /* and all of these sections generate at *least* one ELF section. */  int this_section;  int idx;    /* check if we're making a PROGBITS section... */  /* if ((asect->flags & SEC_ALLOC) && (asect->flags & SEC_LOAD)) */  /* this was too strict... what *do* we want to check here? */  if(1)    {      Elf_Internal_Shdr *this_hdr;      this_section = thunk->i_ehdr->e_shnum++;      this_hdr = &thunk->i_shdrp[this_section];      this_hdr->sh_name = 	bfd_add_to_strtab (abfd, thunk->shstrtab, asect->name);      /* we need to log the type *now* so that elf_section_from_bfd_section	 can find us... have to set rawdata too. */      this_hdr->rawdata = (void*)asect;      if ((asect->flags & SEC_ALLOC) && (asect->flags & SEC_LOAD))	this_hdr->sh_type = SHT_PROGBITS;      else	/* what *do* we put here? */	this_hdr->sh_type = SHT_PROGBITS;      if (asect->flags & SEC_RELOC)	{	  /* emit a reloc section, and thus strtab and symtab... */	  Elf_Internal_Shdr *rela_hdr;	  Elf_Internal_Shdr *symtab_hdr;	  Elf_Internal_Shdr *symstrtab_hdr;	  Elf_External_Rela *outbound_relocs;	  Elf_External_Sym *outbound_syms;	  int rela_section;	  int symstrtab_section;	  	  /* note that only one symtab is used, so just remember it	     for now */	  if (! thunk->symtab_section)	    {	      thunk->symtab_section = thunk->i_ehdr->e_shnum++;	      symtab_hdr = &thunk->i_shdrp[thunk->symtab_section];	      symtab_hdr->sh_name =		bfd_add_to_strtab (abfd, thunk->shstrtab, ".symtab");	      symtab_hdr->sh_type = SHT_SYMTAB;	      symtab_hdr->sh_entsize = sizeof (Elf_External_Sym);	      symstrtab_section = thunk->i_ehdr->e_shnum++;	      BFD_ASSERT(symstrtab_section == thunk->symtab_section+1);	      symstrtab_hdr = &thunk->i_shdrp[symstrtab_section];	      symtab_hdr->sh_link = symstrtab_section;	      symstrtab_hdr->sh_name =		bfd_add_to_strtab (abfd, thunk->shstrtab, ".strtab");	      symstrtab_hdr->sh_type = SHT_STRTAB;	      symtab_hdr->contents = 0;	      symstrtab_hdr->contents = 0;	      symstrtab_hdr->sh_size = 0;	    } 	  else	    symtab_hdr = &thunk->i_shdrp[thunk->symtab_section];	  rela_section = thunk->i_ehdr->e_shnum++;	  rela_hdr = &thunk->i_shdrp[rela_section];	  rela_hdr->sh_name =	    bfd_add_2_to_strtab (abfd, thunk->shstrtab, ".rela", asect->name);	  rela_hdr->sh_type = SHT_RELA;	  rela_hdr->sh_link = thunk->symtab_section;	  rela_hdr->sh_info = this_section;	  rela_hdr->sh_entsize = sizeof (Elf_External_Rela);	}    }}static booleanDEFUN (elf_compute_section_file_positions, (abfd), bfd *abfd){  Elf_Internal_Ehdr *i_ehdrp;	/* Elf file header, internal form */  Elf_Internal_Shdr *i_shdrp;	/* Section header table, internal form */  struct strtab *shstrtab;  int count, maxsections;  int outbase;  elf_sect_thunk est;  if (! elf_shstrtab (abfd)) {    i_ehdrp = elf_elfheader (abfd);	/* build new header in tdata memory */    shstrtab = bfd_new_strtab(abfd);        i_ehdrp->e_ident[EI_MAG0] = ELFMAG0;    i_ehdrp->e_ident[EI_MAG1] = ELFMAG1;    i_ehdrp->e_ident[EI_MAG2] = ELFMAG2;    i_ehdrp->e_ident[EI_MAG3] = ELFMAG3;    i_ehdrp->e_ident[EI_CLASS] = ELFCLASS32; /* FIXME: find out from bfd */    i_ehdrp->e_ident[EI_DATA] =      abfd->xvec->byteorder_big_p ? ELFDATA2MSB : ELFDATA2LSB;    i_ehdrp->e_ident[EI_VERSION] = EV_CURRENT;    for(count = EI_PAD; count < EI_NIDENT; count ++)      i_ehdrp->e_ident[count] = 0;          i_ehdrp->e_type = (abfd->flags & EXEC_P)? ET_EXEC : ET_REL;    switch(bfd_get_arch(abfd))      {      case bfd_arch_unknown:	i_ehdrp->e_machine = EM_NONE;	break;      case bfd_arch_sparc:	i_ehdrp->e_machine = EM_SPARC;	break;      case bfd_arch_i386:	i_ehdrp->e_machine = EM_386;	break;      case bfd_arch_m68k:	i_ehdrp->e_machine = EM_68K;	break;      case bfd_arch_m88k:	i_ehdrp->e_machine = EM_88K;	break;      case bfd_arch_i860:	i_ehdrp->e_machine = EM_860;	break;      case bfd_arch_mips:		  /* MIPS Rxxxx */	i_ehdrp->e_machine = EM_MIPS; /* only MIPS R3000 */	break;	/* also note that EM_M32, AT&T WE32100 is unknown to bfd */      default:	i_ehdrp->e_machine = EM_NONE;      }    i_ehdrp->e_version = EV_CURRENT;    i_ehdrp->e_ehsize = sizeof(Elf_External_Ehdr);        /* no program header, for now. */    i_ehdrp->e_phoff = 0;    i_ehdrp->e_phentsize = 0;    i_ehdrp->e_phnum = 0;    /* each bfd section is section header entry */    i_ehdrp->e_entry = bfd_get_start_address (abfd);    i_ehdrp->e_shentsize = sizeof (Elf_External_Shdr);    /* figure at most each section can have a rel, strtab, symtab */    maxsections = 4*bfd_count_sections(abfd)+2;    i_ehdrp->e_shoff = i_ehdrp->e_ehsize;    /* and we'll just have to fix up the offsets later. */    /* outbase += i_ehdr.e_shentsize * i_ehdr.e_shnum; */        i_shdrp = (Elf_Internal_Shdr *)      bfd_alloc (abfd, sizeof (*i_shdrp) * maxsections);    if (! i_shdrp)      {	bfd_error = no_memory;	return (false);      }    for (count=0; count < maxsections; count++)       {	i_shdrp[count].rawdata = 0;	i_shdrp[count].contents = 0;      }            i_shdrp[0].sh_name = 0;    i_shdrp[0].sh_type = SHT_NULL;    i_shdrp[0].sh_flags = 0;    i_shdrp[0].sh_addr = 0;    i_shdrp[0].sh_offset = 0;    i_shdrp[0].sh_size = 0;    i_shdrp[0].sh_link = SHN_UNDEF;    i_shdrp[0].sh_info = 0;    i_shdrp[0].sh_addralign = 0;    i_shdrp[0].sh_entsize = 0;    i_ehdrp->e_shnum = 1;    elf_elfsections (abfd) = i_shdrp;    elf_shstrtab (abfd) = shstrtab;  }  est.i_ehdr = elf_elfheader(abfd);  est.i_shdrp = elf_elfsections(abfd);  est.shstrtab = elf_shstrtab(abfd);  est.symtab_section = 0;	/* elf_fake_sections fils it in */  bfd_map_over_sections(abfd, elf_fake_sections, &est);  elf_onesymtab (abfd) = est.symtab_section;  return (true);}static booleanDEFUN (elf_write_object_contents, (abfd), bfd *abfd){  Elf_External_Ehdr x_ehdr;	/* Elf file header, external form */  Elf_Internal_Ehdr *i_ehdrp;	/* Elf file header, internal form */  Elf_External_Phdr *x_phdrp;	/* Program header table, external form */  Elf_Internal_Phdr *i_phdrp;	/* Program header table, internal form */  Elf_External_Shdr *x_shdrp;	/* Section header table, external form */  Elf_Internal_Shdr *i_shdrp;	/* Section header table, internal form */  asection *nsect;  int maxsections;  elf_sect_thunk est;    int outbase = 0;  int count;  struct strtab *shstrtab;    if(abfd->output_has_begun == false)     elf_compute_section_file_positions(abfd);  i_ehdrp = elf_elfheader (abfd);  i_shdrp = elf_elfsections (abfd);  shstrtab = elf_shstrtab (abfd);  est.i_ehdr = i_ehdrp;  est.i_shdrp = i_shdrp;  est.shstrtab = shstrtab;  est.symtab_section = elf_onesymtab (abfd); /* filled in by elf_fake */

⌨️ 快捷键说明

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