From: Tobias Stoeckmann Date: Wed, 16 Oct 2024 14:52:26 +0000 (+0200) Subject: libkmod: Split elf->class into two booleans X-Git-Tag: v34~206 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e41e2c471912fe8bbeab7ad67357a1a6308ad2ed;p=thirdparty%2Fkmod.git libkmod: Split elf->class into two booleans Compilers on x86_64 use two instructions to test value of class variable, i.e. loading a mask and then comparing with value. A boolean is faster, shows directly what it is about, and the struct does not even grow. Signed-off-by: Tobias Stoeckmann Reviewed-by: Emil Velikov Link: https://github.com/kmod-project/kmod/pull/187 Signed-off-by: Lucas De Marchi --- diff --git a/libkmod/libkmod-elf.c b/libkmod/libkmod-elf.c index c90b6611..9660bcd6 100644 --- a/libkmod/libkmod-elf.c +++ b/libkmod/libkmod-elf.c @@ -15,13 +15,6 @@ #include "libkmod.h" #include "libkmod-internal.h" -enum kmod_elf_class { - KMOD_ELF_32 = (1 << 1), - KMOD_ELF_64 = (1 << 2), - KMOD_ELF_LSB = (1 << 3), - KMOD_ELF_MSB = (1 << 4), -}; - /* as defined in module-init-tools */ struct kmod_modversion32 { uint32_t crc; @@ -36,7 +29,8 @@ struct kmod_modversion64 { struct kmod_elf { const uint8_t *memory; uint64_t size; - enum kmod_elf_class class; + bool x32; + bool msb; struct kmod_elf_header { struct { uint64_t offset; @@ -68,17 +62,16 @@ _printf_format_(5, 6) static inline void _elf_dbg(const struct kmod_elf *elf, { va_list args; - fprintf(stderr, "ELFDBG-%d%c: %s:%u %s() ", (elf->class & KMOD_ELF_32) ? 32 : 64, - (elf->class & KMOD_ELF_MSB) ? 'M' : 'L', fname, line, func); + fprintf(stderr, "ELFDBG-%d%c: %s:%u %s() ", elf->x32 ? 32 : 64, + elf->msb ? 'M' : 'L', fname, line, func); va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); } -static int elf_identify(const void *memory, uint64_t size) +static int elf_identify(struct kmod_elf *elf, const void *memory, uint64_t size) { const uint8_t *p = memory; - int class = 0; if (size <= EI_NIDENT || memcmp(p, ELFMAG, SELFMAG) != 0) return -ENOEXEC; @@ -87,12 +80,12 @@ static int elf_identify(const void *memory, uint64_t size) case ELFCLASS32: if (size <= sizeof(Elf32_Ehdr)) return -EINVAL; - class |= KMOD_ELF_32; + elf->x32 = true; break; case ELFCLASS64: if (size <= sizeof(Elf64_Ehdr)) return -EINVAL; - class |= KMOD_ELF_64; + elf->x32 = false; break; default: return -EINVAL; @@ -100,16 +93,16 @@ static int elf_identify(const void *memory, uint64_t size) switch (p[EI_DATA]) { case ELFDATA2LSB: - class |= KMOD_ELF_LSB; + elf->msb = false; break; case ELFDATA2MSB: - class |= KMOD_ELF_MSB; + elf->msb = true; break; default: return -EINVAL; } - return class; + return 0; } static inline uint64_t elf_get_uint(const struct kmod_elf *elf, uint64_t offset, @@ -130,7 +123,7 @@ static inline uint64_t elf_get_uint(const struct kmod_elf *elf, uint64_t offset, } p = elf->memory + offset; - if (elf->class & KMOD_ELF_MSB) { + if (elf->msb) { for (i = 0; i < size; i++) ret = (ret << 8) | p[i]; } else { @@ -165,7 +158,7 @@ static inline int elf_set_uint(const struct kmod_elf *elf, uint64_t offset, uint } p = changed + offset; - if (elf->class & KMOD_ELF_MSB) { + if (elf->msb) { for (i = 1; i <= size; i++) { p[size - i] = value & 0xff; value = (value & 0xffffffffffffff00) >> 8; @@ -222,7 +215,7 @@ static inline int elf_get_section_info(const struct kmod_elf *elf, uint16_t idx, #define READV(field) \ elf_get_uint(elf, off + offsetof(typeof(*hdr), field), sizeof(hdr->field)) - if (elf->class & KMOD_ELF_32) { + if (elf->x32) { Elf32_Shdr *hdr; *size = READV(sh_size); *offset = READV(sh_offset); @@ -260,7 +253,7 @@ struct kmod_elf *kmod_elf_new(const void *memory, off_t size) struct kmod_elf *elf; uint64_t min_size; size_t shdrs_size, shdr_size; - int class; + int err; assert_cc(sizeof(uint16_t) == sizeof(Elf32_Half)); assert_cc(sizeof(uint16_t) == sizeof(Elf64_Half)); @@ -272,20 +265,20 @@ struct kmod_elf *kmod_elf_new(const void *memory, off_t size) return NULL; } - class = elf_identify(memory, size); - if (class < 0) { - errno = -class; + elf = malloc(sizeof(struct kmod_elf)); + if (elf == NULL) { return NULL; } - elf = malloc(sizeof(struct kmod_elf)); - if (elf == NULL) { + err = elf_identify(elf, memory, size); + if (err < 0) { + free(elf); + errno = -err; return NULL; } elf->memory = memory; elf->size = size; - elf->class = class; #define READV(field) elf_get_uint(elf, offsetof(typeof(*hdr), field), sizeof(hdr->field)) @@ -295,7 +288,7 @@ struct kmod_elf *kmod_elf_new(const void *memory, off_t size) elf->header.section.entry_size = READV(e_shentsize); \ elf->header.strings.section = READV(e_shstrndx); \ elf->header.machine = READV(e_machine) - if (elf->class & KMOD_ELF_32) { + if (elf->x32) { Elf32_Ehdr *hdr; LOAD_HEADER; shdr_size = sizeof(Elf32_Shdr); @@ -507,7 +500,7 @@ int kmod_elf_get_modversions(const struct kmod_elf *elf, struct kmod_modversion assert_cc(sizeof(struct kmod_modversion64) == sizeof(struct kmod_modversion32)); - if (elf->class & KMOD_ELF_32) + if (elf->x32) offcrc = sizeof(uint32_t); else offcrc = sizeof(uint64_t); @@ -577,7 +570,7 @@ static int elf_strip_versions_section(const struct kmod_elf *elf, uint8_t *chang buf = elf_get_section_header(elf, idx); off = (const uint8_t *)buf - elf->memory; - if (elf->class & KMOD_ELF_32) { + if (elf->x32) { off += offsetof(Elf32_Shdr, sh_flags); size = sizeof(((Elf32_Shdr *)buf)->sh_flags); } else { @@ -820,7 +813,7 @@ int kmod_elf_get_symbols(const struct kmod_elf *elf, struct kmod_modversion **ar goto fallback; } - if (elf->class & KMOD_ELF_32) + if (elf->x32) symlen = sizeof(Elf32_Sym); else symlen = sizeof(Elf64_Sym); @@ -844,7 +837,7 @@ int kmod_elf_get_symbols(const struct kmod_elf *elf, struct kmod_modversion **ar #define READV(field) \ elf_get_uint(elf, sym_off + offsetof(typeof(*s), field), sizeof(s->field)) - if (elf->class & KMOD_ELF_32) { + if (elf->x32) { Elf32_Sym *s; name_off = READV(st_name); } else { @@ -889,7 +882,7 @@ int kmod_elf_get_symbols(const struct kmod_elf *elf, struct kmod_modversion **ar #define READV(field) \ elf_get_uint(elf, sym_off + offsetof(typeof(*s), field), sizeof(s->field)) - if (elf->class & KMOD_ELF_32) { + if (elf->x32) { Elf32_Sym *s; name_off = READV(st_name); crc = READV(st_value); @@ -908,7 +901,7 @@ int kmod_elf_get_symbols(const struct kmod_elf *elf, struct kmod_modversion **ar continue; name += crc_strlen; - if (elf->class & KMOD_ELF_32) + if (elf->x32) bind = ELF32_ST_BIND(info); else bind = ELF64_ST_BIND(info); @@ -935,7 +928,7 @@ static int kmod_elf_crc_find(const struct kmod_elf *elf, const void *versions, size_t verlen, crclen, off; uint64_t i; - if (elf->class & KMOD_ELF_32) { + if (elf->x32) { struct kmod_modversion32 *mv; verlen = sizeof(*mv); crclen = sizeof(mv->crc); @@ -985,7 +978,7 @@ int kmod_elf_get_dependency_symbols(const struct kmod_elf *elf, verlen = 0; crclen = 0; } else { - if (elf->class & KMOD_ELF_32) { + if (elf->x32) { struct kmod_modversion32 *mv; verlen = sizeof(*mv); crclen = sizeof(mv->crc); @@ -1016,7 +1009,7 @@ int kmod_elf_get_dependency_symbols(const struct kmod_elf *elf, return -EINVAL; } - if (elf->class & KMOD_ELF_32) + if (elf->x32) symlen = sizeof(Elf32_Sym); else symlen = sizeof(Elf64_Sym); @@ -1064,7 +1057,7 @@ int kmod_elf_get_dependency_symbols(const struct kmod_elf *elf, #define READV(field) \ elf_get_uint(elf, sym_off + offsetof(typeof(*s), field), sizeof(s->field)) - if (elf->class & KMOD_ELF_32) { + if (elf->x32) { Elf32_Sym *s; name_off = READV(st_name); secidx = READV(st_shndx); @@ -1081,7 +1074,7 @@ int kmod_elf_get_dependency_symbols(const struct kmod_elf *elf, if (handle_register_symbols) { uint8_t type; - if (elf->class & KMOD_ELF_32) + if (elf->x32) type = ELF32_ST_TYPE(info); else type = ELF64_ST_TYPE(info); @@ -1162,7 +1155,7 @@ int kmod_elf_get_dependency_symbols(const struct kmod_elf *elf, #define READV(field) \ elf_get_uint(elf, sym_off + offsetof(typeof(*s), field), sizeof(s->field)) - if (elf->class & KMOD_ELF_32) { + if (elf->x32) { Elf32_Sym *s; name_off = READV(st_name); secidx = READV(st_shndx); @@ -1179,7 +1172,7 @@ int kmod_elf_get_dependency_symbols(const struct kmod_elf *elf, if (handle_register_symbols) { uint8_t type; - if (elf->class & KMOD_ELF_32) + if (elf->x32) type = ELF32_ST_TYPE(info); else type = ELF64_ST_TYPE(info); @@ -1199,7 +1192,7 @@ int kmod_elf_get_dependency_symbols(const struct kmod_elf *elf, continue; } - if (elf->class & KMOD_ELF_32) + if (elf->x32) bind = ELF32_ST_BIND(info); else bind = ELF64_ST_BIND(info);