From: Christophe Lyon Date: Wed, 14 Apr 2021 14:22:34 +0000 (+0000) Subject: ARM/FDPIC: Add support for GDB call command X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=82934b09cd4edee8ab0c005c3b4b25bee7c51910;p=thirdparty%2Fbinutils-gdb.git ARM/FDPIC: Add support for GDB call command 2021-04-14 Mickael Guene Christophe Lyon * gdb/arm-tdep.c (arm_push_dummy_call): Handle FDPIC case. * gdb/arm-tdep.h (fdpic_find_global_pointer): Declare. * gdb/solib-fdpic.c (fdpic_find_global_pointer): New. --- diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 4b2130a4ead..9e8b382f66d 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -44,6 +44,7 @@ #include "target-descriptions.h" #include "user-regs.h" #include "observer.h" +#include "infcall.h" #include "arm-tdep.h" #include "gdb/sim-arm.h" @@ -3749,6 +3750,14 @@ arm_push_dummy_call (struct gdbarch *gdbarch, struct value *function, si = pop_stack_item (si); } + if (gdbarch_tdep (gdbarch)->is_fdpic) + { + CORE_ADDR func_addr = find_function_addr (function, NULL); + + regcache_cooked_write_unsigned (regcache, 9, + fdpic_find_global_pointer (func_addr)); + } + /* Finally, update teh SP register. */ regcache_cooked_write_unsigned (regcache, ARM_SP_REGNUM, sp); diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h index d32e6561eb8..8be97652f15 100644 --- a/gdb/arm-tdep.h +++ b/gdb/arm-tdep.h @@ -359,5 +359,6 @@ extern struct target_desc *tdesc_arm_with_neon; /* FDPIC structure and api. */ extern struct target_so_ops fdpic_so_ops; extern CORE_ADDR fdpic_fetch_objfile_link_map (struct objfile *objfile); +extern CORE_ADDR fdpic_find_global_pointer (CORE_ADDR addr); #endif /* arm-tdep.h */ diff --git a/gdb/solib-fdpic.c b/gdb/solib-fdpic.c index a0b7db94c73..497742d00e8 100644 --- a/gdb/solib-fdpic.c +++ b/gdb/solib-fdpic.c @@ -598,6 +598,36 @@ enable_break2 (void) return 0; } +/* Exported functions. */ +/* Find the global pointer for the given function address ADDR. */ +CORE_ADDR +fdpic_find_global_pointer (CORE_ADDR addr) +{ + struct so_list *so; + + so = master_so_list (); + while (so) + { + int seg; + struct elf32_fdpic_loadmap *map; + + map = so->lm_info->map; + + for (seg = 0; seg < map->nsegs; seg++) + { + if (map->segs[seg].addr <= addr + && addr < map->segs[seg].addr + map->segs[seg].p_memsz) + return so->lm_info->got_value; + } + + so = so->next; + } + + /* Didn't find it in any of the shared objects. + So assume it's in the main executable. */ + return main_got (); +} + /* Shared object operations. */ static int fdpic_in_dynsym_resolve_code (CORE_ADDR pc)