Skip to content

Commit

Permalink
Added xread_fatelf_header().
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Sep 7, 2009
1 parent 1095d4e commit 269ba2a
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 6 deletions.
2 changes: 1 addition & 1 deletion utils/fatelf-glue.c
Expand Up @@ -13,7 +13,7 @@
static int fatelf_glue(const char *out, const char **bins, const int bincount)
{
int i = 0;
const size_t struct_size = header_size(bincount);
const size_t struct_size = fatelf_header_size(bincount);
FATELF_header *header = (FATELF_header *) xmalloc(struct_size);
const int outfd = xopen(out, O_WRONLY | O_CREAT | O_TRUNC, 0755);
uint64_t offset = FATELF_DISK_FORMAT_SIZE(bincount);
Expand Down
94 changes: 89 additions & 5 deletions utils/fatelf-utils.c
Expand Up @@ -158,6 +158,12 @@ static void xread_elf_header(const char *fname, const int fd,
} // xread_elf_header


static inline 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)
{
Expand Down Expand Up @@ -193,6 +199,40 @@ static inline uint8_t *putui64(uint8_t *ptr, const uint64_t val)
} // putui64


// Read a littleendian uint16_t from a buffer in native format.
static inline 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)
{
*val = ( (((uint32_t) ptr[0]) << 0) |
(((uint32_t) ptr[1]) << 8) |
(((uint32_t) ptr[2]) << 16) |
(((uint32_t) ptr[3]) << 24) );
return ptr + sizeof (*val);
} // getui32


// Read a littleendian uint64_t from a buffer in native format.
static inline uint8_t *getui64(uint8_t *ptr, uint64_t *val)
{
*val = ( (((uint64_t) ptr[0]) << 0) |
(((uint64_t) ptr[1]) << 8) |
(((uint64_t) ptr[2]) << 16) |
(((uint64_t) ptr[3]) << 24) |
(((uint64_t) ptr[4]) << 32) |
(((uint64_t) ptr[5]) << 40) |
(((uint64_t) ptr[6]) << 48) |
(((uint64_t) ptr[7]) << 56) );
return ptr + sizeof (*val);
} // getui64


static void xwrite_fatelf_header(const char *fname, const int fd,
const FATELF_header *header)
{
Expand Down Expand Up @@ -221,12 +261,53 @@ static void xwrite_fatelf_header(const char *fname, const int fd,
free(buf);
} // xwrite_fatelf_header


// Return enough bytes to definitely cover both memory and on-disk format.
static inline size_t header_size(const int bincount)
// don't forget to free() the returned pointer!
static FATELF_header *xread_fatelf_header(const char *fname, const int fd)
{
return (sizeof (FATELF_header) + (sizeof (FATELF_binary_info) * bincount));
} // header_size
FATELF_header *header = NULL;
uint8_t buf[8];
uint8_t *fullbuf = NULL;
uint8_t *ptr = buf;
uint32_t magic = 0;
uint16_t version = 0;
uint16_t bincount = 0;
size_t buflen = 0;
int i = 0;

xlseek(fname, fd, 0, SEEK_SET); // just in case.
xread(fname, fd, buf, sizeof (buf), 1);
ptr = getui32(ptr, &magic);
ptr = getui16(ptr, &version);
ptr = getui16(ptr, &bincount);

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

buflen = FATELF_DISK_FORMAT_SIZE(bincount) - sizeof (buf);
ptr = fullbuf = (uint8_t *) xmalloc(buflen);
xread(fname, fd, fullbuf, buflen, 1);

header = (FATELF_header *) xmalloc(fatelf_header_size(bincount));
header->magic = magic;
header->version = version;
header->num_binaries = bincount;

for (i = 0; i < bincount; i++)
{
ptr = getui16(ptr, &header->binaries[i].abi);
ptr = getui16(ptr, &header->binaries[i].abi_version);
ptr = getui32(ptr, &header->binaries[i].cpu);
ptr = getui64(ptr, &header->binaries[i].offset);
} // for

assert(ptr == (fullbuf + buflen));

free(fullbuf);
return header;
} // xread_fatelf_header


static uint64_t align_to_page(const uint64_t offset)
{
Expand All @@ -235,3 +316,6 @@ static uint64_t align_to_page(const uint64_t offset)
return overflow ? (offset + (pagesize - overflow)) : offset;
} // align_to_page


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

0 comments on commit 269ba2a

Please sign in to comment.