]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
backends: check_special_symbol _GLOBAL_OFFSET_TABLE_ points inside .got users/mark/try-riscv-got
authorMark Wielaard <mark@klomp.org>
Mon, 30 Dec 2024 00:17:02 +0000 (01:17 +0100)
committerMark Wielaard <mark@klomp.org>
Mon, 30 Dec 2024 00:18:14 +0000 (01:18 +0100)
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 <mark@klomp.org>
backends/riscv_symbol.c

index c149b8ba27cf5d7cb7bd695ca8fba8fe75b97d68..3de8070be87389ca7b082c73b5609d0d15b87612 100644 (file)
@@ -1,4 +1,5 @@
 /* RISC-V specific symbolic name handling.
+   Copyright (C) 2024 Mark J. Wielaard <mark@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