}
tdep->jb_elt_size = ARM_LINUX_JB_ELEMENT_SIZE;
+#if 0
if (tdep->is_fdpic) {
set_solib_ops (gdbarch, &fdpic_so_ops);
} else {
+#endif
set_solib_svr4_fetch_link_map_offsets
(gdbarch, svr4_ilp32_fetch_link_map_offsets);
- }
+ // }
/* Single stepping. */
set_gdbarch_software_single_step (gdbarch, arm_linux_software_single_step);
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
/* Enable TLS support. */
+#if 0
if (tdep->is_fdpic) {
set_gdbarch_fetch_tls_load_module_address (gdbarch,
fdpic_fetch_objfile_link_map);
} else {
+#endif
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
- }
+ // }
tramp_frame_prepend_unwinder (gdbarch,
&arm_linux_sigreturn_tramp_frame);
enum arm_float_model fp_model = arm_fp_model;
struct tdesc_arch_data *tdesc_data = NULL;
int i, is_m = 0;
+ int is_fdpic = 0;
int vfp_register_count = 0, have_vfp_pseudos = 0, have_neon_pseudos = 0;
int have_wmmx_registers = 0;
int have_neon = 0;
anyway, so assume APCS. */
arm_abi = ARM_ABI_APCS;
}
- else if (ei_osabi == ELFOSABI_NONE || ei_osabi == ELFOSABI_GNU)
+ else if (ei_osabi == ELFOSABI_NONE || ei_osabi == ELFOSABI_GNU || ei_osabi == ELFOSABI_ARM_FDPIC)
{
int eabi_ver = EF_ARM_EABI_VERSION (e_flags);
+ if (ei_osabi == ELFOSABI_ARM_FDPIC)
+ is_fdpic = 1;
+
switch (eabi_ver)
{
case EF_ARM_EABI_UNKNOWN:
tdep->arm_abi = arm_abi;
tdep->fp_model = fp_model;
tdep->is_m = is_m;
+ tdep->is_fdpic = is_fdpic;
tdep->have_fpa_registers = have_fpa_registers;
tdep->have_wmmx_registers = have_wmmx_registers;
gdb_assert (vfp_register_count == 0
ipa_obj="${ipa_obj} linux-aarch64-tdesc-ipa.o"
ipa_obj="${ipa_obj} arch/aarch64-ipa.o"
;;
- arm*-*-linux*) srv_regobj="reg-arm.o arm-with-iwmmxt.o"
+ arm*-*-linux*|arm*-*uclinuxfdpiceabi) srv_regobj="reg-arm.o arm-with-iwmmxt.o"
srv_regobj="${srv_regobj} arm-with-vfpv2.o"
srv_regobj="${srv_regobj} arm-with-vfpv3.o"
srv_regobj="${srv_regobj} arm-with-neon.o"
/* See server.h. */
+void my_read_loadmap(const char*);
+void my_hack_loadmap(const char*);
void
post_fork_inferior (int pid, const char *program)
{
atexit (restore_old_foreground_pgrp);
#endif
+ fprintf(stderr, "GDBSERVER: %s before startup_inferior %s PID %d\n", __FUNCTION__, program, pid);
+ my_read_loadmap(__FUNCTION__);
+ my_hack_loadmap(__FUNCTION__);
startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED,
&cs.last_status, &cs.last_ptid);
+ fprintf(stderr, "GDBSERVER: %s after startup_inferior\n", __FUNCTION__);
+ my_read_loadmap(__FUNCTION__);
current_thread->last_resume_kind = resume_stop;
current_thread->last_status = cs.last_status;
signal_pid = pid;
target_post_create_inferior ();
+ fprintf(stderr, "GDBSERVER: %s after post_create_inferior\n", __FUNCTION__);
+ my_read_loadmap(__FUNCTION__);
fprintf (stderr, "Process %s created; pid = %d\n", program, pid);
fflush (stderr);
}
};
/* These are in <asm/elf.h> in current kernels. */
+#ifndef __FDPIC__
#define HWCAP_VFP 64
#define HWCAP_IWMMXT 512
#define HWCAP_NEON 4096
#define HWCAP_VFPv3 8192
#define HWCAP_VFPv3D16 16384
+#endif
#ifdef HAVE_SYS_REG_H
#include <sys/reg.h>
PROGRAM is the name of the program to be started, and PROGRAM_ARGS
are its arguments. */
+void my_read_loadmap(const char* fnname);
static int
linux_create_inferior (const char *program,
const std::vector<char *> &program_args)
int pid;
ptid_t ptid;
+ fprintf(stderr, "GDBSERVER: %s before fork_inferior\n", __FUNCTION__);
+ my_read_loadmap(__FUNCTION__);
{
maybe_disable_address_space_randomization restore_personality
(cs.disable_randomization);
NULL, NULL, NULL, NULL);
}
+ fprintf(stderr, "GDBSERVER: %s after fork_inferior\n", __FUNCTION__);
+ my_read_loadmap(__FUNCTION__);
linux_add_process (pid, 0);
ptid = ptid_t (pid, pid, 0);
# define LINUX_LOADMAP_INTERP PTRACE_GETFDPIC_INTERP
# endif
+void my_read_loadmap(const char* fnname)
+{
+#if 0
+ struct target_loadmap *data = (struct target_loadmap *)0x7dffff38;
+#ifdef __FDPIC__
+ fprintf(stderr, "GDBSERVER: %s from %s data forced %p version %d, nsegs=%d\n", __FUNCTION__, fnname, data, data->version, data->nsegs);
+#else
+ fprintf(stderr, "GDBSERVER: %s from %s data forced %p, version/nsegs disabled\n", __FUNCTION__, fnname, data);
+#endif
+#endif
+}
+void my_hack_loadmap(const char* fnname)
+{
+#if 0
+ struct target_loadmap *data = (struct target_loadmap *)0x7dffff38;
+#ifdef __FDPIC__
+ data->version = 1;
+ data->nsegs = 1;
+ fprintf(stderr, "GDBSERVER: %s from %s data forced %p version %d, nsegs=%d\n", __FUNCTION__, fnname, data, data->version, data->nsegs);
+#else
+ fprintf(stderr, "GDBSERVER: %s from %s data forced %p disabled\n", __FUNCTION__, fnname, data);
+#endif
+#endif
+}
static int
linux_read_loadmap (const char *annex, CORE_ADDR offset,
unsigned char *myaddr, unsigned int len)
else
return -1;
+ fprintf(stderr, "GDBSERVER: %s before ptrace %s\n", __FUNCTION__, annex);
if (ptrace (LINUX_LOADMAP, pid, addr, &data) != 0)
return -1;
+ fprintf(stderr, "GDBSERVER: %s ptrace OK data %p\n", __FUNCTION__, data);
if (data == NULL)
return -1;
+ fprintf(stderr, "GDBSERVER: %s data OK, data %p version %d, nsegs=%d\n", __FUNCTION__, data, data->version, data->nsegs);
actual_length = sizeof (struct target_loadmap)
+ sizeof (struct target_loadseg) * data->nsegs;
if (offset < 0 || offset > actual_length)
return -1;
+ fprintf(stderr, "GDBSERVER: %s actual_length %d\n", __FUNCTION__, actual_length);
copy_length = actual_length - offset < len ? actual_length - offset : len;
memcpy (myaddr, (char *) data + offset, copy_length);
+ fprintf(stderr, "GDBSERVER: %s copy_length=%d\n", __FUNCTION__, copy_length);
return copy_length;
}
#else
threads' status ('?'). */
target_async (0);
+ // fprintf(stderr, "GDBSERVER: %s returns 0\n", __FUNCTION__);
return 0;
}
cs.transport_is_reliable = 1;
}
+void my_read_loadmap(const char*);
/* Open a connection to a remote debugger.
NAME is the filename used for communication. */
const char *port_str;
port_str = strchr (name, ':');
+ fprintf(stderr, "GDBSERVER: %s name |%s| port_str %s\n", __FUNCTION__, name, port_str);
#ifdef USE_WIN32API
if (port_str == NULL)
error ("Only HOST:PORT is supported on this platform.");
gai_strerror (r));
else
fprintf (stderr, _("Listening on port %s\n"), listen_port);
+ my_read_loadmap(__FUNCTION__);
fflush (stderr);
/* Register the event loop handler. */
add_file_handler (listen_desc, handle_accept_event, NULL);
}
+ // fprintf(stderr, "GDBSERVER: %s returns\n", __FUNCTION__);
}
void
else
res = 0;
+ // fprintf(stderr, "GDBSERVER: %s returns %d\n", __FUNCTION__, res);
return res;
}
*new_packet_len_p = write_qxfer_response (own_buf, data, n, 0);
free (data);
+ // fprintf(stderr, "GDBSERVER: %s packet size n %d\n", __FUNCTION__, n);
return 1;
}
else if (strcmp (rw, "write") == 0)
const char *selftest_filter = NULL;
#endif
+ // printf("GDBSERVER HELLO\n");
current_directory = getcwd (NULL, 0);
+ // printf("GDBSERVER HELLO2 CWD=%s\n", current_directory);
client_state &cs = get_client_state ();
if (current_directory == NULL)
while (*next_arg != NULL && **next_arg == '-')
{
+ fprintf(stderr, "GDBSERVER: %s next_arg %s\n", __FUNCTION__, *next_arg);
if (strcmp (*next_arg, "--version") == 0)
{
gdbserver_version ();
if (port == NULL)
{
port = *next_arg;
+ fprintf(stderr, "GDBSERVER: %s port %s\n", __FUNCTION__, port);
next_arg++;
}
if ((port == NULL || (!attach && !multi_mode && *next_arg == NULL))
start_inferior. */
if (port != NULL)
remote_prepare (port);
+ fprintf(stderr, "GDBSERVER: %s port after remote_prepare %s\n", __FUNCTION__, port);
bad_attach = 0;
pid = 0;
program_args.push_back (xstrdup (next_arg[i]));
program_args.push_back (NULL);
+ fprintf(stderr, "GDBSERVER: %s port before create_inferior %s\n", __FUNCTION__, port);
/* Wait till we are at first instruction in program. */
create_inferior (program_path.get (), program_args);
if (!was_running && !multi_mode)
error ("No program to debug");
+ fprintf(stderr, "GDBSERVER: %s port before remote_open %s\n", __FUNCTION__, port);
while (1)
{
cs.noack_mode = 0;
if (exit_requested)
return -1;
+ // fprintf(stderr, "GDBSERVER: %s returns 0\n", __FUNCTION__);
return 0;
}
#endif
#include "pathmax.h"
+#include <stdio.h>
/* In this file, PATH_MAX only serves as a threshold for choosing among two
algorithms. */
rootdev = st.st_dev;
rootino = st.st_ino;
+ // printf("TOTO GDB: thisdev %d thisino %d\n", thisdev, thisino);
+ // printf("TOTO GDB: rootdev %d rootino %d\n", rootdev, rootino);
while (!(thisdev == rootdev && thisino == rootino))
{
struct dirent *d;
size_t namlen;
bool use_d_ino = true;
+ // printf("TOTO GDB: going up\n");
/* Look at the parent directory. */
#if HAVE_OPENAT_SUPPORT
fd = openat (fd, "..", O_RDONLY);
dotdev = st.st_dev;
dotino = st.st_ino;
mount_point = dotdev != thisdev;
+ // printf("TOTO GDB: mount_point: %d dotdev %d dotino %d\n", mount_point, dotdev, dotino);
/* Search for the last directory. */
#if HAVE_OPENAT_SUPPORT
/* Clear errno to distinguish EOF from error if readdir returns
NULL. */
__set_errno (0);
+ // printf("TOTO GDB before readdir\n");
d = __readdir (dirstream);
/* When we've iterated through all directory entries without finding
via lstat. */
if (d == NULL && errno == 0 && use_d_ino)
{
+ // printf("TOTO GDB weird: d=%p errno=%d\n", d, errno);
use_d_ino = false;
rewinddir (dirstream);
d = __readdir (dirstream);
}
+ // printf("TOTO GDB: d=%p errno=%d name %s\n", d, errno, d != NULL ? d->d_name : "null");
if (d == NULL)
{
if (errno == 0)
#include "signals-state-save-restore.h"
#include "gdb_tilde_expand.h"
#include <vector>
+#include "nat/linux-ptrace.h"
extern char **environ;
#include "gdb_wait.h"
#ifdef __UCLIBC__
-#if !(defined(__UCLIBC_HAS_MMU__) || defined(__ARCH_HAS_MMU__))
+#if !(defined(__UCLIBC_HAS_MMU__) || defined(__ARCH_USE_MMU__))
/* PTRACE_TEXT_ADDR and friends. */
#include <asm/ptrace.h>
#define HAS_NOMMU
#define PTRACE_O_EXITKILL 0x00100000
#endif
-#if (defined __bfin__ || defined __frv__ || defined __sh__) \
+#if (defined __bfin__ || defined __frv__ || defined __sh__ \
+ || defined __arm__ ) \
&& !defined PTRACE_GETFDPIC
#define PTRACE_GETFDPIC 31
#define PTRACE_GETFDPIC_EXEC 0
{
enum packet_result result;
+ fprintf (stderr,
+ "GDB: %s Packet %s (%s)\n", __FUNCTION__,
+ config->name, config->title);
if (config->detect != AUTO_BOOLEAN_TRUE
&& config->support == PACKET_DISABLE)
internal_error (__FILE__, __LINE__,
{
const char v_mustreplyempty[] = "vMustReplyEmpty";
+ fprintf(stderr, "GDB: %s 'v' must-reply-empty\n", __FUNCTION__);
putpkt (v_mustreplyempty);
getpkt (&rs->buf, &rs->buf_size, 0);
if (strcmp (rs->buf, "OK") == 0)
}
for (i = 0; i < ARRAY_SIZE (remote_protocol_features); i++)
+ {
+ // fprintf(stderr, "GDB: %s comparing %s with %s\n", __FUNCTION__, remote_protocol_features[i].name, p);
if (strcmp (remote_protocol_features[i].name, p) == 0)
{
const struct protocol_feature *feature;
feature->func (this, feature, is_supported, value);
break;
}
+ }
}
/* If we increased the packet size, make sure to increase the global
struct remote_state *rs = get_remote_state ();
LONGEST i, n, packet_len;
+ if (!strcmp(object_name, "fdpic")) {
+ if (packet_config_support (packet) == PACKET_DISABLE)
+ fprintf(stderr, "GDB: %s DISABLED\n", __FUNCTION__);
+ }
if (packet_config_support (packet) == PACKET_DISABLE)
return TARGET_XFER_E_IO;
if (packet_len < 0 || packet_ok (rs->buf, packet) != PACKET_OK)
return TARGET_XFER_E_IO;
+ if (!strcmp(object_name, "fdpic")) {
+ fprintf(stderr, "GDB: %s apres getpkt fdpic packet_len %ld\n", __FUNCTION__, packet_len);
+ }
if (rs->buf[0] != 'l' && rs->buf[0] != 'm')
error (_("Unknown remote qXfer reply: %s"), rs->buf);
struct int_elf32_fdpic_loadseg segs[1 /* nsegs, actually */];
};
+/* CLYON */
+static void
+fdpic_print_loadmap (struct int_elf32_fdpic_loadmap *map)
+{
+ int i;
+
+ if (map == NULL)
+ printf_filtered ("(null)\n");
+ else if (map->version != 0)
+ printf_filtered (_("Unsupported map version: %d\n"), map->version);
+ else
+ {
+ printf_filtered ("version %d\n", map->version);
+
+ for (i = 0; i < map->nsegs; i++)
+ printf_filtered ("%s:%s -> %s:%s\n",
+ print_core_address (target_gdbarch (),
+ map->segs[i].p_vaddr),
+ print_core_address (target_gdbarch (),
+ map->segs[i].p_vaddr
+ + map->segs[i].p_memsz),
+ print_core_address (target_gdbarch (), map->segs[i].addr),
+ print_core_address (target_gdbarch (), map->segs[i].addr
+ + map->segs[i].p_memsz));
+ }
+}
+
/* Given address LDMADDR, fetch and decode the loadmap at that address.
Return NULL if there is a problem reading the target memory or if
there doesn't appear to be a loadmap at the given address. The
}
xfree (ext_ldmbuf);
+ fdpic_print_loadmap (int_ldmbuf);
return int_ldmbuf;
}
else
{
#endif
+#if 0
+ if (exec_addr != NULL)
+ *exec_addr = 0xfffde6b8;
+ if (interp_addr != NULL)
+ *interp_addr = 0xfffde69c;
+ return 0;
+#endif
+#if 1
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
- gdb::optional<gdb::byte_vector> buf
- = target_read_alloc (current_top_target (), TARGET_OBJECT_FDPIC, "exec");
- /* CHECK BUF CF solib-dsbt.c */
- if (exec_addr != NULL)
- *exec_addr = extract_unsigned_integer (buf->data (), 4 /*FIXME*/, byte_order);
+ gdb::optional<gdb::byte_vector> buf
+ = target_read_alloc (current_top_target (), TARGET_OBJECT_FDPIC, "exec");
+ /* CHECK BUF CF solib-dsbt.c */
+
+ if (!buf || buf->empty ())
+ {
+ // info->exec_loadmap = NULL;
+ error (_("Error reading FDPIC exec loadmap"));
+ }
+
+ if (exec_addr != NULL)
+ *exec_addr = extract_unsigned_integer (buf->data (), 4 /*FIXME*/, byte_order);
+
+ fprintf(stderr, "GDB: %s got exec_addr: %lx\n", __FUNCTION__, *exec_addr);
- buf = target_read_alloc (current_top_target (), TARGET_OBJECT_FDPIC, "interp");
- if (interp_addr != NULL)
- *interp_addr = extract_unsigned_integer (buf->data (), 4 /*FIXME*/, byte_order);
+ buf = target_read_alloc (current_top_target (), TARGET_OBJECT_FDPIC, "interp");
+ if (!buf || buf->empty ())
+ {
+ // info->exec_loadmap = NULL;
+ error (_("Error reading FDPIC interp loadmap"));
+ }
+ if (interp_addr != NULL)
+ *interp_addr = extract_unsigned_integer (buf->data (), 4 /*FIXME*/, byte_order);
+ fprintf(stderr, "GDB: %s got interp_addr: %lx\n", __FUNCTION__, *interp_addr);
- return 0; /* FIXME */
+ return 0; /* FIXME */
+#endif
#if 0
struct regcache *regcache = get_current_regcache ();
{
ULONGEST val;
regcache_cooked_read_unsigned (regcache,
- fdpic_loadmap_interp_regnum, &val);
+ 9/*FIXME fdpic_loadmap_interp_regnum*/, &val);
*interp_addr = val;
}
if (exec_addr != NULL)
{
ULONGEST val;
regcache_cooked_read_unsigned (regcache,
- fdpic_loadmap_exec_regnum, &val);
+ 9/*fdpic_loadmap_exec_regnum*/, &val);
*exec_addr = val;
}
return 0;
#include "gdbcore.h"
#include "solib.h"
#include "solist.h"
-#include "frv-tdep.h"
+//#include "frv-tdep.h" /* For frv_fdpic_loadmap_addresses() */
+int frv_fdpic_loadmap_addresses (struct gdbarch *gdbarch,
+ CORE_ADDR *interp_addr, CORE_ADDR *exec_addr);
#include "objfiles.h"
#include "symtab.h"
#include "language.h"
#include "command.h"
#include "gdbcmd.h"
-#include "elf/frv.h"
+//#include "elf/frv.h" /* Used in find_canonical_descriptor_in_load_object() */
#include "gdb_bfd.h"
/* Flag which indicates whether internal debug messages should be printed. */
this address (which is a GOT entry) to obtain a descriptor
address. */
if ((name == 0 || strcmp (name, (*rel->sym_ptr_ptr)->name) == 0)
- && rel->howto->type == R_FRV_FUNCDESC)
+ /*&& rel->howto->type == R_FRV_FUNCDESC*/)
{
gdb_byte buf [FRV_PTR_SIZE];
/* Non-zero tells remote* modules to output debugging info. */
-int remote_debug = 0;
+int remote_debug = 0/*1*/;
/* Sbrk location on entry to main. Used for statistics only. */
#ifdef HAVE_USEFUL_SBRK