Re: [PATCH v2] gdbserver: bfin: new port

Andrew Stubbs
2010-12-15T11:54:26Z

[-- Attachment #1: Type: text/plain, Size: 741 bytes --]

On 14/12/10 17:25, Mike Frysinger wrote:
>> I did start implementing something vaguely target independent (included
>> > in CodeSourcery SG++), but the state of the SH-2A kernel debug support
>> > put that project on the back burner, so it remains the bare minimum.
> i'm not asking for a finished project. i would like to simply review the code
> you said you have already. so where might one find your SuperH/FDPIC
> gdb/gdbserver code ?

The latest CodeSourcery SH-2A toolchain binaries and source can be
downloaded from here:
http://www.codesourcery.com/sgpp/lite/superh/portal/release1602

I've attached my original patch. I didn't do the forward port when we
updated GDB myself, so it may be out-of-date in a few places.

Andrew

[-- Attachment #2: gdb-fdpic.patch --]
[-- Type: text/x-patch, Size: 21343 bytes --]

gdb/
* configure.tgt: Add support for sh*-*-uclinux*.
(gdb_target_obs): Add solib-fdpic.o for sh*-*-linux and sh*-*-uclinux.
* remote.c (PACKET_qXfer_fdpic): New enum value.
(remote_protocol_features): Add qXfer:fdpic:read packet.
(remote_xfer_partial): Support TARGET_OBJECT_FDPIC.
(_initialize_remote): Add set/show remote read-fdpic-loadmap command.
* sh-linux-tdep.c: Include elf/sh.h, elf-bfd.h, solib.h, solist.h and
solib-fdpic.h.
(sh_linux_init_abi): Detect FDPIC binaries and enable solib-fdpic.
* solib-fdpic.c: New file.
* solib-fdpic.h: New file.
* target.h (enum target_object): Add TARGET_OBJECT_FDPIC.

gdb/gdbserver:
* configure.srv: Add support for sh*-*-uclinux*.
* linux-low.c (struct elf32_fdpic_loadseg): New type.
(struct elf32_fdpic_loadmap): New type.
(linux_read_fdpic_loadmap): New function.
(linux_target_ops): Add linux_read_fdpic_loadmap.
* server.c (handle_query): Support qXfer:fdpic:read packet.
* target.h (struct target_ops): Add read_fdpic_loadmap.

include/
* elf/sh.h (EF_SH_PIC, EF_SH_FDPIC): New defines.
(R_SH_LAST_INVALID_RELOC_5, R_SH_GOT20): New relocations.
(R_SH_GOTOFF20, R_SH_GOTFUNCDESC, R_SH_GOTFUNCDESC20): Likewise.
(R_SH_GOTOFFFUNCDESC, R_SH_GOTOFFFUNCDESC20): Likewise.
(R_SH_FUNCDESC, R_SH_FUNCDESC_VALUE): Likewise.
(R_SH_FIRST_INVALID_RELOC_6, R_SH_LAST_INVALID_RELOC_6): Likewise.

---
src/gdb-trunk/gdb/configure.tgt | 6 -
src/gdb-trunk/gdb/gdbserver/configure.srv | 6 +
src/gdb-trunk/gdb/gdbserver/linux-low.c | 57 ++++++
src/gdb-trunk/gdb/gdbserver/server.c | 44 +++++
src/gdb-trunk/gdb/gdbserver/target.h | 4
src/gdb-trunk/gdb/remote.c | 9 +
src/gdb-trunk/gdb/sh-linux-tdep.c | 12 +
src/gdb-trunk/gdb/solib-fdpic.c | 266 +++++++++++++++++++++++++++++
src/gdb-trunk/gdb/solib-fdpic.h | 25 +++
src/gdb-trunk/gdb/target.h | 2
src/gdb-trunk/include/elf/sh.h | 18 ++
11 files changed, 444 insertions(+), 5 deletions(-)
create mode 100644 src/gdb-trunk/gdb/solib-fdpic.c
create mode 100644 src/gdb-trunk/gdb/solib-fdpic.h

diff --git a/src/gdb-trunk/gdb/configure.tgt b/src/gdb-trunk/gdb/configure.tgt
index 876c5bd..7da3381 100644
--- a/src/gdb-trunk/gdb/configure.tgt
+++ b/src/gdb-trunk/gdb/configure.tgt
@@ -431,11 +431,11 @@ score-*-*)
build_gdbserver=yes
;;

-sh*-*-linux*)
+sh*-*-linux* | sh*-*-uclinux*)
# Target: GNU/Linux Super-H
gdb_target_obs="sh-tdep.o sh64-tdep.o sh-linux-tdep.o monitor.o \
- dsrec.o solib.o solib-svr4.o symfile-mem.o \
- glibc-tdep.o corelow.o"
+ dsrec.o solib.o solib-svr4.o solib-fdpic.o \
+ symfile-mem.o glibc-tdep.o corelow.o"
gdb_sim=../sim/sh/libsim.a
build_gdbserver=yes
;;
diff --git a/src/gdb-trunk/gdb/gdbserver/configure.srv b/src/gdb-trunk/gdb/gdbserver/configure.srv
index dae9bef..4e0f5a5 100644
--- a/src/gdb-trunk/gdb/gdbserver/configure.srv
+++ b/src/gdb-trunk/gdb/gdbserver/configure.srv
@@ -215,6 +215,12 @@ case "${target}" in
srv_linux_regsets=yes
srv_linux_thread_db=yes
;;
+ sh*-*-uclinux*) srv_regobj=reg-sh.o
+ srv_tgtobj="linux-low.o linux-sh-low.o"
+ srv_linux_usrregs=yes
+ srv_linux_regsets=yes
+ srv_linux_thread_db=yes
+ ;;
sparc*-*-linux*) srv_regobj=reg-sparc64.o
srv_tgtobj="linux-low.o linux-sparc-low.o"
srv_linux_regsets=yes
diff --git a/src/gdb-trunk/gdb/gdbserver/linux-low.c b/src/gdb-trunk/gdb/gdbserver/linux-low.c
index 6043f22..147bedc 100644
--- a/src/gdb-trunk/gdb/gdbserver/linux-low.c
+++ b/src/gdb-trunk/gdb/gdbserver/linux-low.c
@@ -3452,6 +3452,56 @@ linux_core_of_thread (ptid_t ptid)
return core;
}

