|
CS471/571 - Operating Systems
| Displaying exercises/e7/solution/elf.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <elf.h>
void *mapfile(char *filename)
{
struct stat st;
int fd = open(filename, O_RDONLY);
if (fstat(fd, &st) < 0) {
perror("fstat");
return NULL;
}
void *mem = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (mem == MAP_FAILED) {
perror("mmap");
return NULL;
}
return mem;
}
void header(Elf64_Ehdr *hdr)
{
printf("ELF Header:\n");
printf(" Magic: ");
for(int i = 0; i < EI_NIDENT; i++) printf("%02x ", hdr->e_ident[i]);
printf("\n");
printf(" Class: ");
switch(hdr->e_ident[EI_CLASS]) {
case ELFCLASSNONE: printf("NONE\n"); break;
case ELFCLASS32: printf("ELF32\n"); break;
case ELFCLASS64: printf("ELF64\n"); break;
}
printf(" Data: ");
switch(hdr->e_ident[EI_DATA]) {
case ELFDATANONE: printf("Unknown data format.\n"); break;
case ELFDATA2LSB: printf("2's complement, little-endian\n"); break;
case ELFDATA2MSB: printf("2's complement, big-endian\n"); break;
}
printf(" Version: %d", hdr->e_ident[EI_VERSION]);
switch(hdr->e_ident[EI_VERSION]) {
case EV_NONE: printf("(invalid)\n"); break;
case EV_CURRENT: printf("(current)\n"); break;
}
printf(" OS/ABI: ");
switch(hdr->e_ident[EI_OSABI]) {
case ELFOSABI_SYSV: printf("UNIX - System V\n"); break;
case ELFOSABI_HPUX: printf("HP-UX\n"); break;
case ELFOSABI_NETBSD: printf("NetBSD\n"); break;
case ELFOSABI_LINUX: printf("Linux\n"); break;
case ELFOSABI_SOLARIS: printf("Solaris\n");break;
case ELFOSABI_IRIX: printf("IRIX\n"); break;
case ELFOSABI_FREEBSD: printf("FreeBSD\n");break;
case ELFOSABI_TRU64: printf("TRU64 UNIX\n");break;
case ELFOSABI_ARM: printf("ARM architecture\n");break;
case ELFOSABI_STANDALONE: printf("Stand-alone (embedded)\n");break;
}
printf(" ABI Version: %d\n", hdr->e_ident[EI_ABIVERSION]);
printf(" Type: ");
switch(hdr->e_type) {
case ET_NONE: printf("NONE (Unknown type)\n"); break;
case ET_REL : printf("REL (Relocatable file)\n"); break;
case ET_EXEC: printf("EXEC (Executable file)\n"); break;
case ET_DYN : printf("DYN (Shared object)\n"); break;
case ET_CORE: printf("CORE (Core file)\n"); break;
}
printf(" Machine: ");
switch(hdr->e_machine) {
case EM_NONE : printf("An unknown machine\n"); break;
case EM_M32 : printf("AT&T WE 32100\n"); break;
case EM_SPARC : printf("Sun Microsystems SPARC\n"); break;
case EM_386 : printf("Intel 80386\n"); break;
case EM_68K : printf("Motorola 68000\n"); break;
case EM_88K : printf("Motorola 88000\n"); break;
case EM_860 : printf("Intel 80860\n"); break;
case EM_MIPS : printf("MIPS RS3000 (big-endian only)\n"); break;
case EM_PARISC : printf("HP/PA\n"); break;
case EM_SPARC32PLUS: printf("SPARC with enhanced instruction set\n"); break;
case EM_PPC : printf("PowerPC\n"); break;
case EM_PPC64 : printf("PowerPC 64-bit\n"); break;
case EM_S390 : printf("IBM S/390\n"); break;
case EM_ARM : printf("Advanced RISC Machines\n"); break;
case EM_SH : printf("Renesas SuperH\n"); break;
case EM_SPARCV9 : printf("SPARC v9 64-bit\n"); break;
case EM_IA_64 : printf("Intel Itanium\n"); break;
case EM_X86_64 : printf("Advanced Micro Devices X86-64\n"); break;
case EM_VAX : printf("DEC Vax\n"); break;
}
printf(" Version: 0x%x\n", hdr->e_version);
printf(" Entry point address: 0x%x\n", hdr->e_entry);
printf(" Start of program headers: %d (bytes into file)\n", hdr->e_phoff);
printf(" Start of section headers: %d (bytes into file)\n", hdr->e_shoff);
printf(" Flags: 0x%x\n", hdr->e_flags);
printf(" Size of this header: %d (bytes)\n", hdr->e_ehsize);
printf(" Size of program headers: %d (bytes)\n", hdr->e_phentsize);
printf(" Number of program headers: %d\n", hdr->e_phnum);
printf(" Size of section headers: %d (bytes)\n", hdr->e_shentsize);
printf(" Number of section headers: %d\n", hdr->e_shnum);
printf(" Section header string table index: %d\n", hdr->e_shstrndx);
}
int main(int argc, char *argv[])
{
if (argc < 2) {
printf("Usage: elf <elf-file>\n");
return 0;
}
void *memory = mapfile(argv[1]);
if (memory == NULL) return 0;
header(memory);
return 0;
}
|