Skip to content

Commit

Permalink
Cleaned up that #include nastiness.
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Sep 7, 2009
1 parent 269ba2a commit c6e9ed8
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 75 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Expand Up @@ -3,7 +3,8 @@ PROJECT(FatELF)

INCLUDE_DIRECTORIES(include)
ADD_DEFINITIONS(-c99 -Wall -Werror)
ADD_EXECUTABLE(fatelf-glue utils/fatelf-glue.c)

ADD_EXECUTABLE(fatelf-glue utils/fatelf-glue.c utils/fatelf-utils.c)

# end of CMakeLists.txt ...

17 changes: 8 additions & 9 deletions utils/fatelf-glue.c
Expand Up @@ -6,9 +6,8 @@
* This file written by Ryan C. Gordon.
*/

// !!! FIXME: this include is nasty.
#define FATELF_UTILS 1
#include "fatelf-utils.c"
#include "fatelf-utils.h"

static int fatelf_glue(const char *out, const char **bins, const int bincount)
{
Expand All @@ -18,12 +17,12 @@ static int fatelf_glue(const char *out, const char **bins, const int bincount)
const int outfd = xopen(out, O_WRONLY | O_CREAT | O_TRUNC, 0755);
uint64_t offset = FATELF_DISK_FORMAT_SIZE(bincount);

unlink_on_fail = out;
unlink_on_xfail = out;

if (bincount == 0)
fail("Nothing to do.");
xfail("Nothing to do.");
else if (bincount > 0xFFFF)
fail("Too many binaries (max is %d).", 0xFFFF);
xfail("Too many binaries (max is %d).", 0xFFFF);

header->magic = FATELF_MAGIC;
header->version = FATELF_FORMAT_VERSION;
Expand All @@ -48,7 +47,7 @@ static int fatelf_glue(const char *out, const char **bins, const int bincount)
(other->abi == info->abi) &&
(other->abi_version == info->abi_version);
if (same)
fail("'%s' and '%s' are for the same target.", bins[j], fname);
xfail("'%s' and '%s' are for the same target.", bins[j], fname);
} // for

// append this binary to the final file, padded to page alignment.
Expand All @@ -64,17 +63,17 @@ static int fatelf_glue(const char *out, const char **bins, const int bincount)
xclose(out, outfd);
free(header);

unlink_on_fail = NULL;
unlink_on_xfail = NULL;

return 0; // success.
} // fatelf_glue


int main(int argc, const char **argv)
{
memset(zerobuf, '\0', sizeof (zerobuf)); // just in case.
xfatelf_init(argc, argv);
if (argc < 4) // this could stand to use getopt(), later.
fail("USAGE: %s <out> <bin1> <bin2> [... binN]", argv[0]);
xfail("USAGE: %s <out> <bin1> <bin2> [... binN]", argv[0]);
return fatelf_glue(argv[1], &argv[2], argc - 2);
} // main

Expand Down
121 changes: 56 additions & 65 deletions utils/fatelf-utils.c
Expand Up @@ -8,27 +8,14 @@

/* code shared between all FatELF utilities... */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdarg.h>
#include <fcntl.h>
#include <stdint.h>
#include <assert.h>

#include "fatelf.h"

#if !FATELF_UTILS
#error Do not compile this file directly.
#endif

static const char *unlink_on_fail = NULL;
#define FATELF_UTILS 1
#include "fatelf-utils.h"

const char *unlink_on_xfail = NULL;
static uint8_t zerobuf[4096];

// Report an error to stderr and terminate immediately with exit(1).
static void fail(const char *fmt, ...)
void xfail(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
Expand All @@ -37,60 +24,60 @@ static void fail(const char *fmt, ...)
fprintf(stderr, "\n");
fflush(stderr);

if (unlink_on_fail != NULL)
unlink(unlink_on_fail); // don't care if this fails.
unlink_on_fail = NULL;
if (unlink_on_xfail != NULL)
unlink(unlink_on_xfail); // don't care if this fails.
unlink_on_xfail = NULL;

exit(1);
} // fail
} // xfail


// Wrap malloc() with a fail(), so this returns memory or calls exit().
// Wrap malloc() with an xfail(), so this returns memory or calls exit().
// Memory is guaranteed to be initialized to zero.
static void *xmalloc(const size_t len)
void *xmalloc(const size_t len)
{
void *retval = calloc(1, len);
if (retval == NULL)
fail("Out of memory!");
xfail("Out of memory!");
return retval;
} // xmalloc