+#ifdef __FDPIC__
+struct elf32_fdpic_loadseg
+{
+ /* Core address to which the segment is mapped. */
+ Elf32_Addr addr;
+ /* VMA recorded in the program header. */
+ Elf32_Addr p_vaddr;
+ /* Size of this segment in memory. */
+ Elf32_Word p_memsz;
+};
+
+struct elf32_fdpic_loadmap {
+ /* Protocol version number, must be zero. */
+ Elf32_Half version;
+ /* Number of segments in this map. */
+ Elf32_Half nsegs;
+ /* The actual memory map. */
+ struct elf32_fdpic_loadseg segs[/*nsegs*/];
+};
+
+static int
+linux_read_fdpic_loadmap (const char *annex, CORE_ADDR offset,
+ unsigned char *myaddr, unsigned int len)
+{
+ int pid = lwpid_of (get_thread_lwp (current_inferior));
+ int addr = (strcmp (annex, "exec") == 0 ? PTRACE_GETFDPIC_EXEC :
+ (strcmp (annex, "interp") == 0 ? PTRACE_GETFDPIC_INTERP :
+ -1));
+ struct elf32_fdpic_loadmap *data = NULL;
+ unsigned int actual_length, copy_length;
+
+ if (addr == -1)
+ return -1;
+
+ ptrace (PTRACE_GETFDPIC, pid, addr, &data);
+ if (data == NULL)
+ return -1;
+
+ actual_length = sizeof (struct elf32_fdpic_loadmap)
+ + sizeof (struct elf32_fdpic_loadseg) * data->nsegs;
+
+ if (offset < 0 || offset > actual_length)
+ return -1;
+
+ copy_length = actual_length - offset < len ? actual_length - offset : len;
+ memcpy (myaddr, ((char *)data) + offset, copy_length);
+ return copy_length;
+}
+#endif
+
static struct target_ops linux_target_ops = {
linux_create_inferior,
linux_attach,
@@ -3495,7 +3545,12 @@ static struct target_ops linux_target_ops = {
#else
NULL,
#endif
- linux_core_of_thread
+ linux_core_of_thread,
+#ifdef __FDPIC__
+ linux_read_fdpic_loadmap
+#else
+ NULL
+#endif
};

static void
diff --git a/src/gdb-trunk/gdb/gdbserver/server.c b/src/gdb-trunk/gdb/gdbserver/server.c
index 9d21be4..9aec881 100644
--- a/src/gdb-trunk/gdb/gdbserver/server.c
+++ b/src/gdb-trunk/gdb/gdbserver/server.c
@@ -1268,6 +1268,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
if (the_target->qxfer_siginfo != NULL)
strcat (own_buf, ";qXfer:siginfo:read+;qXfer:siginfo:write+");

+ if (the_target->read_fdpic_loadmap != NULL)
+ strcat (own_buf, ";qXfer:fdpic:read+");
+
/* We always report qXfer:features:read, as targets may
install XML files on a subsequent call to arch_setup.
If we reported to GDB on startup that we don't support
@@ -1421,6 +1424,47 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
return;
}

+ if (the_target->read_fdpic_loadmap != NULL
+ && strncmp ("qXfer:fdpic:read:", own_buf, 17) == 0)
+ {
+ unsigned char *data;
+ int n;
+ CORE_ADDR ofs;
+ unsigned int len;
+ char *annex;
+
+ require_running (own_buf);
+
+ /* Grab the offset and length. */
+ if (decode_xfer_read (own_buf + 17, &annex, &ofs, &len) < 0)
+ {
+ strcpy (own_buf, "E00");
+ return;
+ }
+
+ /* Read one extra byte, as an indicator of whether there is
+ more. */
+ if (len > PBUFSIZ - 2)
+ len = PBUFSIZ - 2;
+ data = malloc (len + 1);
+ if (data == NULL)
+ {
+ write_enn (own_buf);
+ return;
+ }
+ n = (*the_target->read_fdpic_loadmap) (annex, ofs, data, len + 1);
+ if (n < 0)
+ write_enn (own_buf);
+ else if (n > len)
+ *new_packet_len_p = write_qxfer_response (own_buf, data, len, 1);
+ else
+ *new_packet_len_p = write_qxfer_response (own_buf, data, n, 0);
+
+ free (data);
+
+ return;
+ }
+
/* Otherwise we didn't know what packet it was. Say we didn't
understand it. */
own_buf[0] = 0;
diff --git a/src/gdb-trunk/gdb/gdbserver/target.h b/src/gdb-trunk/gdb/gdbserver/target.h
index ac68652..c47f01b 100644
--- a/src/gdb-trunk/gdb/gdbserver/target.h
+++ b/src/gdb-trunk/gdb/gdbserver/target.h
@@ -286,6 +286,10 @@ struct target_ops

