Dear all,
Following is a tiny tool used to change a symbol name in your module.
So you can replace, for example, 'kmalloc' with 'fmalloc'. And then you
can write fmalloc implementation yourself in a module. In this way, you
can intercept any software API in kernel only if it is not a macro. Any
comments?
--
Yours truly,
Louis Zhuang
---------------
Fault Injection Test Harness Project
BK tree: http://fault-injection.bkbits.net/linux-2.5
Home Page: http://sf.net/projects/fault-injection
# This is a BitKeeper generated patch for the following project:
# Project Name: Fault Injection Test Harness tools
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.22 -> 1.25
# fith_utility/Makefile.am 1.1 -> 1.2
# fith_utility/configure.in 1.1 -> 1.2
# (new) -> 1.2 fith_utility/replacesym/replacesym.c
# (new) -> 1.1 fith_utility/replacesym/Makefile.am
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/02/27 lo...@ha... 1.23
# Add replace symbol mechanism
# --------------------------------------------
# 03/02/27 lo...@ha... 1.24
# add replacesym
# --------------------------------------------
# 03/02/27 lo...@ha... 1.25
# Fix a bug -- Should seek in .strtab instead of .shstrtab
# --------------------------------------------
#
diff -Nru a/fith_utility/Makefile.am b/fith_utility/Makefile.am
--- a/fith_utility/Makefile.am Tue Mar 4 09:06:35 2003
+++ b/fith_utility/Makefile.am Tue Mar 4 09:06:35 2003
@@ -1,4 +1,4 @@
AUTOMAKE_OPTIONS = foreign
EXTRA_DIST = ./*
-SUBDIRS = ficl
+SUBDIRS = ficl replacesym
diff -Nru a/fith_utility/configure.in b/fith_utility/configure.in
--- a/fith_utility/configure.in Tue Mar 4 09:06:35 2003
+++ b/fith_utility/configure.in Tue Mar 4 09:06:35 2003
@@ -36,4 +36,5 @@
AC_OUTPUT([
Makefile
- ficl/Makefile])
+ ficl/Makefile
+ replacesym/Makefile])
diff -Nru a/fith_utility/replacesym/Makefile.am b/fith_utility/replacesym/Makefile.am
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/fith_utility/replacesym/Makefile.am Tue Mar 4 09:06:35 2003
@@ -0,0 +1,8 @@
+AUTOMAKE_OPTIONS = foreign
+sbin_PROGRAMS = replacesym
+
+include $(top_srcdir)/rules.mk
+
+replacesym_SOURCES = replacesym.c
+
+
diff -Nru a/fith_utility/replacesym/replacesym.c b/fith_utility/replacesym/replacesym.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/fith_utility/replacesym/replacesym.c Tue Mar 4 09:06:35 2003
@@ -0,0 +1,98 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <asm/unistd.h>
+
+#include <elf.h>
+
+typedef Elf32_Ehdr Elf_Ehdr;
+typedef Elf32_Shdr Elf_Shdr;
+
+static int replace_symbol(void *map, int len, const char *old, const char *new)
+{
+ Elf_Ehdr *hdr;
+ Elf_Shdr *sechdrs;
+ char *strtab;
+ char *s;
+ int n;
+
+ hdr = map;
+ if (len < sizeof(*hdr)) {
+ fprintf(stderr, "File is too short\n");
+ return -1;
+ }
+
+ /* Sanity checks against insmoding binaries or wrong arch,
+ * weird elf version */
+ if (memcmp(hdr->e_ident, ELFMAG, 4) != 0
+ || hdr->e_type != ET_REL
+ || hdr->e_shentsize != sizeof(*sechdrs)) {
+ fprintf(stderr, "File is weird\n");
+ return -1;
+ }
+
+ sechdrs = map + hdr->e_shoff;
+ strtab = map + sechdrs[hdr->e_shnum-1].sh_offset;
+
+ n = sechdrs[hdr->e_shnum-1].sh_size;
+ s = strtab;
+ while (n) {
+ int len;
+
+ len = strnlen(s, n);
+ if (len >= n) {
+ fprintf(stderr, "Bad string table\n");
+ break;
+ }
+ printf("Symbol name:'%s'\n", s);
+
+ if (!strcmp(s, old)) {
+ if (strlen(new) <= len) {
+ strncpy(s, new, len);
+ } else {
+ fprintf(stderr,
+ "New symbol name is too long\n");
+ }
+ }
+
+ s += len+1;
+ n -= len+1;
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int fd;
+ struct stat st;
+ void *map;
+
+ if (argc != 4) {
+ printf("Usage: %s <module_file> <old_sym> <new_sym>\n", argv[0]);
+ exit(1);
+ }
+
+ fd = open(argv[1], O_RDWR, 0);
+ if (fd < 0) {
+ perror("Unable to open file");
+ exit(1);
+ }
+
+ fstat(fd, &st);
+ map = mmap(NULL, st.st_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
+ if (MAP_FAILED == map) {
+ perror("Unable to mmap file");
+ exit(1);
+ }
+
+ replace_symbol(map, st.st_size, argv[2], argv[3]);
+ return 0;
+}
|