// fail() on error.
static int xopen(const char *fname, const int flags, const int perms)
// xfail() on error.
int xopen(const char *fname, const int flags, const int perms)
{
const int retval = open(fname, flags, perms);
if (retval == -1)
fail("Failed to open '%s': %s", fname, strerror(errno));
xfail("Failed to open '%s': %s", fname, strerror(errno));
return retval;
} // xopen


// fail() on error, handle EINTR.
static ssize_t xread(const char *fname, const int fd, void *buf,
const size_t len, const int must_read)
// xfail() on error, handle EINTR.
ssize_t xread(const char *fname, const int fd, void *buf,
const size_t len, const int must_read)
{
ssize_t rc;
while (((rc = read(fd,buf,len)) == -1) && (errno == EINTR)) { /* spin */ }
if ( (rc == -1) || ((must_read) && (rc != len)) )
fail("Failed to read '%s': %s", fname, strerror(errno));
xfail("Failed to read '%s': %s", fname, strerror(errno));
return rc;
} // xread


// fail() on error, handle EINTR.
static ssize_t xwrite(const char *fname, const int fd,
const void *buf, const size_t len)
// xfail() on error, handle EINTR.
ssize_t xwrite(const char *fname, const int fd,
const void *buf, const size_t len)
{
ssize_t rc;
while (((rc = write(fd,buf,len)) == -1) && (errno == EINTR)) { /* spin */ }
if (rc == -1)
fail("Failed to write '%s': %s", fname, strerror(errno));
xfail("Failed to write '%s': %s", fname, strerror(errno));
return rc;
} // xwrite

// fail() on error, handle EINTR.
static void xwrite_zeros(const char *fname, const int fd, size_t len)
// xfail() on error, handle EINTR.
void xwrite_zeros(const char *fname, const int fd, size_t len)
{
while (len > 0)
{
Expand All @@ -100,28 +87,28 @@ static void xwrite_zeros(const char *fname, const int fd, size_t len)
} // while
} // xwrite_zeros

// fail() on error, handle EINTR.
static void xclose(const char *fname, const int fd)
// xfail() on error, handle EINTR.
void xclose(const char *fname, const int fd)
{
int rc;
while ( ((rc = close(fd)) == -1) && (errno == EINTR) ) { /* spin. */ }
if (rc == -1)
fail("Failed to close '%s': %s", fname, strerror(errno));
xfail("Failed to close '%s': %s", fname, strerror(errno));
} // xopen


// fail() on error.
static void xlseek(const char *fname, const int fd,
const off_t offset, const int whence)
// xfail() on error.
void xlseek(const char *fname, const int fd,
const off_t offset, const int whence)
{
if (lseek(fd, offset, whence) == -1)
fail("Failed to seek in '%s': %s", fname, strerror(errno));
xfail("Failed to seek in '%s': %s", fname, strerror(errno));
} // xlseek