/* Returns the core given a thread, or -1 if not known. */
int (*core_of_thread) (ptid_t);
+
+ /* Read FDPIC loadmaps. Read LEN bytes at OFFSET into a buffer at MYADDR. */
+ int (*read_fdpic_loadmap) (const char *annex, CORE_ADDR offset,
+ unsigned char *myaddr, unsigned int len);
};

extern struct target_ops *the_target;
diff --git a/src/gdb-trunk/gdb/remote.c b/src/gdb-trunk/gdb/remote.c
index bcb42a7..b11b63d 100644
--- a/src/gdb-trunk/gdb/remote.c
+++ b/src/gdb-trunk/gdb/remote.c
@@ -1301,6 +1301,7 @@ enum {
PACKET_FastTracepoints,
PACKET_bc,
PACKET_bs,
+ PACKET_qXfer_fdpic,
PACKET_MAX
};

@@ -3641,6 +3642,8 @@ static struct protocol_feature remote_protocol_features[] = {
PACKET_bc },
{ "ReverseStep", PACKET_DISABLE, remote_supported_packet,
PACKET_bs },
+ { "qXfer:fdpic:read", PACKET_DISABLE, remote_supported_packet,
+ PACKET_qXfer_fdpic },
};

static void
@@ -8038,6 +8041,9 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
return remote_read_qxfer (ops, "threads", annex, readbuf, offset, len,
&remote_protocol_packets[PACKET_qXfer_threads]);

+ case TARGET_OBJECT_FDPIC:
+ return remote_read_qxfer (ops, "fdpic", annex, readbuf, offset, len,
+ &remote_protocol_packets[PACKET_qXfer_fdpic]);
default:
return -1;
}
@@ -10335,6 +10341,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
add_packet_config_cmd (&remote_protocol_packets[PACKET_FastTracepoints],
"FastTracepoints", "fast-tracepoints", 0);

