2011-09-23 12:00:45 +04:00
|
|
|
#ifndef UTIL_H_
|
|
|
|
#define UTIL_H_
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Some bits are stolen from perf and kvm tools
|
|
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <signal.h>
|
2011-10-24 13:43:21 +04:00
|
|
|
#include <stdio.h>
|
2012-01-22 20:20:40 +04:00
|
|
|
#include <errno.h>
|
2011-09-23 12:00:45 +04:00
|
|
|
|
|
|
|
#include <sys/types.h>
|
2011-10-24 13:43:21 +04:00
|
|
|
#include <dirent.h>
|
2011-09-23 12:00:45 +04:00
|
|
|
|
|
|
|
#include "compiler.h"
|
|
|
|
#include "types.h"
|
|
|
|
|
2012-01-31 15:31:21 +04:00
|
|
|
extern void printk(const char *format, ...)
|
|
|
|
__attribute__ ((__format__ (__printf__, 1, 2)));
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2011-11-24 15:07:03 +04:00
|
|
|
#define PREF_SHIFT_OP(pref, op, size) ((size) op (pref ##BYTES_SHIFT))
|
|
|
|
#define KBYTES_SHIFT 10
|
|
|
|
#define MBYTES_SHIFT 20
|
|
|
|
#define GBYTES_SHIFT 30
|
|
|
|
|
|
|
|
#define KBYTES(size) PREF_SHIFT_OP(K, >>, size)
|
|
|
|
#define MBYTES(size) PREF_SHIFT_OP(M, >>, size)
|
|
|
|
#define GBYTES(size) PREF_SHIFT_OP(G, >>, size)
|
|
|
|
|
|
|
|
#define KILO(size) PREF_SHIFT_OP(K, <<, size)
|
|
|
|
#define MEGA(size) PREF_SHIFT_OP(K, <<, size)
|
|
|
|
#define GIGA(size) PREF_SHIFT_OP(K, <<, size)
|
|
|
|
|
2011-09-23 12:00:45 +04:00
|
|
|
#define pr_info(fmt, ...) printk(fmt, ##__VA_ARGS__)
|
2011-09-30 14:37:12 +04:00
|
|
|
#define pr_err(fmt, ...) printk("Error (%s:%d): " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
|
2011-09-23 12:00:45 +04:00
|
|
|
#define pr_panic(fmt, ...) printk("PANIC (%s:%d): " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
|
2011-12-27 02:13:29 +04:00
|
|
|
#define pr_warning(fmt, ...) printk("Warning (%s:%d): " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2011-12-27 02:27:20 +04:00
|
|
|
#ifdef CR_DEBUG
|
2011-09-23 12:00:45 +04:00
|
|
|
#define pr_debug(fmt, ...) \
|
|
|
|
do { \
|
2011-12-27 02:27:20 +04:00
|
|
|
printk("%s:%d:%s: " fmt, \
|
|
|
|
__FILE__, __LINE__,__func__, \
|
2011-09-23 12:00:45 +04:00
|
|
|
##__VA_ARGS__); \
|
|
|
|
} while (0)
|
2011-12-27 02:27:20 +04:00
|
|
|
#define dprintk(fmt, ...) printk(fmt, ##__VA_ARGS__)
|
2011-09-23 12:00:45 +04:00
|
|
|
#else
|
|
|
|
#define pr_debug(fmt, ...)
|
2011-12-27 02:27:20 +04:00
|
|
|
#define dprintk(fmt, ...)
|
2011-09-23 12:00:45 +04:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#define die(fmt, ...) \
|
|
|
|
do { \
|
|
|
|
printk("die (%s:%d): " fmt, __FILE__, \
|
|
|
|
__LINE__, ##__VA_ARGS__); \
|
|
|
|
exit(1); \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define pr_perror(fmt, ...) \
|
|
|
|
do { \
|
2012-01-31 15:13:05 +04:00
|
|
|
pr_err(fmt ": %m\n", ##__VA_ARGS__); \
|
2011-09-23 12:00:45 +04:00
|
|
|
} while (0)
|
|
|
|
|
2011-12-26 15:31:51 +04:00
|
|
|
#ifndef BUG_ON_HANDLER
|
2012-01-18 18:38:47 +04:00
|
|
|
|
2012-01-16 13:53:51 +03:00
|
|
|
#ifdef CR_NOGLIBC
|
2012-01-18 18:38:47 +04:00
|
|
|
|
2012-01-16 13:53:51 +03:00
|
|
|
#define BUG_ON_HANDLER(condition) \
|
|
|
|
do { \
|
2012-01-17 11:27:29 +03:00
|
|
|
if ((condition)) { \
|
2012-01-18 18:38:47 +04:00
|
|
|
write_string("BUG at " __FILE__ ": "); \
|
2012-01-17 11:27:29 +03:00
|
|
|
write_num(__LINE__); \
|
2012-01-18 18:38:47 +04:00
|
|
|
write_string("\n"); \
|
2012-01-31 15:34:21 +04:00
|
|
|
*(volatile unsigned long *)NULL = 0xdead0000 + __LINE__; \
|
2012-01-17 11:27:29 +03:00
|
|
|
} \
|
2012-01-16 13:53:51 +03:00
|
|
|
} while (0)
|
2012-01-18 18:38:47 +04:00
|
|
|
|
|
|
|
#else /* CR_NOGLIBC */
|
|
|
|
|
2011-12-26 15:31:51 +04:00
|
|
|
# define BUG_ON_HANDLER(condition) \
|
|
|
|
do { \
|
|
|
|
if ((condition)) { \
|
|
|
|
pr_err("BUG at %s:%d", __FILE__, __LINE__); \
|
|
|
|
raise(SIGABRT); \
|
|
|
|
} \
|
|
|
|
} while (0)
|
2012-01-18 18:38:47 +04:00
|
|
|
|
|
|
|
#endif /* CR_NOGLIBC */
|
|
|
|
|
|
|
|
#endif /* BUG_ON_HANDLER */
|
2011-12-26 15:31:51 +04:00
|
|
|
|
|
|
|
#define BUG_ON(condition) BUG_ON_HANDLER((condition))
|
|
|
|
|
2012-01-22 20:20:40 +04:00
|
|
|
/*
|
|
|
|
* Write buffer @ptr of @size bytes into @fd file
|
|
|
|
* Returns
|
|
|
|
* 0 on success
|
|
|
|
* -1 on error (error message is printed)
|
|
|
|
*/
|
|
|
|
static inline int write_img_buf(int fd, void *ptr, int size)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
ret = write(fd, ptr, size);
|
|
|
|
if (ret == size)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (ret < 0)
|
2012-01-31 15:13:05 +04:00
|
|
|
pr_perror("Can't write img file");
|
2012-01-22 20:20:40 +04:00
|
|
|
else
|
|
|
|
pr_err("Img trimmed %d/%d\n", ret, size);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define write_img(fd, ptr) write_img_buf((fd), (ptr), sizeof(*(ptr)))
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Read buffer @ptr of @size bytes from @fd file
|
|
|
|
* Returns
|
|
|
|
* 1 on success
|
|
|
|
* 0 on EOF (silently)
|
|
|
|
* -1 on error (error message is printed)
|
|
|
|
*/
|
|
|
|
static inline int read_img_buf_eof(int fd, void *ptr, int size)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
ret = read(fd, ptr, size);
|
|
|
|
if (ret == size)
|
|
|
|
return 1;
|
|
|
|
if (ret == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (ret < 0)
|
2012-01-31 15:13:05 +04:00
|
|
|
pr_perror("Can't read img file");
|
2012-01-22 20:20:40 +04:00
|
|
|
else
|
|
|
|
pr_err("Img trimmed %d/%d\n", ret, size);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define read_img_eof(fd, ptr) read_img_buf_eof((fd), (ptr), sizeof(*(ptr)))
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2012-01-22 20:20:40 +04:00
|
|
|
/*
|
|
|
|
* Read buffer @ptr of @size bytes from @fd file
|
|
|
|
* Returns
|
|
|
|
* 1 on success
|
|
|
|
* -1 on error or EOF (error message is printed)
|
|
|
|
*/
|
|
|
|
static inline int read_img_buf(int fd, void *ptr, int size)
|
|
|
|
{
|
|
|
|
int ret;
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2012-01-22 20:20:40 +04:00
|
|
|
ret = read_img_buf_eof(fd, ptr, size);
|
|
|
|
if (ret == 0) {
|
|
|
|
pr_err("Unexpected EOF\n");
|
|
|
|
ret = -1;
|
|
|
|
}
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2012-01-22 20:20:40 +04:00
|
|
|
return ret;
|
|
|
|
}
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2012-01-22 20:20:40 +04:00
|
|
|
#define read_img(fd, ptr) read_img_buf((fd), (ptr), sizeof(*(ptr)))
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2011-10-22 20:41:31 +04:00
|
|
|
#define memzero_p(p) memset(p, 0, sizeof(*p))
|
|
|
|
#define memzero(p, size) memset(p, 0, size)
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2011-12-19 21:46:03 +04:00
|
|
|
extern void printk_siginfo(siginfo_t *siginfo);
|
2011-09-23 12:00:45 +04:00
|
|
|
|
|
|
|
struct vma_area;
|
|
|
|
struct list_head;
|
|
|
|
|
2011-12-19 21:46:03 +04:00
|
|
|
extern void printk_vma(struct vma_area *vma_area);
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2012-01-18 18:38:47 +04:00
|
|
|
#define pr_info_vma_list(head) \
|
|
|
|
do { \
|
|
|
|
struct vma_area *vma; \
|
|
|
|
list_for_each_entry(vma, head, list) \
|
|
|
|
pr_info_vma(vma); \
|
2011-09-23 12:00:45 +04:00
|
|
|
} while (0)
|
|
|
|
|
2012-01-18 18:38:47 +04:00
|
|
|
/*
|
|
|
|
* Note since VMA_AREA_NONE = 0 we can skip assignment
|
|
|
|
* here and simply rely on xzalloc
|
|
|
|
*/
|
2011-09-23 12:00:45 +04:00
|
|
|
#define alloc_vma_area() \
|
|
|
|
({ \
|
|
|
|
struct vma_area *p__ = xzalloc(sizeof(*p__)); \
|
|
|
|
if (p__) { \
|
|
|
|
p__->shmid = -1; \
|
|
|
|
p__->vm_file_fd = -1; \
|
|
|
|
p__->vma.fd = -1; \
|
|
|
|
} \
|
|
|
|
p__; \
|
|
|
|
})
|
|
|
|
|
|
|
|
#define pr_info_vma(vma_area) printk_vma(vma_area)
|
|
|
|
#define pr_info_siginfo(siginfo) printk_siginfo(siginfo)
|
|
|
|
|
2011-12-26 21:48:00 +04:00
|
|
|
extern int move_img_fd(int *img_fd, int want_fd);
|
2011-12-19 21:46:03 +04:00
|
|
|
extern int close_safe(int *fd);
|
2011-09-23 12:00:45 +04:00
|
|
|
|
2012-01-13 13:15:57 +04:00
|
|
|
extern int reopen_fd_as_safe(int new_fd, int old_fd, bool allow_reuse_fd);
|
|
|
|
#define reopen_fd_as(new_fd, old_fd) reopen_fd_as_safe(new_fd, old_fd, false)
|
|
|
|
#define reopen_fd_as_nocheck(new_fd, old_fd) reopen_fd_as_safe(new_fd, old_fd, true)
|
|
|
|
|
2011-12-19 21:46:03 +04:00
|
|
|
extern void hex_dump(void *addr, unsigned long len);
|
2011-10-26 10:10:19 +04:00
|
|
|
|
2012-01-12 23:50:45 +04:00
|
|
|
int open_pid_proc(pid_t pid);
|
2012-02-17 01:39:36 +04:00
|
|
|
int close_pid_proc(void);
|
2012-02-17 01:39:35 +04:00
|
|
|
|
2012-02-17 01:39:36 +04:00
|
|
|
int do_open_proc(pid_t pid, int flags, const char *fmt, ...);
|
|
|
|
|
|
|
|
#define __open_proc(pid, flags, fmt, ...) \
|
2012-02-17 01:39:35 +04:00
|
|
|
({ \
|
2012-02-17 01:39:36 +04:00
|
|
|
int __fd = do_open_proc(pid, flags, \
|
2012-02-17 01:39:35 +04:00
|
|
|
fmt, ##__VA_ARGS__); \
|
|
|
|
if (__fd < 0) \
|
|
|
|
pr_perror("Can't open /proc/%d/" fmt, \
|
|
|
|
pid, ##__VA_ARGS__); \
|
|
|
|
\
|
|
|
|
__fd; \
|
|
|
|
})
|
|
|
|
|
2012-02-17 01:39:36 +04:00
|
|
|
/* int open_proc(pid_t pid, const char *fmt, ...); */
|
|
|
|
#define open_proc(pid, fmt, ...) \
|
|
|
|
__open_proc(pid, O_RDONLY, fmt, ##__VA_ARGS__)
|
2012-02-17 01:39:35 +04:00
|
|
|
|
2012-02-17 01:39:36 +04:00
|
|
|
/* int open_proc_rw(pid_t pid, const char *fmt, ...); */
|
|
|
|
#define open_proc_rw(pid, fmt, ...) \
|
|
|
|
__open_proc(pid, O_RDWR, fmt, ##__VA_ARGS__)
|
2012-02-17 01:39:35 +04:00
|
|
|
|
2012-02-17 01:39:36 +04:00
|
|
|
/* DIR *opendir_proc(pid_t pid, const char *fmt, ...); */
|
|
|
|
#define opendir_proc(pid, fmt, ...) \
|
2012-02-17 01:39:35 +04:00
|
|
|
({ \
|
2012-02-17 01:39:36 +04:00
|
|
|
int __fd = open_proc(pid, fmt, ##__VA_ARGS__); \
|
2012-02-17 01:39:35 +04:00
|
|
|
DIR *__d = NULL; \
|
|
|
|
\
|
|
|
|
if (__fd >= 0) \
|
|
|
|
__d = fdopendir(__fd); \
|
|
|
|
if (__d == NULL) \
|
|
|
|
pr_perror("Can't fdopendir %d " \
|
|
|
|
"(/proc/%d/" fmt ")", \
|
|
|
|
__fd, pid, ##__VA_ARGS__); \
|
|
|
|
\
|
|
|
|
__d; \
|
|
|
|
})
|
|
|
|
|
2012-02-17 01:39:36 +04:00
|
|
|
/* FILE *fopen_proc(pid_t pid, const char *fmt, ...); */
|
|
|
|
#define fopen_proc(pid, fmt, ...) \
|
2012-02-17 01:39:35 +04:00
|
|
|
({ \
|
2012-02-17 01:39:36 +04:00
|
|
|
int __fd = open_proc(pid, fmt, ##__VA_ARGS__); \
|
2012-02-17 01:39:35 +04:00
|
|
|
FILE *__f = NULL; \
|
|
|
|
\
|
|
|
|
if (__fd >= 0) \
|
|
|
|
__f = fdopen(__fd, "r"); \
|
|
|
|
if (__f == NULL) \
|
|
|
|
pr_perror("Can't fdopen %d " \
|
|
|
|
"(/proc/%d/" fmt ")", \
|
|
|
|
__fd, pid, ##__VA_ARGS__); \
|
|
|
|
\
|
|
|
|
__f; \
|
|
|
|
})
|
2011-10-24 13:43:21 +04:00
|
|
|
|
2011-09-23 12:00:45 +04:00
|
|
|
#define __xalloc(op, size, ...) \
|
|
|
|
({ \
|
|
|
|
void *___p = op( __VA_ARGS__ ); \
|
|
|
|
if (!___p) \
|
2011-09-30 14:37:12 +04:00
|
|
|
pr_err("%s: Can't allocate %li bytes\n", \
|
|
|
|
__func__, (long)(size)); \
|
2011-09-23 12:00:45 +04:00
|
|
|
___p; \
|
|
|
|
})
|
|
|
|
|
2011-10-20 01:41:02 +04:00
|
|
|
#define xstrdup(str) __xalloc(strdup, strlen(str) + 1, str)
|
2011-09-23 12:00:45 +04:00
|
|
|
#define xmalloc(size) __xalloc(malloc, size, size)
|
|
|
|
#define xzalloc(size) __xalloc(calloc, size, 1, size)
|
|
|
|
#define xrealloc(p, size) __xalloc(realloc, size, p, size)
|
|
|
|
|
|
|
|
#define xfree(p) if (p) free(p)
|
|
|
|
|
|
|
|
#define xrealloc_safe(pptr, size) \
|
|
|
|
({ \
|
|
|
|
int __ret = -1; \
|
|
|
|
void *new = xrealloc(*pptr, size); \
|
|
|
|
if (new) { \
|
|
|
|
*pptr = new; \
|
|
|
|
__ret = 0; \
|
|
|
|
} \
|
|
|
|
__ret; \
|
|
|
|
})
|
|
|
|
|
2012-01-12 15:16:33 +04:00
|
|
|
#define pr_img_head(type, ...) pr_info("\n"#type __VA_ARGS__ "\n----------------\n")
|
2012-01-14 15:03:38 +04:00
|
|
|
#define pr_img_tail(type) pr_info("----------------\n")
|
2012-01-12 15:16:33 +04:00
|
|
|
|
2012-02-08 16:09:04 +04:00
|
|
|
#define KDEV_MINORBITS 20
|
|
|
|
#define KDEV_MINORMASK ((1UL << KDEV_MINORBITS) - 1)
|
|
|
|
|
|
|
|
static inline u32 kdev_major(u32 kdev)
|
|
|
|
{
|
|
|
|
return kdev >> KDEV_MINORBITS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u32 kdev_minor(u32 kdev)
|
|
|
|
{
|
|
|
|
return kdev & KDEV_MINORMASK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline dev_t kdev_to_odev(u32 kdev)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* New kernels envcode devices in a new form
|
|
|
|
*/
|
|
|
|
return (kdev_major(kdev) << 8) | kdev_minor(kdev);
|
|
|
|
}
|
|
|
|
|
2011-09-23 12:00:45 +04:00
|
|
|
#endif /* UTIL_H_ */
|