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