+ add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_fdpic],
+ "qXfer:fdpic:read", "read-fdpic-loadmap", 0);
+
/* Keep the old ``set remote Z-packet ...'' working. Each individual
Z sub-packet has its own set and show commands, but users may
have sets to this variable in their .gdbinit files (or in their
diff --git a/src/gdb-trunk/gdb/sh-linux-tdep.c b/src/gdb-trunk/gdb/sh-linux-tdep.c
index 19cf1b9..2238620 100644
--- a/src/gdb-trunk/gdb/sh-linux-tdep.c
+++ b/src/gdb-trunk/gdb/sh-linux-tdep.c
@@ -28,6 +28,12 @@
#include "regcache.h"
#include "regset.h"

+#include "elf/sh.h"
+#include "elf-bfd.h"
+#include "solib.h"
+#include "solist.h"
+#include "solib-fdpic.h"
+
#include "glibc-tdep.h"
#include "sh-tdep.h"

@@ -94,6 +100,12 @@ sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->core_gregmap = (struct sh_corefile_regmap *)gregs_table;
tdep->core_fpregmap = (struct sh_corefile_regmap *)fpregs_table;
}
+
+ if (info.abfd && elf_elfheader(info.abfd)->e_flags & EF_SH_FDPIC)
+ {
+ /* FDPIC detected. Switch shared library mode. */
+ set_solib_ops (gdbarch, &fdpic_so_ops);
+ }
}

