From 4b55befd3739364861dfaaf95fafda4111e80944 Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Tue, 20 Dec 2011 10:11:22 -0200 Subject: [PATCH] elf: add bind type to kmod_modversion. will be used to share this structure with get_dependency_symbols() --- libkmod/libkmod-elf.c | 26 ++++++++++++++++++++++++++ libkmod/libkmod-private.h | 7 +++++++ 2 files changed, 33 insertions(+) diff --git a/libkmod/libkmod-elf.c b/libkmod/libkmod-elf.c index b4d6882..8c39c06 100644 --- a/libkmod/libkmod-elf.c +++ b/libkmod/libkmod-elf.c @@ -533,6 +533,7 @@ int kmod_elf_get_modversions(const struct kmod_elf *elf, struct kmod_modversion symbol++; a[i].crc = crc; + a[i].bind = KMOD_MODVERSION_UNDEF; a[i].symbol = itr; symbollen = strlen(symbol) + 1; memcpy(itr, symbol, symbollen); @@ -683,6 +684,7 @@ static int kmod_elf_get_symbols_symtab(const struct kmod_elf *elf, struct kmod_m continue; } a[count].crc = 0; + a[count].bind = KMOD_MODVERSION_GLOBAL; a[count].symbol = itr; memcpy(itr, strings + last, slen); itr[slen] = '\0'; @@ -694,6 +696,7 @@ static int kmod_elf_get_symbols_symtab(const struct kmod_elf *elf, struct kmod_m if (strings[i - 1] != '\0') { size_t slen = i - last; a[count].crc = 0; + a[count].bind = KMOD_MODVERSION_GLOBAL; a[count].symbol = itr; memcpy(itr, strings + last, slen); itr[slen] = '\0'; @@ -704,6 +707,20 @@ static int kmod_elf_get_symbols_symtab(const struct kmod_elf *elf, struct kmod_m return count; } +static inline uint8_t kmod_modversion_bind_from_elf(uint8_t elf_value) +{ + switch (elf_value) { + case STB_LOCAL: + return KMOD_MODVERSION_LOCAL; + case STB_GLOBAL: + return KMOD_MODVERSION_GLOBAL; + case STB_WEAK: + return KMOD_MODVERSION_WEAK; + default: + return KMOD_MODVERSION_NONE; + } +} + /* array will be allocated with strings in a single malloc, just free *array */ int kmod_elf_get_symbols(const struct kmod_elf *elf, struct kmod_modversion **array) { @@ -786,6 +803,7 @@ int kmod_elf_get_symbols(const struct kmod_elf *elf, struct kmod_modversion **ar const char *name; uint32_t name_off; uint64_t crc; + uint8_t info, bind; #define READV(field) \ elf_get_uint(elf, sym_off + offsetof(typeof(*s), field),\ @@ -794,10 +812,12 @@ int kmod_elf_get_symbols(const struct kmod_elf *elf, struct kmod_modversion **ar Elf32_Sym *s; name_off = READV(st_name); crc = READV(st_value); + info = READV(st_info); } else { Elf64_Sym *s; name_off = READV(st_name); crc = READV(st_value); + info = READV(st_info); } #undef READV name = elf_get_mem(elf, str_off + name_off); @@ -805,7 +825,13 @@ int kmod_elf_get_symbols(const struct kmod_elf *elf, struct kmod_modversion **ar continue; name += crc_strlen; + if (elf->class & KMOD_ELF_32) + bind = ELF32_ST_BIND(info); + else + bind = ELF64_ST_BIND(info); + a[count].crc = crc; + a[count].bind = kmod_modversion_bind_from_elf(bind); a[count].symbol = itr; slen = strlen(name); memcpy(itr, name, slen); diff --git a/libkmod/libkmod-private.h b/libkmod/libkmod-private.h index d32b6d7..6da8eef 100644 --- a/libkmod/libkmod-private.h +++ b/libkmod/libkmod-private.h @@ -144,6 +144,13 @@ void kmod_file_unref(struct kmod_file *file) __attribute__((nonnull(1))); struct kmod_elf; struct kmod_modversion { uint64_t crc; + enum kmod_modversion_bind { + KMOD_MODVERSION_NONE = '\0', + KMOD_MODVERSION_LOCAL = 'L', + KMOD_MODVERSION_GLOBAL = 'G', + KMOD_MODVERSION_WEAK = 'W', + KMOD_MODVERSION_UNDEF = 'U' + } bind; char *symbol; }; -- 2.7.4