]> git.ipfire.org Git - thirdparty/kmod.git/commitdiff
libkmod: Allow better optimization
authorTobias Stoeckmann <tobias@stoeckmann.org>
Wed, 16 Oct 2024 14:55:43 +0000 (16:55 +0200)
committerLucas De Marchi <lucas.de.marchi@gmail.com>
Fri, 18 Oct 2024 19:00:27 +0000 (14:00 -0500)
If we have native endianess, i.e. parsing modules for the running
system, assist the compiler to note that it is really much faster to
move a word/qword etc. instead of actually running through a loop.

Reduces library instructions on x86_64 by 1.4 % and binary instructions
by 3 % with default configuration.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Link: https://github.com/kmod-project/kmod/pull/187
Signed-off-by: Lucas De Marchi <lucas.de.marchi@gmail.com>
libkmod/libkmod-elf.c

index 9660bcd6b1482a308432d346f160dc15894430af..cbdcd75aa49a2164b79427cf615204644f2150bd 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <assert.h>
 #include <elf.h>
+#include <endian.h>
 #include <errno.h>
 #include <limits.h>
 #include <stdlib.h>
@@ -110,7 +111,6 @@ static inline uint64_t elf_get_uint(const struct kmod_elf *elf, uint64_t offset,
 {
        const uint8_t *p;
        uint64_t ret = 0;
-       size_t i;
 
        assert(size <= sizeof(uint64_t));
        assert(offset + size <= elf->size);
@@ -123,12 +123,13 @@ static inline uint64_t elf_get_uint(const struct kmod_elf *elf, uint64_t offset,
        }
 
        p = elf->memory + offset;
+
        if (elf->msb) {
-               for (i = 0; i < size; i++)
-                       ret = (ret << 8) | p[i];
+               memcpy((char *)&ret + sizeof(ret) - size, p, size);
+               ret = be64toh(ret);
        } else {
-               for (i = 1; i <= size; i++)
-                       ret = (ret << 8) | p[size - i];
+               memcpy(&ret, p, size);
+               ret = le64toh(ret);
        }
 
        ELFDBG(elf, "size=%" PRIu16 " offset=%" PRIu64 " value=%" PRIu64 "\n", size,