Added a bunch of enums for the ELF header.
This commit is contained in:
@@ -1,2 +1,3 @@
|
|||||||
*.o
|
*.o
|
||||||
bin/*
|
bin/*
|
||||||
|
.vscode/*
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#ifndef FUTIL_READ_SIZE
|
||||||
|
#define FUTIL_READ_SIZE 2097152 //Default here is 2MiB
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//Reference: https://stackoverflow.com/a/44894946
|
||||||
|
int ReadAllString(const char* path, char** content_ptr, size_t* bytes_read) {
|
||||||
|
if (!path || !content_ptr || !bytes_read) return 0;
|
||||||
|
|
||||||
|
FILE *file = fopen(path, "rb");
|
||||||
|
|
||||||
|
if (!file) {
|
||||||
|
fprintf(stderr, "Failed to open '%s'. %s.\n", path, strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *content = NULL, *temp = NULL;
|
||||||
|
size_t used = 0, capacity = 0, read = 0;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
if (used + FUTIL_READ_SIZE + 1 > capacity) {
|
||||||
|
capacity = used + FUTIL_READ_SIZE + 1;
|
||||||
|
|
||||||
|
temp = realloc(content, capacity);
|
||||||
|
|
||||||
|
if (!temp) {
|
||||||
|
fprintf(stderr, "Failed to realloc space for file contents. %s.\n", strerror(errno));
|
||||||
|
free(content);
|
||||||
|
fclose(file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
content = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
read = fread(content + used, 1, FUTIL_READ_SIZE, file);
|
||||||
|
|
||||||
|
if (read == 0) break;
|
||||||
|
|
||||||
|
used += read;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
//Shrink the buffer to fit just the contents of the buffer.
|
||||||
|
temp = realloc(content, used + 1);
|
||||||
|
|
||||||
|
if (!temp) {
|
||||||
|
fprintf(stderr, "Failed to realloc to only hold the file contents. %s.\n", strerror(errno));
|
||||||
|
free(content);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
content = temp;
|
||||||
|
content[used] = '\0';
|
||||||
|
|
||||||
|
*content_ptr = content;
|
||||||
|
*bytes_read = used;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
@@ -1,6 +1,227 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "futil.c"
|
||||||
|
|
||||||
|
typedef enum EIdent
|
||||||
|
{
|
||||||
|
EI_MAG0 = 0, //Magic number position zero - three.
|
||||||
|
EI_MAG1 = 1,
|
||||||
|
EI_MAG2 = 2,
|
||||||
|
EI_MAG3 = 3,
|
||||||
|
EI_CLASS = 4,
|
||||||
|
EI_DATA = 5,
|
||||||
|
EI_VERSION = 6,
|
||||||
|
EI_OSABI = 7,
|
||||||
|
EI_ABIVERSION = 8,
|
||||||
|
EI_PAD = 9,
|
||||||
|
EI_NIDENT = 16 //End of reserved 16 bytes for the header.
|
||||||
|
} EIdent;
|
||||||
|
|
||||||
|
typedef enum EIClass
|
||||||
|
{
|
||||||
|
ELFClassNone = 0,
|
||||||
|
ELFClass32 = 1,
|
||||||
|
ELFClass64 = 2
|
||||||
|
} EIClass;
|
||||||
|
|
||||||
|
typedef enum EI_Data
|
||||||
|
{
|
||||||
|
ELFDataNone = 0,
|
||||||
|
ELFDataLSB = 1,
|
||||||
|
ELFDataMSB = 2
|
||||||
|
} EIData;
|
||||||
|
|
||||||
|
typedef enum ELFType{
|
||||||
|
ET_None = 0, //No file type
|
||||||
|
ET_Rel = 1, //Relocatable file
|
||||||
|
ET_Exec = 2, //Executable file
|
||||||
|
ET_Dyn = 3, //Shared object file
|
||||||
|
ET_Core = 4, //Core file
|
||||||
|
ET_LOProc = 0xff00, //Processor
|
||||||
|
ET_HIProc = 0xffff //Specific
|
||||||
|
} ELFType;
|
||||||
|
|
||||||
|
typedef enum ELFMachine
|
||||||
|
{
|
||||||
|
EM_None = 0,
|
||||||
|
EM_M32 = 1, //AT&T WE 32100
|
||||||
|
EM_Sparc = 2,
|
||||||
|
EM_386 = 3,
|
||||||
|
EM_68k = 4,
|
||||||
|
EM_88k = 5,
|
||||||
|
EM_860 = 7,
|
||||||
|
EM_MIPS = 8
|
||||||
|
} ELFMachine;
|
||||||
|
|
||||||
|
typedef enum ELFOSABI
|
||||||
|
{
|
||||||
|
ELFOSABI_NONE = 0,
|
||||||
|
ELFOSABI_HPUX = 1,
|
||||||
|
ELFOSABI_NETBSD = 2,
|
||||||
|
ELFOSABI_GNU = 3,
|
||||||
|
ELFOSABI_LINUX = 3,
|
||||||
|
ELFOSABI_SOLARIS = 6,
|
||||||
|
ELFOSABI_AIX,
|
||||||
|
ELFOSABI_IRIX,
|
||||||
|
ELFOSABI_FREEBSD,
|
||||||
|
ELFOSABI_TRU64,
|
||||||
|
ELFOSABI_MODESTO,
|
||||||
|
ELFOSABI_OPENBSD,
|
||||||
|
ELFOSABI_OPENVMS,
|
||||||
|
ELFOSABI_NSK,
|
||||||
|
ELFOSABI_AROS,
|
||||||
|
ELFOSABI_FENIXOS,
|
||||||
|
ELFOSABI_CLOUDABI,
|
||||||
|
ELFOSABI_OPENVOS
|
||||||
|
} ELFOSABI;
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
printf("Hello, world!\n");
|
char* bytes;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
printf("No argcs\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ReadAllString(argv[1], &bytes, &size)) return 0;
|
||||||
|
|
||||||
|
char magic[5] = { bytes[EI_MAG0], bytes[EI_MAG1], bytes[EI_MAG2], bytes[EI_MAG3], '\0' };
|
||||||
|
|
||||||
|
if (strcmp(magic, "\x7f""ELF") != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to find ELF magic number in file header.\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else printf("Magic ELF number found!\n");
|
||||||
|
|
||||||
|
switch(bytes[EI_CLASS])
|
||||||
|
{
|
||||||
|
case ELFClass32:
|
||||||
|
printf("32-bit object detected\n");
|
||||||
|
break;
|
||||||
|
case ELFClass64:
|
||||||
|
printf("64-bit object detected\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Invalid class type detected\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(bytes[EI_DATA])
|
||||||
|
{
|
||||||
|
case ELFDataLSB:
|
||||||
|
printf("2's complement, little endian.\n");
|
||||||
|
break;
|
||||||
|
case ELFDataMSB:
|
||||||
|
printf("2's complement, big endian.\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Unknown byte order\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes[EI_VERSION] == 1) printf("Version: current\n");
|
||||||
|
else printf("Invalid version number\n");
|
||||||
|
|
||||||
|
switch(bytes[EI_OSABI])
|
||||||
|
{
|
||||||
|
case ELFOSABI_NONE:
|
||||||
|
printf("No extension or unspecified OS ABI.\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_HPUX:
|
||||||
|
printf("Hewlett-Packard HP-UX ABI\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_NETBSD:
|
||||||
|
printf("NetBSD ABI\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_LINUX:
|
||||||
|
printf("GNU ABI\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_SOLARIS:
|
||||||
|
printf("Sun Solaris ABI\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_AIX:
|
||||||
|
printf("AIX ABI\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_IRIX:
|
||||||
|
printf("IRIX ABI\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_FREEBSD:
|
||||||
|
printf("FreeBSd ABI\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_TRU64:
|
||||||
|
printf("Compaq TRU64 UNIX ABI\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_MODESTO:
|
||||||
|
printf("Novell Modesto ABI\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_OPENBSD:
|
||||||
|
printf("OpenBSD ABI\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_OPENVMS:
|
||||||
|
printf("Open VMS ABI\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_NSK:
|
||||||
|
printf("Hewlett-Packard Non-Stop Kernel ABI\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_AROS:
|
||||||
|
printf("Amiga Research OS ABI\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_FENIXOS:
|
||||||
|
printf("The FenixOS highly scalable multi-core OS ABI\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_CLOUDABI:
|
||||||
|
printf("Nuxi CloudABI ABI\n");
|
||||||
|
break;
|
||||||
|
case ELFOSABI_OPENVOS:
|
||||||
|
printf("Stratus Technologies OpenVOS ABI\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Reserved ABI (%d)\n", bytes[EI_ABIVERSION]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("ABI Version: %d\n", bytes[EI_ABIVERSION]);
|
||||||
|
|
||||||
|
switch(bytes[EI_NIDENT] + bytes[EI_NIDENT + 1])
|
||||||
|
{
|
||||||
|
case ET_None:
|
||||||
|
printf("No file type\n");
|
||||||
|
break;
|
||||||
|
case ET_Rel:
|
||||||
|
printf("Rel\n");
|
||||||
|
break;
|
||||||
|
case ET_Exec:
|
||||||
|
printf("Exec\n");
|
||||||
|
break;
|
||||||
|
case ET_Dyn:
|
||||||
|
printf("File type is DYN (Position-Independent Executable file)\n");
|
||||||
|
break;
|
||||||
|
case ET_Core:
|
||||||
|
printf("Core\n");
|
||||||
|
break;
|
||||||
|
case ET_LOProc:
|
||||||
|
printf("LO\n");
|
||||||
|
break;
|
||||||
|
case ET_HIProc:
|
||||||
|
printf("HI\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Unknown file type\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (bytes[EI_NIDENT + 2] + bytes[EI_NIDENT + 3]) {
|
||||||
|
case EM_860:
|
||||||
|
printf("Intel 80860\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Failed to identify machine type\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Read %ld bytes from file '%s'\n", size, argv[1]);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user