/* Provide a prototype to silence -Wmissing-prototypes. */
diff --git a/src/gdb-trunk/gdb/solib-fdpic.c b/src/gdb-trunk/gdb/solib-fdpic.c
new file mode 100644
index 0000000..85ba688
--- /dev/null
+++ b/src/gdb-trunk/gdb/solib-fdpic.c
@@ -0,0 +1,266 @@
+/* Handle FDPIC shared libraries for GDB, the GNU Debugger.
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* FDPIC dynamic libraries work like svr4 shared libraries in many ways,
+ but not quite. The main differences are that even the main executable
+ can be relocated unpredictably, and the read-only and writable sections
+ of the inferior can be relocated independently (indeed, there may be an
+ arbitrary number of separate regions).
+
+ The load maps cannot be determined by reading from program memory,
+ because it's not at a fixed location. Instead they must be obtained
+ from the Linux kernel using a special ptrace call.
+
+ The added complexity of the load maps means that we need more than a
+ single offset to do the relocation. Each relocation requires a table
+ lookup to determine what range it falls into. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "solib-svr4.h"
+#include "solist.h"
+#include "bfd.h"
+#include "exec.h"
+#include "target.h"
+#include "elf.h"
+#include "objfiles.h"
+#include "cli/cli-decode.h"
+
+/* These data structures are taken from elf-fdpic.h in uCLibc. */
+
+struct elf32_fdpic_loadseg
+{
+ /* Core address to which the segment is mapped. */
+ Elf32_Addr addr;
+ /* VMA recorded in the program header. */
+ Elf32_Addr p_vaddr;
+ /* Size of this segment in memory. */
+ Elf32_Word p_memsz;
+};
+
+struct elf32_fdpic_loadmap {
+ /* Protocol version number, must be zero. */
+ Elf32_Half version;
+ /* Number of segments in this map. */
+ Elf32_Half nsegs;
+ /* The actual memory map. */
+ struct elf32_fdpic_loadseg segs[/*nsegs*/];
+};
+
+/* Load maps for the main executable and the interpreter.
+ These are obtained from ptrace. They are the starting point for getting
+ into the program, and are required to find the solib list with the
+ individual load maps for each module. */
+
+static struct elf32_fdpic_loadmap *exec_loadmap = NULL, *interp_loadmap = NULL;
+
+
+/* normalize_loadmap_endian
+
+ Convert a load map from target endian to host endian. */
+
+static void
+normalize_loadmap_endian (struct elf32_fdpic_loadmap *map)
+{
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
+ int i;
+
+#define NORMAILIZE_ENDIAN(field) \
+ (field) = extract_unsigned_integer ((gdb_byte*)&(field), sizeof (field), \
+ byte_order);
+
+ NORMAILIZE_ENDIAN (map->version);
+ NORMAILIZE_ENDIAN (map->nsegs);
+
+ for (i = 0; i < map->nsegs; i++)
+ {
+ NORMAILIZE_ENDIAN (map->segs[i].addr);
+ NORMAILIZE_ENDIAN (map->segs[i].p_vaddr);
+ NORMAILIZE_ENDIAN (map->segs[i].p_memsz);
+ }
+
+#undef NORMAILIZE_ENDIAN
+}
+
+static void
+fdpic_print_loadmap (struct 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
+ for (i = 0; i < map->nsegs; i++)
+ printf_filtered ("0x%08x:0x%08x -> 0x%08x:0x%08x\n",
+ map->segs[i].p_vaddr,
+ map->segs[i].p_vaddr + map->segs[i].p_memsz,
+ map->segs[i].addr,
+ map->segs[i].addr + map->segs[i].p_memsz);
+}
+
+/* fdpic_get_initial_loadmaps
+
+ Interrogate the Linux kernel to find out where the program was loaded.
+ There are two load maps; one for the executable and one for the
+ interpreter (only in the case of a dynamically linked executable). */
+
+static void
+fdpic_get_initial_loadmaps (void)
+{
+ if (0 >= target_read_alloc (&current_target, TARGET_OBJECT_FDPIC,
+ "exec", (gdb_byte**)&exec_loadmap))
+ {
+ error (_("Error reading FDPIC exec loadmap\n"));
+ exec_loadmap = NULL;
+ return;
+ }
+ else
+ normalize_loadmap_endian (exec_loadmap);
+
+ if (0 >= target_read_alloc (&current_target, TARGET_OBJECT_FDPIC,
+ "interp", (gdb_byte**)&interp_loadmap))
+ interp_loadmap = NULL;
+ else
+ normalize_loadmap_endian (interp_loadmap);
+}
+
+/* fdpic_find_load_offset
+
+ Return the offset from the given objfile address to the actual loaded
+ address. Note that, unlike normal svr4, different sections in the same
+ objfile might have different offsets. */
+
+static CORE_ADDR
+fdpic_find_load_offset (CORE_ADDR addr, struct elf32_fdpic_loadmap *map)
+{
+ int seg;
+
+ for (seg = 0; seg < map->nsegs; seg++)
+ {
+ CORE_ADDR sectionoffset = addr - map->segs[seg].p_vaddr;
+ if (sectionoffset >= 0 && sectionoffset < map->segs[seg].p_memsz)
+ {
+ return map->segs[seg].addr - map->segs[seg].p_vaddr;
+ }
+ }
+
+ /* The address did not match the load map. */
+ return 0;
+}
+
+/* fdpic_relocate_file
+
+ Relocate all the symbols/sections in the given file.
+
+ If SYMFILE is NULL then relocate BFD instead.
+ If SYMFILE is non-NULL, then BFD is not used. */
+
+static int
+fdpic_relocate_file (struct objfile *symfile, bfd *bfd,
+ struct elf32_fdpic_loadmap *map)
+{
+ if (map == NULL)
+ return 0;
+
+ if (symfile)
+ {
+ struct section_offsets *new_offsets;
+ struct obj_section *osect;
+ int i = 0;
+
+ new_offsets = alloca (symfile_objfile->num_sections
+ * sizeof (*new_offsets));
+
+ ALL_OBJFILE_OSECTIONS (symfile_objfile, osect)
+ new_offsets->offsets[i++] =
+ fdpic_find_load_offset (bfd_get_section_vma (osect->objfile->abfd,
+ osect->the_bfd_section),
+ map);
+
+ objfile_relocate (symfile_objfile, new_offsets);
+ }
+ else if (bfd)
+ {
+ asection *asect;
+
+ for (asect = exec_bfd->sections; asect != NULL; asect = asect->next)
+ {
+ CORE_ADDR vma = bfd_get_section_vma (exec_bfd, asect);
+ exec_set_section_address (bfd_get_filename (exec_bfd), asect->index,
+ vma + fdpic_find_load_offset (vma, map));
+ }
+ }
+ else
+ return 0;
+
+ return 1;
+}
+
+
+static void
+fdpic_clear_solib (void)
+{
+ /* GDB crashes if this function doesn't exist. */
+}
+
+static void
+fdpic_solib_create_inferior_hook (int from_tty)
+{
+ if (exec_bfd == NULL)
+ return;
+
+ fdpic_get_initial_loadmaps ();
+
+ if (!fdpic_relocate_file (symfile_objfile, exec_bfd, exec_loadmap))
+ return;
+
+ /* TODO: actually place a hook. */
+}
+
+static struct so_list *
+fdpic_current_sos (void)
+{
+ /* FDPIC shared libraries are not yet supported. */
+ return NULL;
+}
+
+static void
+info_fdpic_command (char *args, int from_tty)
+{
+ printf_filtered (_("Main executable load map:\n"));
+ fdpic_print_loadmap (exec_loadmap);
+}
+
+
+struct target_so_ops fdpic_so_ops;
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+extern initialize_file_ftype _initialize_fdpic_solib;
+
+void
+_initialize_fdpic_solib (void)
+{
+ fdpic_so_ops.clear_solib = fdpic_clear_solib;
+ fdpic_so_ops.solib_create_inferior_hook =
+ fdpic_solib_create_inferior_hook;
+ fdpic_so_ops.current_sos = fdpic_current_sos;
+
+ add_info ("fdpic", info_fdpic_command, _("Display the FDPIC load maps.\n"));
+}
diff --git a/src/gdb-trunk/gdb/solib-fdpic.h b/src/gdb-trunk/gdb/solib-fdpic.h
new file mode 100644
index 0000000..5cb45a1
--- /dev/null
+++ b/src/gdb-trunk/gdb/solib-fdpic.h
@@ -0,0 +1,25 @@
+/* Handle FDPIC shared libraries for GDB, the GNU Debugger.
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SOLIB_FDPIC_H
+#define SOLIB_FDPIC_H
+
+struct target_so_ops;
+extern struct target_so_ops fdpic_so_ops;
+
+#endif
diff --git a/src/gdb-trunk/gdb/target.h b/src/gdb-trunk/gdb/target.h
index 27e250a..6d0eac6 100644
--- a/src/gdb-trunk/gdb/target.h
+++ b/src/gdb-trunk/gdb/target.h
@@ -266,6 +266,8 @@ enum target_object
TARGET_OBJECT_SIGNAL_INFO,
/* The list of threads that are being debugged. */
TARGET_OBJECT_THREADS,
+ /* Load maps for FDPIC systems. */
+ TARGET_OBJECT_FDPIC
/* Possible future objects: TARGET_OBJECT_FILE, ... */
};

