?? loader.c.svn-base
字號:
#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");
}
}*/
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -