LUI (load upper immediate) is used to build 32-bit constants and uses
the U-type format. LUI places the 32-bit U-immediate value into the
destination register rd, filling in the lowest 12 bits with zeros.
LUI
mstatus 寄存器的结构是怎么样的?
The mstatus (Machine Status) register is an MXLEN-bit read/write
register formatted as shown in figures below. It's a Control and
Status Register.
为什么要使用 -Wall 和 -Werror?
At section 3.9, we found that:
-Werror Turn all warnings into errors.
-Wall This enables all the warnings about constructions
that some users consider questionable, and that are easy to avoid (or
modify to prevent the warning), even in conjunction with macros. This
also enables some language-specific warnings.
To add these options, we can leverage compilers to identify potential
issues in our programs.
### Override checks when `make clean/clean-all/html` ifeq ($(findstring$(MAKECMDGOALS),clean|clean-all|html),)
### Print build info message $(info # Building $(NAME)-$(MAKECMDGOALS) [$(ARCH)])
//...
### Check: environment variable `$ARCH` must be in the supported list ARCHS = $(basename $(notdir $(shell ls $(AM_HOME)/scripts/*.mk))) ifeq ($(filter$(ARCHS), $(ARCH)), ) $(error Expected $$ARCH in {$(ARCHS)}, Got "$(ARCH)") endif
### Checks end here endif
Include AM makefile specified by $(ARCH):
1
-include$(AM_HOME)/scripts/$(ARCH).mk
in $(ARCH).mk,
it includes nemu.mk, which builds NEMU related driver
and runs NEMU.
it also includes another arch related .mk that overwrites
ARCH_H.
/* Count number of gp and fp argument registers used. */ words = crtl->args.info.words; n_gpr = crtl->args.info.regno; n_fpr = crtl->args.info.sse_regno;
if (cfun->va_list_gpr_size) { type = TREE_TYPE (gpr); t = build2 (MODIFY_EXPR, type, gpr, build_int_cst (type, n_gpr * 8)); TREE_SIDE_EFFECTS (t) = 1; expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); }
if (ix86_varargs_gpr_size || ix86_varargs_fpr_size) { /* Find the register save area. Prologue of the function save it right above stack frame. */ type = TREE_TYPE (sav); t = make_tree (type, frame_pointer_rtx); if (!ix86_varargs_gpr_size) t = fold_build_pointer_plus_hwi (t, -8 * X86_64_REGPARM_MAX);
Section header (Shdr) A file's section header table lets one locate all the file's sections. The section header table is an array of Elf32_Shdr or Elf64_Shdr structures. The ELF header's e_shoff member gives the byte offset from the beginning of the file to the section header table. e_shnum holds the number of entries the section header table contains. e_shentsize holds the size in bytes of each entry.
A section header table index is a subscript into this array. Some section header table indices are reserved: the initial entry and the indices between SHN_LORESERVE and SHN_HIRESERVE. The initial entry is used in ELF extensions for e_phnum, e_shnum, and e_shstrndx; in other cases, each field in the initial entry is set to zero. An object file does not have sections for these special indices:
SHN_UNDEF This value marks an undefined, missing, irrelevant, or otherwise meaningless section reference.
SHN_LORESERVE This value specifies the lower bound of the range of reserved indices.
SHN_LOPROC SHN_HIPROC Values greater in the inclusive range [SHN_LOPROC, SHN_HIPROC] are reserved for processor-specific semantics.
SHN_ABS This value specifies the absolute value for the corresponding reference. For example, a symbol defined relative to section number SHN_ABS has an ab‐ solute value and is not affected by relocation.
SHN_COMMON Symbols defined relative to this section are common symbols, such as FORTRAN COMMON or unallocated C external variables.
SHN_HIRESERVE This value specifies the upper bound of the range of reserved indices. The system reserves indices between SHN_LORESERVE and SHN_HIRESERVE, inclu‐ sive. The section header table does not contain entries for the reserved indices.
String and symbol tables String table sections hold null-terminated character sequences, commonly called strings. The ob‐ ject file uses these strings to represent symbol and section names. One references a string as an index into the string table section. The first byte, which is index zero, is defined to hold a null byte ('\0'). Similarly, a string table's last byte is defined to hold a null byte, ensur‐ ing null termination for all strings.
An object file's symbol table holds information needed to locate and relocate a program's sym‐ bolic definitions and references. A symbol table index is a subscript into this array.
typedef struct { uint32_t st_name; //This member holds an index into the object file's symbol string table, which holds character representations of the symbol names. If the value is nonzero, it represents a string table index that gives the symbol name. Otherwise, the symbol has no name. unsigned char st_info; unsigned char st_other; uint16_t st_shndx; Elf64_Addr st_value; uint64_t st_size; } Elf64_Sym;
后面遇到 jal 等跳转指令查找这个链表,计算偏移就可以了。
Differential Testing
框架已经实现好了相应的接口,实现一下比较寄存器的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14
boolisa_difftest_checkregs(CPU_state *ref_r, vaddr_t pc) { bool ok = true; for(int i=0;i<32;i++) { if(ref_r->gpr[i] != cpu.gpr[i]) { printf("\n [difftest] inequal reg value in %s: 0x%lx\n", regs[i], ref_r->gpr[i]); ok = false; } } if(ref_r->pc != cpu.pc) { printf("\n [difftest] inequal pc: 0x%lx\n",ref_r->pc); ok = false; } return ok; }