diff --git a/src/gdb-trunk/include/elf/sh.h b/src/gdb-trunk/include/elf/sh.h
index 4969116..158eb88 100644
--- a/src/gdb-trunk/include/elf/sh.h
+++ b/src/gdb-trunk/include/elf/sh.h
@@ -85,6 +85,12 @@ int sh_find_elf_flags (unsigned int arch_set);
/* Convert bfd_mach_* into EF_SH*. */
int sh_elf_get_flags_from_mach (unsigned long mach);

+/* Other e_flags bits. */
+
+#define EF_SH_PIC 0x100 /* Segments of an FDPIC binary may
+ be relocated independently. */
+#define EF_SH_FDPIC 0x8000 /* Uses the FDPIC ABI. */
+
/* Flags for the st_other symbol field.
Keep away from the STV_ visibility flags (bit 0..1). */

@@ -213,7 +219,17 @@ START_RELOC_NUMBERS (elf_sh_reloc_type)
RELOC_NUMBER (R_SH_JMP_SLOT64, 195)
RELOC_NUMBER (R_SH_RELATIVE64, 196)
FAKE_RELOC (R_SH_FIRST_INVALID_RELOC_5, 197)
- FAKE_RELOC (R_SH_LAST_INVALID_RELOC_5, 241)
+ FAKE_RELOC (R_SH_LAST_INVALID_RELOC_5, 200)
+ RELOC_NUMBER (R_SH_GOT20, 201)
+ RELOC_NUMBER (R_SH_GOTOFF20, 202)
+ RELOC_NUMBER (R_SH_GOTFUNCDESC, 203)
+ RELOC_NUMBER (R_SH_GOTFUNCDESC20, 204)
+ RELOC_NUMBER (R_SH_GOTOFFFUNCDESC, 205)
+ RELOC_NUMBER (R_SH_GOTOFFFUNCDESC20, 206)
+ RELOC_NUMBER (R_SH_FUNCDESC, 207)
+ RELOC_NUMBER (R_SH_FUNCDESC_VALUE, 208)
+ FAKE_RELOC (R_SH_FIRST_INVALID_RELOC_6, 209)
+ FAKE_RELOC (R_SH_LAST_INVALID_RELOC_6, 241)
RELOC_NUMBER (R_SH_SHMEDIA_CODE, 242)
RELOC_NUMBER (R_SH_PT_16, 243)
RELOC_NUMBER (R_SH_IMMS16, 244)