CS520
Spring 2016
Laboratory 5
Friday February 26
The lab must be submitted prior to noon on Sunday February 28.


The goal for this lab is to read a file and confirm that it is a 64-bit, little-endian ELF file containing RISC-V instructions. The file will be given as the only command-line argument to the program.

I recommend that to simplify the program you first open the file and read the whole program into a malloc-ed buffer. A simple way to do this is to read the file twice using getc. The first time you can discard the bytes that are read because you are just counting the number of bytes in the file. Once you know how long the file is, then malloc the buffer. And then read the file a second time into the buffer. (If you cannot open the file, print this error message to stderr on its own line, "cannot open", and follow it with the name of the file given on the command line.

Next you want to check the first 16 bytes in the file, which contains the identification information for the file. The first four bytes should contain the ELF "magic" numbers: 0x7F, 0x45, 0x4C and 0x46. If this check fails print the error message "Not an ELF" to stderr on its own line and exit the program.

Now check two more bytes of the identication information. The fifth byte should be 0x02, indicating that it is a 64-bit file. The sixth byte should be 0x01, indicating that it is a little endian file. For each of these checks that fail, print a specific error message to stderr. The error messages should be of the following form: "Not a 64-bit file", or "Not in little endian". These errors should be printed on their own line. If either check fails, exit the program.

Now that you have confirmed that the file is a 64-bit, little-endian ELF file, check the rest of the ELF header. Here is a C struct that describes the ELF header:

typedef struct {
  unsigned char  e_ident[16];
  unsigned short e_type;
  unsigned short e_machine;
  unsigned int   e_version;
  unsigned long  e_entry;
  unsigned long  e_phoff;
  unsigned long  e_shoff;
  unsigned int   e_flags;
  unsigned short e_ehsize;
  unsigned short e_phentsize;
  unsigned short e_phnum;
  unsigned short e_shentsize;
  unsigned short e_shnum;
  unsigned short e_shstrndx;
} Elf64_Ehdr;
(Note that the identification information is the first 16 bytes in this struct.) Confirm that the e_type field is either 0x0001 or 0x0002, indicating a relocatable object file or an executable file. Confirm that the e_machine field is 0x00f3, indicating the RISC-V. For each of these checks that fail, print a specific error message to stderr. The error messages should be of the following form: "Not a relocatable object or an executable file", or "Not a RISC-V file". These errors should be printed on their own line. If either of these checks fail, exit the program.

The final step in the lab is to print the following values to stderr:

  1. the file length
  2. the value of the e_shoff field of the header
  3. the value of the e_shnum field of the header
  4. the value of the e_shstrndx field of the header
Print all these values in decimal on their own line with a label from the list above. For example: fprintf(stderr, the file length is %d\n"m fileLength);

Put all your source code in a single file, "emRISCV.c". (This is the beginning of your RISC-V emulator for Program 3.)

There will be a variety of test files in ~cs520/public/lab5. Some of them will be 64-bit ELF files and some will not be.

Turn in this laboratory by typing:

% ~cs520/bin/submit lab5 emRISCV.c

Submissions can be checked by typing:

% ~cs520/bin/scheck lab5

Remember that there are no late submissions of labs. Submit what you have prior to 12noon on Sunday February 28.


Last modified on February 20, 2016.

Comments and questions should be directed to pjh@cs.unh.edu