Add basic cpio features
This commit is contained in:
parent
a4ce9f6f05
commit
1e3bcfc8cd
@ -9,7 +9,7 @@ LOCAL_C_INCLUDES := \
|
||||
jni/ndk-compression/lz4/lib/ \
|
||||
jni/ndk-compression/bzip2/
|
||||
|
||||
LOCAL_SRC_FILES := main.c unpack.c repack.c hexpatch.c parseimg.c compress.c utils.c
|
||||
LOCAL_SRC_FILES := main.c unpack.c repack.c hexpatch.c parseimg.c compress.c utils.c cpio.c
|
||||
LOCAL_CFLAGS += -DZLIB_CONST
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
|
158
jni/magiskboot/cpio.c
Normal file
158
jni/magiskboot/cpio.c
Normal file
@ -0,0 +1,158 @@
|
||||
#include "magiskboot.h"
|
||||
#include "cpio.h"
|
||||
|
||||
static uint32_t x8u(char *hex) {
|
||||
uint32_t val, inpos = 8, outpos;
|
||||
char pattern[6];
|
||||
|
||||
while (*hex == '0') {
|
||||
hex++;
|
||||
if (!--inpos) return 0;
|
||||
}
|
||||
// Because scanf gratuitously treats %*X differently than printf does.
|
||||
sprintf(pattern, "%%%dx%%n", inpos);
|
||||
sscanf(hex, pattern, &val, &outpos);
|
||||
if (inpos != outpos) error(1, "bad cpio header");
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void cpio_vec_insert(vector *v, cpio_file *n) {
|
||||
cpio_file *f, *t;
|
||||
int shift = 0;
|
||||
// Insert in alphabet order
|
||||
vec_for_each(v, f) {
|
||||
if (shift) {
|
||||
vec_entry(v)[_i] = t;
|
||||
t = f;
|
||||
continue;
|
||||
}
|
||||
t = f;
|
||||
if (strcmp(f->filename, n->filename) == 0) {
|
||||
// Replace, then all is done
|
||||
vec_entry(v)[_i] = n;
|
||||
return;
|
||||
} else if (strcmp(f->filename, n->filename) > 0) {
|
||||
// Insert, then start shifting
|
||||
vec_entry(v)[_i] = n;
|
||||
t = f;
|
||||
shift = 1;
|
||||
}
|
||||
}
|
||||
vec_push_back(v, t);
|
||||
}
|
||||
|
||||
// Parse cpio file to a vector of cpio_file
|
||||
void parse_cpio(const char *filename, vector *v) {
|
||||
printf("\nLoading cpio: [%s]\n\n", filename);
|
||||
int fd = open(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
error(1, "Cannot open %s", filename);
|
||||
cpio_newc_header header;
|
||||
cpio_file *f;
|
||||
while(read(fd, &header, 110) == 110) {
|
||||
f = calloc(sizeof(*f), 1);
|
||||
// f->ino = x8u(header.ino);
|
||||
f->mode = x8u(header.mode);
|
||||
f->uid = x8u(header.uid);
|
||||
f->gid = x8u(header.gid);
|
||||
// f->nlink = x8u(header.nlink);
|
||||
// f->mtime = x8u(header.mtime);
|
||||
f->filesize = x8u(header.filesize);
|
||||
// f->devmajor = x8u(header.devmajor);
|
||||
// f->devminor = x8u(header.devminor);
|
||||
// f->rdevmajor = x8u(header.rdevmajor);
|
||||
// f->rdevminor = x8u(header.rdevminor);
|
||||
f->namesize = x8u(header.namesize);
|
||||
// f->check = x8u(header.check);
|
||||
f->filename = malloc(f->namesize);
|
||||
read(fd, f->filename, f->namesize);
|
||||
file_align(fd, 4, 0);
|
||||
if (f->filesize) {
|
||||
f->data = malloc(f->filesize);
|
||||
read(fd, f->data, f->filesize);
|
||||
file_align(fd, 4, 0);
|
||||
}
|
||||
vec_push_back(v, f);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void dump_cpio(const char *filename, vector *v) {
|
||||
printf("\nDump cpio: [%s]\n\n", filename);
|
||||
int fd = open_new(filename);
|
||||
unsigned inode = 300000;
|
||||
char header[111];
|
||||
cpio_file *f;
|
||||
vec_for_each(v, f) {
|
||||
if (f->remove) continue;
|
||||
sprintf(header, "070701%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
|
||||
inode++, // f->ino
|
||||
f->mode,
|
||||
f->uid,
|
||||
f->gid,
|
||||
1, // f->nlink
|
||||
0, // f->mtime
|
||||
f->filesize,
|
||||
0, // f->devmajor
|
||||
0, // f->devminor
|
||||
0, // f->rdevmajor
|
||||
0, // f->rdevminor
|
||||
f->namesize,
|
||||
0 // f->check
|
||||
);
|
||||
write(fd, header, 110);
|
||||
write(fd, f->filename, f->namesize);
|
||||
file_align(fd, 4, 1);
|
||||
if (f->filesize) {
|
||||
write(fd, f->data, f->filesize);
|
||||
file_align(fd, 4, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cpio_vec_destroy(vector *v) {
|
||||
// Free each cpio_file
|
||||
cpio_file *f;
|
||||
vec_for_each(v, f) {
|
||||
free(f->filename);
|
||||
free(f->data);
|
||||
free(f);
|
||||
}
|
||||
vec_destroy(v);
|
||||
}
|
||||
|
||||
void cpio_rm(int recursive, const char *entry, vector *v) {
|
||||
cpio_file *f;
|
||||
vec_for_each(v, f) {
|
||||
if ((recursive && strncmp(f->filename, entry, strlen(entry)) == 0)
|
||||
|| (strcmp(f->filename, entry) == 0) ) {
|
||||
f->remove = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cpio_mkdir(mode_t mode, const char *entry, vector *v) {
|
||||
cpio_file *f = calloc(sizeof(*f), 1);
|
||||
f->mode = S_IFDIR | mode;
|
||||
f->namesize = strlen(entry) + 1;
|
||||
f->filename = malloc(f->namesize);
|
||||
memcpy(f->filename, entry, f->namesize);
|
||||
cpio_vec_insert(v, f);
|
||||
}
|
||||
|
||||
void cpio_add(mode_t mode, const char *entry, const char *filename, vector *v) {
|
||||
int fd = open(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
error(1, "Cannot open %s", filename);
|
||||
cpio_file *f = calloc(sizeof(*f), 1);
|
||||
f->mode = S_IFREG | mode;
|
||||
f->namesize = strlen(entry) + 1;
|
||||
f->filename = malloc(f->namesize);
|
||||
memcpy(f->filename, entry, f->namesize);
|
||||
f->filesize = lseek(fd, 0, SEEK_END);
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
f->data = malloc(f->filesize);
|
||||
read(fd, f->data, f->filesize);
|
||||
cpio_vec_insert(v, f);
|
||||
}
|
42
jni/magiskboot/cpio.h
Normal file
42
jni/magiskboot/cpio.h
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef _CPIO_H_
|
||||
#define _CPIO_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct cpio_file {
|
||||
// uint32_t ino;
|
||||
uint32_t mode;
|
||||
uint32_t uid;
|
||||
uint32_t gid;
|
||||
// uint32_t nlink;
|
||||
// uint32_t mtime;
|
||||
uint32_t filesize;
|
||||
// uint32_t devmajor;
|
||||
// uint32_t devminor;
|
||||
// uint32_t rdevmajor;
|
||||
// uint32_t rdevminor;
|
||||
uint32_t namesize;
|
||||
// uint32_t check;
|
||||
char *filename;
|
||||
void *data;
|
||||
int remove;
|
||||
} cpio_file;
|
||||
|
||||
typedef struct cpio_newc_header {
|
||||
char magic[6];
|
||||
char ino[8];
|
||||
char mode[8];
|
||||
char uid[8];
|
||||
char gid[8];
|
||||
char nlink[8];
|
||||
char mtime[8];
|
||||
char filesize[8];
|
||||
char devmajor[8];
|
||||
char devminor[8];
|
||||
char rdevmajor[8];
|
||||
char rdevminor[8];
|
||||
char namesize[8];
|
||||
char check[8];
|
||||
} cpio_newc_header;
|
||||
|
||||
#endif
|
@ -1,27 +1,11 @@
|
||||
#include "magiskboot.h"
|
||||
|
||||
static int hex2int(char c) {
|
||||
int first = c / 16 - 3;
|
||||
int second = c % 16;
|
||||
int result = first * 10 + second;
|
||||
if(result > 9) result--;
|
||||
return result;
|
||||
}
|
||||
|
||||
static unsigned hex2ascii(char c, char d) {
|
||||
int high = hex2int(c) * 16;
|
||||
int low = hex2int(d);
|
||||
return high + low;
|
||||
}
|
||||
|
||||
static void hexstr2str(const char *hex, unsigned char *str) {
|
||||
char buf = 0;
|
||||
for(int i = 0, length = strlen(hex); i < length; ++i){
|
||||
if(i % 2){
|
||||
str[i / 2] = hex2ascii(buf, hex[i]);
|
||||
} else{
|
||||
buf = hex[i];
|
||||
}
|
||||
static void hex2byte(const char *hex, unsigned char *str) {
|
||||
char high, low;
|
||||
for (int i = 0, length = strlen(hex); i < length; i += 2) {
|
||||
high = toupper(hex[i]) - '0';
|
||||
low = toupper(hex[i + 1]) - '0';
|
||||
str[i / 2] = ((high > 9 ? high - 7 : high) << 4) + (low > 9 ? low - 7 : low);
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,8 +16,8 @@ void hexpatch(const char *image, const char *from, const char *to) {
|
||||
mmap_rw(image, &file, &filesize);
|
||||
pattern = malloc(patternsize);
|
||||
patch = malloc(patchsize);
|
||||
hexstr2str(from, pattern);
|
||||
hexstr2str(to, patch);
|
||||
hex2byte(from, pattern);
|
||||
hex2byte(to, patch);
|
||||
for (size_t i = 0; i < filesize - patternsize; ++i) {
|
||||
if (memcmp(file + i, pattern, patternsize) == 0) {
|
||||
printf("Pattern %s found!\nPatching to %s\n", from, to);
|
||||
|
@ -3,7 +3,9 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sendfile.h>
|
||||
@ -48,12 +50,37 @@ typedef enum {
|
||||
QCDT,
|
||||
} file_t;
|
||||
|
||||
typedef enum {
|
||||
NONE,
|
||||
RM,
|
||||
MKDIR,
|
||||
ADD
|
||||
} command_t;
|
||||
|
||||
extern char *SUP_EXT_LIST[SUP_NUM];
|
||||
extern file_t SUP_TYPE_LIST[SUP_NUM];
|
||||
// Cannot declare in header, but place a copy here for convenience
|
||||
// char *SUP_EXT_LIST[SUP_NUM] = { "gz", "xz", "lzma", "bz2", "lz4" };
|
||||
// file_t SUP_TYPE_LIST[SUP_NUM] = { GZIP, XZ, LZMA, BZIP2, LZ4 };
|
||||
|
||||
// Vector
|
||||
typedef struct vector {
|
||||
size_t size;
|
||||
size_t cap;
|
||||
void **data;
|
||||
} vector;
|
||||
void vec_init(vector *v);
|
||||
void vec_push_back(vector *v, void *p);
|
||||
void vec_destroy(vector *v);
|
||||
|
||||
#define vec_size(v) (v)->size
|
||||
#define vec_cap(v) (v)->cap
|
||||
#define vec_entry(v) (v)->data
|
||||
// vec_for_each(vector *v, void *e)
|
||||
#define vec_for_each(v, e) \
|
||||
e = (v)->data[0]; \
|
||||
for (size_t _i = 0; _i < (v)->size; ++_i, e = (v)->data[_i])
|
||||
|
||||
// Global variables
|
||||
extern unsigned char *kernel, *ramdisk, *second, *dtb;
|
||||
extern boot_img_hdr hdr;
|
||||
@ -62,9 +89,8 @@ extern int mtk_kernel, mtk_ramdisk;
|
||||
|
||||
// Main entries
|
||||
void unpack(const char *image);
|
||||
void repack(const char *image);
|
||||
void repack(const char* orig_image, const char* out_image);
|
||||
void hexpatch(const char *image, const char *from, const char *to);
|
||||
void cpio(const char *filename);
|
||||
void error(int rc, const char *msg, ...);
|
||||
void parse_img(unsigned char *orig, size_t size);
|
||||
void cleanup();
|
||||
@ -79,12 +105,20 @@ void comp_file(const char *method, const char *from);
|
||||
int decomp(file_t type, const char *to, const unsigned char *from, size_t size);
|
||||
void decomp_file(char *from);
|
||||
|
||||
// CPIO
|
||||
void parse_cpio(const char *filename, vector *v);
|
||||
void dump_cpio(const char *filename, vector *v);
|
||||
void cpio_vec_destroy(vector *v);
|
||||
void cpio_rm(int recursive, const char *entry, vector *v);
|
||||
void cpio_mkdir(mode_t mode, const char *entry, vector *v);
|
||||
void cpio_add(mode_t mode, const char *entry, const char *filename, vector *v);
|
||||
|
||||
// Utils
|
||||
void mmap_ro(const char *filename, unsigned char **buf, size_t *size);
|
||||
void mmap_rw(const char *filename, unsigned char **buf, size_t *size);
|
||||
file_t check_type(const unsigned char *buf);
|
||||
void mem_align(size_t *pos, size_t align);
|
||||
void file_align(int fd, size_t align);
|
||||
void file_align(int fd, size_t align, int out);
|
||||
int open_new(const char *filename);
|
||||
void print_info();
|
||||
|
||||
|
@ -6,22 +6,36 @@
|
||||
|
||||
static void usage(char *arg0) {
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "%s --unpack <bootimage>\n", arg0);
|
||||
fprintf(stderr, " Unpack <bootimage> to kernel, ramdisk.cpio, (second), (dtb) into the\n current directory\n\n");
|
||||
fprintf(stderr, "%s --repack <bootimage>\n", arg0);
|
||||
fprintf(stderr, "%s --unpack <bootimg>\n", arg0);
|
||||
fprintf(stderr, " Unpack <bootimg> to kernel, ramdisk.cpio, (second), (dtb) into the\n current directory\n\n");
|
||||
|
||||
fprintf(stderr, "%s --repack <origbootimg> [outbootimg]\n", arg0);
|
||||
fprintf(stderr, " Repack kernel, ramdisk.cpio[.ext], second, dtb... from current directory\n");
|
||||
fprintf(stderr, " to new-image.img. <bootimage> is the original boot image you've just unpacked.\n");
|
||||
fprintf(stderr, " If file ramdisk.cpio exists, it will auto re-compress with the same method\n");
|
||||
fprintf(stderr, " used in <bootimage>, or it will attempt to find ramdisk.cpio.[ext], and repack\n");
|
||||
fprintf(stderr, " directly with the compressed file\n\n");
|
||||
fprintf(stderr, " to [outbootimg], or new-boot.img if not specified.\n");
|
||||
fprintf(stderr, " It will compress ramdisk.cpio with the same method used in <origbootimg>\n");
|
||||
fprintf(stderr, " if exists, or attempt to find ramdisk.cpio.[ext], and repack\n");
|
||||
fprintf(stderr, " directly with the compressed ramdisk file\n\n");
|
||||
|
||||
fprintf(stderr, "%s --hexpatch <file> <hexpattern1> <hexpattern2>\n", arg0);
|
||||
fprintf(stderr, " Search <hexpattern1> in <file>, and replace with <hexpattern2>\n\n");
|
||||
|
||||
fprintf(stderr, "%s --cpio-<cmd> <incpio> <outcpio> [flags...] [params...]\n", arg0);
|
||||
fprintf(stderr, " Do cpio related cmds to <incpio> and output to <outcpio>\n Supported commands:\n");
|
||||
fprintf(stderr, " --cpio-rm [-r] <entry>\n Remove entry from cpio, flag -r to remove recursively\n");
|
||||
fprintf(stderr, " --cpio-mkdir <mode> <entry>\n Create directory as an <entry>\n");
|
||||
fprintf(stderr, " --cpio-add <mode> <entry> <infile>\n Add <infile> as an <entry>; will replace <entry> if already exists\n");
|
||||
fprintf(stderr, " e.g: the command to add /tmp/tmpfile as entry init.magisk.rc:\n");
|
||||
fprintf(stderr, " %s --cpio-add <incpio> <outcpio> 0750 init.magisk.rc /tmp/tmpfile\n\n", arg0);
|
||||
|
||||
fprintf(stderr, "%s --compress[=method] <file>\n", arg0);
|
||||
fprintf(stderr, " Compress <file> with [method], or gzip if not specified.\n Supported methods: " SUP_LIST "\n\n");
|
||||
|
||||
fprintf(stderr, "%s --decompress <file>\n", arg0);
|
||||
fprintf(stderr, " Auto check file type, and decompress <file> accordingly\n Supported methods: " SUP_LIST "\n\n");
|
||||
|
||||
fprintf(stderr, "%s --cleanup\n", arg0);
|
||||
fprintf(stderr, " Cleanup the current working directory\n\n");
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -36,33 +50,67 @@ void error(int rc, const char *msg, ...) {
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
printf("MagiskBoot (by topjohnwu) - Boot Image Modification Tool\n");
|
||||
if (argc < 3) {
|
||||
if (strcmp(argv[1], "--cleanup") == 0) {
|
||||
cleanup();
|
||||
} else {
|
||||
usage(argv[0]);
|
||||
}
|
||||
} else {
|
||||
if (strcmp(argv[1], "--unpack") == 0) {
|
||||
unpack(argv[2]);
|
||||
} else if (strcmp(argv[1], "--repack") == 0) {
|
||||
repack(argv[2]);
|
||||
} else if (strcmp(argv[1], "--hexpatch") == 0) {
|
||||
if (argc < 5)
|
||||
usage(argv[0]);
|
||||
hexpatch(argv[2], argv[3], argv[4]);
|
||||
} else if (strcmp(argv[1], "--decompress") == 0) {
|
||||
decomp_file(argv[2]);
|
||||
} else if (strstr(argv[1], "--compress") != NULL) {
|
||||
char *method;
|
||||
method = strchr(argv[1], '=');
|
||||
if (method == NULL) method = "gzip";
|
||||
else method++;
|
||||
comp_file(method, argv[2]);
|
||||
} else {
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
if (argc > 1 && strcmp(argv[1], "--cleanup") == 0) {
|
||||
cleanup();
|
||||
} else if (argc > 2 && strcmp(argv[1], "--unpack") == 0) {
|
||||
unpack(argv[2]);
|
||||
} else if (argc > 2 && strcmp(argv[1], "--repack") == 0) {
|
||||
repack(argv[2], argc > 3 ? argv[3] : NEW_BOOT);
|
||||
} else if (argc > 2 && strcmp(argv[1], "--decompress") == 0) {
|
||||
decomp_file(argv[2]);
|
||||
} else if (argc > 2 && strncmp(argv[1], "--compress", 10) == 0) {
|
||||
char *method;
|
||||
method = strchr(argv[1], '=');
|
||||
if (method == NULL) method = "gzip";
|
||||
else method++;
|
||||
comp_file(method, argv[2]);
|
||||
} else if (argc > 4 && strcmp(argv[1], "--hexpatch") == 0) {
|
||||
hexpatch(argv[2], argv[3], argv[4]);
|
||||
} else if (argc > 4 && strncmp(argv[1], "--cpio", 6) == 0) {
|
||||
int recursive = 0;
|
||||
char *command;
|
||||
command_t cmd;
|
||||
command = strchr(argv[1] + 2, '-');
|
||||
if (command == NULL) usage(argv[0]);
|
||||
else command++;
|
||||
if (strcmp(command, "rm") == 0) {
|
||||
cmd = RM;
|
||||
if (argc > 5 && strcmp(argv[4], "-r") == 0) {
|
||||
recursive = 1;
|
||||
argv[4] = argv[5];
|
||||
argc--;
|
||||
}
|
||||
} else if (argc > 5 && strcmp(command, "mkdir") == 0) {
|
||||
cmd = MKDIR;
|
||||
} else if (argc > 6 && strcmp(command, "add") == 0) {
|
||||
cmd = ADD;
|
||||
} else {
|
||||
cmd = NONE;
|
||||
usage(argv[0]);
|
||||
}
|
||||
vector v;
|
||||
vec_init(&v);
|
||||
parse_cpio(argv[2], &v);
|
||||
switch(cmd) {
|
||||
case RM:
|
||||
cpio_rm(recursive, argv[4], &v);
|
||||
break;
|
||||
case MKDIR:
|
||||
cpio_mkdir(strtoul(argv[4], NULL, 8), argv[5], &v);
|
||||
break;
|
||||
case ADD:
|
||||
cpio_add(strtoul(argv[4], NULL, 8), argv[5], argv[6], &v);
|
||||
break;
|
||||
default:
|
||||
// Never happen
|
||||
break;
|
||||
}
|
||||
dump_cpio(argv[3], &v);
|
||||
cpio_vec_destroy(&v);
|
||||
} else {
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -20,20 +20,20 @@ static void restore_buf(const void *buf, size_t size, int fd) {
|
||||
}
|
||||
}
|
||||
|
||||
void repack(const char* image) {
|
||||
void repack(const char* orig_image, const char* out_image) {
|
||||
size_t size;
|
||||
unsigned char *orig;
|
||||
char name[PATH_MAX];
|
||||
|
||||
// Load original image
|
||||
mmap_ro(image, &orig, &size);
|
||||
mmap_ro(orig_image, &orig, &size);
|
||||
|
||||
// Parse original image
|
||||
printf("\nParsing boot image: [%s]\n\n", image);
|
||||
printf("\nParsing boot image: [%s]\n\n", orig_image);
|
||||
parse_img(orig, size);
|
||||
|
||||
// Create new image
|
||||
int fd = open_new(NEW_BOOT);
|
||||
int fd = open_new(out_image);
|
||||
|
||||
// Set all sizes to 0
|
||||
hdr.kernel_size = 0;
|
||||
@ -51,7 +51,7 @@ void repack(const char* image) {
|
||||
hdr.kernel_size += 512;
|
||||
}
|
||||
hdr.kernel_size += restore(KERNEL_FILE, fd);
|
||||
file_align(fd, hdr.page_size);
|
||||
file_align(fd, hdr.page_size, 1);
|
||||
|
||||
// Restore ramdisk
|
||||
if (mtk_ramdisk) {
|
||||
@ -90,22 +90,22 @@ void repack(const char* image) {
|
||||
if (!found)
|
||||
error(1, "No ramdisk exists!");
|
||||
hdr.ramdisk_size += restore(name, fd);
|
||||
file_align(fd, hdr.page_size);
|
||||
file_align(fd, hdr.page_size, 1);
|
||||
|
||||
// Restore second
|
||||
if (access(SECOND_FILE, R_OK) == 0) {
|
||||
hdr.second_size += restore(SECOND_FILE, fd);
|
||||
file_align(fd, hdr.page_size);
|
||||
file_align(fd, hdr.page_size, 1);
|
||||
}
|
||||
|
||||
// Restore dtb
|
||||
if (access(DTB_FILE, R_OK) == 0) {
|
||||
hdr.dt_size += restore(DTB_FILE, fd);
|
||||
file_align(fd, hdr.page_size);
|
||||
file_align(fd, hdr.page_size, 1);
|
||||
}
|
||||
|
||||
// Write header back
|
||||
printf("\nRepack to boot image: [%s]\n\n", NEW_BOOT);
|
||||
printf("\nRepack to boot image: [%s]\n\n", out_image);
|
||||
print_info();
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
write(fd, &hdr, sizeof(hdr));
|
||||
|
@ -62,13 +62,15 @@ void mem_align(size_t *pos, size_t align) {
|
||||
}
|
||||
}
|
||||
|
||||
void file_align(int fd, size_t align) {
|
||||
void file_align(int fd, size_t align, int out) {
|
||||
size_t pos = lseek(fd, 0, SEEK_CUR);
|
||||
size_t mask = align - 1;
|
||||
if (pos & mask) {
|
||||
pos += align - (pos & mask);
|
||||
ftruncate(fd, pos);
|
||||
lseek(fd, 0, SEEK_END);
|
||||
if (out) {
|
||||
ftruncate(fd, pos);
|
||||
}
|
||||
lseek(fd, pos, SEEK_SET);
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,3 +140,27 @@ void cleanup() {
|
||||
unlink(name);
|
||||
}
|
||||
}
|
||||
|
||||
void vec_init(vector *v) {
|
||||
vec_size(v) = 0;
|
||||
vec_cap(v) = 1;
|
||||
vec_entry(v) = malloc(sizeof(void*));
|
||||
}
|
||||
|
||||
void vec_push_back(vector *v, void *p) {
|
||||
if (v == NULL) return;
|
||||
if (vec_size(v) == vec_cap(v)) {
|
||||
vec_cap(v) *= 2;
|
||||
vec_entry(v) = realloc(vec_entry(v), sizeof(void*) * vec_cap(v));
|
||||
}
|
||||
vec_entry(v)[vec_size(v)] = p;
|
||||
++vec_size(v);
|
||||
}
|
||||
|
||||
void vec_destroy(vector *v) {
|
||||
// Will not free each entry!
|
||||
// Manually free each entry, then call this function
|
||||
vec_size(v) = 0;
|
||||
vec_cap(v) = 0;
|
||||
free(v->data);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user