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

📄 elf.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
  case SHT_PROGBITS:  case SHT_NOBITS:    /* Bits that get saved. This one is real. */    if (! hdr->rawdata )       {	newsect = bfd_make_section (abfd, name);	newsect->vma = hdr->sh_addr;	newsect->_raw_size = hdr->sh_size;	newsect->filepos = hdr->sh_offset; /* so we can read back the bits */	newsect->flags |= SEC_HAS_CONTENTS;		if (hdr->sh_flags & SHF_ALLOC)	  {	    newsect->flags |= SEC_ALLOC;	    if (hdr->sh_type != SHT_NOBITS)	      newsect->flags |= SEC_LOAD;	  }		if (!(hdr->sh_flags & SHF_WRITE))	  newsect->flags |= SEC_READONLY;		if (hdr->sh_flags & SHF_EXECINSTR)	  newsect->flags |= SEC_CODE;	/* FIXME: may only contain SOME code */	else	  newsect->flags |= SEC_DATA;		hdr->rawdata = (void*)newsect;      }    return true;    break;  case SHT_SYMTAB:			/* A symbol table */    BFD_ASSERT (hdr->sh_entsize == sizeof (Elf_External_Sym));    elf_onesymtab (abfd) = shindex;    abfd->flags |= HAS_SYMS;    return true;  case SHT_STRTAB:			/* A string table */    return true;  case SHT_REL:  case SHT_RELA:    /* *these* do a lot of work -- but build no sections! */    /* the spec says there can be multiple strtabs, but only one symtab */    /* but there can be lots of REL* sections. */    /* FIXME:  The above statement is wrong!  There are typically at least       two symbol tables in a dynamically linked executable, ".dynsym"       which is the dynamic linkage symbol table and ".symtab", which is       the "traditional" symbol table.  -fnf */           {      asection		*target_sect;            bfd_section_from_shdr (abfd, hdr->sh_link); /* symbol table */      bfd_section_from_shdr (abfd, hdr->sh_info); /* target */      target_sect = section_from_elf_index (abfd, hdr->sh_info);      if (target_sect == NULL)	  return false;#if 0      /* FIXME:  We are only prepared to read one symbol table, so	 do NOT read the dynamic symbol table since it is only a	 subset of the full symbol table.  Also see comment above. -fnf */      if (!elf_slurp_symbol_table(abfd, i_shdrp + hdr->sh_link))	return false;#endif      target_sect->reloc_count = hdr->sh_size / hdr->sh_entsize;      target_sect->flags |= SEC_RELOC;      target_sect->relocation = 0;      target_sect->rel_filepos = hdr->sh_offset;      return true;    }    break;  case SHT_HASH:  case SHT_DYNAMIC:  case SHT_DYNSYM:		/* could treat this like symtab... */#if 0    fprintf(stderr, "Dynamic Linking sections not yet supported.\n");    abort ();#endif    break;  case SHT_NOTE:#if 0    fprintf(stderr, "Note Sections not yet supported.\n");    abort ();#endif    break;  case SHT_SHLIB:#if 0    fprintf(stderr, "SHLIB Sections not supported (and non conforming.)\n");#endif    return true;  default:    break;  }    return (true);}struct strtab {  char *tab;  int nentries;  int length;};static struct strtab *DEFUN(bfd_new_strtab, (abfd),      bfd		*abfd){  struct strtab *ss;  ss = (struct strtab *)malloc(sizeof(struct strtab));  ss->tab = malloc(1);  BFD_ASSERT(ss->tab != 0);  *ss->tab = 0;  ss->nentries = 0;  ss->length = 1;  return ss;}static intDEFUN(bfd_add_to_strtab, (abfd, ss, str),      bfd		*abfd AND      struct strtab	*ss AND      CONST char	*str){  /* should search first, but for now: */  /* include the trailing NUL */  int ln = strlen(str)+1;    /* should this be using obstacks? */  ss->tab = realloc(ss->tab, ss->length + ln);  BFD_ASSERT(ss->tab != 0);  strcpy(ss->tab + ss->length, str);  ss->nentries++;  ss->length += ln;  return ss->length - ln;}static intDEFUN(bfd_add_2_to_strtab, (abfd, ss, str, str2),      bfd		*abfd AND      struct strtab	*ss AND      char		*str AND      CONST char	*str2){  /* should search first, but for now: */  /* include the trailing NUL */  int ln = strlen(str)+strlen(str2)+1;    /* should this be using obstacks? */  if (ss->length)    ss->tab = realloc(ss->tab, ss->length + ln);  else     ss->tab = malloc(ln);  BFD_ASSERT(ss->tab != 0);  strcpy(ss->tab + ss->length, str);  strcpy(ss->tab + ss->length + strlen(str), str2);  ss->nentries++;  ss->length += ln;  return ss->length - ln;}/* Create a new ELF section from a bfd section. */static booleanDEFUN(bfd_shdr_from_section, (abfd, hdr, shstrtab, indx),      bfd               *abfd AND      Elf_Internal_Shdr *hdr AND      struct strtab	*shstrtab AND      int		indx){  asection *sect;  int ndx;    /* figure out out to write the section name from the bfd section name. MWE */  	        sect = abfd->sections;  for (ndx = indx; --ndx; )    {      sect = sect->next;    }  hdr[indx].sh_name = bfd_add_to_strtab(abfd, shstrtab,					bfd_section_name(abfd, sect));  hdr[indx].sh_addr = sect->vma;  hdr[indx].sh_size = sect->_raw_size;  hdr[indx].sh_flags = 0;  /* these need to be preserved on */  hdr[indx].sh_link = 0;  hdr[indx].sh_info = 0;  hdr[indx].sh_addralign = 0;  hdr[indx].sh_entsize = 0;  hdr[indx].sh_type = 0;  if (sect->flags & SEC_RELOC) {    hdr[indx].sh_type = SHT_RELA; /* FIXME -- sparc specific */  }    if (sect->flags & SEC_HAS_CONTENTS)    {      hdr[indx].sh_offset = sect->filepos;      hdr[indx].sh_size = sect->_raw_size;    }  if (sect->flags & SEC_ALLOC)    {      hdr[indx].sh_flags |= SHF_ALLOC;      if (sect->flags & SEC_LOAD)	{	  /* do something with sh_type ? */	}    }  if (!(sect->flags & SEC_READONLY))     hdr[indx].sh_flags |= SHF_WRITE;  if (sect->flags & SEC_CODE)    hdr[indx].sh_flags |= SHF_EXECINSTR;  return (true);}/* Create a new bfd section from an ELF program header.   Since program segments have no names, we generate a synthetic name   of the form segment<NUM>, where NUM is generally the index in the   program header table.  For segments that are split (see below) we   generate the names segment<NUM>a and segment<NUM>b.   Note that some program segments may have a file size that is different than   (less than) the memory size.  All this means is that at execution the   system must allocate the amount of memory specified by the memory size,   but only initialize it with the first "file size" bytes read from the   file.  This would occur for example, with program segments consisting   of combined data+bss.   To handle the above situation, this routine generates TWO bfd sections   for the single program segment.  The first has the length specified by   the file size of the segment, and the second has the length specified   by the difference between the two sizes.  In effect, the segment is split   into it's initialized and uninitialized parts. */static booleanDEFUN(bfd_section_from_phdr, (abfd, hdr, index),      bfd               *abfd AND      Elf_Internal_Phdr *hdr AND      int		 index){  asection *newsect;  char *name;  char namebuf[64];  int split;  split = ((hdr -> p_memsz > 0) &&	   (hdr -> p_filesz > 0) &&	   (hdr -> p_memsz > hdr -> p_filesz));  sprintf (namebuf, split ? "segment%da" : "segment%d", index);  name = bfd_alloc (abfd, strlen (namebuf) + 1);  strcpy (name, namebuf);  newsect = bfd_make_section (abfd, name);  newsect -> vma = hdr -> p_vaddr;  newsect -> _raw_size = hdr -> p_filesz;  newsect -> filepos = hdr -> p_offset;  newsect -> flags |= SEC_HAS_CONTENTS;  if (hdr -> p_type == PT_LOAD)    {      newsect -> flags |= SEC_ALLOC;      newsect -> flags |= SEC_LOAD;      if (hdr -> p_flags & PF_X)	{	  /* FIXME: all we known is that it has execute PERMISSION,	     may be data. */	  newsect -> flags |= SEC_CODE;	}    }  if (!(hdr -> p_flags & PF_W))    {      newsect -> flags |= SEC_READONLY;    }  if (split)    {      sprintf (namebuf, "segment%db", index);      name = bfd_alloc (abfd, strlen (namebuf) + 1);      strcpy (name, namebuf);      newsect = bfd_make_section (abfd, name);      newsect -> vma = hdr -> p_vaddr + hdr -> p_filesz;      newsect -> _raw_size = hdr -> p_memsz - hdr -> p_filesz;      if (hdr -> p_type == PT_LOAD)	{	  newsect -> flags |= SEC_ALLOC;	  if (hdr -> p_flags & PF_X)	    newsect -> flags |= SEC_CODE;	}      if (!(hdr -> p_flags & PF_W))	newsect -> flags |= SEC_READONLY;    }  return (true);}#ifdef HAVE_PROCFSstatic voidDEFUN(bfd_prstatus,(abfd, descdata, descsz, filepos),      bfd	*abfd AND      char	*descdata AND      int	 descsz AND      long	 filepos){  asection *newsect;  prstatus_t *status = (prstatus_t *)0;  if (descsz == sizeof (prstatus_t))    {      newsect = bfd_make_section (abfd, ".reg");      newsect -> _raw_size = sizeof (status->pr_reg);      newsect -> filepos = filepos + (long) &status->pr_reg;      newsect -> flags = SEC_ALLOC | SEC_HAS_CONTENTS;      newsect -> alignment_power = 2;      if ((core_prstatus (abfd) = bfd_alloc (abfd, descsz)) != NULL)	{	  memcpy (core_prstatus (abfd), descdata, descsz);	}    }}/* Stash a copy of the prpsinfo structure away for future use. */static voidDEFUN(bfd_prpsinfo,(abfd, descdata, descsz, filepos),      bfd	*abfd AND      char	*descdata AND      int	 descsz AND      long	 filepos){  asection *newsect;  if (descsz == sizeof (prpsinfo_t))    {      if ((core_prpsinfo (abfd) = bfd_alloc (abfd, descsz)) != NULL)	{	  memcpy (core_prpsinfo (abfd), descdata, descsz);	}    }}static voidDEFUN(bfd_fpregset,(abfd, descdata, descsz, filepos),      bfd	*abfd AND      char	*descdata AND      int	 descsz AND      long	 filepos){  asection *newsect;  newsect = bfd_make_section (abfd, ".reg2");  newsect -> _raw_size = descsz;  newsect -> filepos = filepos;  newsect -> flags = SEC_ALLOC | SEC_HAS_CONTENTS;  newsect -> alignment_power = 2;}#endif	/* HAVE_PROCFS *//* Return a pointer to the args (including the command name) that were   seen by the program that generated the core dump.  Note that for   some reason, a spurious space is tacked onto the end of the args   in some (at least one anyway) implementations, so strip it off if   it exists. */char *DEFUN(elf_core_file_failing_command, (abfd),     bfd *abfd){#ifdef HAVE_PROCFS  if (core_prpsinfo (abfd))    {      prpsinfo_t *p = core_prpsinfo (abfd);      char *scan = p -> pr_psargs;      while (*scan++) {;}      scan -= 2;      if ((scan > p -> pr_psargs) && (*scan == ' '))	{	  *scan = '\000';	}      return (p -> pr_psargs);    }#endif  return (NULL);}/* Return the number of the signal that caused the core dump.  Presumably,   since we have a core file, we got a signal of some kind, so don't bother   checking the other process status fields, just return the signal number.   */static intDEFUN(elf_core_file_failing_signal, (abfd),      bfd *abfd){#ifdef HAVE_PROCFS  if (core_prstatus (abfd))    {      return (((prstatus_t *)(core_prstatus (abfd))) -> pr_cursig);    }#endif  return (-1);}

⌨️ 快捷键说明

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