backends: check_special_symbol _GLOBAL_OFFSET_TABLE_ points inside .got
Commit Message
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 | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
Comments
Hi,
On Mon, 2024-12-30 at 01:25 +0100, Mark Wielaard wrote:
> 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.
Pushed this to get the riscv ci buildbots green again.
Cheers,
Mark
@@ -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