/* Rounding; only works for n = power of two */ #define ROUND(a, n) (((((u_long)(a))+(n)-1)) & ~((n)-1)) #define ROUNDDOWN(a, n) (((u_long)(a)) & ~((n)-1))
/* Rounding; only works for n = power of two */ #define ROUND(a, n) (((((u_long)(a))+(n)-1)) & ~((n)-1)) #define ROUNDDOWN(a, n) (((u_long)(a)) & ~((n)-1))
/* This file defines standard ELF types, structures, and macros. Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ian Lance Taylor <ian@cygnus.com>. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef _KER_ELF_H #define _KER_ELF_H
/* ELF defination file from GNU C Library. We simplefied this * file for our lab, removing definations about ELF64, structs and * enums which we don't care. */
externintreadelf(u_char* binary, int size); /* overview: input a elf format file name from control line, call the readelf function to parse it. params: argc: the number of parameters argv: array of parameters, argv[1] shuold be the file name. */
intmain(int argc,char *argv[]) { FILE* fp; int fsize; unsignedchar *p;
// argc < 2 说明只输入了 readelf,没有输入文件名 if (argc < 2) { printf("Please input the filename.\n"); return0; } // 没有打开文件 if ((fp = fopen(argv[1], "rb")) == NULL) { printf("File not found\n"); return0; }
#include"kerelf.h" #include<stdio.h> /* Overview: * Check whether it is a ELF file. * * Pre-Condition: * binary must longer than 4 byte. * * Post-Condition: * Return 0 if `binary` isn't an elf. Otherwise * return 1. */ // 这里就是在检验魔数 intis_elf_format(u_char *binary) { Elf32_Ehdr *ehdr = (Elf32_Ehdr *)binary; if (ehdr->e_ident[EI_MAG0] == ELFMAG0 && ehdr->e_ident[EI_MAG1] == ELFMAG1 && ehdr->e_ident[EI_MAG2] == ELFMAG2 && ehdr->e_ident[EI_MAG3] == ELFMAG3) { return1; }
return0; }
/* Overview: * read an elf format binary file. get ELF's information * * Pre-Condition: * `binary` can't be NULL and `size` is the size of binary. * * Post-Condition: * Return 0 if success. Otherwise return < 0. * If success, output address of every section in ELF. */
/* disable kernel mode cache */ mfc0 t0, CP0_CONFIG and t0, ~0x7 ori t0, 0x2 mtc0 t0, CP0_CONFIG /* To do: set up stack you can reference the memory layout in the include/mmu.h */
loop: j loop nop END(_start) /*the function defined in asm.h*/
2.3.1 伪指令补充
set,如注释所言
/*.set is used to instruct how the assembler works and control the order of instructions */ .set mips2 .set reorder
/* * Definitions used by the "cons" device in GXemul. * * $Id: dev_cons.h,v 1.2 2006/07/05 05:38:36 debug Exp $ * This file is in the public domain. */
/* * $Id: hello.c,v 1.3 2006/05/22 04:53:52 debug Exp $ * * GXemul demo: Hello World * * This file is in the Public Domain. */
#include"dev_cons.h"
/* Note: The ugly cast to a signed int (32-bit) causes the address to be sign-extended correctly on MIPS when compiled in 64-bit mode */ #define PHYSADDR_OFFSET ((signed int)0xA0000000)
int longFlag; int negFlag; int width; int prec; int ladjust; char padc;
int length;
fmt++; } /* for(;;) */
/* special termination call */ OUTPUT(arg, "\0", 1); }
/* --------------- local help functions --------------------- */ intPrintChar(char *buf, char c, int length, int ladjust) { int i;
if (length < 1) length = 1; if (ladjust) { *buf = c; for (i = 1; i < length; i++) buf[i] = ' '; } else { for (i = 0; i < length - 1; i++) buf[i] = ' '; buf[length - 1] = c; } return length; }
intPrintString(char *buf, char *s, int length, int ladjust) { int i; int len = 0; char *s1 = s; while (*s1++) len++; if (length < len) length = len;
if (ladjust) { for (i = 0; i < len; i++) buf[i] = s[i]; for (i = len; i < length; i++) buf[i] = ' '; } else { for (i = 0; i < length - len; i++) buf[i] = ' '; for (i = length - len; i < length; i++) buf[i] = s[i - length + len]; } return length; }
intPrintNum(char *buf, unsignedlong u, int base, int negFlag, int length, int ladjust, char padc, int upcase) { /* algorithm : * 1. prints the number from left to right in reverse form. * 2. fill the remaining spaces with padc if length is longer than * the actual length * TRICKY : if left adjusted, no "0" padding. * if negtive, insert "0" padding between "0" and number. * 3. if (!ladjust) we reverse the whole string including paddings * 4. otherwise we only reverse the actual string representing the num. */
int actualLength = 0; char *p = buf; int i;
do { int tmp = u % base; if (tmp <= 9) { *p++ = '0' + tmp; } elseif (upcase) { *p++ = 'A' + tmp - 10; } else { *p++ = 'a' + tmp - 10; } u /= base; } while (u != 0);
if (negFlag) { *p++ = '-'; }
/* figure out actual length and adjust the maximum length */ actualLength = p - buf; if (length < actualLength) length = actualLength;
/* add padding */ if (ladjust) { padc = ' '; } if (negFlag && !ladjust && (padc == '0')) { for (i = actualLength - 1; i < length - 1; i++) buf[i] = padc; buf[length - 1] = '-'; } else { for (i = actualLength; i < length; i++) buf[i] = padc; }
/* prepare to reverse the string */ { int begin = 0; int end; if (ladjust) { end = actualLength - 1; } else { end = length - 1; }
intPrintString(char *buf, char *s, int length, int ladjust) { int i; int len = 0; char *s1 = s; while (*s1++) len++; if (length < len) length = len;
if (ladjust) { for (i = 0; i < len; i++) buf[i] = s[i]; for (i = len; i < length; i++) buf[i] = ' '; } else { for (i = 0; i < length - len; i++) buf[i] = ' '; for (i = length - len; i < length; i++) buf[i] = s[i - length + len]; } return length; }
这个函数实现的功能就是把字符串 s 中内容拷贝到 buf 中。同样涉及到一个左对齐还是右对齐的问题,如果 ladjust(left-adjust)大于零,那就进行左对齐,否则右对齐,里面引入了一个 len 就是为了实现这个功能(对齐补空格)。
最后是 PrintNum
intPrintNum(char *buf, unsignedlong u, int base, int negFlag, int length, int ladjust, char padc, int upcase) { /* algorithm : * 1. prints the number from left to right in reverse form. * 2. fill the remaining spaces with padc if length is longer than * the actual length * TRICKY : if left adjusted, no "0" padding. * if negtive, insert "0" padding between "0" and number. * 3. if (!ladjust) we reverse the whole string including paddings * 4. otherwise we only reverse the actual string representing the num. */
int actualLength = 0; char *p = buf; int i;
do { int tmp = u % base; if (tmp <= 9) { *p++ = '0' + tmp; } elseif (upcase) { *p++ = 'A' + tmp - 10; } else { *p++ = 'a' + tmp - 10; } u /= base; } while (u != 0);
if (negFlag) { *p++ = '-'; }
/* figure out actual length and adjust the maximum length */ actualLength = p - buf; if (length < actualLength) length = actualLength;
/* add padding */ if (ladjust) { padc = ' '; } if (negFlag && !ladjust && (padc == '0')) { for (i = actualLength - 1; i < length - 1; i++) buf[i] = padc; buf[length - 1] = '-'; } else { for (i = actualLength; i < length; i++) buf[i] = padc; }
/* prepare to reverse the string */ { int begin = 0; int end; if (ladjust) { end = actualLength - 1; } else { end = length - 1; }