- Fix powerpc recent secure PLTs handling (shared library calls) (BZ
452960). - Fix the testsuite .spec runner to run biarch also on ppc. - Reenable testcases threadcrash.exp, chng-syms.exp, checkpoint.exp (BZ 207002). - Fix PRPSINFO in the core files dumped by gcore (BZ 254229), reformatted patch from Denys Vlasenko. - Fix register assignments with no GDB stack frames, Denys Vlasenko (BZ 436037).
This commit is contained in:
parent
8b1b3fd689
commit
3a094fb8da
344
gdb-6.8-bz254229-gcore-prpsinfo.patch
Normal file
344
gdb-6.8-bz254229-gcore-prpsinfo.patch
Normal file
@ -0,0 +1,344 @@
|
||||
diff -d -urpN gdb-6.8.4/bfd/elf-bfd.h gdb-6.8.7/bfd/elf-bfd.h
|
||||
--- gdb-6.8.4/bfd/elf-bfd.h 2008-07-25 16:16:15.000000000 +0200
|
||||
+++ gdb-6.8.7/bfd/elf-bfd.h 2008-07-29 12:29:20.000000000 +0200
|
||||
@@ -2125,7 +2125,7 @@ extern Elf_Internal_Phdr * _bfd_elf_find
|
||||
extern char *elfcore_write_note
|
||||
(bfd *, char *, int *, const char *, int, const void *, int);
|
||||
extern char *elfcore_write_prpsinfo
|
||||
- (bfd *, char *, int *, const char *, const char *);
|
||||
+ (bfd *, char *, int *, void *, const char *, const char *);
|
||||
extern char *elfcore_write_prstatus
|
||||
(bfd *, char *, int *, long, int, const void *);
|
||||
extern char * elfcore_write_pstatus
|
||||
diff -d -urpN gdb-6.8.4/bfd/elf.c gdb-6.8.7/bfd/elf.c
|
||||
--- gdb-6.8.4/bfd/elf.c 2008-07-25 16:16:15.000000000 +0200
|
||||
+++ gdb-6.8.7/bfd/elf.c 2008-07-29 12:45:52.000000000 +0200
|
||||
@@ -8256,6 +8256,7 @@ char *
|
||||
elfcore_write_prpsinfo (bfd *abfd,
|
||||
char *buf,
|
||||
int *bufsiz,
|
||||
+ void *info,
|
||||
const char *fname,
|
||||
const char *psargs)
|
||||
{
|
||||
@@ -8282,9 +8283,15 @@ elfcore_write_prpsinfo (bfd *abfd,
|
||||
int note_type = NT_PRPSINFO;
|
||||
#endif
|
||||
|
||||
- memset (&data, 0, sizeof (data));
|
||||
- strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
|
||||
- strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
|
||||
+ if (info)
|
||||
+ memcpy (&data, info, sizeof (data));
|
||||
+ else
|
||||
+ {
|
||||
+ memset (&data, 0, sizeof (data));
|
||||
+ strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
|
||||
+ strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
|
||||
+ }
|
||||
+
|
||||
return elfcore_write_note (abfd, buf, bufsiz,
|
||||
note_name, note_type, &data, sizeof (data));
|
||||
}
|
||||
@@ -8299,9 +8306,15 @@ elfcore_write_prpsinfo (bfd *abfd,
|
||||
int note_type = NT_PRPSINFO;
|
||||
#endif
|
||||
|
||||
- memset (&data, 0, sizeof (data));
|
||||
- strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
|
||||
- strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
|
||||
+ if (info)
|
||||
+ memcpy (&data, info, sizeof (data));
|
||||
+ else
|
||||
+ {
|
||||
+ memset (&data, 0, sizeof (data));
|
||||
+ strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
|
||||
+ strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
|
||||
+ }
|
||||
+
|
||||
return elfcore_write_note (abfd, buf, bufsiz,
|
||||
note_name, note_type, &data, sizeof (data));
|
||||
}
|
||||
diff -d -urpN gdb-6.8.4/gdb/amd64-linux-nat.c gdb-6.8.7/gdb/amd64-linux-nat.c
|
||||
--- gdb-6.8.4/gdb/amd64-linux-nat.c 2008-07-25 16:16:15.000000000 +0200
|
||||
+++ gdb-6.8.7/gdb/amd64-linux-nat.c 2008-07-29 12:46:02.000000000 +0200
|
||||
@@ -139,6 +139,7 @@ static int amd64_linux_gregset32_reg_off
|
||||
|
||||
static char *
|
||||
amd64_linux_elfcore_write_prpsinfo (bfd *abfd, char *buf, int *bufsiz,
|
||||
+ void *info,
|
||||
const char *fname, const char *psargs)
|
||||
{
|
||||
if (gdbarch_ptr_bit(current_gdbarch) == 32)
|
||||
@@ -148,14 +149,20 @@ amd64_linux_elfcore_write_prpsinfo (bfd
|
||||
struct elf_prpsinfo32 data;
|
||||
note_type = NT_PRPSINFO;
|
||||
|
||||
- memset (&data, 0, sizeof (data));
|
||||
- strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
|
||||
- strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
|
||||
+ if (info)
|
||||
+ memcpy (&data, info, sizeof (data));
|
||||
+ else
|
||||
+ {
|
||||
+ memset (&data, 0, sizeof (data));
|
||||
+ strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
|
||||
+ strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
|
||||
+ }
|
||||
+
|
||||
return elfcore_write_note (abfd, buf, bufsiz,
|
||||
note_name, note_type, &data, sizeof (data));
|
||||
}
|
||||
else
|
||||
- return elfcore_write_prpsinfo (abfd, buf, bufsiz, fname, psargs);
|
||||
+ return elfcore_write_prpsinfo (abfd, buf, bufsiz, info, fname, psargs);
|
||||
}
|
||||
|
||||
static void
|
||||
diff -d -urpN gdb-6.8.4/gdb/fbsd-nat.c gdb-6.8.7/gdb/fbsd-nat.c
|
||||
--- gdb-6.8.4/gdb/fbsd-nat.c 2008-07-25 16:16:15.000000000 +0200
|
||||
+++ gdb-6.8.7/gdb/fbsd-nat.c 2008-07-29 12:29:20.000000000 +0200
|
||||
@@ -184,6 +184,7 @@ fbsd_make_corefile_notes (bfd *obfd, int
|
||||
psargs = reconcat (psargs, psargs, " ", get_inferior_args (), NULL);
|
||||
|
||||
note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
|
||||
+ NULL,
|
||||
fname, psargs);
|
||||
}
|
||||
|
||||
diff -d -urpN gdb-6.8.4/gdb/linux-nat.c gdb-6.8.7/gdb/linux-nat.c
|
||||
--- gdb-6.8.4/gdb/linux-nat.c 2008-07-25 16:16:15.000000000 +0200
|
||||
+++ gdb-6.8.7/gdb/linux-nat.c 2008-07-29 13:50:52.000000000 +0200
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "gdbthread.h" /* for struct thread_info etc. */
|
||||
#include "gdb_stat.h" /* for struct stat */
|
||||
#include <fcntl.h> /* for O_RDONLY */
|
||||
+#include "gdb_procfs32.h" /* for struct elf_prpsinfo32 */
|
||||
|
||||
#ifndef O_LARGEFILE
|
||||
#define O_LARGEFILE 0
|
||||
@@ -108,7 +109,7 @@ static LONGEST (*super_xfer_partial) (st
|
||||
/* This functions make elfcore note sections.
|
||||
They may get overriden by code adjusting data for multi-target builds. */
|
||||
char *(*linux_elfcore_write_prpsinfo)
|
||||
- (bfd *, char *, int *, const char *, const char *) = elfcore_write_prpsinfo;
|
||||
+ (bfd *, char *, int *, void *, const char *, const char *) = elfcore_write_prpsinfo;
|
||||
char *(*linux_elfcore_write_prstatus)
|
||||
(bfd *, char *, int *, long, int, const void *) = elfcore_write_prstatus;
|
||||
static char *
|
||||
@@ -2812,6 +2813,159 @@ linux_nat_do_registers (bfd *obfd, ptid_
|
||||
note_data, note_size);
|
||||
}
|
||||
|
||||
+/* Should be always true for Linux */
|
||||
+#define HAVE_PRPSINFO_T 1
|
||||
+
|
||||
+#if defined (HAVE_PRPSINFO_T)
|
||||
+
|
||||
+/* Fills struct elf_prpsinfo{32,64} as much as possible, imitate Linux kernel
|
||||
+ binfmt_elf.c. Unknown values are filled with zeroes. The structure is
|
||||
+ malloced. */
|
||||
+
|
||||
+static void*
|
||||
+fill_prpsinfo (void)
|
||||
+{
|
||||
+ struct stat sb;
|
||||
+ char filename[sizeof ("/proc//cmdline") + sizeof (int) * 3 + 2];
|
||||
+ char buf[1024];
|
||||
+ char proc_state[5];
|
||||
+ char proc_cmdline[sizeof (((struct elf_prpsinfo*)0)->pr_psargs) + 1];
|
||||
+ unsigned flags;
|
||||
+ long proc_nice;
|
||||
+ unsigned proc_ppid;
|
||||
+ unsigned proc_pgid;
|
||||
+ unsigned proc_sid;
|
||||
+ pid_t pid;
|
||||
+ int fd, n;
|
||||
+ char *cp, *proc_comm, *state_s;
|
||||
+ /* String comes from Linux kernel binfmt_elf.c FILL_PSINFO but it is already
|
||||
+ obsolete there to <linux/sched.h> TASK_* constants. */
|
||||
+ const char state_string[] = "RSDTZW";
|
||||
+ int state_num;
|
||||
+
|
||||
+ /* Get /proc/$PID/stat. */
|
||||
+ pid = ptid_get_pid (inferior_ptid);
|
||||
+ sprintf (filename, "/proc/%u/stat", (unsigned)pid);
|
||||
+ fd = open (filename, O_RDONLY);
|
||||
+ if (fd < 0)
|
||||
+ return NULL;
|
||||
+ fstat (fd, &sb); /* No error checking (can it ever happen?). */
|
||||
+ n = read (fd, buf, sizeof (buf) - 1);
|
||||
+ close (fd);
|
||||
+ if (n < 0)
|
||||
+ return NULL;
|
||||
+ buf[n] = 0;
|
||||
+
|
||||
+ cp = strrchr (buf, ')'); /* Split into "PID (COMM" and "<rest>". */
|
||||
+ if (!cp)
|
||||
+ return NULL;
|
||||
+ *cp = 0;
|
||||
+
|
||||
+ /* Grab COMM. */
|
||||
+ proc_comm = strchr (buf, '(');
|
||||
+ if (!proc_comm)
|
||||
+ return NULL;
|
||||
+ proc_comm++;
|
||||
+
|
||||
+ /* Read /proc/$PID/cmdline. */
|
||||
+ proc_cmdline[0] = 0;
|
||||
+ strcpy (strrchr (filename, '/'), "/cmdline");
|
||||
+ fd = open (filename, O_RDONLY);
|
||||
+ if (fd >= 0)
|
||||
+ {
|
||||
+ int n;
|
||||
+
|
||||
+ n = read (fd, proc_cmdline, sizeof (proc_cmdline) - 1);
|
||||
+ if (n < 0)
|
||||
+ n = 0;
|
||||
+ proc_cmdline[n] = 0;
|
||||
+ while (n--) /* Replace NULs with spaces. */
|
||||
+ if (proc_cmdline[n] == 0)
|
||||
+ proc_cmdline[n] = ' ';
|
||||
+ close (fd);
|
||||
+ }
|
||||
+
|
||||
+ /* Parse /proc/$PID/stat. */
|
||||
+ n = sscanf (cp + 2, /* skip ") " */
|
||||
+ "%4s %u " /* state, ppid */
|
||||
+ "%u %u %*s %*s " /* pgid, sid, tty, tpgid */
|
||||
+ "%u %*s %*s %*s " /* flags, min_flt, cmin_flt, maj_flt */
|
||||
+ "%*s " /* cmaj_flt */
|
||||
+ "%*s %*s " /* utime, stime */
|
||||
+ "%*s %*s %*s " /* cutime, cstime, priority */
|
||||
+ "%ld " /* nice */
|
||||
+ /*"%*s %*s " timeout, it_real_value */
|
||||
+ /*"%lu " start_time */
|
||||
+ /*"%lu " vsize */
|
||||
+ /*"%lu " rss */
|
||||
+ /*"%lu %lu %lu " rss_rlim, start_code, end_code */
|
||||
+ /*"%lu %lu %lu " start_stack, kstk_esp, kstk_eip */
|
||||
+ /*"%u %u %u %u " signal, blocked, sigignore, sigcatch */
|
||||
+ /*"%lu %lu %lu" wchan, nswap, cnswap */
|
||||
+ , proc_state, &proc_ppid,
|
||||
+ &proc_pgid, &proc_sid,
|
||||
+ &flags,
|
||||
+ &proc_nice);
|
||||
+ if (n != 6)
|
||||
+ return NULL;
|
||||
+
|
||||
+ state_s = strchr (state_string, proc_state[0]);
|
||||
+ if (state_s != NULL)
|
||||
+ state_num = state_s - state_string;
|
||||
+ else
|
||||
+ {
|
||||
+ /* 0 means Running, some more unusal state would be better. */
|
||||
+ state_num = 0;
|
||||
+ }
|
||||
+
|
||||
+#if ULONG_MAX > 0xffffffffU
|
||||
+ /* We skip this code on 32-bit gdb. */
|
||||
+ if (gdbarch_ptr_bit (current_gdbarch) == 64)
|
||||
+ {
|
||||
+ struct elf_prpsinfo *info = xzalloc (sizeof (*info));
|
||||
+
|
||||
+ info->pr_state = state_num;
|
||||
+ info->pr_sname = proc_state[0];
|
||||
+ info->pr_zomb = (proc_state[0] == 'Z');
|
||||
+ info->pr_nice = proc_nice;
|
||||
+ info->pr_flag = flags;
|
||||
+ info->pr_uid = sb.st_uid;
|
||||
+ info->pr_gid = sb.st_gid;
|
||||
+ info->pr_pid = pid;
|
||||
+ info->pr_ppid = proc_ppid;
|
||||
+ info->pr_pgrp = proc_pgid;
|
||||
+ info->pr_sid = proc_sid;
|
||||
+ strncpy (info->pr_fname, proc_comm, sizeof (info->pr_fname));
|
||||
+ strncpy (info->pr_psargs, proc_cmdline, sizeof (info->pr_psargs));
|
||||
+
|
||||
+ return info;
|
||||
+ }
|
||||
+#endif
|
||||
+ if (gdbarch_ptr_bit (current_gdbarch) == 32)
|
||||
+ {
|
||||
+ struct elf_prpsinfo32 *info = xzalloc (sizeof (*info));
|
||||
+
|
||||
+ info->pr_state = state_num;
|
||||
+ info->pr_sname = proc_state[0];
|
||||
+ info->pr_zomb = (proc_state[0] == 'Z');
|
||||
+ info->pr_nice = proc_nice;
|
||||
+ info->pr_flag = flags;
|
||||
+ info->pr_uid = sb.st_uid;
|
||||
+ info->pr_gid = sb.st_gid;
|
||||
+ info->pr_pid = pid;
|
||||
+ info->pr_ppid = proc_ppid;
|
||||
+ info->pr_pgrp = proc_pgid;
|
||||
+ info->pr_sid = proc_sid;
|
||||
+ strncpy (info->pr_fname, proc_comm, sizeof (info->pr_fname));
|
||||
+ strncpy (info->pr_psargs, proc_cmdline, sizeof (info->pr_psargs));
|
||||
+
|
||||
+ return info;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/* Fills the "to_make_corefile_note" target vector. Builds the note
|
||||
section for a corefile, and returns it in a malloc buffer. */
|
||||
|
||||
@@ -2831,8 +2985,14 @@ linux_nat_make_corefile_notes (bfd *obfd
|
||||
|
||||
if (get_exec_file (0))
|
||||
{
|
||||
+#if defined (HAVE_PRPSINFO_T)
|
||||
+ void *data = fill_prpsinfo ();
|
||||
+#define DATAPTR data
|
||||
+#else
|
||||
+#define DATAPTR NULL
|
||||
strncpy (fname, strrchr (get_exec_file (0), '/') + 1, sizeof (fname));
|
||||
strncpy (psargs, get_exec_file (0), sizeof (psargs));
|
||||
+#endif
|
||||
if (get_inferior_args ())
|
||||
{
|
||||
char *string_end;
|
||||
@@ -2848,9 +3008,15 @@ linux_nat_make_corefile_notes (bfd *obfd
|
||||
psargs_end - string_end);
|
||||
}
|
||||
}
|
||||
- note_data = (char *) linux_elfcore_write_prpsinfo (obfd, note_data,
|
||||
- note_size, fname,
|
||||
+ note_data = (char *) linux_elfcore_write_prpsinfo (obfd,
|
||||
+ note_data, note_size,
|
||||
+ DATAPTR,
|
||||
+ fname,
|
||||
psargs);
|
||||
+#if defined (HAVE_PRPSINFO_T)
|
||||
+ xfree (DATAPTR);
|
||||
+#endif
|
||||
+#undef DATAPTR
|
||||
}
|
||||
|
||||
/* Dump information for threads. */
|
||||
diff -d -urpN gdb-6.8.4/gdb/linux-nat.h gdb-6.8.7/gdb/linux-nat.h
|
||||
--- gdb-6.8.4/gdb/linux-nat.h 2008-07-25 16:16:15.000000000 +0200
|
||||
+++ gdb-6.8.7/gdb/linux-nat.h 2008-07-29 12:29:20.000000000 +0200
|
||||
@@ -133,7 +133,7 @@ struct siginfo *linux_nat_get_siginfo (p
|
||||
/* These functions make elfcore note sections.
|
||||
They may get overriden by code adjusting data for multi-target builds. */
|
||||
extern char *(*linux_elfcore_write_prpsinfo)
|
||||
- (bfd *, char *, int *, const char *, const char *);
|
||||
+ (bfd *, char *, int *, void *, const char *, const char *);
|
||||
extern char *(*linux_elfcore_write_prstatus)
|
||||
(bfd *, char *, int *, long, int, const void *);
|
||||
extern char *(*linux_elfcore_write_prfpreg)
|
||||
diff -d -urpN gdb-6.8.4/gdb/procfs.c gdb-6.8.7/gdb/procfs.c
|
||||
--- gdb-6.8.4/gdb/procfs.c 2008-07-25 16:16:15.000000000 +0200
|
||||
+++ gdb-6.8.7/gdb/procfs.c 2008-07-29 12:29:20.000000000 +0200
|
||||
@@ -6118,6 +6118,7 @@ procfs_make_note_section (bfd *obfd, int
|
||||
note_data = (char *) elfcore_write_prpsinfo (obfd,
|
||||
note_data,
|
||||
note_size,
|
||||
+ NULL,
|
||||
fname,
|
||||
psargs);
|
||||
|
24
gdb-6.8-bz436037-reg-no-longer-active.patch
Normal file
24
gdb-6.8-bz436037-reg-no-longer-active.patch
Normal file
@ -0,0 +1,24 @@
|
||||
diff -d -urpN src.0/gdb/valops.c src.1/gdb/valops.c
|
||||
--- src.0/gdb/valops.c 2008-07-27 04:00:03.000000000 +0200
|
||||
+++ src.1/gdb/valops.c 2008-07-31 15:17:42.000000000 +0200
|
||||
@@ -813,10 +813,18 @@ value_assign (struct value *toval, struc
|
||||
struct frame_info *frame;
|
||||
int value_reg;
|
||||
|
||||
- /* Figure out which frame this is in currently. */
|
||||
- frame = frame_find_by_id (VALUE_FRAME_ID (toval));
|
||||
value_reg = VALUE_REGNUM (toval);
|
||||
|
||||
+ /* Figure out which frame this is in currently. */
|
||||
+ frame = frame_find_by_id (VALUE_FRAME_ID (toval));
|
||||
+ /* "set $reg+=1" should work on programs with no debug info,
|
||||
+ but frame_find_by_id returns NULL here (RH bug 436037).
|
||||
+ Use current frame, it represents CPU state in this case.
|
||||
+ If frame_find_by_id is changed to do it internally
|
||||
+ (it is contemplated there), remove this. */
|
||||
+ if (!frame)
|
||||
+ frame = get_current_frame ();
|
||||
+ /* Probably never happens. */
|
||||
if (!frame)
|
||||
error (_("Value being assigned to is no longer active."));
|
||||
|
@ -971,3 +971,710 @@ diff -u -r1.7 -r1.8
|
||||
|
||||
# Start with a fresh gdb
|
||||
|
||||
|
||||
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=452960
|
||||
|
||||
bfd/
|
||||
2008-05-14 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* elf32-ppc.c (ppc_elf_get_synthetic_symtab): Fix memset calls.
|
||||
* elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Likewise.
|
||||
|
||||
bfd/
|
||||
2008-05-14 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf32-ppc.c (section_covers_vma): New function.
|
||||
(ppc_elf_get_synthetic_symtab): New function.
|
||||
(bfd_elf32_get_synthetic_symtab): Define.
|
||||
* elf64-ppc.c (section_covers_vma): New function.
|
||||
(ppc64_elf_get_synthetic_symtab): Generate sym@plt on glink branch
|
||||
table entries, and __glink_PLTresolve on resolver stub.
|
||||
(ppc64_elf_build_stubs): Rename __glink sym to __glink_PLTresolve.
|
||||
|
||||
gdb/
|
||||
2008-05-14 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* ppc-linux-tdep.c (ppc_linux_convert_from_func_ptr_addr): Rename ...
|
||||
(ppc64_linux_convert_from_func_ptr_addr): ... to this. No longer try
|
||||
to handle ppc32 PLT entries.
|
||||
(ppc_linux_init_abi): Install ppc64_linux_convert_from_func_ptr_addr
|
||||
only on ppc64.
|
||||
|
||||
gdb/
|
||||
2008-05-14 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* elfread.c (elf_symtab_read): Create trampolines for @plt symbols.
|
||||
* minsyms.c (lookup_minimal_symbol_by_pc_section_1): Renamed from
|
||||
lookup_minimal_symbol_by_pc_section. Prefer trampolines if requested.
|
||||
(lookup_minimal_symbol_by_pc_section): Use
|
||||
lookup_minimal_symbol_by_pc_section_1.
|
||||
(lookup_solib_trampoline_symbol_by_pc): Likewise.
|
||||
|
||||
[ Backported for GDB-6.8f. ]
|
||||
|
||||
--- ./bfd/elf32-ppc.c 2008-02-26 09:36:03.000000000 +0100
|
||||
+++ ./bfd/elf32-ppc.c 2008-07-24 15:42:47.000000000 +0200
|
||||
@@ -2291,6 +2291,208 @@ ppc_elf_final_write_processing (bfd *abf
|
||||
apuinfo_list_finish ();
|
||||
}
|
||||
|
||||
+static bfd_boolean
|
||||
+section_covers_vma (bfd *abfd ATTRIBUTE_UNUSED, asection *section, void *ptr)
|
||||
+{
|
||||
+ bfd_vma vma = *(bfd_vma *) ptr;
|
||||
+ return ((section->flags & SEC_ALLOC) != 0
|
||||
+ && section->vma <= vma
|
||||
+ && vma < section->vma + section->size);
|
||||
+}
|
||||
+
|
||||
+static long
|
||||
+ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
|
||||
+ long dynsymcount, asymbol **dynsyms,
|
||||
+ asymbol **ret)
|
||||
+{
|
||||
+ bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
|
||||
+ asection *plt, *relplt, *dynamic, *glink;
|
||||
+ bfd_vma glink_vma = 0;
|
||||
+ bfd_vma resolv_vma = 0;
|
||||
+ bfd_vma stub_vma;
|
||||
+ asymbol *s;
|
||||
+ arelent *p;
|
||||
+ long count, i;
|
||||
+ size_t size;
|
||||
+ char *names;
|
||||
+ bfd_byte buf[4];
|
||||
+
|
||||
+ *ret = NULL;
|
||||
+
|
||||
+ if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (dynsymcount <= 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ relplt = bfd_get_section_by_name (abfd, ".rela.plt");
|
||||
+ if (relplt == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
+ plt = bfd_get_section_by_name (abfd, ".plt");
|
||||
+ if (plt == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Call common code to handle old-style executable PLTs. */
|
||||
+ if (elf_section_flags (plt) & SHF_EXECINSTR)
|
||||
+ return _bfd_elf_get_synthetic_symtab (abfd, symcount, syms,
|
||||
+ dynsymcount, dynsyms, ret);
|
||||
+
|
||||
+ /* If this object was prelinked, the prelinker stored the address
|
||||
+ of .glink at got[1]. If it wasn't prelinked, got[1] will be zero. */
|
||||
+ dynamic = bfd_get_section_by_name (abfd, ".dynamic");
|
||||
+ if (dynamic != NULL)
|
||||
+ {
|
||||
+ bfd_byte *dynbuf, *extdyn, *extdynend;
|
||||
+ size_t extdynsize;
|
||||
+ void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
|
||||
+
|
||||
+ if (!bfd_malloc_and_get_section (abfd, dynamic, &dynbuf))
|
||||
+ return -1;
|
||||
+
|
||||
+ extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
|
||||
+ swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
|
||||
+
|
||||
+ extdyn = dynbuf;
|
||||
+ extdynend = extdyn + dynamic->size;
|
||||
+ for (; extdyn < extdynend; extdyn += extdynsize)
|
||||
+ {
|
||||
+ Elf_Internal_Dyn dyn;
|
||||
+ (*swap_dyn_in) (abfd, extdyn, &dyn);
|
||||
+
|
||||
+ if (dyn.d_tag == DT_NULL)
|
||||
+ break;
|
||||
+
|
||||
+ if (dyn.d_tag == DT_PPC_GOT)
|
||||
+ {
|
||||
+ unsigned int g_o_t = dyn.d_un.d_val;
|
||||
+ asection *got = bfd_get_section_by_name (abfd, ".got");
|
||||
+ if (got != NULL
|
||||
+ && bfd_get_section_contents (abfd, got, buf,
|
||||
+ g_o_t - got->vma + 4, 4))
|
||||
+ glink_vma = bfd_get_32 (abfd, buf);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ free (dynbuf);
|
||||
+ }
|
||||
+
|
||||
+ /* Otherwise we read the first plt entry. */
|
||||
+ if (glink_vma == 0)
|
||||
+ {
|
||||
+ if (bfd_get_section_contents (abfd, plt, buf, 0, 4))
|
||||
+ glink_vma = bfd_get_32 (abfd, buf);
|
||||
+ }
|
||||
+
|
||||
+ if (glink_vma == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* The .glink section usually does not survive the final
|
||||
+ link; search for the section (usually .text) where the
|
||||
+ glink stubs now reside. */
|
||||
+ glink = bfd_sections_find_if (abfd, section_covers_vma, &glink_vma);
|
||||
+ if (glink == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Determine glink PLT resolver by reading the relative branch
|
||||
+ from the first glink stub. */
|
||||
+ if (bfd_get_section_contents (abfd, glink, buf,
|
||||
+ glink_vma - glink->vma, 4))
|
||||
+ {
|
||||
+ unsigned int insn = bfd_get_32 (abfd, buf);
|
||||
+
|
||||
+ /* The first glink stub may either branch to the resolver ... */
|
||||
+ insn ^= B;
|
||||
+ if ((insn & ~0x3fffffc) == 0)
|
||||
+ resolv_vma = glink_vma + (insn ^ 0x2000000) - 0x2000000;
|
||||
+
|
||||
+ /* ... or fall through a bunch of NOPs. */
|
||||
+ else if ((insn ^ B ^ NOP) == 0)
|
||||
+ for (i = 4;
|
||||
+ bfd_get_section_contents (abfd, glink, buf,
|
||||
+ glink_vma - glink->vma + i, 4);
|
||||
+ i += 4)
|
||||
+ if (bfd_get_32 (abfd, buf) != NOP)
|
||||
+ {
|
||||
+ resolv_vma = glink_vma + i;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
|
||||
+ if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
|
||||
+ return -1;
|
||||
+
|
||||
+ count = relplt->size / sizeof (Elf32_External_Rela);
|
||||
+ stub_vma = glink_vma - (bfd_vma) count * 16;
|
||||
+ size = count * sizeof (asymbol);
|
||||
+ p = relplt->relocation;
|
||||
+ for (i = 0; i < count; i++, p++)
|
||||
+ size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
|
||||
+
|
||||
+ size += sizeof (asymbol) + sizeof ("__glink");
|
||||
+
|
||||
+ if (resolv_vma)
|
||||
+ size += sizeof (asymbol) + sizeof ("__glink_PLTresolve");
|
||||
+
|
||||
+ s = *ret = bfd_malloc (size);
|
||||
+ if (s == NULL)
|
||||
+ return -1;
|
||||
+
|
||||
+ names = (char *) (s + count + 1 + (resolv_vma != 0));
|
||||
+ p = relplt->relocation;
|
||||
+ for (i = 0; i < count; i++, p++)
|
||||
+ {
|
||||
+ size_t len;
|
||||
+
|
||||
+ *s = **p->sym_ptr_ptr;
|
||||
+ /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since
|
||||
+ we are defining a symbol, ensure one of them is set. */
|
||||
+ if ((s->flags & BSF_LOCAL) == 0)
|
||||
+ s->flags |= BSF_GLOBAL;
|
||||
+ s->section = glink;
|
||||
+ s->value = stub_vma - glink->vma;
|
||||
+ s->name = names;
|
||||
+ s->udata.p = NULL;
|
||||
+ len = strlen ((*p->sym_ptr_ptr)->name);
|
||||
+ memcpy (names, (*p->sym_ptr_ptr)->name, len);
|
||||
+ names += len;
|
||||
+ memcpy (names, "@plt", sizeof ("@plt"));
|
||||
+ names += sizeof ("@plt");
|
||||
+ ++s;
|
||||
+ stub_vma += 16;
|
||||
+ }
|
||||
+
|
||||
+ /* Add a symbol at the start of the glink branch table. */
|
||||
+ memset (s, 0, sizeof *s);
|
||||
+ s->the_bfd = abfd;
|
||||
+ s->flags = BSF_GLOBAL;
|
||||
+ s->section = glink;
|
||||
+ s->value = glink_vma - glink->vma;
|
||||
+ s->name = names;
|
||||
+ memcpy (names, "__glink", sizeof ("__glink"));
|
||||
+ names += sizeof ("__glink");
|
||||
+ s++;
|
||||
+ count++;
|
||||
+
|
||||
+ if (resolv_vma)
|
||||
+ {
|
||||
+ /* Add a symbol for the glink PLT resolver. */
|
||||
+ memset (s, 0, sizeof *s);
|
||||
+ s->the_bfd = abfd;
|
||||
+ s->flags = BSF_GLOBAL;
|
||||
+ s->section = glink;
|
||||
+ s->value = resolv_vma - glink->vma;
|
||||
+ s->name = names;
|
||||
+ memcpy (names, "__glink_PLTresolve", sizeof ("__glink_PLTresolve"));
|
||||
+ names += sizeof ("__glink_PLTresolve");
|
||||
+ s++;
|
||||
+ count++;
|
||||
+ }
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
/* The following functions are specific to the ELF linker, while
|
||||
functions above are used generally. They appear in this file more
|
||||
or less in the order in which they are called. eg.
|
||||
@@ -7733,6 +7935,7 @@ ppc_elf_finish_dynamic_sections (bfd *ou
|
||||
#define bfd_elf32_bfd_reloc_name_lookup ppc_elf_reloc_name_lookup
|
||||
#define bfd_elf32_bfd_set_private_flags ppc_elf_set_private_flags
|
||||
#define bfd_elf32_bfd_link_hash_table_create ppc_elf_link_hash_table_create
|
||||
+#define bfd_elf32_get_synthetic_symtab ppc_elf_get_synthetic_symtab
|
||||
|
||||
#define elf_backend_object_p ppc_elf_object_p
|
||||
#define elf_backend_gc_mark_hook ppc_elf_gc_mark_hook
|
||||
@@ -7847,6 +8050,8 @@ ppc_elf_vxworks_final_write_processing (
|
||||
#undef elf_backend_got_header_size
|
||||
#define elf_backend_got_header_size 12
|
||||
|
||||
+#undef bfd_elf32_get_synthetic_symtab
|
||||
+
|
||||
#undef bfd_elf32_bfd_link_hash_table_create
|
||||
#define bfd_elf32_bfd_link_hash_table_create \
|
||||
ppc_elf_vxworks_link_hash_table_create
|
||||
--- ./bfd/elf64-ppc.c 2008-02-15 09:27:19.000000000 +0100
|
||||
+++ ./bfd/elf64-ppc.c 2008-07-24 15:42:47.000000000 +0200
|
||||
@@ -2771,8 +2771,17 @@ sym_exists_at (asymbol **syms, long lo,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static bfd_boolean
|
||||
+section_covers_vma (bfd *abfd ATTRIBUTE_UNUSED, asection *section, void *ptr)
|
||||
+{
|
||||
+ bfd_vma vma = *(bfd_vma *) ptr;
|
||||
+ return ((section->flags & SEC_ALLOC) != 0
|
||||
+ && section->vma <= vma
|
||||
+ && vma < section->vma + section->size);
|
||||
+}
|
||||
+
|
||||
/* Create synthetic symbols, effectively restoring "dot-symbol" function
|
||||
- entry syms. */
|
||||
+ entry syms. Also generate @plt symbols for the glink branch table. */
|
||||
|
||||
static long
|
||||
ppc64_elf_get_synthetic_symtab (bfd *abfd,
|
||||
@@ -2862,8 +2871,6 @@ ppc64_elf_get_synthetic_symtab (bfd *abf
|
||||
symcount = i;
|
||||
|
||||
count = 0;
|
||||
- if (opdsymend == secsymend)
|
||||
- goto done;
|
||||
|
||||
if (relocatable)
|
||||
{
|
||||
@@ -2872,6 +2879,9 @@ ppc64_elf_get_synthetic_symtab (bfd *abf
|
||||
size_t size;
|
||||
long relcount;
|
||||
|
||||
+ if (opdsymend == secsymend)
|
||||
+ goto done;
|
||||
+
|
||||
slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
|
||||
relcount = (opd->flags & SEC_RELOC) ? opd->reloc_count : 0;
|
||||
if (relcount == 0)
|
||||
@@ -2960,8 +2970,13 @@ ppc64_elf_get_synthetic_symtab (bfd *abf
|
||||
}
|
||||
else
|
||||
{
|
||||
+ bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
|
||||
bfd_byte *contents;
|
||||
size_t size;
|
||||
+ long plt_count = 0;
|
||||
+ bfd_vma glink_vma = 0, resolv_vma = 0;
|
||||
+ asection *dynamic, *glink = NULL, *relplt = NULL;
|
||||
+ arelent *p;
|
||||
|
||||
if (!bfd_malloc_and_get_section (abfd, opd, &contents))
|
||||
{
|
||||
@@ -2988,11 +3003,85 @@ ppc64_elf_get_synthetic_symtab (bfd *abf
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Get start of .glink stubs from DT_PPC64_GLINK. */
|
||||
+ dynamic = bfd_get_section_by_name (abfd, ".dynamic");
|
||||
+ if (dynamic != NULL)
|
||||
+ {
|
||||
+ bfd_byte *dynbuf, *extdyn, *extdynend;
|
||||
+ size_t extdynsize;
|
||||
+ void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
|
||||
+
|
||||
+ if (!bfd_malloc_and_get_section (abfd, dynamic, &dynbuf))
|
||||
+ goto free_contents_and_exit;
|
||||
+
|
||||
+ extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
|
||||
+ swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
|
||||
+
|
||||
+ extdyn = dynbuf;
|
||||
+ extdynend = extdyn + dynamic->size;
|
||||
+ for (; extdyn < extdynend; extdyn += extdynsize)
|
||||
+ {
|
||||
+ Elf_Internal_Dyn dyn;
|
||||
+ (*swap_dyn_in) (abfd, extdyn, &dyn);
|
||||
+
|
||||
+ if (dyn.d_tag == DT_NULL)
|
||||
+ break;
|
||||
+
|
||||
+ if (dyn.d_tag == DT_PPC64_GLINK)
|
||||
+ {
|
||||
+ /* The first glink stub starts at offset 32; see comment in
|
||||
+ ppc64_elf_finish_dynamic_sections. */
|
||||
+ glink_vma = dyn.d_un.d_val + 32;
|
||||
+ /* The .glink section usually does not survive the final
|
||||
+ link; search for the section (usually .text) where the
|
||||
+ glink stubs now reside. */
|
||||
+ glink = bfd_sections_find_if (abfd, section_covers_vma,
|
||||
+ &glink_vma);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ free (dynbuf);
|
||||
+ }
|
||||
+
|
||||
+ if (glink != NULL)
|
||||
+ {
|
||||
+ /* Determine __glink trampoline by reading the relative branch
|
||||
+ from the first glink stub. */
|
||||
+ bfd_byte buf[4];
|
||||
+ if (bfd_get_section_contents (abfd, glink, buf,
|
||||
+ glink_vma + 4 - glink->vma, 4))
|
||||
+ {
|
||||
+ unsigned int insn = bfd_get_32 (abfd, buf);
|
||||
+ insn ^= B_DOT;
|
||||
+ if ((insn & ~0x3fffffc) == 0)
|
||||
+ resolv_vma = glink_vma + 4 + (insn ^ 0x2000000) - 0x2000000;
|
||||
+ }
|
||||
+
|
||||
+ if (resolv_vma)
|
||||
+ size += sizeof (asymbol) + sizeof ("__glink_PLTresolve");
|
||||
+ }
|
||||
+
|
||||
+ relplt = bfd_get_section_by_name (abfd, ".rela.plt");
|
||||
+ if (glink != NULL && relplt != NULL)
|
||||
+ {
|
||||
+ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
|
||||
+ if (! (*slurp_relocs) (abfd, relplt, dyn_syms, TRUE))
|
||||
+ goto free_contents_and_exit;
|
||||
+
|
||||
+ plt_count = relplt->size / sizeof (Elf64_External_Rela);
|
||||
+ size += plt_count * sizeof (asymbol);
|
||||
+
|
||||
+ p = relplt->relocation;
|
||||
+ for (i = 0; i < plt_count; i++, p++)
|
||||
+ size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
|
||||
+ }
|
||||
+
|
||||
s = *ret = bfd_malloc (size);
|
||||
if (s == NULL)
|
||||
goto free_contents_and_exit;
|
||||
|
||||
- names = (char *) (s + count);
|
||||
+ names = (char *) (s + count + plt_count + (resolv_vma != 0));
|
||||
|
||||
for (i = secsymend; i < opdsymend; ++i)
|
||||
{
|
||||
@@ -3048,6 +3137,66 @@ ppc64_elf_get_synthetic_symtab (bfd *abf
|
||||
}
|
||||
}
|
||||
free (contents);
|
||||
+
|
||||
+ if (glink != NULL && relplt != NULL)
|
||||
+ {
|
||||
+ if (resolv_vma)
|
||||
+ {
|
||||
+ /* Add a symbol for the main glink trampoline. */
|
||||
+ memset (s, 0, sizeof *s);
|
||||
+ s->the_bfd = abfd;
|
||||
+ s->flags = BSF_GLOBAL;
|
||||
+ s->section = glink;
|
||||
+ s->value = resolv_vma - glink->vma;
|
||||
+ s->name = names;
|
||||
+ memcpy (names, "__glink_PLTresolve", sizeof ("__glink_PLTresolve"));
|
||||
+ names += sizeof ("__glink_PLTresolve");
|
||||
+ s++;
|
||||
+ count++;
|
||||
+ }
|
||||
+
|
||||
+ /* FIXME: It would be very much nicer to put sym@plt on the
|
||||
+ stub rather than on the glink branch table entry. The
|
||||
+ objdump disassembler would then use a sensible symbol
|
||||
+ name on plt calls. The difficulty in doing so is
|
||||
+ a) finding the stubs, and,
|
||||
+ b) matching stubs against plt entries, and,
|
||||
+ c) there can be multiple stubs for a given plt entry.
|
||||
+
|
||||
+ Solving (a) could be done by code scanning, but older
|
||||
+ ppc64 binaries used different stubs to current code.
|
||||
+ (b) is the tricky one since you need to known the toc
|
||||
+ pointer for at least one function that uses a pic stub to
|
||||
+ be able to calculate the plt address referenced.
|
||||
+ (c) means gdb would need to set multiple breakpoints (or
|
||||
+ find the glink branch itself) when setting breakpoints
|
||||
+ for pending shared library loads. */
|
||||
+ p = relplt->relocation;
|
||||
+ for (i = 0; i < plt_count; i++, p++)
|
||||
+ {
|
||||
+ size_t len;
|
||||
+
|
||||
+ *s = **p->sym_ptr_ptr;
|
||||
+ /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set. Since
|
||||
+ we are defining a symbol, ensure one of them is set. */
|
||||
+ if ((s->flags & BSF_LOCAL) == 0)
|
||||
+ s->flags |= BSF_GLOBAL;
|
||||
+ s->section = glink;
|
||||
+ s->value = glink_vma - glink->vma;
|
||||
+ s->name = names;
|
||||
+ s->udata.p = NULL;
|
||||
+ len = strlen ((*p->sym_ptr_ptr)->name);
|
||||
+ memcpy (names, (*p->sym_ptr_ptr)->name, len);
|
||||
+ names += len;
|
||||
+ memcpy (names, "@plt", sizeof ("@plt"));
|
||||
+ names += sizeof ("@plt");
|
||||
+ s++;
|
||||
+ glink_vma += 8;
|
||||
+ if (i >= 0x8000)
|
||||
+ glink_vma += 4;
|
||||
+ }
|
||||
+ count += plt_count;
|
||||
+ }
|
||||
}
|
||||
|
||||
done:
|
||||
@@ -9705,7 +9854,8 @@ ppc64_elf_build_stubs (bfd_boolean emit_
|
||||
if (htab->emit_stub_syms)
|
||||
{
|
||||
struct elf_link_hash_entry *h;
|
||||
- h = elf_link_hash_lookup (&htab->elf, "__glink", TRUE, FALSE, FALSE);
|
||||
+ h = elf_link_hash_lookup (&htab->elf, "__glink_PLTresolve",
|
||||
+ TRUE, FALSE, FALSE);
|
||||
if (h == NULL)
|
||||
return FALSE;
|
||||
if (h->root.type == bfd_link_hash_new)
|
||||
--- ./gdb/elfread.c 2008-07-24 15:41:07.000000000 +0200
|
||||
+++ ./gdb/elfread.c 2008-07-24 15:42:48.000000000 +0200
|
||||
@@ -514,6 +514,34 @@ elf_symtab_read (struct objfile *objfile
|
||||
if (msym != NULL)
|
||||
msym->filename = filesymname;
|
||||
gdbarch_elf_make_msymbol_special (current_gdbarch, sym, msym);
|
||||
+
|
||||
+ /* For @plt symbols, also record a trampoline to the
|
||||
+ destination symbol. The @plt symbol will be used in
|
||||
+ disassembly, and the trampoline will be used when we are
|
||||
+ trying to find the target. */
|
||||
+ if (msym && ms_type == mst_text && type == ST_SYNTHETIC)
|
||||
+ {
|
||||
+ int len = strlen (sym->name);
|
||||
+
|
||||
+ if (len > 4 && strcmp (sym->name + len - 4, "@plt") == 0)
|
||||
+ {
|
||||
+ char *base_name = alloca (len - 4 + 1);
|
||||
+ struct minimal_symbol *mtramp;
|
||||
+
|
||||
+ memcpy (base_name, sym->name, len - 4);
|
||||
+ base_name[len - 4] = '\0';
|
||||
+ mtramp = record_minimal_symbol (base_name, symaddr,
|
||||
+ mst_solib_trampoline,
|
||||
+ sym->section, objfile);
|
||||
+ if (mtramp)
|
||||
+ {
|
||||
+ MSYMBOL_SIZE (mtramp) = MSYMBOL_SIZE (msym);
|
||||
+ mtramp->filename = filesymname;
|
||||
+ gdbarch_elf_make_msymbol_special (current_gdbarch, sym,
|
||||
+ mtramp);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
--- ./gdb/minsyms.c 2008-07-24 15:41:07.000000000 +0200
|
||||
+++ ./gdb/minsyms.c 2008-07-24 15:42:48.000000000 +0200
|
||||
@@ -357,10 +357,15 @@ lookup_minimal_symbol_solib_trampoline (
|
||||
ALL the minimal symbol tables before deciding on the symbol that
|
||||
comes closest to the specified PC. This is because objfiles can
|
||||
overlap, for example objfile A has .text at 0x100 and .data at
|
||||
- 0x40000 and objfile B has .text at 0x234 and .data at 0x40048. */
|
||||
+ 0x40000 and objfile B has .text at 0x234 and .data at 0x40048.
|
||||
|
||||
-struct minimal_symbol *
|
||||
-lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
|
||||
+ If WANT_TRAMPOLINE is set, prefer mst_solib_trampoline symbols when
|
||||
+ there are text and trampoline symbols at the same address.
|
||||
+ Otherwise prefer mst_text symbols. */
|
||||
+
|
||||
+static struct minimal_symbol *
|
||||
+lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, asection *section,
|
||||
+ int want_trampoline)
|
||||
{
|
||||
int lo;
|
||||
int hi;
|
||||
@@ -369,7 +374,11 @@ lookup_minimal_symbol_by_pc_section (COR
|
||||
struct minimal_symbol *msymbol;
|
||||
struct minimal_symbol *best_symbol = NULL;
|
||||
struct obj_section *pc_section;
|
||||
+ enum minimal_symbol_type want_type, other_type;
|
||||
|
||||
+ want_type = want_trampoline ? mst_solib_trampoline : mst_text;
|
||||
+ other_type = want_trampoline ? mst_text : mst_solib_trampoline;
|
||||
+
|
||||
/* PC has to be in a known section. This ensures that anything
|
||||
beyond the end of the last segment doesn't appear to be part of
|
||||
the last function in the last segment. */
|
||||
@@ -491,6 +500,24 @@ lookup_minimal_symbol_by_pc_section (COR
|
||||
continue;
|
||||
}
|
||||
|
||||
+ /* If we are looking for a trampoline and this is a
|
||||
+ text symbol, or the other way around, check the
|
||||
+ preceeding symbol too. If they are otherwise
|
||||
+ identical prefer that one. */
|
||||
+ if (hi > 0
|
||||
+ && MSYMBOL_TYPE (&msymbol[hi]) == other_type
|
||||
+ && MSYMBOL_TYPE (&msymbol[hi - 1]) == want_type
|
||||
+ && (MSYMBOL_SIZE (&msymbol[hi])
|
||||
+ == MSYMBOL_SIZE (&msymbol[hi - 1]))
|
||||
+ && (SYMBOL_VALUE_ADDRESS (&msymbol[hi])
|
||||
+ == SYMBOL_VALUE_ADDRESS (&msymbol[hi - 1]))
|
||||
+ && (SYMBOL_BFD_SECTION (&msymbol[hi])
|
||||
+ == SYMBOL_BFD_SECTION (&msymbol[hi - 1])))
|
||||
+ {
|
||||
+ hi--;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
/* If the minimal symbol has a zero size, save it
|
||||
but keep scanning backwards looking for one with
|
||||
a non-zero size. A zero size may mean that the
|
||||
@@ -571,6 +598,12 @@ lookup_minimal_symbol_by_pc_section (COR
|
||||
return (best_symbol);
|
||||
}
|
||||
|
||||
+struct minimal_symbol *
|
||||
+lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
|
||||
+{
|
||||
+ return lookup_minimal_symbol_by_pc_section_1 (pc, section, 0);
|
||||
+}
|
||||
+
|
||||
/* Backward compatibility: search through the minimal symbol table
|
||||
for a matching PC (no section given) */
|
||||
|
||||
@@ -1024,7 +1057,13 @@ msymbols_sort (struct objfile *objfile)
|
||||
struct minimal_symbol *
|
||||
lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc)
|
||||
{
|
||||
- struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
|
||||
+ struct obj_section *section = find_pc_section (pc);
|
||||
+ struct minimal_symbol *msymbol;
|
||||
+
|
||||
+ if (section == NULL)
|
||||
+ return NULL;
|
||||
+ msymbol = lookup_minimal_symbol_by_pc_section_1 (pc, section->the_bfd_section,
|
||||
+ 1);
|
||||
|
||||
if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
|
||||
return msymbol;
|
||||
--- ./gdb/ppc-linux-tdep.c 2008-02-20 15:31:40.000000000 +0100
|
||||
+++ ./gdb/ppc-linux-tdep.c 2008-07-24 15:43:24.000000000 +0200
|
||||
@@ -545,7 +545,7 @@ ppc64_skip_trampoline_code (struct frame
|
||||
}
|
||||
|
||||
|
||||
-/* Support for convert_from_func_ptr_addr (ARCH, ADDR, TARG) on PPC
|
||||
+/* Support for convert_from_func_ptr_addr (ARCH, ADDR, TARG) on PPC64
|
||||
GNU/Linux.
|
||||
|
||||
Usually a function pointer's representation is simply the address
|
||||
@@ -557,12 +557,6 @@ ppc64_skip_trampoline_code (struct frame
|
||||
function, the second word is the TOC pointer (r2), and the third word
|
||||
is the static chain value.
|
||||
|
||||
- For PPC32, there are two kinds of function pointers: non-secure and
|
||||
- secure. Non-secure function pointers point directly to the
|
||||
- function in a code section and thus need no translation. Secure
|
||||
- ones (from GCC's -msecure-plt option) are in a data section and
|
||||
- contain one word: the address of the function.
|
||||
-
|
||||
Throughout GDB it is currently assumed that a function pointer contains
|
||||
the address of the function, which is not easy to fix. In addition, the
|
||||
conversion of a function address to a function pointer would
|
||||
@@ -578,40 +572,15 @@ ppc64_skip_trampoline_code (struct frame
|
||||
random addresses such as occur when there is no symbol table. */
|
||||
|
||||
static CORE_ADDR
|
||||
-ppc_linux_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
|
||||
- CORE_ADDR addr,
|
||||
- struct target_ops *targ)
|
||||
+ppc64_linux_convert_from_func_ptr_addr (struct gdbarch *gdbarch,
|
||||
+ CORE_ADDR addr,
|
||||
+ struct target_ops *targ)
|
||||
{
|
||||
- struct gdbarch_tdep *tdep;
|
||||
struct section_table *s = target_section_by_addr (targ, addr);
|
||||
- char *sect_name = NULL;
|
||||
-
|
||||
- if (!s)
|
||||
- return addr;
|
||||
-
|
||||
- tdep = gdbarch_tdep (gdbarch);
|
||||
-
|
||||
- switch (tdep->wordsize)
|
||||
- {
|
||||
- case 4:
|
||||
- sect_name = ".plt";
|
||||
- break;
|
||||
- case 8:
|
||||
- sect_name = ".opd";
|
||||
- break;
|
||||
- default:
|
||||
- internal_error (__FILE__, __LINE__,
|
||||
- _("failed internal consistency check"));
|
||||
- }
|
||||
|
||||
/* Check if ADDR points to a function descriptor. */
|
||||
-
|
||||
- /* NOTE: this depends on the coincidence that the address of a functions
|
||||
- entry point is contained in the first word of its function descriptor
|
||||
- for both PPC-64 and for PPC-32 with secure PLTs. */
|
||||
- if ((strcmp (s->the_bfd_section->name, sect_name) == 0)
|
||||
- && s->the_bfd_section->flags & SEC_DATA)
|
||||
- return get_target_memory_unsigned (targ, addr, tdep->wordsize);
|
||||
+ if (s && strcmp (s->the_bfd_section->name, ".opd") == 0)
|
||||
+ return get_target_memory_unsigned (targ, addr, 8);
|
||||
|
||||
return addr;
|
||||
}
|
||||
@@ -905,11 +874,6 @@ ppc_linux_init_abi (struct gdbarch_info
|
||||
set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT);
|
||||
set_gdbarch_long_double_format (gdbarch, floatformats_ibm_long_double);
|
||||
|
||||
- /* Handle PPC GNU/Linux 64-bit function pointers (which are really
|
||||
- function descriptors) and 32-bit secure PLT entries. */
|
||||
- set_gdbarch_convert_from_func_ptr_addr
|
||||
- (gdbarch, ppc_linux_convert_from_func_ptr_addr);
|
||||
-
|
||||
if (tdep->wordsize == 4)
|
||||
{
|
||||
/* Until November 2001, gcc did not comply with the 32 bit SysV
|
||||
@@ -937,6 +901,11 @@ ppc_linux_init_abi (struct gdbarch_info
|
||||
|
||||
if (tdep->wordsize == 8)
|
||||
{
|
||||
+ /* Handle PPC GNU/Linux 64-bit function pointers (which are really
|
||||
+ function descriptors). */
|
||||
+ set_gdbarch_convert_from_func_ptr_addr
|
||||
+ (gdbarch, ppc64_linux_convert_from_func_ptr_addr);
|
||||
+
|
||||
/* Shared library handling. */
|
||||
set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
|
||||
set_solib_svr4_fetch_link_map_offsets
|
||||
|
65
gdb.spec
65
gdb.spec
@ -13,7 +13,7 @@ Version: 6.8
|
||||
|
||||
# The release always contains a leading reserved number, start it at 1.
|
||||
# `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
|
||||
Release: 17%{?_with_upstream:.upstream}%{?dist}
|
||||
Release: 18%{?_with_upstream:.upstream}%{?dist}
|
||||
|
||||
License: GPLv3+
|
||||
Group: Development/Debuggers
|
||||
@ -382,6 +382,12 @@ Patch326: gdb-6.8-tui-singlebinary.patch
|
||||
Patch327: gdb-6.8-inlining.patch
|
||||
Patch328: gdb-6.8-inlining-by-name.patch
|
||||
|
||||
# Fix PRPSINFO in the core files dumped by gcore (BZ 254229).
|
||||
Patch329: gdb-6.8-bz254229-gcore-prpsinfo.patch
|
||||
|
||||
# Fix register assignments with no GDB stack frames (BZ 436037).
|
||||
Patch330: gdb-6.8-bz436037-reg-no-longer-active.patch
|
||||
|
||||
BuildRequires: ncurses-devel glibc-devel gcc make gzip texinfo dejagnu gettext
|
||||
BuildRequires: flex bison sharutils expat-devel
|
||||
Requires: readline
|
||||
@ -569,6 +575,8 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c
|
||||
%patch326 -p1
|
||||
%patch327 -p1
|
||||
%patch328 -p1
|
||||
%patch329 -p1
|
||||
%patch330 -p1
|
||||
%patch124 -p1
|
||||
|
||||
find -name "*.orig" | xargs rm -f
|
||||
@ -669,8 +677,6 @@ echo ====================TESTING=========================
|
||||
cd gdb
|
||||
gcc -o ./orphanripper %{SOURCE2} -Wall -lutil
|
||||
# Need to use a single --ignore option, second use overrides first.
|
||||
# "chng-syms.exp" for possibly avoiding Linux kernel crash - Bug 207002.
|
||||
# "threadcrash.exp" is incompatible on ia64 with old kernels.
|
||||
# No `%{?_smp_mflags}' here as it may race.
|
||||
# WARNING: can't generate a core file - core tests suppressed - check ulimit
|
||||
# "readline-overflow.exp" - Testcase is broken, functionality is OK.
|
||||
@ -680,26 +686,34 @@ gcc -o ./orphanripper %{SOURCE2} -Wall -lutil
|
||||
ulimit -c unlimited || :
|
||||
|
||||
# Setup $CHECK as `check//unix/' or `check//unix/-m64' for explicit bitsize.
|
||||
# Simple `check' is not used for $CHECK as different escaping rules apply
|
||||
# for the --ignore list delimiting spaces.
|
||||
# Never use two different bitsizes as it fails on ppc64.
|
||||
echo 'int main (void) { return 0; }' >biarch.c
|
||||
gcc $RPM_OPT_FLAGS -o biarch biarch.c
|
||||
mv -f biarch biarch-native
|
||||
# Do not try -m64 for biarch as GDB cannot handle inferior larger than itself.
|
||||
for BI in -m32 -m31 ""
|
||||
CHECK=""
|
||||
for BI in -m64 -m32 -m31 ""
|
||||
do
|
||||
if gcc 2>/dev/null $RPM_OPT_FLAGS $BI -o biarch biarch.c
|
||||
then
|
||||
break
|
||||
# Do not use size-less options if any of the sizes works.
|
||||
# On ia64 there is no -m64 flag while we must not leave a bare `check' here
|
||||
# as it would switch over some testing scripts to the backward compatibility
|
||||
# mode: when `make check' was executed from inside the testsuite/ directory.
|
||||
if [ -z "$BI" -a -n "$CHECK" ];then
|
||||
continue
|
||||
fi
|
||||
# Do not use $RPM_OPT_FLAGS as the other non-size options will not be used
|
||||
# in the real run of the testsuite.
|
||||
if ! gcc $BI -o biarch biarch.c
|
||||
then
|
||||
continue
|
||||
fi
|
||||
done
|
||||
# On ia64 there is no -m64 flag while we must not leave a bare `check' here
|
||||
# as it would switch over some testing scripts to the backward compatibility
|
||||
# mode - when `make check' was executed from inside the testsuite/ directory.
|
||||
CHECK="check//unix$(echo " $RPM_OPT_FLAGS "|sed -n 's#^.* \(-m[36][241]\) .*$#/\1#p')"
|
||||
if ! cmp -s biarch-native biarch
|
||||
then
|
||||
CHECK="$CHECK check//unix/$BI"
|
||||
done
|
||||
# Do not try -m64 inferiors for -m32 GDB as it cannot handle inferiors larger
|
||||
# than itself.
|
||||
# s390 -m31 still uses the standard ELF32 binary format.
|
||||
gcc $RPM_OPT_FLAGS -o biarch biarch.c
|
||||
RPM_SIZE="$(file ./biarch|sed -n 's/^.*: ELF \(32\|64\)-bit .*$/\1/p')"
|
||||
if [ "$RPM_SIZE" != "64" ]
|
||||
then
|
||||
CHECK="$(echo " $CHECK "|sed 's# check//unix/-m64 # #')"
|
||||
fi
|
||||
|
||||
# Disable some problematic testcases.
|
||||
@ -707,10 +721,7 @@ gcc -o ./orphanripper %{SOURCE2} -Wall -lutil
|
||||
# `check//...' target spawn and too much escaping there would be dense.
|
||||
for test in \
|
||||
gdb.base/readline-overflow.exp \
|
||||
gdb.base/chng-syms.exp \
|
||||
gdb.base/checkpoint.exp \
|
||||
gdb.base/bigcore.exp \
|
||||
gdb.threads/threadcrash.exp \
|
||||
; do
|
||||
mv -f ../../gdb/testsuite/$test ../gdb/testsuite/$test-DISABLED || :
|
||||
done
|
||||
@ -718,7 +729,7 @@ gcc -o ./orphanripper %{SOURCE2} -Wall -lutil
|
||||
%if 0%{!?_with_upstream:1}
|
||||
# Run all the scheduled testsuite runs also in the PIE mode.
|
||||
# Upstream GDB would lock up the testsuite run for too long on its failures.
|
||||
CHECK="$(echo $CHECK|sed 's#check//unix[^ ]*#& &/-fPIE/-pie#g')"
|
||||
CHECK="$(echo $CHECK|sed 's#check//unix/[^ ]*#& &/-fPIE/-pie#g')"
|
||||
%endif # 0%{!?_with_upstream:1}
|
||||
|
||||
for CURRENT in $CHECK
|
||||
@ -832,6 +843,14 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Fri Aug 1 2008 Jan Kratochvil <jan.kratochvil@redhat.com> - 6.8-18
|
||||
- Fix powerpc recent secure PLTs handling (shared library calls) (BZ 452960).
|
||||
- Fix the testsuite .spec runner to run biarch also on ppc.
|
||||
- Reenable testcases threadcrash.exp, chng-syms.exp, checkpoint.exp (BZ 207002).
|
||||
- Fix PRPSINFO in the core files dumped by gcore (BZ 254229), reformatted patch
|
||||
from Denys Vlasenko.
|
||||
- Fix register assignments with no GDB stack frames, Denys Vlasenko (BZ 436037).
|
||||
|
||||
* Mon Jul 14 2008 Jan Kratochvil <jan.kratochvil@redhat.com> - 6.8-17
|
||||
- Refresh the patchset with fuzz 0 (for new rpmbuild).
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user