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

📄 grub-mkimage.c

📁 有助于了解操作系统如何启动之过程
💻 C
📖 第 1 页 / 共 3 页
字号:
	    sym_addr = get_symbol_address (e, symtab_section,					   ELF32_R_SYM (info));	    switch (ELF32_R_TYPE (info))	      {	      case R_386_NONE:		break;	      case R_386_32:		/* This is absolute.  */		*target = grub_cpu_to_le32 (grub_le_to_cpu32 (*target)					    + sym_addr);		grub_util_info ("relocating an R_386_32 entry to 0x%x at the offset 0x%x",				*target, offset);		break;	      case R_386_PC32:		/* This is relative.  */		*target = grub_cpu_to_le32 (grub_le_to_cpu32 (*target)					    + sym_addr					    - target_section_addr - offset);		grub_util_info ("relocating an R_386_PC32 entry to 0x%x at the offset 0x%x",				*target, offset);		break;	      default:		grub_util_error ("unknown relocation type %d",				 ELF32_R_TYPE (info));		break;	      }	  }      }}voidwrite_padding (FILE *out, size_t size){  size_t i;  for (i = 0; i < size; i++)    if (fputc (0, out) == EOF)      grub_util_error ("padding failed");}/* Add a PE32's fixup entry for a relocation. Return the resulting address   after having written to the file OUT.  */Elf32_Addradd_fixup_entry (struct grub_pe32_fixup_block **block, grub_uint16_t type,		 Elf32_Addr addr, int flush, Elf32_Addr current_address,		 FILE *out){  struct grub_pe32_fixup_block *b = *block;    /* First, check if it is necessary to write out the current block.  */  if (b)    {      if (flush || addr < b->page_rva || b->page_rva + 0x1000 <= addr)	{	  grub_uint32_t size;	  if (flush)	    {	      /* Add as much padding as necessary to align the address		 with a section boundary.  */	      Elf32_Addr next_address;	      unsigned padding_size;              size_t index;	      	      next_address = current_address + b->block_size;	      padding_size = ((align_pe32_section (next_address)			       - next_address)			      >> 1);              index = ((b->block_size - sizeof (*b)) >> 1);              grub_util_info ("adding %d padding fixup entries", padding_size);	      while (padding_size--)		{		  b->entries[index++] = 0;		  b->block_size += 2;		}	    }          else if (b->block_size & (8 - 1))            {	      /* If not aligned with a 32-bit boundary, add		 a padding entry.  */              size_t index;              grub_util_info ("adding a padding fixup entry");              index = ((b->block_size - sizeof (*b)) >> 1);              b->entries[index] = 0;              b->block_size += 2;            }          /* Flush it.  */          grub_util_info ("writing %d bytes of a fixup block starting at 0x%x",                          b->block_size, b->page_rva);          size = b->block_size;	  current_address += size;	  b->page_rva = grub_cpu_to_le32 (b->page_rva);	  b->block_size = grub_cpu_to_le32 (b->block_size);	  if (fwrite (b, size, 1, out) != 1)	    grub_util_error ("write failed");	  free (b);	  *block = b = 0;	}    }  if (! flush)    {      grub_uint16_t entry;      size_t index;            /* If not allocated yet, allocate a block with enough entries.  */      if (! b)	{	  *block = b = xmalloc (sizeof (*b) + 2 * 0x1000);	  /* The spec does not mention the requirement of a Page RVA.	     Here, align the address with a 4K boundary for safety.  */	  b->page_rva = (addr & ~(0x1000 - 1));	  b->block_size = sizeof (*b);	}      /* Sanity check.  */      if (b->block_size >= sizeof (*b) + 2 * 0x1000)	grub_util_error ("too many fixup entries");      /* Add a new entry.  */      index = ((b->block_size - sizeof (*b)) >> 1);      entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva);      b->entries[index] = grub_cpu_to_le16 (entry);      b->block_size += 2;    }  return current_address;}/* Write out zeros to make space for the header.  */static Elf32_Addrmake_header_space (FILE *out){  Elf32_Addr addr;    addr = get_starting_section_address ();  write_padding (out, addr);  return addr;}/* Write text sections.  */static Elf32_Addrwrite_text_sections (FILE *out, Elf32_Addr current_address,		     Elf32_Ehdr *e, Elf32_Shdr *sections,		     Elf32_Half section_entsize, Elf32_Half num_sections,		     const char *strtab){  Elf32_Half i;  Elf32_Shdr *s;  Elf32_Addr addr;    for (i = 0, s = sections;       i < num_sections;       i++, s = (Elf32_Shdr *) ((char *) s + section_entsize))    if (is_text_section (s))      {	Elf32_Word align = grub_le_to_cpu32 (s->sh_addralign);	Elf32_Off offset = grub_le_to_cpu32 (s->sh_offset);	Elf32_Word size = grub_le_to_cpu32 (s->sh_size);	const char *name = strtab + grub_le_to_cpu32 (s->sh_name);		if (align)	  {	    addr = align_address (current_address, align);	    if (current_address != addr)	      {		grub_util_info ("padding %d bytes for the ELF section alignment",				addr - current_address);		write_padding (out, addr - current_address);		current_address = addr;	      }	  }		grub_util_info ("writing the text section %s at 0x%x",			name, current_address);		if (fwrite ((char *) e + offset, size, 1, out) != 1)	  grub_util_error ("write failed");		current_address += size;      }  addr = align_pe32_section (current_address);  if (addr != current_address)    {      grub_util_info ("padding %d bytes for the PE32 section alignment",		      addr - current_address);      write_padding (out, addr - current_address);    }    return addr;}/* Write data sections.  */static Elf32_Addrwrite_data_sections (FILE *out, Elf32_Addr current_address,		     Elf32_Ehdr *e, Elf32_Shdr *sections,		     Elf32_Half section_entsize, Elf32_Half num_sections,		     const char *strtab){  Elf32_Half i;  Elf32_Shdr *s;  Elf32_Addr addr;    for (i = 0, s = sections;       i < num_sections;       i++, s = (Elf32_Shdr *) ((char *) s + section_entsize))    if (is_data_section (s))      {	Elf32_Word align = grub_le_to_cpu32 (s->sh_addralign);	Elf32_Off offset = grub_le_to_cpu32 (s->sh_offset);	Elf32_Word size = grub_le_to_cpu32 (s->sh_size);	const char *name = strtab + grub_le_to_cpu32 (s->sh_name);		if (align)	  {	    addr = align_address (current_address, align);	    if (current_address != addr)	      {		grub_util_info ("padding %d bytes for the ELF section alignment",				addr - current_address);		write_padding (out, addr - current_address);		current_address = addr;	      }	  }		grub_util_info ("writing the data section %s at 0x%x",			name, current_address);		if (s->sh_type == grub_cpu_to_le32 (SHT_NOBITS))	  write_padding (out, size);	else	  if (fwrite ((char *) e + offset, size, 1, out) != 1)	    grub_util_error ("write failed");		current_address += size;      }    addr = align_pe32_section (current_address);  if (addr != current_address)    {      grub_util_info ("padding %d bytes for the PE32 section alignment",		      addr - current_address);      write_padding (out, addr - current_address);    }    return addr;}/* Write modules.  */static Elf32_Addrmake_mods_section (FILE *out, Elf32_Addr current_address,		   const char *dir, char *mods[]){  struct grub_util_path_list *path_list;  grub_size_t total_module_size;  struct grub_util_path_list *p;  struct grub_module_info modinfo;  Elf32_Addr addr;  path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);    total_module_size = sizeof (struct grub_module_info);  for (p = path_list; p; p = p->next)    {      total_module_size += (grub_util_get_image_size (p->name)			    + sizeof (struct grub_module_header));    }  grub_util_info ("the total module size is 0x%x", total_module_size);  modinfo.magic = grub_cpu_to_le32 (GRUB_MODULE_MAGIC);  modinfo.offset = grub_cpu_to_le32 (sizeof (modinfo));  modinfo.size = grub_cpu_to_le32 (total_module_size);  if (fwrite (&modinfo, sizeof (modinfo), 1, out) != 1)    grub_util_error ("write failed");  for (p = path_list; p; p = p->next)    {      struct grub_module_header header;      size_t mod_size;      char *mod_image;            grub_util_info ("adding module %s", p->name);            mod_size = grub_util_get_image_size (p->name);      header.offset = grub_cpu_to_le32 (sizeof (header));      header.size = grub_cpu_to_le32 (mod_size + sizeof (header));            mod_image = grub_util_read_image (p->name);      if (fwrite (&header, sizeof (header), 1, out) != 1	  || fwrite (mod_image, mod_size, 1, out) != 1)	grub_util_error ("write failed");      free (mod_image);    }    for (p = path_list; p; )    {      struct grub_util_path_list *q;      q = p->next;      free (p);      p = q;    }        current_address += total_module_size;    addr = align_pe32_section (current_address);  if (addr != current_address)    {      grub_util_info ("padding %d bytes for the PE32 section alignment",		      addr - current_address);      write_padding (out, addr - current_address);    }  return addr;}/* Make a .reloc section.  */static Elf32_Addrmake_reloc_section (FILE *out, Elf32_Addr current_address, Elf32_Ehdr *e, 		    Elf32_Addr *section_addresses, Elf32_Shdr *sections,		    Elf32_Half section_entsize, Elf32_Half num_sections,		    const char *strtab){  Elf32_Half i;  Elf32_Shdr *s;

⌨️ 快捷键说明

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