Skip to content

Commit

Permalink
Added fatelf-remove utility.
Browse files Browse the repository at this point in the history
  • Loading branch information
icculus committed Sep 24, 2009
1 parent 0468475 commit a5a2097
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Expand Up @@ -8,6 +8,7 @@ ADD_EXECUTABLE(fatelf-glue utils/fatelf-glue.c utils/fatelf-utils.c)
ADD_EXECUTABLE(fatelf-info utils/fatelf-info.c utils/fatelf-utils.c)
ADD_EXECUTABLE(fatelf-extract utils/fatelf-extract.c utils/fatelf-utils.c)
ADD_EXECUTABLE(fatelf-replace utils/fatelf-replace.c utils/fatelf-utils.c)
ADD_EXECUTABLE(fatelf-remove utils/fatelf-remove.c utils/fatelf-utils.c)

# end of CMakeLists.txt ...

75 changes: 75 additions & 0 deletions utils/fatelf-remove.c
@@ -0,0 +1,75 @@
/**
* 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_remove(const char *out, const char *fname,
const char *target)
{
const int fd = xopen(fname, O_RDONLY, 0755);
FATELF_header *header = xread_fatelf_header(fname, fd);
const int idx = xfind_fatelf_record(header, target);
const int outfd = xopen(out, O_WRONLY | O_CREAT | O_TRUNC, 0755);
uint64_t offset = FATELF_DISK_FORMAT_SIZE(((int)header->num_records));
int i;

unlink_on_xfail = out;

// pad out some bytes for the header we'll write at the end...
xwrite_zeros(out, outfd, (size_t) offset);

for (i = 0; i < ((int) header->num_records); i++)
{
if (i != idx) // not the thing we're removing?
{
const uint64_t binary_offset = align_to_page(offset);
FATELF_record *rec = &header->records[i];

// append this binary to the final file, padded to page alignment.
xwrite_zeros(out, outfd, (size_t) (binary_offset - offset));
xcopyfile_range(fname, fd, out, outfd, binary_offset, rec->size);

rec->offset = binary_offset;
offset = binary_offset + rec->size;
} // if
} // for

// remove the record we chopped out.
header->num_records--;
if (idx < ((int) header->num_records))
{
void *dst = &header->records[idx];
const void *src = &header->records[idx+1];
const size_t count = (header->num_records - idx);
memmove(dst, src, sizeof (FATELF_record) * count);
} // if

// Write the actual FatELF header now...
xwrite_fatelf_header(out, outfd, header);

xclose(out, outfd);
xclose(fname, fd);
free(header);

unlink_on_xfail = NULL;

return 0; // success.
} // fatelf_remove


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

// end of fatelf-remove.c ...

0 comments on commit a5a2097

Please sign in to comment.