]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libelf: Use GElf_Ehdr instead of Elf handle in __libelf_data_type
authorMark Wielaard <mark@klomp.org>
Sun, 1 Nov 2020 17:50:04 +0000 (18:50 +0100)
committerMark Wielaard <mark@klomp.org>
Fri, 6 Nov 2020 17:39:40 +0000 (18:39 +0100)
GCC with -flto detects some (very) unlikely issues in error paths.
In theory getting the Ehdr from an Elf handle might fail. But in
most cases where __libelf_data_type is used, we already have the
Ehdr anyway. So simply pass that to __libelf_data_type. In the one
place where we don't have it yet, get it and check for failure
before calling __libelf_data_type.

Signed-off-by: Mark Wielaard <mark@klomp.org>
libelf/ChangeLog
libelf/elf_compress.c
libelf/elf_compress_gnu.c
libelf/elf_getdata.c
libelf/libelfP.h

index b15508f2fda5fa73bd9843fac66f413b93b1be12..7bd15a284a5403468687493ccd9181c01e1af2b8 100644 (file)
@@ -1,3 +1,12 @@
+2020-11-01  Mark Wielaard  <mark@klomp.org>
+
+       * libelfP.h (__libelf_data_type): Take an GElf_Ehdr instead of an
+       Elf handle.
+       * elf_getdata.c (__libelf_data_type): Likewise. And check ehdr
+       directly instead of fetching a new one.
+       (__libelf_set_rawdata_wrlock): Fetch Ehdr, report an error when that
+       fails, otherwise call __libelf_data_type.
+
 2020-10-28  Mark Wielaard  <mark@klomp.org>
 
        * elf.h: Update from glibc.
index e5d3d2e09c8eeb522239ccbff09492b335ad7253..9d6f15c085411886076cecd930d940a5f9fc5ca1 100644 (file)
@@ -522,7 +522,7 @@ elf_compress (Elf_Scn *scn, int type, unsigned int flags)
 
       __libelf_reset_rawdata (scn, scn->zdata_base,
                              scn->zdata_size, scn->zdata_align,
-                             __libelf_data_type (elf, sh_type,
+                             __libelf_data_type (&ehdr, sh_type,
                                                  scn->zdata_align));
 
       return 1;
index 1ecd6a08edc6c7e7061012de0ca4f78e91135a84..7aed4640375671a7d55c94e9dab0f0dc5bf8b7bb 100644 (file)
@@ -197,7 +197,8 @@ elf_compress_gnu (Elf_Scn *scn, int inflate, unsigned int flags)
        }
 
       __libelf_reset_rawdata (scn, buf_out, size, sh_addralign,
-                             __libelf_data_type (elf, sh_type, sh_addralign));
+                             __libelf_data_type (&ehdr, sh_type,
+                                                 sh_addralign));
 
       scn->zdata_base = buf_out;
 
index 0d8f8d2eec54cbec0a0e2993d45e1ab437a7c8b5..6ed44504f27a66fb9c75199067df99030bd86811 100644 (file)
@@ -113,14 +113,12 @@ const uint_fast8_t __libelf_type_aligns[ELFCLASSNUM - 1][ELF_T_NUM] =
 
 Elf_Type
 internal_function
-__libelf_data_type (Elf *elf, int sh_type, GElf_Xword align)
+__libelf_data_type (GElf_Ehdr *ehdr, int sh_type, GElf_Xword align)
 {
   /* Some broken ELF ABI for 64-bit machines use the wrong hash table
      entry size.  See elf-knowledge.h for more information.  */
-  if (sh_type == SHT_HASH && elf->class == ELFCLASS64)
+  if (sh_type == SHT_HASH && ehdr->e_ident[EI_CLASS] == ELFCLASS64)
     {
-      GElf_Ehdr ehdr_mem;
-      GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
       return (SH_ENTSIZE_HASH (ehdr) == 4 ? ELF_T_WORD : ELF_T_XWORD);
     }
   else
@@ -365,7 +363,13 @@ __libelf_set_rawdata_wrlock (Elf_Scn *scn)
   if ((flags & SHF_COMPRESSED) != 0)
     scn->rawdata.d.d_type = ELF_T_CHDR;
   else
-    scn->rawdata.d.d_type = __libelf_data_type (elf, type, align);
+    {
+      GElf_Ehdr ehdr_mem;
+      GElf_Ehdr *ehdr = __gelf_getehdr_rdlock (elf, &ehdr_mem);
+      if (unlikely (ehdr == NULL))
+       return 1;
+      scn->rawdata.d.d_type = __libelf_data_type (ehdr, type, align);
+    }
   scn->rawdata.d.d_off = 0;
 
   /* Make sure the alignment makes sense.  d_align should be aligned both
index b55d5c48a62f3b928c5873320a0c2a1d71f75ddb..6a3243de9c73e120c023fae94e4be5ada008914f 100644 (file)
@@ -436,10 +436,11 @@ extern const uint_fast8_t __libelf_type_aligns[ELFCLASSNUM - 1][ELF_T_NUM]
 # define __libelf_type_align(class, type)      \
     (__libelf_type_aligns[class - 1][type] ?: 1)
 
-/* Given an Elf handle and a section type returns the Elf_Data d_type.
+/* Given an GElf_Ehdr handle and a section type returns the Elf_Data d_type.
    Should not be called when SHF_COMPRESSED is set, the d_type should
    be ELF_T_BYTE.  */
-extern Elf_Type __libelf_data_type (Elf *elf, int sh_type, GElf_Xword align)
+extern Elf_Type __libelf_data_type (GElf_Ehdr *ehdr,
+                                   int sh_type, GElf_Xword align)
   internal_function;