From c6d0b5450b2aeab2aa200428212be9f6794223a1 Mon Sep 17 00:00:00 2001 From: Vasily Gorbik Date: Tue, 29 Mar 2022 10:20:08 +0200 Subject: [PATCH] lookup: fix symtab parsing symtab_read tries to skip '.dynsym' symbol table and only read '.symtab' symbol table. Newer readelf from binutils 2.37 now adds section names (see the diff): --- vmlinux.symtab 2022-02-18 02:10:06.691220932 +0100 +++ vmlinux.symtab.new 2022-02-18 01:16:06.161210458 +0100 Symbol table '.dynsym' contains 1541 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000100000 0 SECTION LOCAL DEFAULT 1 .text 2: 00000000017a3ac0 4 OBJECT GLOBAL DEFAULT 19 sclp_console_pages Symbol table '.symtab' contains 159980 entries: Num: Value Size Type Bind Vis Ndx Name - 41: 0000000001a93600 0 SECTION LOCAL DEFAULT 41 - 42: 0000000001a9c678 0 SECTION LOCAL DEFAULT 42 ... + 41: 0000000001a93600 0 SECTION LOCAL DEFAULT 41 .dynsym + 42: 0000000001a9c678 0 SECTION LOCAL DEFAULT 42 .rela.dyn ... 54: 0000000000000000 0 FILE LOCAL DEFAULT ABS main.c Simple matching of ".dynsym" in the line buffer is not enough anymore, because it hits not just Symbol table '.dynsym' contains 1541 entries: line, but also 41: 0000000001a93600 0 SECTION LOCAL DEFAULT 41 .dynsym skipping the rest of the file and leading to an error: create-diff-object: ERROR: *.o: find_local_syms: 189: couldn't find matching *.c local symbols in vmlinux symbol table Limit matching only to lines containing "Symbol table" header. This works with readelf from the binutils, as well as readelf from elfutils (its output looks slightly different). Symbol table [41] '.dynsym' contains 1541 entries: Signed-off-by: Vasily Gorbik --- kpatch-build/lookup.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c index 06f4b38..c9e6cc7 100644 --- a/kpatch-build/lookup.c +++ b/kpatch-build/lookup.c @@ -272,12 +272,14 @@ static void symtab_read(struct lookup_table *table, char *path) * tables. .dynsym is just a subset of .symtab, so skip it to * avoid duplicates. */ - if (strstr(line, ".dynsym")) { - skip = true; - continue; - } else if (strstr(line, ".symtab")) { - skip = false; - continue; + if (!strncmp(line, "Symbol table ", 13)) { + if (strstr(line, ".dynsym")) { + skip = true; + continue; + } else if (strstr(line, ".symtab")) { + skip = false; + continue; + } } if (skip) continue;