Skip to content

Commit

Permalink
Added fatelf-validate utility.
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Sep 25, 2009
1 parent e1488bd commit 7ba2a87
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 11 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Expand Up @@ -11,6 +11,7 @@ ADD_EXECUTABLE(fatelf-replace utils/fatelf-replace.c utils/fatelf-utils.c)
ADD_EXECUTABLE(fatelf-remove utils/fatelf-remove.c utils/fatelf-utils.c)
ADD_EXECUTABLE(fatelf-verify utils/fatelf-verify.c utils/fatelf-utils.c)
ADD_EXECUTABLE(fatelf-split utils/fatelf-split.c utils/fatelf-utils.c)
ADD_EXECUTABLE(fatelf-validate utils/fatelf-validate.c utils/fatelf-utils.c)

# end of CMakeLists.txt ...

2 changes: 1 addition & 1 deletion utils/fatelf-glue.c
Expand Up @@ -40,7 +40,7 @@ static int fatelf_glue(const char *out, const char **bins, const int bincount)
FATELF_record *record = &header->records[i];

record->offset = binary_offset;
xread_elf_header(fname, fd, record);
xread_elf_header(fname, fd, 0, record);

// make sure we don't have a duplicate target.
for (j = 0; j < i; j++)
Expand Down
2 changes: 1 addition & 1 deletion utils/fatelf-replace.c
Expand Up @@ -16,7 +16,7 @@ static int xfind_fatelf_record_by_elf(const char *fname, const int fd,
FATELF_record record;
int i;

xread_elf_header(fname, fd, &record);
xread_elf_header(fname, fd, 0, &record);
for (i = 0; i < ((int)header->num_records); i++)
{
if (fatelf_record_matches(&header->records[i], &record))
Expand Down
17 changes: 9 additions & 8 deletions utils/fatelf-utils.c
Expand Up @@ -156,11 +156,12 @@ void xcopyfile_range(const char *in, const int infd,
} // xcopyfile_range


void xread_elf_header(const char *fname, const int fd, FATELF_record *record)
void xread_elf_header(const char *fname, const int fd, const uint64_t offset,
FATELF_record *record)
{
const uint8_t magic[4] = { 0x7F, 0x45, 0x4C, 0x46 };
uint8_t buf[20]; // we only care about the first 20 bytes.
xlseek(fname, fd, 0, SEEK_SET); // just in case.
xlseek(fname, fd, offset, SEEK_SET);
xread(fname, fd, buf, sizeof (buf), 1);
if (memcmp(magic, buf, sizeof (magic)) != 0)
xfail("'%s' is not an ELF binary");
Expand Down Expand Up @@ -734,24 +735,24 @@ const char *fatelf_get_byteorder_name(const uint8_t byteorder)
} // get_byteorder_name


static const char *get_byteorder_target_name(const uint8_t byteorder)
const char *fatelf_get_byteorder_target_name(const uint8_t byteorder)
{
if (byteorder == FATELF_LITTLEENDIAN)
return "le";
else if (byteorder == FATELF_BIGENDIAN)
return "be";
return NULL;
} // get_byteorder_target_name
} // fatelf_get_byteorder_target_name


const char *get_wordsize_name(const uint8_t wordsize)
const char *fatelf_get_wordsize_target_name(const uint8_t wordsize)
{
if (wordsize == FATELF_32BITS)
return "32bits";
else if (wordsize == FATELF_64BITS)
return "64bits";
return NULL;
} // get_wordsize_name
} // fatelf_get_wordsize_target_name



Expand All @@ -761,8 +762,8 @@ const char *fatelf_get_target_string(const FATELF_record *rec, const int wants)
static char buffer[128];
const fatelf_osabi_info *osabi = get_osabi_by_id(rec->osabi);
const fatelf_machine_info *machine = get_machine_by_id(rec->machine);
const char *order = get_byteorder_target_name(rec->byte_order);
const char *wordsize = get_wordsize_name(rec->word_size);
const char *order = fatelf_get_byteorder_target_name(rec->byte_order);
const char *wordsize = fatelf_get_wordsize_target_name(rec->word_size);

