|
Michal Suchanek |
9cd1e1 |
From: Michal Suchanek <msuchanek@suse.de>
|
|
Michal Suchanek |
9cd1e1 |
Date: Wed, 7 Feb 2018 15:16:04 +0100
|
|
Michal Kubecek |
00fe0a |
Subject: Add ksym-provides tool.
|
|
Michal Suchanek |
9cd1e1 |
|
|
Michal Suchanek |
9cd1e1 |
References: bsc#1077692
|
|
Michal Suchanek |
9cd1e1 |
Patch-mainline: no, not needed
|
|
Michal Suchanek |
9cd1e1 |
|
|
Michal Suchanek |
9cd1e1 |
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
|
|
Michal Suchanek |
9cd1e1 |
---
|
|
Michal Kubecek |
a3b9ca |
scripts/mod/Makefile | 6 +-
|
|
Michal Kubecek |
a3b9ca |
scripts/mod/ksym-provides.c | 124 ++++++++++++++++++++++++++++++++++++
|
|
Michal Suchanek |
9cd1e1 |
2 files changed, 129 insertions(+), 1 deletion(-)
|
|
Michal Suchanek |
9cd1e1 |
create mode 100644 scripts/mod/ksym-provides.c
|
|
Michal Suchanek |
9cd1e1 |
|
|
Michal Suchanek |
9cd1e1 |
--- a/scripts/mod/Makefile
|
|
Michal Suchanek |
9cd1e1 |
+++ b/scripts/mod/Makefile
|
|
Michal Kubecek |
42fc05 |
@@ -2,11 +2,15 @@
|
|
Michal Suchanek |
9cd1e1 |
OBJECT_FILES_NON_STANDARD := y
|
|
Michal Kubecek |
42fc05 |
CFLAGS_REMOVE_empty.o += $(CC_FLAGS_LTO)
|
|
Michal Suchanek |
9cd1e1 |
|
|
Michal Kubecek |
6a3065 |
-hostprogs-always-y += modpost mk_elfconfig
|
|
Michal Kubecek |
6a3065 |
+hostprogs-always-y += modpost mk_elfconfig ksym-provides
|
|
Michal Kubecek |
6a3065 |
always-y += empty.o
|
|
Michal Suchanek |
9cd1e1 |
|
|
Michal Suchanek |
9cd1e1 |
modpost-objs := modpost.o file2alias.o sumversion.o
|
|
Michal Suchanek |
9cd1e1 |
|
|
Michal Suchanek |
9cd1e1 |
+ksym-provides-objs := ksym-provides.o
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Kubecek |
a3b9ca |
+HOSTLDLIBS_ksym-provides := -lelf
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
devicetable-offsets-file := devicetable-offsets.h
|
|
Michal Suchanek |
9cd1e1 |
|
|
Michal Suchanek |
9cd1e1 |
$(obj)/$(devicetable-offsets-file): $(obj)/devicetable-offsets.s FORCE
|
|
Michal Suchanek |
9cd1e1 |
--- /dev/null
|
|
Michal Suchanek |
9cd1e1 |
+++ b/scripts/mod/ksym-provides.c
|
|
Michal Suchanek |
9cd1e1 |
@@ -0,0 +1,124 @@
|
|
Michal Suchanek |
9cd1e1 |
+#include <stdio.h>
|
|
Michal Suchanek |
9cd1e1 |
+#include <sys/types.h>
|
|
Michal Suchanek |
9cd1e1 |
+#include <sys/stat.h>
|
|
Michal Suchanek |
9cd1e1 |
+#include <fcntl.h>
|
|
Michal Suchanek |
9cd1e1 |
+#include <unistd.h>
|
|
Michal Suchanek |
9cd1e1 |
+#include <gelf.h>
|
|
Michal Suchanek |
9cd1e1 |
+#include <string.h>
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+int main(int argc, char *argv[])
|
|
Michal Suchanek |
9cd1e1 |
+{
|
|
Michal Suchanek |
9cd1e1 |
+ int fd;
|
|
Michal Suchanek |
9cd1e1 |
+ Elf *elf;
|
|
Michal Suchanek |
9cd1e1 |
+ Elf_Scn *scn;
|
|
Michal Suchanek |
9cd1e1 |
+ GElf_Shdr shdr;
|
|
Michal Suchanek |
9cd1e1 |
+ size_t strndx;
|
|
Michal Suchanek |
9cd1e1 |
+ int ndx;
|
|
Michal Suchanek |
9cd1e1 |
+ Elf_Data *symdata, *data;
|
|
Michal Suchanek |
9cd1e1 |
+ GElf_Sym sym;
|
|
Michal Suchanek |
9cd1e1 |
+ char *name;
|
|
Michal Suchanek |
9cd1e1 |
+ const char * flavor = argv[1];
|
|
Michal Suchanek |
9cd1e1 |
+ const char * prefix = "__crc_";
|
|
Michal Suchanek |
9cd1e1 |
+ size_t prefixlen = strlen(prefix);
|
|
Michal Suchanek |
9cd1e1 |
+ const char * symformat = "ksym(%s:%s) = %lx\n";
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+ if (argc != 3) {
|
|
Michal Suchanek |
9cd1e1 |
+ fprintf(stderr, "Usage: %s <flavor> <filename>\n", argv[0]);
|
|
Michal Suchanek |
9cd1e1 |
+ return 1;
|
|
Michal Suchanek |
9cd1e1 |
+ }
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+ if (elf_version(EV_CURRENT) == EV_NONE) {
|
|
Michal Suchanek |
9cd1e1 |
+ fprintf(stderr, "libelf initialization failed: %s\n",
|
|
Michal Suchanek |
9cd1e1 |
+ elf_errmsg(-1));
|
|
Michal Suchanek |
9cd1e1 |
+ return 1;
|
|
Michal Suchanek |
9cd1e1 |
+ }
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+ fd = open(argv[2], O_RDONLY);
|
|
Michal Suchanek |
9cd1e1 |
+ if (fd < 0) {
|
|
Michal Suchanek |
9cd1e1 |
+ perror("open failed");
|
|
Michal Suchanek |
9cd1e1 |
+ return 1;
|
|
Michal Suchanek |
9cd1e1 |
+ }
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+ elf = elf_begin(fd, ELF_C_READ, NULL);
|
|
Michal Suchanek |
9cd1e1 |
+ if (!elf) {
|
|
Michal Suchanek |
9cd1e1 |
+ fprintf(stderr, "elf_begin failed: %s\n", elf_errmsg(-1));
|
|
Michal Suchanek |
9cd1e1 |
+ goto err_close;
|
|
Michal Suchanek |
9cd1e1 |
+ }
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+ scn = NULL;
|
|
Michal Suchanek |
9cd1e1 |
+ while ((scn = elf_nextscn(elf, scn)) != NULL) {
|
|
Michal Suchanek |
9cd1e1 |
+ if (!gelf_getshdr(scn, &shdr)) {
|
|
Michal Suchanek |
9cd1e1 |
+ fprintf(stderr, "gelf_getshdr failed: %s\n",
|
|
Michal Suchanek |
9cd1e1 |
+ elf_errmsg(-1));
|
|
Michal Suchanek |
9cd1e1 |
+ goto err_end;
|
|
Michal Suchanek |
9cd1e1 |
+ }
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+ if (shdr.sh_type == SHT_SYMTAB)
|
|
Michal Suchanek |
9cd1e1 |
+ break;
|
|
Michal Suchanek |
9cd1e1 |
+ }
|
|
Michal Suchanek |
9cd1e1 |
+ if (!scn) {
|
|
Michal Suchanek |
9cd1e1 |
+ fputs("symbol table not found\n", stderr);
|
|
Michal Suchanek |
9cd1e1 |
+ goto err_end;
|
|
Michal Suchanek |
9cd1e1 |
+ }
|
|
Michal Suchanek |
9cd1e1 |
+ strndx = shdr.sh_link;
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+ symdata = elf_getdata(scn, NULL);
|
|
Michal Suchanek |
9cd1e1 |
+ if (!symdata) {
|
|
Michal Suchanek |
9cd1e1 |
+ fprintf(stderr, "elf_getdata failed: %s\n", elf_errmsg(-1));
|
|
Michal Suchanek |
9cd1e1 |
+ goto err_end;
|
|
Michal Suchanek |
9cd1e1 |
+ }
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+ for (ndx = 0; gelf_getsym(symdata, ndx, &sym) != NULL; ++ndx) {
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+ name = elf_strptr(elf, strndx, sym.st_name);
|
|
Michal Suchanek |
9cd1e1 |
+ if (!name) {
|
|
Michal Suchanek |
9cd1e1 |
+ fprintf(stderr, "elf_strptr failed: %s\n",
|
|
Michal Suchanek |
9cd1e1 |
+ elf_errmsg(-1));
|
|
Michal Suchanek |
9cd1e1 |
+ goto err_end;
|
|
Michal Suchanek |
9cd1e1 |
+ }
|
|
Michal Suchanek |
9cd1e1 |
+ if (strncmp(prefix, name, prefixlen))
|
|
Michal Suchanek |
9cd1e1 |
+ continue;
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+ if (sym.st_shndx >= SHN_LORESERVE) {
|
|
Michal Suchanek |
9cd1e1 |
+ printf(symformat, flavor, name + prefixlen,
|
|
Michal Suchanek |
9cd1e1 |
+ sym.st_value);
|
|
Michal Suchanek |
9cd1e1 |
+ continue;
|
|
Michal Suchanek |
9cd1e1 |
+ }
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+ scn = elf_getscn(elf, sym.st_shndx);
|
|
Michal Suchanek |
9cd1e1 |
+ if (!scn) {
|
|
Michal Suchanek |
9cd1e1 |
+ fprintf(stderr, "elf_getscn failed: %s\n",
|
|
Michal Suchanek |
9cd1e1 |
+ elf_errmsg(-1));
|
|
Michal Suchanek |
9cd1e1 |
+ goto err_end;
|
|
Michal Suchanek |
9cd1e1 |
+ }
|
|
Michal Suchanek |
9cd1e1 |
+ if (!gelf_getshdr(scn, &shdr)) {
|
|
Michal Suchanek |
9cd1e1 |
+ fprintf(stderr, "gelf_getshdr failed: %s\n",
|
|
Michal Suchanek |
9cd1e1 |
+ elf_errmsg(-1));
|
|
Michal Suchanek |
9cd1e1 |
+ goto err_end;
|
|
Michal Suchanek |
9cd1e1 |
+ }
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+ if (shdr.sh_type != SHT_PROGBITS)
|
|
Michal Suchanek |
9cd1e1 |
+ continue;
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+ data = elf_getdata_rawchunk(
|
|
Michal Suchanek |
9cd1e1 |
+ elf, shdr.sh_offset + sym.st_value - shdr.sh_addr,
|
|
Michal Suchanek |
9cd1e1 |
+ sizeof(GElf_Word), ELF_T_WORD);
|
|
Michal Suchanek |
9cd1e1 |
+ if (!data) {
|
|
Michal Suchanek |
9cd1e1 |
+ fprintf(stderr, "elf_getdata_rawchunk failed: %s\n",
|
|
Michal Suchanek |
9cd1e1 |
+ elf_errmsg(-1));
|
|
Michal Suchanek |
9cd1e1 |
+ goto err_end;
|
|
Michal Suchanek |
9cd1e1 |
+ }
|
|
Michal Suchanek |
9cd1e1 |
+ printf(symformat, flavor, name + prefixlen,
|
|
Michal Suchanek |
9cd1e1 |
+ (unsigned long) *(GElf_Word*)data->d_buf);
|
|
Michal Suchanek |
9cd1e1 |
+ }
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+ elf_end(elf);
|
|
Michal Suchanek |
9cd1e1 |
+ close(fd);
|
|
Michal Suchanek |
9cd1e1 |
+ return 0;
|
|
Michal Suchanek |
9cd1e1 |
+
|
|
Michal Suchanek |
9cd1e1 |
+ err_end:
|
|
Michal Suchanek |
9cd1e1 |
+ elf_end(elf);
|
|
Michal Suchanek |
9cd1e1 |
+ err_close:
|
|
Michal Suchanek |
9cd1e1 |
+ close(fd);
|
|
Michal Suchanek |
9cd1e1 |
+ return 1;
|
|
Michal Suchanek |
9cd1e1 |
+}
|