[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] abg-dwarf-reader: resolve relocation sections by index



Looking up relocation sections by name introduces a dependency to the
linker in use. Relocation sections might be named differently. For
instance, linking kernel modules with the bfd linker leads to a
.rela__ksymtab section corresponding to the __ksymtab section. Using lld
as a linker leads to .rela___ksymtab as section name. Both are valid.
When the kernel loads these, it simply applies all relocations from all
sections it finds. Tools should not depend on the concrete name (even
though I would prefer consistency among them). Libabigail hit an
assertion when trying to extract the ABI from a kernel module linked
with lld.

Hence, resolve the relocation sections for __ksymtab and __ksymtab_gpl
by iterating over the ELF sections, searching for relocation sections
and identifying the one that points to the respective ksymtab.

	* src/abg-dwarf-reader.cc (find_relocation_section): New function.
	(find_ksymtab_reloc_section): Use find_relocation_section to
	resolve the ksymtab's relocation section.
	(find_ksymtab_gpl_reloc_section): Likewise.

Fixes: e6870326e01a ("Support pre and post v4.19 ksymtabs for Linux kernel modules")
Cc: Jessica Yu <jeyu@kernel.org>
Cc: Android Kernel Team <kernel-team@android.com>
Signed-off-by: Matthias Maennich <maennich@google.com>
---
 src/abg-dwarf-reader.cc | 41 +++++++++++++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc
index 6f8f5beb3b30..4065b82512ba 100644
--- a/src/abg-dwarf-reader.cc
+++ b/src/abg-dwarf-reader.cc
@@ -6167,6 +6167,35 @@ public:
     return ksymtab_section_;
   }
 
+  /// Return the .rel{a,} section corresponding to a given section.
+  ///
+  /// @return the .rel{a,} section if found, null otherwise.
+  Elf_Scn*
+  find_relocation_section(Elf_Scn* target_section) const
+  {
+    if (target_section)
+      {
+	// the relo section we are searching for has this index as sh_info
+	size_t target_index = elf_ndxscn(target_section);
+
+	// now iterate over all the sections, look for relocation sections and
+	// find the one that points to the section we are searching for
+	Elf_Scn*  section = 0;
+	GElf_Shdr header_mem, *header;
+	while ((section = elf_nextscn(elf_handle(), section)) != 0)
+	  {
+	    header = gelf_getshdr(section, &header_mem);
+	    if (header == NULL
+		|| (header->sh_type != SHT_RELA && header->sh_type != SHT_REL))
+	      continue;
+
+	    if (header->sh_info == target_index)
+	      return section;
+	  }
+      }
+    return NULL;
+  }
+
   /// Return the .rel{a,}__ksymtab section of a linux kernel ELF file (either
   /// a vmlinux binary or a kernel module).
   ///
@@ -6176,10 +6205,8 @@ public:
   {
     if (!ksymtab_reloc_section_)
       {
-        Elf_Scn *sec = find_section(elf_handle(), ".rela__ksymtab", SHT_RELA);
-	if (!sec)
-	  sec = find_section(elf_handle(), ".rel__ksymtab", SHT_REL);
-	const_cast<read_context*>(this)->ksymtab_reloc_section_ = sec;
+	const_cast<read_context*>(this)->ksymtab_reloc_section_
+	    = find_relocation_section(find_ksymtab_section());
       }
     return ksymtab_reloc_section_;
   }
@@ -6206,10 +6233,8 @@ public:
   {
     if (!ksymtab_gpl_reloc_section_)
       {
-	Elf_Scn *sec = find_section(elf_handle(), ".rela__ksymtab_gpl", SHT_RELA);
-	if (!sec)
-	  sec = find_section(elf_handle(), ".rel__ksymtab_gpl", SHT_REL);
-	const_cast<read_context*>(this)->ksymtab_gpl_reloc_section_ = sec;
+	const_cast<read_context*>(this)->ksymtab_gpl_reloc_section_
+	    = find_relocation_section(find_ksymtab_gpl_section());
       }
     return ksymtab_gpl_reloc_section_;
   }
-- 
2.24.0.rc1.363.gb1bccd3e3d-goog