* [ppc64-linux]: skip linkage functions
@ 2003-06-05 23:54 Jim Blandy
2003-06-06 0:03 ` Daniel Jacobowitz
2003-06-10 0:05 ` Kevin Buettner
0 siblings, 2 replies; 11+ messages in thread
From: Jim Blandy @ 2003-06-05 23:54 UTC (permalink / raw)
To: gdb-patches
2003-06-05 Jim Blandy <jimb@redhat.com>
Recognize and skip 64-bit PowerPC Linux linkage functions.
* ppc-linux-tdep.c (insn_d, insn_ds, insn_xfx, read_insn, struct
insn_pattern, insns_match_pattern, d_field, ds_field): New
functions, macros, and types for working with PPC instructions.
(ppc64_standard_linkage, PPC64_STANDARD_LINKAGE_LEN,
ppc64_in_solib_call_trampoline, ppc64_standard_linkage_target,
ppc64_skip_trampoline_code): New functions, variables, and macros
for recognizing and skipping linkage functions.
(ppc_linux_init_abi): Use ppc64_in_solib_call_trampoline and
ppc64_skip_trampoline_code for the 64-bit PowerPC Linux ABI.
Index: gdb/ppc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.28.8.3
diff -c -r1.28.8.3 ppc-linux-tdep.c
*** gdb/ppc-linux-tdep.c 5 Jun 2003 22:51:45 -0000 1.28.8.3
--- gdb/ppc-linux-tdep.c 5 Jun 2003 23:48:13 -0000
***************
*** 632,637 ****
--- 632,888 ----
return lmp;
}
+
+ /* Macros for matching instructions. Note that, since all the
+ operands are masked off before they're or-ed into the instruction,
+ you can use -1 to make masks. */
+
+ #define insn_d(opcd, rts, ra, d) \
+ ((((opcd) & 0x3f) << 26) \
+ | (((rts) & 0x1f) << 21) \
+ | (((ra) & 0x1f) << 16) \
+ | ((d) & 0xffff))
+
+ #define insn_ds(opcd, rts, ra, d, xo) \
+ ((((opcd) & 0x3f) << 26) \
+ | (((rts) & 0x1f) << 21) \
+ | (((ra) & 0x1f) << 16) \
+ | ((d) & 0xfffc) \
+ | ((xo) & 0x3))
+
+ #define insn_xfx(opcd, rts, spr, xo) \
+ ((((opcd) & 0x3f) << 26) \
+ | (((rts) & 0x1f) << 21) \
+ | (((spr) & 0x1f) << 16) \
+ | (((spr) & 0x3e0) << 6) \
+ | (((xo) & 0x3ff) << 1))
+
+ /* Read a PPC instruction from memory. PPC instructions are always
+ big-endian, no matter what endianness the program is running in, so
+ we can't use read_memory_integer or one of its friends here. */
+ static unsigned int
+ read_insn (CORE_ADDR pc)
+ {
+ unsigned char buf[4];
+
+ read_memory (pc, buf, 4);
+ return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+ }
+
+
+ /* An instruction to match. */
+ struct insn_pattern
+ {
+ unsigned int mask; /* mask the insn with this... */
+ unsigned int data; /* ...and see if it matches this. */
+ int optional; /* If non-zero, this insn may be absent. */
+ };
+
+ /* Return non-zero if the instructions at PC match the series
+ described in PATTERN, or zero otherwise. PATTERN is an array of
+ 'struct insn_pattern' objects, terminated by an entry whose mask is
+ zero.
+
+ When the match is successful, fill INSN[i] with what PATTERN[i]
+ matched. If PATTERN[i] is optional, and the instruction wasn't
+ present, set INSN[i] to -1. INSN should have as many elements as
+ PATTERN. Note that, if PATTERN contains optional instructions
+ which aren't present in memory, then INSN will have holes, so
+ INSN[i] isn't necessarily the i'th instruction in memory. */
+ static int
+ insns_match_pattern (CORE_ADDR pc,
+ struct insn_pattern *pattern,
+ unsigned int *insn)
+ {
+ int i;
+
+ for (i = 0; pattern[i].mask; i++)
+ {
+ insn[i] = read_insn (pc);
+ if ((insn[i] & pattern[i].mask) == pattern[i].data)
+ pc += 4;
+ else if (pattern[i].optional)
+ insn[i] = 0;
+ else
+ return 0;
+ }
+
+ return 1;
+ }
+
+
+ /* Return the 'd' field of the d-form instruction INSN, properly
+ sign-extended. */
+ static CORE_ADDR
+ insn_d_field (unsigned int insn)
+ {
+ return ((((CORE_ADDR) insn & 0xffff) ^ 0x8000) - 0x8000);
+ }
+
+
+ /* Return the 'ds' field of the ds-form instruction INSN, with the two
+ zero bits concatenated at the right, and properly
+ sign-extended. */
+ static CORE_ADDR
+ insn_ds_field (unsigned int insn)
+ {
+ return ((((CORE_ADDR) insn & 0xfffc) ^ 0x8000) - 0x8000);
+ }
+
+
+ /* Pattern for the standard linkage function. These are built by
+ build_plt_stub in elf64-ppc.c, whose GLINK argument is always
+ zero. */
+ static struct insn_pattern ppc64_standard_linkage[] =
+ {
+ /* addis r12, r2, <any> */
+ { insn_d (-1, -1, -1, 0), insn_d (15, 12, 2, 0), 0 },
+
+ /* std r2, 40(r1) */
+ { -1, insn_ds (62, 2, 1, 40, 0), 0 },
+
+ /* ld r11, <any>(r12) */
+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 },
+
+ /* addis r12, r12, 1 <optional> */
+ { insn_d (-1, -1, -1, -1), insn_d (15, 12, 2, 1), 1 },
+
+ /* ld r2, <any>(r12) */
+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 2, 12, 0, 0), 0 },
+
+ /* addis r12, r12, 1 <optional> */
+ { insn_d (-1, -1, -1, -1), insn_d (15, 12, 2, 1), 1 },
+
+ /* mtctr r11 */
+ { insn_xfx (-1, -1, -1, -1), insn_xfx (31, 11, 9, 467),
+ 0 },
+
+ /* ld r11, <any>(r12) */
+ { insn_ds (-1, -1, -1, 0, -1), insn_ds (58, 11, 12, 0, 0), 0 },
+
+ /* bctr */
+ { -1, 0x4e800420, 0 },
+
+ { 0, 0, 0 }
+ };
+ #define PPC64_STANDARD_LINKAGE_LEN \
+ (sizeof (ppc64_standard_linkage) / sizeof (ppc64_standard_linkage[0]))
+
+
+ /* Recognize a 64-bit PowerPC Linux linkage function --- what GDB
+ calls a "solib trampoline". */
+ static int
+ ppc64_in_solib_call_trampoline (CORE_ADDR pc, char *name)
+ {
+ /* Detecting solib call trampolines on PPC64 Linux is a pain.
+
+ It's not specifically solib call trampolines that are the issue.
+ Any call from one function to another function that uses a
+ different TOC requires a trampoline, to save the caller's TOC
+ pointer and then load the callee's TOC. An executable or shared
+ library may have more than one TOC, so even intra-object calls
+ may require a trampoline. Since executable and shared libraries
+ will all have their own distinct TOCs, every inter-object call is
+ also an inter-TOC call, and requires a trampoline --- so "solib
+ call trampolines" are just a special case.
+
+ The 64-bit PowerPC Linux ABI calls these call trampolines
+ "linkage functions". Since they need to be near the functions
+ that call them, they all appear in .text, not in any special
+ section. The .plt section just contains an array of function
+ descriptors, from which the linkage functions load the callee's
+ entry point, TOC value, and environment pointer. So
+ in_plt_section is useless. The linkage functions don't have any
+ special linker symbols to name them, either.
+
+ The only way I can see to recognize them is to actually look at
+ their code. They're generated by ppc_build_one_stub and some
+ other functions in bfd/elf64-ppc.c, so that should show us all
+ the instruction sequences we need to recognize. */
+ unsigned int insn[PPC64_STANDARD_LINKAGE_LEN];
+
+ return insns_match_pattern (pc, ppc64_standard_linkage, insn);
+ }
+
+
+ /* When the dynamic linker is doing lazy symbol resolution, the first
+ call to a function in another object will go like this:
+
+ - The user's function calls the linkage function:
+
+ 100007c4: 4b ff fc d5 bl 10000498
+ 100007c8: e8 41 00 28 ld r2,40(r1)
+
+ - The linkage function loads the entry point (and other stuff) from
+ the function descriptor in the PLT, and jumps to it:
+
+ 10000498: 3d 82 00 00 addis r12,r2,0
+ 1000049c: f8 41 00 28 std r2,40(r1)
+ 100004a0: e9 6c 80 98 ld r11,-32616(r12)
+ 100004a4: e8 4c 80 a0 ld r2,-32608(r12)
+ 100004a8: 7d 69 03 a6 mtctr r11
+ 100004ac: e9 6c 80 a8 ld r11,-32600(r12)
+ 100004b0: 4e 80 04 20 bctr
+
+ - But since this is the first time that PLT entry has been used, it
+ sends control to its glink entry. That loads the number of the
+ PLT entry and jumps to the common glink0 code:
+
+ 10000c98: 38 00 00 00 li r0,0
+ 10000c9c: 4b ff ff dc b 10000c78
+
+ - The common glink0 code then transfers control to the dynamic
+ linker's fixup code:
+
+ 10000c78: e8 41 00 28 ld r2,40(r1)
+ 10000c7c: 3d 82 00 00 addis r12,r2,0
+ 10000c80: e9 6c 80 80 ld r11,-32640(r12)
+ 10000c84: e8 4c 80 88 ld r2,-32632(r12)
+ 10000c88: 7d 69 03 a6 mtctr r11
+ 10000c8c: e9 6c 80 90 ld r11,-32624(r12)
+ 10000c90: 4e 80 04 20 bctr
+
+ Eventually, this code will figure out how to skip all of this,
+ including the dynamic linker. At the moment, we just get through
+ the linkage function. */
+
+ /* If the current thread is about to execute a series of instructions
+ at PC matching the ppc64_standard_linkage pattern, and INSN is the result
+ from that pattern match, return the code address to which the
+ standard linkage function will send them. (This doesn't deal with
+ dynamic linker lazy symbol resolution stubs.) */
+ static CORE_ADDR
+ ppc64_standard_linkage_target (CORE_ADDR pc, unsigned int *insn)
+ {
+ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ /* The address of the function descriptor this linkage function
+ references. */
+ CORE_ADDR desc
+ = ((CORE_ADDR) read_register (tdep->ppc_gp0_regnum + 2)
+ + (insn_d_field (insn[0]) << 16)
+ + insn_ds_field (insn[2]));
+
+ /* The first word of the descriptor is the entry point. Return that. */
+ return (CORE_ADDR) read_memory_unsigned_integer (desc, 8);
+ }
+
+
+ /* Given that we've begun executing a call trampoline at PC, return
+ the entry point of the function the trampoline will go to. */
+ static CORE_ADDR
+ ppc64_skip_trampoline_code (CORE_ADDR pc)
+ {
+ unsigned int ppc64_standard_linkage_insn[PPC64_STANDARD_LINKAGE_LEN];
+
+ if (insns_match_pattern (pc, ppc64_standard_linkage,
+ ppc64_standard_linkage_insn))
+ return ppc64_standard_linkage_target (pc, ppc64_standard_linkage_insn);
+ else
+ return 0;
+ }
+
+
enum {
ELF_NGREG = 48,
ELF_NFPREG = 33,
***************
*** 743,755 ****
set_gdbarch_memory_remove_breakpoint (gdbarch,
ppc_linux_memory_remove_breakpoint);
set_solib_svr4_fetch_link_map_offsets
(gdbarch, ppc_linux_svr4_fetch_link_map_offsets);
}
!
! /* Shared library handling. */
! set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
! set_gdbarch_skip_trampoline_code (gdbarch, ppc_linux_skip_trampoline_code);
}
void
--- 994,1013 ----
set_gdbarch_memory_remove_breakpoint (gdbarch,
ppc_linux_memory_remove_breakpoint);
+ /* Shared library handling. */
+ set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
+ set_gdbarch_skip_trampoline_code (gdbarch,
+ ppc_linux_skip_trampoline_code);
set_solib_svr4_fetch_link_map_offsets
(gdbarch, ppc_linux_svr4_fetch_link_map_offsets);
}
!
! if (tdep->wordsize == 8)
! {
! set_gdbarch_in_solib_call_trampoline
! (gdbarch, ppc64_in_solib_call_trampoline);
! set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
! }
}
void
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ppc64-linux]: skip linkage functions
2003-06-05 23:54 [ppc64-linux]: skip linkage functions Jim Blandy
@ 2003-06-06 0:03 ` Daniel Jacobowitz
2003-06-06 6:22 ` Jim Blandy
2003-06-10 0:05 ` Kevin Buettner
1 sibling, 1 reply; 11+ messages in thread
From: Daniel Jacobowitz @ 2003-06-06 0:03 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb-patches
On Thu, Jun 05, 2003 at 06:54:57PM -0500, Jim Blandy wrote:
>
> 2003-06-05 Jim Blandy <jimb@redhat.com>
>
> Recognize and skip 64-bit PowerPC Linux linkage functions.
> * ppc-linux-tdep.c (insn_d, insn_ds, insn_xfx, read_insn, struct
> insn_pattern, insns_match_pattern, d_field, ds_field): New
> functions, macros, and types for working with PPC instructions.
> (ppc64_standard_linkage, PPC64_STANDARD_LINKAGE_LEN,
> ppc64_in_solib_call_trampoline, ppc64_standard_linkage_target,
> ppc64_skip_trampoline_code): New functions, variables, and macros
> for recognizing and skipping linkage functions.
> (ppc_linux_init_abi): Use ppc64_in_solib_call_trampoline and
> ppc64_skip_trampoline_code for the 64-bit PowerPC Linux ABI.
Hmm. Probably not good enough for our needs, but is the
DW_AT_trampoline attribute useful here?
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ppc64-linux]: skip linkage functions
2003-06-06 0:03 ` Daniel Jacobowitz
@ 2003-06-06 6:22 ` Jim Blandy
2003-06-06 13:11 ` Daniel Jacobowitz
0 siblings, 1 reply; 11+ messages in thread
From: Jim Blandy @ 2003-06-06 6:22 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Daniel Jacobowitz <drow@mvista.com> writes:
> On Thu, Jun 05, 2003 at 06:54:57PM -0500, Jim Blandy wrote:
> >
> > 2003-06-05 Jim Blandy <jimb@redhat.com>
> >
> > Recognize and skip 64-bit PowerPC Linux linkage functions.
> > * ppc-linux-tdep.c (insn_d, insn_ds, insn_xfx, read_insn, struct
> > insn_pattern, insns_match_pattern, d_field, ds_field): New
> > functions, macros, and types for working with PPC instructions.
> > (ppc64_standard_linkage, PPC64_STANDARD_LINKAGE_LEN,
> > ppc64_in_solib_call_trampoline, ppc64_standard_linkage_target,
> > ppc64_skip_trampoline_code): New functions, variables, and macros
> > for recognizing and skipping linkage functions.
> > (ppc_linux_init_abi): Use ppc64_in_solib_call_trampoline and
> > ppc64_skip_trampoline_code for the 64-bit PowerPC Linux ABI.
>
> Hmm. Probably not good enough for our needs, but is the
> DW_AT_trampoline attribute useful here?
I'll say it, so nobody else has to feel bad saying it: that patch is
complete shite. I just can't see any other way to do it with the info
I have.
DW_AT_trampoline would allow me to implement in_solib_call_trampoline
and skip_trampoline_code simply by consulting the debugging info,
which would be eons better. And in generic code, to boot. The only
thing is, the trampolines are generated by the linker, not the
compiler. Could the linker contribute its own Dwarf compilation unit
to .debug_info and .debug_abbrev? How should it decide which
debugging format to use, and whether to emit anything at all?
If we could get this working, we could start using it on other
architectures, too.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ppc64-linux]: skip linkage functions
2003-06-06 6:22 ` Jim Blandy
@ 2003-06-06 13:11 ` Daniel Jacobowitz
2003-06-06 20:09 ` Jim Blandy
0 siblings, 1 reply; 11+ messages in thread
From: Daniel Jacobowitz @ 2003-06-06 13:11 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb-patches
On Fri, Jun 06, 2003 at 01:22:27AM -0500, Jim Blandy wrote:
> Daniel Jacobowitz <drow@mvista.com> writes:
>
> > On Thu, Jun 05, 2003 at 06:54:57PM -0500, Jim Blandy wrote:
> > >
> > > 2003-06-05 Jim Blandy <jimb@redhat.com>
> > >
> > > Recognize and skip 64-bit PowerPC Linux linkage functions.
> > > * ppc-linux-tdep.c (insn_d, insn_ds, insn_xfx, read_insn, struct
> > > insn_pattern, insns_match_pattern, d_field, ds_field): New
> > > functions, macros, and types for working with PPC instructions.
> > > (ppc64_standard_linkage, PPC64_STANDARD_LINKAGE_LEN,
> > > ppc64_in_solib_call_trampoline, ppc64_standard_linkage_target,
> > > ppc64_skip_trampoline_code): New functions, variables, and macros
> > > for recognizing and skipping linkage functions.
> > > (ppc_linux_init_abi): Use ppc64_in_solib_call_trampoline and
> > > ppc64_skip_trampoline_code for the 64-bit PowerPC Linux ABI.
> >
> > Hmm. Probably not good enough for our needs, but is the
> > DW_AT_trampoline attribute useful here?
>
> I'll say it, so nobody else has to feel bad saying it: that patch is
> complete shite. I just can't see any other way to do it with the info
> I have.
>
> DW_AT_trampoline would allow me to implement in_solib_call_trampoline
> and skip_trampoline_code simply by consulting the debugging info,
> which would be eons better. And in generic code, to boot. The only
> thing is, the trampolines are generated by the linker, not the
> compiler. Could the linker contribute its own Dwarf compilation unit
> to .debug_info and .debug_abbrev? How should it decide which
> debugging format to use, and whether to emit anything at all?
>
> If we could get this working, we could start using it on other
> architectures, too.
Hmm. I believe it could be done. It would probably require adding
a --gdwarf2 to the linker, matching the one added to GAS. It's
certainly practical for the linker to add a CU.
As always, it wouldn't free us from the need to grub through assembly
trampolines by hand. There's always something without debug info. But
it would make that code a little less important...
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ppc64-linux]: skip linkage functions
2003-06-06 13:11 ` Daniel Jacobowitz
@ 2003-06-06 20:09 ` Jim Blandy
2003-06-06 20:17 ` Daniel Jacobowitz
0 siblings, 1 reply; 11+ messages in thread
From: Jim Blandy @ 2003-06-06 20:09 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Daniel Jacobowitz <drow@mvista.com> writes:
> On Fri, Jun 06, 2003 at 01:22:27AM -0500, Jim Blandy wrote:
> > Daniel Jacobowitz <drow@mvista.com> writes:
> >
> > > On Thu, Jun 05, 2003 at 06:54:57PM -0500, Jim Blandy wrote:
> > > >
> > > > 2003-06-05 Jim Blandy <jimb@redhat.com>
> > > >
> > > > Recognize and skip 64-bit PowerPC Linux linkage functions.
> > > > * ppc-linux-tdep.c (insn_d, insn_ds, insn_xfx, read_insn, struct
> > > > insn_pattern, insns_match_pattern, d_field, ds_field): New
> > > > functions, macros, and types for working with PPC instructions.
> > > > (ppc64_standard_linkage, PPC64_STANDARD_LINKAGE_LEN,
> > > > ppc64_in_solib_call_trampoline, ppc64_standard_linkage_target,
> > > > ppc64_skip_trampoline_code): New functions, variables, and macros
> > > > for recognizing and skipping linkage functions.
> > > > (ppc_linux_init_abi): Use ppc64_in_solib_call_trampoline and
> > > > ppc64_skip_trampoline_code for the 64-bit PowerPC Linux ABI.
> > >
> > > Hmm. Probably not good enough for our needs, but is the
> > > DW_AT_trampoline attribute useful here?
> >
> > I'll say it, so nobody else has to feel bad saying it: that patch is
> > complete shite. I just can't see any other way to do it with the info
> > I have.
> >
> > DW_AT_trampoline would allow me to implement in_solib_call_trampoline
> > and skip_trampoline_code simply by consulting the debugging info,
> > which would be eons better. And in generic code, to boot. The only
> > thing is, the trampolines are generated by the linker, not the
> > compiler. Could the linker contribute its own Dwarf compilation unit
> > to .debug_info and .debug_abbrev? How should it decide which
> > debugging format to use, and whether to emit anything at all?
> >
> > If we could get this working, we could start using it on other
> > architectures, too.
>
> Hmm. I believe it could be done. It would probably require adding
> a --gdwarf2 to the linker, matching the one added to GAS. It's
> certainly practical for the linker to add a CU.
>
> As always, it wouldn't free us from the need to grub through assembly
> trampolines by hand. There's always something without debug info. But
> it would make that code a little less important...
I haven't been living with CFI long enough to know how these stories
turn out, but my gut feeling is that replacing these heuristic
techniques like prologue unwinding with real debug info has got to be
the Right Thing.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ppc64-linux]: skip linkage functions
2003-06-06 20:09 ` Jim Blandy
@ 2003-06-06 20:17 ` Daniel Jacobowitz
2003-06-06 20:31 ` Jim Blandy
0 siblings, 1 reply; 11+ messages in thread
From: Daniel Jacobowitz @ 2003-06-06 20:17 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb-patches
On Fri, Jun 06, 2003 at 03:10:09PM -0500, Jim Blandy wrote:
> Daniel Jacobowitz <drow@mvista.com> writes:
>
> > On Fri, Jun 06, 2003 at 01:22:27AM -0500, Jim Blandy wrote:
> > > Daniel Jacobowitz <drow@mvista.com> writes:
> > >
> > > > On Thu, Jun 05, 2003 at 06:54:57PM -0500, Jim Blandy wrote:
> > > > >
> > > > > 2003-06-05 Jim Blandy <jimb@redhat.com>
> > > > >
> > > > > Recognize and skip 64-bit PowerPC Linux linkage functions.
> > > > > * ppc-linux-tdep.c (insn_d, insn_ds, insn_xfx, read_insn, struct
> > > > > insn_pattern, insns_match_pattern, d_field, ds_field): New
> > > > > functions, macros, and types for working with PPC instructions.
> > > > > (ppc64_standard_linkage, PPC64_STANDARD_LINKAGE_LEN,
> > > > > ppc64_in_solib_call_trampoline, ppc64_standard_linkage_target,
> > > > > ppc64_skip_trampoline_code): New functions, variables, and macros
> > > > > for recognizing and skipping linkage functions.
> > > > > (ppc_linux_init_abi): Use ppc64_in_solib_call_trampoline and
> > > > > ppc64_skip_trampoline_code for the 64-bit PowerPC Linux ABI.
> > > >
> > > > Hmm. Probably not good enough for our needs, but is the
> > > > DW_AT_trampoline attribute useful here?
> > >
> > > I'll say it, so nobody else has to feel bad saying it: that patch is
> > > complete shite. I just can't see any other way to do it with the info
> > > I have.
> > >
> > > DW_AT_trampoline would allow me to implement in_solib_call_trampoline
> > > and skip_trampoline_code simply by consulting the debugging info,
> > > which would be eons better. And in generic code, to boot. The only
> > > thing is, the trampolines are generated by the linker, not the
> > > compiler. Could the linker contribute its own Dwarf compilation unit
> > > to .debug_info and .debug_abbrev? How should it decide which
> > > debugging format to use, and whether to emit anything at all?
> > >
> > > If we could get this working, we could start using it on other
> > > architectures, too.
> >
> > Hmm. I believe it could be done. It would probably require adding
> > a --gdwarf2 to the linker, matching the one added to GAS. It's
> > certainly practical for the linker to add a CU.
> >
> > As always, it wouldn't free us from the need to grub through assembly
> > trampolines by hand. There's always something without debug info. But
> > it would make that code a little less important...
>
> I haven't been living with CFI long enough to know how these stories
> turn out, but my gut feeling is that replacing these heuristic
> techniques like prologue unwinding with real debug info has got to be
> the Right Thing.
The only problem is that DW_AT_trampoline doesn't live in the CFI - it
lives in the .debug_info section with the full debug info. Some
architectures are moving to always providing CFI, but debug info is
more than we can count on.
What blows up if we don't recognize the trampolines though?
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ppc64-linux]: skip linkage functions
2003-06-06 20:17 ` Daniel Jacobowitz
@ 2003-06-06 20:31 ` Jim Blandy
2003-06-06 21:40 ` Daniel Jacobowitz
0 siblings, 1 reply; 11+ messages in thread
From: Jim Blandy @ 2003-06-06 20:31 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Daniel Jacobowitz <drow@mvista.com> writes:
> On Fri, Jun 06, 2003 at 03:10:09PM -0500, Jim Blandy wrote:
> > Daniel Jacobowitz <drow@mvista.com> writes:
> >
> > > On Fri, Jun 06, 2003 at 01:22:27AM -0500, Jim Blandy wrote:
> > > > Daniel Jacobowitz <drow@mvista.com> writes:
> > > >
> > > > > On Thu, Jun 05, 2003 at 06:54:57PM -0500, Jim Blandy wrote:
> > > > > >
> > > > > > 2003-06-05 Jim Blandy <jimb@redhat.com>
> > > > > >
> > > > > > Recognize and skip 64-bit PowerPC Linux linkage functions.
> > > > > > * ppc-linux-tdep.c (insn_d, insn_ds, insn_xfx, read_insn, struct
> > > > > > insn_pattern, insns_match_pattern, d_field, ds_field): New
> > > > > > functions, macros, and types for working with PPC instructions.
> > > > > > (ppc64_standard_linkage, PPC64_STANDARD_LINKAGE_LEN,
> > > > > > ppc64_in_solib_call_trampoline, ppc64_standard_linkage_target,
> > > > > > ppc64_skip_trampoline_code): New functions, variables, and macros
> > > > > > for recognizing and skipping linkage functions.
> > > > > > (ppc_linux_init_abi): Use ppc64_in_solib_call_trampoline and
> > > > > > ppc64_skip_trampoline_code for the 64-bit PowerPC Linux ABI.
> > > > >
> > > > > Hmm. Probably not good enough for our needs, but is the
> > > > > DW_AT_trampoline attribute useful here?
> > > >
> > > > I'll say it, so nobody else has to feel bad saying it: that patch is
> > > > complete shite. I just can't see any other way to do it with the info
> > > > I have.
> > > >
> > > > DW_AT_trampoline would allow me to implement in_solib_call_trampoline
> > > > and skip_trampoline_code simply by consulting the debugging info,
> > > > which would be eons better. And in generic code, to boot. The only
> > > > thing is, the trampolines are generated by the linker, not the
> > > > compiler. Could the linker contribute its own Dwarf compilation unit
> > > > to .debug_info and .debug_abbrev? How should it decide which
> > > > debugging format to use, and whether to emit anything at all?
> > > >
> > > > If we could get this working, we could start using it on other
> > > > architectures, too.
> > >
> > > Hmm. I believe it could be done. It would probably require adding
> > > a --gdwarf2 to the linker, matching the one added to GAS. It's
> > > certainly practical for the linker to add a CU.
> > >
> > > As always, it wouldn't free us from the need to grub through assembly
> > > trampolines by hand. There's always something without debug info. But
> > > it would make that code a little less important...
> >
> > I haven't been living with CFI long enough to know how these stories
> > turn out, but my gut feeling is that replacing these heuristic
> > techniques like prologue unwinding with real debug info has got to be
> > the Right Thing.
>
> The only problem is that DW_AT_trampoline doesn't live in the CFI - it
> lives in the .debug_info section with the full debug info. Some
> architectures are moving to always providing CFI, but debug info is
> more than we can count on.
Oh, I know where DW_AT_trampoline lives. I was referring to the
general trend of providing debug info for stuff GDB previously had to
guess about, e.g., CFI and location lists replacing prologue analysis.
You can never really get rid of the old heuristics, but since they
won't be used every day any more, they're going to bit-rot. Even if
we included actual binaries in the test suite to make sure the
prologue analyzers continued to recognize what we'd once taught them,
compilers will continue to change the prologues they emit. In the
end, if it rots badly enough, is it worth keeping it at all?
> What blows up if we don't recognize the trampolines though?
On the PPC64, 'next' blows up.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ppc64-linux]: skip linkage functions
2003-06-06 20:31 ` Jim Blandy
@ 2003-06-06 21:40 ` Daniel Jacobowitz
2003-06-06 22:47 ` Jim Blandy
0 siblings, 1 reply; 11+ messages in thread
From: Daniel Jacobowitz @ 2003-06-06 21:40 UTC (permalink / raw)
To: Jim Blandy; +Cc: gdb-patches
On Fri, Jun 06, 2003 at 03:31:58PM -0500, Jim Blandy wrote:
> Daniel Jacobowitz <drow@mvista.com> writes:
>
> > On Fri, Jun 06, 2003 at 03:10:09PM -0500, Jim Blandy wrote:
> > > Daniel Jacobowitz <drow@mvista.com> writes:
> > >
> > > > On Fri, Jun 06, 2003 at 01:22:27AM -0500, Jim Blandy wrote:
> > > > > Daniel Jacobowitz <drow@mvista.com> writes:
> > > > >
> > > > > > On Thu, Jun 05, 2003 at 06:54:57PM -0500, Jim Blandy wrote:
> > > > > > >
> > > > > > > 2003-06-05 Jim Blandy <jimb@redhat.com>
> > > > > > >
> > > > > > > Recognize and skip 64-bit PowerPC Linux linkage functions.
> > > > > > > * ppc-linux-tdep.c (insn_d, insn_ds, insn_xfx, read_insn, struct
> > > > > > > insn_pattern, insns_match_pattern, d_field, ds_field): New
> > > > > > > functions, macros, and types for working with PPC instructions.
> > > > > > > (ppc64_standard_linkage, PPC64_STANDARD_LINKAGE_LEN,
> > > > > > > ppc64_in_solib_call_trampoline, ppc64_standard_linkage_target,
> > > > > > > ppc64_skip_trampoline_code): New functions, variables, and macros
> > > > > > > for recognizing and skipping linkage functions.
> > > > > > > (ppc_linux_init_abi): Use ppc64_in_solib_call_trampoline and
> > > > > > > ppc64_skip_trampoline_code for the 64-bit PowerPC Linux ABI.
> > > > > >
> > > > > > Hmm. Probably not good enough for our needs, but is the
> > > > > > DW_AT_trampoline attribute useful here?
> > > > >
> > > > > I'll say it, so nobody else has to feel bad saying it: that patch is
> > > > > complete shite. I just can't see any other way to do it with the info
> > > > > I have.
> > > > >
> > > > > DW_AT_trampoline would allow me to implement in_solib_call_trampoline
> > > > > and skip_trampoline_code simply by consulting the debugging info,
> > > > > which would be eons better. And in generic code, to boot. The only
> > > > > thing is, the trampolines are generated by the linker, not the
> > > > > compiler. Could the linker contribute its own Dwarf compilation unit
> > > > > to .debug_info and .debug_abbrev? How should it decide which
> > > > > debugging format to use, and whether to emit anything at all?
> > > > >
> > > > > If we could get this working, we could start using it on other
> > > > > architectures, too.
> > > >
> > > > Hmm. I believe it could be done. It would probably require adding
> > > > a --gdwarf2 to the linker, matching the one added to GAS. It's
> > > > certainly practical for the linker to add a CU.
> > > >
> > > > As always, it wouldn't free us from the need to grub through assembly
> > > > trampolines by hand. There's always something without debug info. But
> > > > it would make that code a little less important...
> > >
> > > I haven't been living with CFI long enough to know how these stories
> > > turn out, but my gut feeling is that replacing these heuristic
> > > techniques like prologue unwinding with real debug info has got to be
> > > the Right Thing.
> >
> > The only problem is that DW_AT_trampoline doesn't live in the CFI - it
> > lives in the .debug_info section with the full debug info. Some
> > architectures are moving to always providing CFI, but debug info is
> > more than we can count on.
>
> Oh, I know where DW_AT_trampoline lives. I was referring to the
> general trend of providing debug info for stuff GDB previously had to
> guess about, e.g., CFI and location lists replacing prologue analysis.
> You can never really get rid of the old heuristics, but since they
> won't be used every day any more, they're going to bit-rot. Even if
> we included actual binaries in the test suite to make sure the
> prologue analyzers continued to recognize what we'd once taught them,
> compilers will continue to change the prologues they emit. In the
> end, if it rots badly enough, is it worth keeping it at all?
>
> > What blows up if we don't recognize the trampolines though?
>
> On the PPC64, 'next' blows up.
Oh, I hit this problem on another platform recently. And I had to do a
similar hack for trampolines.
It seems that there shold be a simpler solution than trying to parse
the trampoline...
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ppc64-linux]: skip linkage functions
2003-06-06 21:40 ` Daniel Jacobowitz
@ 2003-06-06 22:47 ` Jim Blandy
0 siblings, 0 replies; 11+ messages in thread
From: Jim Blandy @ 2003-06-06 22:47 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Daniel Jacobowitz <drow@mvista.com> writes:
> On Fri, Jun 06, 2003 at 03:31:58PM -0500, Jim Blandy wrote:
> > Daniel Jacobowitz <drow@mvista.com> writes:
> > > What blows up if we don't recognize the trampolines though?
> >
> > On the PPC64, 'next' blows up.
>
> Oh, I hit this problem on another platform recently. And I had to do a
> similar hack for trampolines.
>
> It seems that there shold be a simpler solution than trying to parse
> the trampoline...
Well, the only relevant piece of machine state is the PC. From there
you can either look at the code (trampoline parsing), or look at
meta-information associated with the address (DW_AT_trampoline). That
exhausts the possibilities, doesn't it?
A simpler meta-information approach might be to insert some new sort
of symbol (STT_GNU_TRAMPOLINE?) whose value was the start address of
the trampoline, and whose name was the name of the function the
trampoline called. Then in_solib_call_trampoline would just check for
an STT_GNU_TRAMPOLINE symbol, and skip_trampoline_code would return
the value of the STT_FUNC symbol of the same name.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ppc64-linux]: skip linkage functions
2003-06-05 23:54 [ppc64-linux]: skip linkage functions Jim Blandy
2003-06-06 0:03 ` Daniel Jacobowitz
@ 2003-06-10 0:05 ` Kevin Buettner
2003-06-10 17:29 ` Jim Blandy
1 sibling, 1 reply; 11+ messages in thread
From: Kevin Buettner @ 2003-06-10 0:05 UTC (permalink / raw)
To: Jim Blandy, gdb-patches
On Jun 5, 6:54pm, Jim Blandy wrote:
> 2003-06-05 Jim Blandy <jimb@redhat.com>
>
> Recognize and skip 64-bit PowerPC Linux linkage functions.
> * ppc-linux-tdep.c (insn_d, insn_ds, insn_xfx, read_insn, struct
> insn_pattern, insns_match_pattern, d_field, ds_field): New
> functions, macros, and types for working with PPC instructions.
> (ppc64_standard_linkage, PPC64_STANDARD_LINKAGE_LEN,
> ppc64_in_solib_call_trampoline, ppc64_standard_linkage_target,
> ppc64_skip_trampoline_code): New functions, variables, and macros
> for recognizing and skipping linkage functions.
> (ppc_linux_init_abi): Use ppc64_in_solib_call_trampoline and
> ppc64_skip_trampoline_code for the 64-bit PowerPC Linux ABI.
Okay...
...except that I can't figure out where "set INSN[i] to -1" (from the
comment) happens in insns_match_pattern(). Once you fix this (or
explain it to me), feel free to commit this patch.
> + /* Return non-zero if the instructions at PC match the series
> + described in PATTERN, or zero otherwise. PATTERN is an array of
> + 'struct insn_pattern' objects, terminated by an entry whose mask is
> + zero.
> +
> + When the match is successful, fill INSN[i] with what PATTERN[i]
> + matched. If PATTERN[i] is optional, and the instruction wasn't
> + present, set INSN[i] to -1. INSN should have as many elements as
> + PATTERN. Note that, if PATTERN contains optional instructions
> + which aren't present in memory, then INSN will have holes, so
> + INSN[i] isn't necessarily the i'th instruction in memory. */
> + static int
> + insns_match_pattern (CORE_ADDR pc,
> + struct insn_pattern *pattern,
> + unsigned int *insn)
> + {
> + int i;
> +
> + for (i = 0; pattern[i].mask; i++)
> + {
> + insn[i] = read_insn (pc);
> + if ((insn[i] & pattern[i].mask) == pattern[i].data)
> + pc += 4;
> + else if (pattern[i].optional)
> + insn[i] = 0;
> + else
> + return 0;
> + }
> +
> + return 1;
> + }
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [ppc64-linux]: skip linkage functions
2003-06-10 0:05 ` Kevin Buettner
@ 2003-06-10 17:29 ` Jim Blandy
0 siblings, 0 replies; 11+ messages in thread
From: Jim Blandy @ 2003-06-10 17:29 UTC (permalink / raw)
To: Kevin Buettner; +Cc: gdb-patches
Kevin Buettner <kevinb@redhat.com> writes:
> Okay...
>
> ...except that I can't figure out where "set INSN[i] to -1" (from the
> comment) happens in insns_match_pattern(). Once you fix this (or
> explain it to me), feel free to commit this patch.
Oops. The comment should say "0", not "-1".
Actually, GDB isn't going to work at all on PPC64 Linux until at least
the following patches go in, for the basic configury and uarea stuff.
http://sources.redhat.com/ml/gdb-patches/2003-05/msg00509.html
http://sources.redhat.com/ml/gdb-patches/2003-05/msg00510.html
http://sources.redhat.com/ml/gdb-patches/2003-05/msg00514.html
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2003-06-10 17:29 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-06-05 23:54 [ppc64-linux]: skip linkage functions Jim Blandy
2003-06-06 0:03 ` Daniel Jacobowitz
2003-06-06 6:22 ` Jim Blandy
2003-06-06 13:11 ` Daniel Jacobowitz
2003-06-06 20:09 ` Jim Blandy
2003-06-06 20:17 ` Daniel Jacobowitz
2003-06-06 20:31 ` Jim Blandy
2003-06-06 21:40 ` Daniel Jacobowitz
2003-06-06 22:47 ` Jim Blandy
2003-06-10 0:05 ` Kevin Buettner
2003-06-10 17:29 ` Jim Blandy
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox