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

📄 loader.c.svn-base

📁 模拟多核状态下龙芯处理器的功能
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
#else /* !BFD_LOADER, i.e., standalone loader */

  {
    FILE *fobj;
    long floc;
    Elf32_Ehdr elf_ehdr;
    Elf32_Phdr elf_phdr;
    Elf32_Shdr elf_shdr,elf_shstrtab;
    char *stringtable,*name;
    
    

    /* set up a local stack pointer, this is where the argv and envp
       data is written into program memory */
    ld_stack_base = MD_STACK_BASE;
    sp = ROUND_DOWN(MD_STACK_BASE - MD_MAX_ENVIRON, sizeof(dfloat_t));
    ld_stack_size = ld_stack_base - sp;

    /* initial stack pointer value */
    ld_environ_base = sp;

    /* record profile file name */
    ld_prog_fname = argv[0];

    /* load the program into memory, try both endians */
#if defined(__CYGWIN32__) || defined(_MSC_VER)
    fobj = fopen(argv[0], "rb");
#else
    fobj = fopen(argv[0], "r");
#endif
    if (!fobj)
      fatal("cannot open executable `%s'", argv[0]);

    if (fread(&elf_ehdr, sizeof(Elf32_Ehdr), 1, fobj) < 1)
      fatal("cannot read elf header from executable `%s'", argv[0]);

    /* record endian of target */
    
	if ((elf_ehdr.e_ident[EI_MAG0] != ELFMAG0)||
		(elf_ehdr.e_ident[EI_MAG1] != ELFMAG1)||
		(elf_ehdr.e_ident[EI_MAG2] != ELFMAG2)||
		(elf_ehdr.e_ident[EI_MAG3] != ELFMAG3))
		fatal("bad magic number in executable `%s' (not a MIPS file?)",argv[0]);	
	else if (elf_ehdr.e_type != ET_EXEC)
		fatal("%s is not executable",argv[0]);
	else if ((elf_ehdr.e_version != EV_CURRENT)||(elf_ehdr.e_ident[EI_VERSION] != EV_CURRENT))
		fatal("invalid object file version");
	else if(elf_ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
		ld_target_big_endian = FALSE;
	else 
		ld_target_big_endian = TRUE;

	/* load the program headers in the elf executable file */
	
	for (i=0; i<elf_ehdr.e_phnum; i++)
	{
		char *p;

		floc = elf_ehdr.e_phoff + i*sizeof(Elf32_Phdr);
		if (fseek(fobj, floc, 0) == -1)
	  	  fatal("could not reset location in executable");

		fread(&elf_phdr, sizeof(Elf32_Phdr), 1, fobj);
		switch (elf_phdr.p_type)
		{
			case PT_LOAD:
		
			/* check whether the segment is text segment or data segment */
			/* the .rdata section contributes to the text segment */
			
			if (elf_phdr.p_flags == (PF_X + PF_R))
			  ld_text_size = elf_phdr.p_memsz;
			if (elf_phdr.p_flags == (PF_W + PF_R))
			  ld_data_size = elf_phdr.p_memsz;
			/* load the loadable segment to the virtual memory */
						
			p = calloc(elf_phdr.p_filesz, sizeof(char));
			if (!p)
	     	  fatal("out of virtual memory");
			if (fseek(fobj, elf_phdr.p_offset, 0) == -1)
			  fatal("could not reset locate the segment in executable file");
			if (fread(p, elf_phdr.p_filesz, 1, fobj) < 1)
			  fatal("could not read the segment from executable file");

			/* copy program segment into simulator target memory */
	    	mem_bcopy(mem_access, mem, Write, elf_phdr.p_vaddr, p, elf_phdr.p_filesz);

	    	/* create tail alignment and copy into simulator target memory */
	    	mem_bzero(mem_access, mem, 
	    		elf_phdr.p_vaddr+elf_phdr.p_memsz, SEGMENT_ALIGNMENT_PADDING);

	    	/* release the section buffer */
	    	free(p);

	    	break;

			case PT_NULL:
						
			case PT_DYNAMIC:
						
			case PT_INTERP:

			case PT_NOTE:

			case PT_SHLIB:

			case PT_PHDR:

			case PT_LOPROC:

			case PT_HIPROC:

			break;
		} /* end of switch */
	}


#if 0
    Data_start = ahdr.data_start;
    Data_size = ahdr.dsize;
    Bss_size = ahdr.bsize;
    Bss_start = ahdr.bss_start;
    Gp_value = ahdr.gp_value;
    Text_entry = ahdr.entry;
#endif


    /* compute data segment size from data break point */
    ld_text_base = MD_TEXT_BASE;
    ld_data_base = MD_DATA_BASE;
    ld_prog_entry = elf_ehdr.e_entry;
    data_break = ld_data_base + ld_data_size;

	/* find the size of .text section header, it contains the actual instructions executecd */

	/* first find the section header string table */
    if (fseek(fobj, elf_ehdr.e_shoff + elf_ehdr.e_shstrndx*sizeof(Elf32_Shdr), 0) == -1)
	  fatal("could not locate the string table section header");
	if (fread(&elf_shstrtab, sizeof(Elf32_Shdr), 1, fobj) < 1)
	  fatal("could not read the information of string table");

	stringtable = calloc(elf_shstrtab.sh_size, sizeof(char));
	if (!stringtable)
	  fatal("out of virtual memory");

	if (fseek(fobj, elf_shstrtab.sh_offset, 0) == -1)
	  fatal("could not locate the string table");
	if ((i=fread(stringtable, elf_shstrtab.sh_size, 1, fobj)) < 1)
	  fatal("could not read the string table");

	/* begin to find the .text section header */
	if (fseek(fobj, elf_ehdr.e_shoff, 0) == -1)
	  fatal("could not locate the first section header");
	for (i=0; i<elf_ehdr.e_shnum; i++)
	{
		if (fread(&elf_shdr, sizeof(Elf32_Shdr), 1, fobj) <1)
		  fatal("could not read the section header");
		name = stringtable + elf_shdr.sh_name;
		if ((*name == '.')&&(*(name+1) == 't')&&(*(name+2) == 'e')
			&&(*(name+3) == 'x')&&(*(name+4) == 't')&&(*(name+5) == '\0'))
		  text_section_size = elf_shdr.sh_size;		
	}


    /* done with the executable, close it */
    if (fclose(fobj))
      fatal("could not close executable `%s'", argv[0]);
  }
#endif /* BFD_LOADER */

  /* perform sanity checks on segment ranges */
  if (!ld_text_base || !ld_text_size)
    fatal("executable is missing a `.text' section");
  if (!ld_data_base || !ld_data_size)
    fatal("executable is missing a `.data' section");
  if (!ld_prog_entry)
    fatal("program entry point not specified");

  /* determine byte/words swapping required to execute on this host */
  sim_swap_bytes = (endian_host_byte_order() != endian_target_byte_order());
  if (sim_swap_bytes)
    {
#if 0 /* FIXME: disabled until further notice... */
      /* cross-endian is never reliable, why this is so is beyond the scope
	 of this comment, e-mail me for details... */
      fprintf(stderr, "sim: *WARNING*: swapping bytes to match host...\n");
      fprintf(stderr, "sim: *WARNING*: swapping may break your program!\n");
#else
      fatal("binary endian does not match host endian");
#endif
    }
  sim_swap_words = (endian_host_word_order() != endian_target_word_order());
  if (sim_swap_words)
    {
#if 0 /* FIXME: disabled until further notice... */
      /* cross-endian is never reliable, why this is so is beyond the scope
	 of this comment, e-mail me for details... */
      fprintf(stderr, "sim: *WARNING*: swapping words to match host...\n");
      fprintf(stderr, "sim: *WARNING*: swapping may break your program!\n");
#else
      fatal("binary endian does not match host endian");
#endif
    }

  /* write [argc] to stack */
  temp = MD_SWAPW(argc);
  mem_access(mem, Write, sp, &temp, sizeof(word_t));
  sp += sizeof(word_t);

  /* skip past argv array and NULL */
  argv_addr = sp;
  sp = sp + (argc + 1) * sizeof(md_addr_t);

  /* save space for envp array and NULL */
  envp_addr = sp;
  for (i=0; envp[i]; i++)
    sp += sizeof(md_addr_t);
  sp += sizeof(md_addr_t);

  /* fill in aux vector --by zfx,new glibc may use it 
   * aux vectors are [type,val] pairs
   */
#define AT_PAGESZ  6
#define AT_NULL    0

  temp = AT_PAGESZ;
  mem_access(mem, Write, sp, &temp, sizeof(word_t));
  sp += sizeof(word_t);
  temp = MD_PAGE_SIZE;
  mem_access(mem, Write, sp, &temp, sizeof(word_t));
  sp += sizeof(word_t);

  temp = AT_NULL;
  mem_access(mem, Write, sp, &temp, sizeof(word_t));
  sp += sizeof(word_t);
  temp = 0;
  mem_access(mem, Write, sp, &temp, sizeof(word_t));
  sp += sizeof(word_t);

  /* fill in the argv pointer array and data */
  for (i=0; i<argc; i++)
    {
      /* write the argv pointer array entry */
      temp = MD_SWAPW(sp);
      mem_access(mem, Write, argv_addr + i*sizeof(md_addr_t),
		 &temp, sizeof(md_addr_t));
      /* and the data */
      mem_strcpy(mem_access, mem, Write, sp, argv[i]);
      sp += strlen(argv[i]) + 1;
    }
  /* terminate argv array with a NULL */
  mem_access(mem, Write, argv_addr + i*sizeof(md_addr_t),
	     &null_ptr, sizeof(md_addr_t));

  /* write envp pointer array and data to stack */
  for (i = 0; envp[i]; i++)
    {
      /* write the envp pointer array entry */
      temp = MD_SWAPW(sp);
      mem_access(mem, Write, envp_addr + i*sizeof(md_addr_t),
		 &temp, sizeof(md_addr_t));
      /* and the data */
      mem_strcpy(mem_access, mem, Write, sp, envp[i]);
      sp += strlen(envp[i]) + 1;
    }
  /* terminate the envp array with a NULL */
  mem_access(mem, Write, envp_addr + i*sizeof(md_addr_t),
	     &null_ptr, sizeof(md_addr_t));

  /* did we tromp off the stop of the stack? */
  if (sp > ld_stack_base)
    {
      /* we did, indicate to the user that MD_MAX_ENVIRON must be increased,
	 alternatively, you can use a smaller environment, or fewer
	 command line arguments */
      fatal("environment overflow, increase MD_MAX_ENVIRON in ss.h");
    }

  /* initialize the bottom of heap to top of data segment */
  //ld_brk_point = ROUND_UP(ld_data_base + ld_data_size, MD_PAGE_SIZE);
  ld_brk_point = ld_data_size + ld_data_base;
  
  /* set initial minimum stack pointer value to initial stack value */
  ld_stack_min = regs->regs_R[MD_REG_SP];

  /* set up initial register state */
  regs->regs_R[MD_REG_SP] = ld_environ_base;
  regs->regs_PC = ld_prog_entry;

  debug("ld_text_base: 0x%08x  ld_text_size: 0x%08x",
	ld_text_base, ld_text_size);
  debug("ld_data_base: 0x%08x  ld_data_size: 0x%08x",
	ld_data_base, ld_data_size);
  debug("ld_stack_base: 0x%08x  ld_stack_size: 0x%08x",
	ld_stack_base, ld_stack_size);
  debug("ld_prog_entry: 0x%08x", ld_prog_entry);

  /* finally, predecode the text segment... */
  /* we only execute the instructions in .text section */
 /*
  {
    md_addr_t addr;
    md_inst_t inst;
    enum md_fault_type fault;

    if (OP_MAX > 255)
      fatal("cannot perform fast decoding, too many opcodes");

    debug("sim: decoding text segment...");
    for (addr = ld_prog_entry;
	 addr < (ld_prog_entry + text_section_size);
	 addr += sizeof(md_inst_t))
      {
	fault = mem_access(mem, Read, addr, &inst, sizeof(inst));
	if (fault != md_fault_none)
	  fatal("could not read instruction memory");
	inst.a = (inst.a & ~0xff) | (word_t)MD_OP_ENUM(MD_OPFIELD(inst));
	fault = mem_access(mem, Write, addr, &inst, sizeof(inst));
	if (fault != md_fault_none)
	  fatal("could not write instruction memory");
      }
  }*/
}

⌨️ 快捷键说明

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