// fail() on error.
static uint64_t xcopyfile(const char *in, const int infd,
const char *out, const int outfd)
// xfail() on error.
uint64_t xcopyfile(const char *in, const int infd,
const char *out, const int outfd)
{
// !!! FIXME: use sendfile() on Linux (if it'll handle non-socket fd's).
static uint8_t buf[256 * 1024];
Expand All @@ -138,34 +125,33 @@ static uint64_t xcopyfile(const char *in, const int infd,
} // xcopyfile


static void xread_elf_header(const char *fname, const int fd,
FATELF_binary_info *info)
void xread_elf_header(const char *fname, const int fd, FATELF_binary_info *info)
{
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.
xread(fname, fd, buf, sizeof (buf), 1);
if (memcmp(magic, buf, sizeof (magic)) != 0)
fail("'%s' is not an ELF binary");
xfail("'%s' is not an ELF binary");
info->abi = (uint16_t) buf[7];
info->abi_version = (uint16_t) buf[8];
if (buf[5] == 0) // bigendian
info->cpu = (((uint32_t)buf[18]) << 8) | (((uint32_t)buf[19]));
else if (buf[5] == 1) // littleendian
info->cpu = (((uint32_t)buf[19]) << 8) | (((uint32_t)buf[18]));
else
fail("Unexpected data encoding in '%s'", fname);
xfail("Unexpected data encoding in '%s'", fname);
} // xread_elf_header


static inline size_t fatelf_header_size(const int bincount)
size_t fatelf_header_size(const int bincount)
{
return (sizeof (FATELF_header) + (sizeof (FATELF_binary_info) * bincount));
} // fatelf_header_size


// Write a native uint16_t to a buffer in littleendian format.
static inline uint8_t *putui16(uint8_t *ptr, const uint16_t val)
uint8_t *putui16(uint8_t *ptr, const uint16_t val)
{
*(ptr++) = ((uint8_t) ((val >> 0) & 0xFF));
*(ptr++) = ((uint8_t) ((val >> 8) & 0xFF));
Expand All @@ -174,7 +160,7 @@ static inline uint8_t *putui16(uint8_t *ptr, const uint16_t val)


// Write a native uint32_t to a buffer in littleendian format.
static inline uint8_t *putui32(uint8_t *ptr, const uint32_t val)
uint8_t *putui32(uint8_t *ptr, const uint32_t val)
{
*(ptr++) = ((uint8_t) ((val >> 0) & 0xFF));
*(ptr++) = ((uint8_t) ((val >> 8) & 0xFF));
Expand All @@ -185,7 +171,7 @@ static inline uint8_t *putui32(uint8_t *ptr, const uint32_t val)


// Write a native uint64_t to a buffer in littleendian format.
static inline uint8_t *putui64(uint8_t *ptr, const uint64_t val)
uint8_t *putui64(uint8_t *ptr, const uint64_t val)
{
*(ptr++) = ((uint8_t) ((val >> 0) & 0xFF));
*(ptr++) = ((uint8_t) ((val >> 8) & 0xFF));
Expand All @@ -200,15 +186,15 @@ static inline uint8_t *putui64(uint8_t *ptr, const uint64_t val)


// Read a littleendian uint16_t from a buffer in native format.
static inline uint8_t *getui16(uint8_t *ptr, uint16_t *val)
uint8_t *getui16(uint8_t *ptr, uint16_t *val)
{
*val = ( (((uint16_t) ptr[0]) << 0) | (((uint16_t) ptr[1]) << 8) );
return ptr + sizeof (*val);
} // getui16


// Read a littleendian uint32_t from a buffer in native format.
static inline uint8_t *getui32(uint8_t *ptr, uint32_t *val)
uint8_t *getui32(uint8_t *ptr, uint32_t *val)
{
*val = ( (((uint32_t) ptr[0]) << 0) |
(((uint32_t) ptr[1]) << 8) |
Expand All @@ -219,7 +205,7 @@ static inline uint8_t *getui32(uint8_t *ptr, uint32_t *val)


// Read a littleendian uint64_t from a buffer in native format.
static inline uint8_t *getui64(uint8_t *ptr, uint64_t *val)
uint8_t *getui64(uint8_t *ptr, uint64_t *val)
{
*val = ( (((uint64_t) ptr[0]) << 0) |
(((uint64_t) ptr[1]) << 8) |
Expand All @@ -233,8 +219,8 @@ static inline uint8_t *getui64(uint8_t *ptr, uint64_t *val)
} // getui64


static void xwrite_fatelf_header(const char *fname, const int fd,
const FATELF_header *header)
void xwrite_fatelf_header(const char *fname, const int fd,
const FATELF_header *header)
{
const size_t buflen = FATELF_DISK_FORMAT_SIZE(header->num_binaries);
uint8_t *buf = (uint8_t *) xmalloc(buflen);
Expand Down Expand Up @@ -262,7 +248,7 @@ static void xwrite_fatelf_header(const char *fname, const int fd,
} // xwrite_fatelf_header

// don't forget to free() the returned pointer!
static FATELF_header *xread_fatelf_header(const char *fname, const int fd)
FATELF_header *xread_fatelf_header(const char *fname, const int fd)
{
FATELF_header *header = NULL;
uint8_t buf[8];
Expand All @@ -281,9 +267,9 @@ static FATELF_header *xread_fatelf_header(const char *fname, const int fd)
ptr = getui16(ptr, &bincount);

if (magic != FATELF_MAGIC)
fail("'%s' is not a FatELF binary.", fname);
xfail("'%s' is not a FatELF binary.", fname);
else if (version != 1)
fail("'%s' uses an unknown FatELF version.", fname);
xfail("'%s' uses an unknown FatELF version.", fname);

buflen = FATELF_DISK_FORMAT_SIZE(bincount) - sizeof (buf);
ptr = fullbuf = (uint8_t *) xmalloc(buflen);
Expand All @@ -309,13 +295,18 @@ static FATELF_header *xread_fatelf_header(const char *fname, const int fd)
} // xread_fatelf_header


static uint64_t align_to_page(const uint64_t offset)
uint64_t align_to_page(const uint64_t offset)
{
const size_t pagesize = 4096; // !!! FIXME: hardcoded pagesize.
const size_t overflow = (offset % pagesize);
return overflow ? (offset + (pagesize - overflow)) : offset;
} // align_to_page


void xfatelf_init(int argc, const char **argv)
{
memset(zerobuf, '\0', sizeof (zerobuf)); // just in case.
} // xfatelf_init

// end of fatelf-utils.c ...

0 comments on commit c6e9ed8

Please sign in to comment.