Skip to content

Commit

Permalink
WIP: kpatch-build: use symbol table instead of kobject
Browse files Browse the repository at this point in the history
Signed-off-by: Artem Savkov <asavkov@redhat.com>
  • Loading branch information
sm00th committed May 11, 2018
1 parent 9477a04 commit d61a44c
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 4 deletions.
4 changes: 3 additions & 1 deletion kpatch-build/kpatch-build
Original file line number Diff line number Diff line change
Expand Up @@ -780,8 +780,10 @@ for i in $FILES; do
fi
cd "$TEMPDIR" || die
if [[ -e "orig/$i" ]]; then
SYMTAB="$KOBJFILE.symtab"
readelf -W -s "$KOBJFILE" | tail -n +4 | awk '{ printf("%s %d %s %s %s %s\n", $2, $3, $4, $5, $7, $8 ? $8 : "__kpatch_noname__"); }' > "$SYMTAB"
# create-diff-object orig.o patched.o kernel-object output.o Module.symvers patch-mod-name
"$TOOLSDIR"/create-diff-object "orig/$i" "patched/$i" "$KOBJFILE" \
"$TOOLSDIR"/create-diff-object "orig/$i" "patched/$i" "$SYMTAB" \
"output/$i" "$SRCDIR/Module.symvers" "${MODNAME//-/_}" 2>&1 | logger 1
check_pipe_status create-diff-object
# create-diff-object returns 3 if no functional change is found
Expand Down
75 changes: 74 additions & 1 deletion kpatch-build/lookup.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ static void find_local_syms(struct lookup_table *table, char *hint,
ERROR("find_local_syms for %s: found_none", hint);
}

#if 0
static void obj_read(struct lookup_table *table, char *path)
{
Elf *elf;
Expand Down Expand Up @@ -253,6 +254,7 @@ static void obj_read(struct lookup_table *table, char *path)
close(fd);
elf_end(elf);
}
#endif

/* Strip the path and replace '-' with '_' */
static char *make_modname(char *modname)
Expand All @@ -272,6 +274,77 @@ static char *make_modname(char *modname)
return basename(modname);
}

// TODO: rename?
static void symtab_read(struct lookup_table *table, char *path)
{
FILE *file;
unsigned int value, size, i = 0;
char name[256], type[256], vis[256], ndx[10];

if ((file = fopen(path, "r")) < 0)
ERROR("fopen");

while (fscanf(file, "%x %d %s %s %s %s\n",
&value, &size, type, vis, ndx, name) != EOF) {
table->obj_nr++;
}

table->obj_syms = malloc(table->obj_nr * sizeof(*table->obj_syms));
if (!table->obj_syms)
ERROR("malloc table.obj_syms");
memset(table->obj_syms, 0, table->obj_nr * sizeof(*table->obj_syms));

rewind(file);

while (fscanf(file, "%x %d %s %s %s %s\n",
&value, &size, type, vis, ndx, name) != EOF) {
if (!strcmp(ndx, "UND")) {
table->obj_syms[i].skip = 1;
i++;
continue;
}

table->obj_syms[i].value = value;
table->obj_syms[i].size = size;
table->obj_syms[i].name = strdup(name);

if (!strcmp(vis, "LOCAL")) {
table->obj_syms[i].bind = STB_LOCAL;
} else if (!strcmp(vis, "GLOBAL")) {
table->obj_syms[i].bind = STB_GLOBAL;
} else {
table->obj_syms[i].bind = STB_WEAK;
}

if (!strcmp(type, "NOTYPE")) {
table->obj_syms[i].type = STT_NOTYPE;
} else if (!strcmp(type, "OBJECT")) {
table->obj_syms[i].type = STT_OBJECT;
} else if (!strcmp(type, "FUNC")) {
table->obj_syms[i].type = STT_FUNC;
} else if (!strcmp(type, "SECTION")) {
table->obj_syms[i].type = STT_SECTION;
} else if (!strcmp(type, "FILE")) {
table->obj_syms[i].type = STT_FILE;
} else if (!strcmp(type, "COMMON")) {
table->obj_syms[i].type = STT_COMMON;
} else {
table->obj_syms[i].type = STT_TLS;
}

if (!strcmp(name, "__kpatch_noname__")) {
table->obj_syms[i].name = strdup("");
} else {
table->obj_syms[i].name = strdup(name);
}
if (!table->obj_syms[i].name)
ERROR("strdup");
i++;
}

fclose(file);
}

static void symvers_read(struct lookup_table *table, char *path)
{
FILE *file;
Expand Down Expand Up @@ -324,7 +397,7 @@ struct lookup_table *lookup_open(char *obj_path, char *symvers_path,
ERROR("malloc table");
memset(table, 0, sizeof(*table));

obj_read(table, obj_path);
symtab_read(table, obj_path);
symvers_read(table, symvers_path);
find_local_syms(table, hint, locals);

Expand Down
9 changes: 7 additions & 2 deletions test/unit/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ EXT_FAIL ?= PATCHED.FAIL.o
EXT_TEST ?= test
EXT_OUTPUT ?= OUTPUT.o
EXT_TEST_OUTPUT ?= test.out
EXT_SYMTAB ?= symtab
TNAME = $(@:.$(EXT_OUTPUT)=)

ifndef VERBOSE
Expand Down Expand Up @@ -31,6 +32,10 @@ define check_all =
$(call check_stripped,$(1))
endef

define symtab_file =
$(if $(wildcard $(1).$(EXT_SYMTAB)),$(1).$(EXT_SYMTAB),vmlinux.$(EXT_SYMTAB))
endef

all: $(TARGETS) $(TEST_TARGETS)

clean:
Expand All @@ -47,14 +52,14 @@ clean:
$(call check_all,$(TNAME).$(EXT_ORIG))
$(call check_all,$(TNAME).$(EXT_PATCHED))
$(CDO_ENV) $(CDO) $(TNAME).$(EXT_ORIG) $(TNAME).$(EXT_PATCHED) \
$(TNAME).$(EXT_ORIG) $@ /dev/null test_$(TNAME) $(MUTE_PASS)
$(call symtab_file,$(TNAME)) $@ /dev/null test_$(TNAME) $(MUTE_PASS)

%.$(EXT_OUTPUT): %.$(EXT_ORIG) %.$(EXT_FAIL) $(CDO)
@echo "BUILD $(TNAME)-FAIL"
$(call check_all,$(TNAME).$(EXT_ORIG))
$(call check_all,$(TNAME).$(EXT_FAIL))
! $(CDO_ENV) $(CDO) $(TNAME).$(EXT_ORIG) $(TNAME).$(EXT_FAIL) \
$(TNAME).$(EXT_ORIG) $@ /dev/null test_$(TNAME) $(MUTE_FAIL)
$(call symtab_file,$(TNAME)) $@ /dev/null test_$(TNAME) $(MUTE_FAIL)
# Expecting to fail, thus create output file manually so we won't rerun the
# test without clean
@touch $@

0 comments on commit d61a44c

Please sign in to comment.