aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Lyon <christophe.lyon@linaro.org>2021-04-14 14:22:34 +0000
committerChristophe Lyon <christophe.lyon@linaro.org>2021-04-14 14:22:34 +0000
commit82934b09cd4edee8ab0c005c3b4b25bee7c51910 (patch)
treea13133d5c405d3360abb117b8de12016a490d420
parent22e43d2b35c3ef435ec8c699e5970674559c441d (diff)
downloadbinutils-82934b09cd4edee8ab0c005c3b4b25bee7c51910.zip
binutils-82934b09cd4edee8ab0c005c3b4b25bee7c51910.tar.gz
binutils-82934b09cd4edee8ab0c005c3b4b25bee7c51910.tar.bz2
ARM/FDPIC: Add support for GDB call command
2021-04-14 Mickael Guene <mickael.guene@st.com> Christophe Lyon <christophe.lyon@st.com> * 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.
-rw-r--r--gdb/arm-tdep.c9
-rw-r--r--gdb/arm-tdep.h1
-rw-r--r--gdb/solib-fdpic.c30
3 files changed, 40 insertions, 0 deletions
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 4b2130a..9e8b382 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 d32e656..8be9765 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 a0b7db9..497742d 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)