buffer[0] = '\0';

Expand Down
5 changes: 4 additions & 1 deletion utils/fatelf-utils.h
Expand Up @@ -83,7 +83,8 @@ void xcopyfile_range(const char *in, const int infd,
const uint64_t offset, const uint64_t size);

// read the parts of an ELF header we care about.
void xread_elf_header(const char *fname, const int fd, FATELF_record *rec);
void xread_elf_header(const char *fname, const int fd, const uint64_t offset,
FATELF_record *rec);

// How many bytes to allocate for a FATELF_header.
size_t fatelf_header_size(const int bincount);
Expand All @@ -110,6 +111,8 @@ const char *fatelf_get_target_string(const FATELF_record *rec, const int wants);
// these return static strings of english words.
const char *fatelf_get_wordsize_string(const uint8_t wordsize);
const char *fatelf_get_byteorder_name(const uint8_t byteorder);
const char *fatelf_get_byteorder_target_name(const uint8_t byteorder);
const char *fatelf_get_wordsize_target_name(const uint8_t wordsize);

// Find the desired record in the FatELF header, based on a string in
// various formats.
Expand Down
74 changes: 74 additions & 0 deletions utils/fatelf-validate.c
@@ -0,0 +1,74 @@
/**
* FatELF; support multiple ELF binaries in one file.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/

#define FATELF_UTILS 1
#include "fatelf-utils.h"

static int fatelf_validate(const char *fname)
{
const int fd = xopen(fname, O_RDONLY, 0755);
FATELF_header *header = xread_fatelf_header(fname, fd);
int i;

if (header->reserved0 != 0)
xfail("FatELF header reserved field isn't zero.");

for (i = 0; i < ((int)header->num_records); i++)
{
const FATELF_record *rec = &header->records[i];
FATELF_record elfrec;

if (rec->reserved0 != 0)
xfail("Reserved0 field is not zero in record #%d", i);
else if (rec->reserved1 != 0)
xfail("Reserved1 field is not zero in record #%d", i);
else if (!get_machine_by_id(rec->machine))
xfail("Unknown machine #%d in record #%d", (int) rec->machine, i);
else if (!get_osabi_by_id(rec->osabi))
xfail("Unknown OSABI #%d in record #%d", (int) rec->osabi, i);
else if (!fatelf_get_byteorder_target_name(rec->byte_order))
xfail("Unknown byte order #%d in record #%d", (int) rec->byte_order, i);
else if (!fatelf_get_wordsize_target_name(rec->word_size))
xfail("Unknown word size #%d in record #%d", (int) rec->word_size, i);
else if (rec->offset != align_to_page(rec->offset))
xfail("Unaligned binary in record #%d", i);
else if ((rec->offset + rec->size) < rec->offset)
{
xfail("Bogus offset+size (%llu + %llu) in record #%d",
(unsigned long long) rec->offset,
(unsigned long long) rec->size, i);
} // else if
else if ( (rec->word_size == FATELF_32BITS) &&
((rec->offset + rec->size) > 0xFFFFFFFF) )
{
xfail("32-bit binary past 4 gig limit in record #%d", i);
} // else if

// !!! FIXME: check for overlap between records?

xread_elf_header(fname, fd, rec->offset, &elfrec);
if (!fatelf_record_matches(rec, &elfrec))
xfail("ELF header differs from FatELF data in record #%d", i);
} // for

xclose(fname, fd);
free(header);
return 0; // success
} // fatelf_validate


int main(int argc, const char **argv)
{
xfatelf_init(argc, argv);
if (argc != 2) // this could stand to use getopt(), later.
xfail("USAGE: %s <in>", argv[0]);
return fatelf_validate(argv[1]);
} // main

// end of fatelf-validate.c ...

0 comments on commit 7ba2a87

Please sign in to comment.