diff options
Diffstat (limited to 'tools/objtool/objtool.c')
| -rw-r--r-- | tools/objtool/objtool.c | 64 | 
1 files changed, 64 insertions, 0 deletions
| diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c index 7b97ce499405..43c1836a06b4 100644 --- a/tools/objtool/objtool.c +++ b/tools/objtool/objtool.c @@ -17,6 +17,7 @@  #include <stdbool.h>  #include <string.h>  #include <stdlib.h> +#include <unistd.h>  #include <subcmd/exec-cmd.h>  #include <subcmd/pager.h>  #include <linux/kernel.h> @@ -44,6 +45,64 @@ bool help;  const char *objname;  static struct objtool_file file; +static bool objtool_create_backup(const char *_objname) +{ +	int len = strlen(_objname); +	char *buf, *base, *name = malloc(len+6); +	int s, d, l, t; + +	if (!name) { +		perror("failed backup name malloc"); +		return false; +	} + +	strcpy(name, _objname); +	strcpy(name + len, ".orig"); + +	d = open(name, O_CREAT|O_WRONLY|O_TRUNC, 0644); +	if (d < 0) { +		perror("failed to create backup file"); +		return false; +	} + +	s = open(_objname, O_RDONLY); +	if (s < 0) { +		perror("failed to open orig file"); +		return false; +	} + +	buf = malloc(4096); +	if (!buf) { +		perror("failed backup data malloc"); +		return false; +	} + +	while ((l = read(s, buf, 4096)) > 0) { +		base = buf; +		do { +			t = write(d, base, l); +			if (t < 0) { +				perror("failed backup write"); +				return false; +			} +			base += t; +			l -= t; +		} while (l); +	} + +	if (l < 0) { +		perror("failed backup read"); +		return false; +	} + +	free(name); +	free(buf); +	close(d); +	close(s); + +	return true; +} +  struct objtool_file *objtool_open_read(const char *_objname)  {  	if (objname) { @@ -59,6 +118,11 @@ struct objtool_file *objtool_open_read(const char *_objname)  	if (!file.elf)  		return NULL; +	if (backup && !objtool_create_backup(objname)) { +		WARN("can't create backup file"); +		return NULL; +	} +  	INIT_LIST_HEAD(&file.insn_list);  	hash_init(file.insn_hash);  	INIT_LIST_HEAD(&file.static_call_list); | 
