If desthdr is ".got.plt" search for the actual ".got" section and make
sure the _GLOBAL_OFFSET_TABLE_ points to it.

     * backends/riscv_symbol.c (riscv_check_special_symbol): Check
     sname is ".got.plt", find ".got" scn to check sym st_value.

Signed-off-by: Mark Wielaard <m...@klomp.org>
---
 backends/riscv_symbol.c | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/backends/riscv_symbol.c b/backends/riscv_symbol.c
index c149b8ba27cf..3de8070be873 100644
--- a/backends/riscv_symbol.c
+++ b/backends/riscv_symbol.c
@@ -1,4 +1,5 @@
 /* RISC-V specific symbolic name handling.
+   Copyright (C) 2024 Mark J. Wielaard <m...@klomp.org>
    This file is part of elfutils.
 
    This file is free software; you can redistribute it and/or modify
@@ -104,9 +105,29 @@ riscv_check_special_symbol (Elf *elf, const GElf_Sym *sym,
   /* _GLOBAL_OFFSET_TABLE_ points to the start of the .got section, but it
      is preceded by the .got.plt section in the output .got section.  */
   if (strcmp (name, "_GLOBAL_OFFSET_TABLE_") == 0)
-    return (strcmp (sname, ".got") == 0
-           && sym->st_value >= destshdr->sh_addr
-           && sym->st_value < destshdr->sh_addr + destshdr->sh_size);
+    {
+      if (strcmp (sname, ".got") == 0
+         && sym->st_value >= destshdr->sh_addr
+         && sym->st_value < destshdr->sh_addr + destshdr->sh_size)
+       return true;
+      else if (strcmp (sname, ".got.plt") == 0)
+       {
+         /* Find .got section and compare against that.  */
+         Elf_Scn *scn = NULL;
+         while ((scn = elf_nextscn (elf, scn)) != NULL)
+           {
+             GElf_Shdr shdr_mem;
+             GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+             if (shdr != NULL)
+               {
+                 sname = elf_strptr (elf, shstrndx, shdr->sh_name);
+                 if (sname != NULL && strcmp (sname, ".got") == 0)
+                   return (sym->st_value >= shdr->sh_addr
+                           && sym->st_value < shdr->sh_addr + shdr->sh_size);
+               }
+           }
+       }
+    }
 
   /* __global_pointer$ points to the .sdata section with an offset of
      0x800.  It might however fall in the .got section, in which case we
-- 
2.47.1

Reply via email to