Bug 29814 - [gdb/tdep, powerpc64le] FAIL: gdb.base/msym-bp-shl.exp: debug=0: before run: info breakpoint
Summary: [gdb/tdep, powerpc64le] FAIL: gdb.base/msym-bp-shl.exp: debug=0: before run: ...
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: tdep (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: 13.1
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-11-21 13:27 UTC by Tom de Vries
Modified: 2022-11-28 09:51 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom de Vries 2022-11-21 13:27:43 UTC
With a gdb 12.1 based package on powerpc64le and target board unix/-fPIE/-pie, I run into:
...
(gdb) PASS: gdb.base/msym-bp-shl.exp: debug=0: before run: break foo
info breakpoint^M
Num     Type           Disp Enb Address            What^M
1       breakpoint     keep y   <MULTIPLE>         ^M
1.1                         y   0x00000000000008d4 <foo+12>^M
1.2                         y   0x0000000000000a34 ../sysdeps/powerpc/powerpc64/crti.S:88^M
(gdb) FAIL: gdb.base/msym-bp-shl.exp: debug=0: before run: info breakpoint
...

What seems to be happening it that foo@plt:
...
0000000000000a28 <foo@plt>:
 a28:   c0 ff ff 4b     b       9e8 <__glink_PLTresolve>

Disassembly of section .fini:

0000000000000a2c <_fini>:
 a2c:   02 00 4c 3c     addis   r2,r12,2
 a30:   d4 74 42 38     addi    r2,r2,29908
 a34:   a6 02 08 7c     mflr    r0

...
is part of .text and (perhaps because of that) treated as a regular function, so we add 8 to get past the global entry point, which gets us to 0xa30 in _fini, and then (considering it part of prologue) skip past that insn to get to 0xa34.
Comment 1 Tom de Vries 2022-11-21 16:32:00 UTC
Reproduces with master.
Comment 2 Tom de Vries 2022-11-23 10:14:09 UTC
This is a point fix:
...
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index cc5a26431ba..a7ee72e24a5 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -1667,9 +1667,11 @@ ppc_elfv2_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR pc)
   if (fun.minsym->target_flag_1 ())
     local_entry_offset = 8;
 
-  if (fun.value_address () <= pc
-      && pc < fun.value_address () + local_entry_offset)
-    return fun.value_address () + local_entry_offset;
+  struct obj_section *section = fun.obj_section ();
+  CORE_ADDR new_pc = fun.value_address () + local_entry_offset;
+  if (fun.value_address () <= pc && pc < new_pc
+      && (section == nullptr || new_pc < section->endaddr ()))
+    return new_pc;
 
   return pc;
 }
...

It does fix the test-case, but not the general problem, since this will work for one or maybe two plt symbols, but if there are more, say foo1@plt, foo2@plt and foo3@plt, then setting a breakpoint at foo1@plt will end up setting a breakpoint at foo3@plt.
Comment 3 Tom de Vries 2022-11-23 11:11:37 UTC
This is a more generic fix:
...
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index cc5a26431ba..f7a7703e01e 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -1662,6 +1662,14 @@ ppc_elfv2_skip_entrypoint (struct gdbarch *gdbarch, CORE_ADDR pc)
   if (fun.minsym == NULL)
     return pc;
 
+  const char *name = fun.minsym->linkage_name ();
+  const char *atsign = strchr (name, '@');
+  bool is_at_symbol = atsign != nullptr && atsign > name;
+  bool is_plt = is_at_symbol && strcmp (atsign, "@plt") == 0;
+
+  if (is_plt)
+    return pc;
+
   /* See ppc_elfv2_elf_make_msymbol_special for how local entry point
      offset values are encoded.  */
   if (fun.minsym->target_flag_1 ())
...

Not great to do the string comparison here, but I'm not sure what else to do.

I saw:
...
 0x0000000070000000 (PPC64_GLINK)        0x9fc
...
and:
...
00000000000009e8 <__glink_PLTresolve>:
 9e8:   a6 02 08 7c     mflr    r0
  ...
 a18:   20 04 80 4e     bctr

0000000000000a1c <__cxa_finalize@plt>:
 a1c:   cc ff ff 4b     b       9e8 <__glink_PLTresolve>

0000000000000a20 <__libc_start_main@plt>:
 a20:   c8 ff ff 4b     b       9e8 <__glink_PLTresolve>

0000000000000a24 <__gmon_start__@plt>:
 a24:   c4 ff ff 4b     b       9e8 <__glink_PLTresolve>

0000000000000a28 <foo@plt>:
 a28:   c0 ff ff 4b     b       9e8 <__glink_PLTresolve>

Disassembly of section .fini:

0000000000000a2c <_fini>:
...

So maybe we can compare the address to PPC64_GLINK, and if it's bigger than that and in the text section we can consider it plt?
Comment 4 Ulrich Weigand 2022-11-23 11:59:40 UTC
This fix seems wrong.  The symbol should have been marked as having no local entry point (i.e. fun.minsym->target_flag_1 () should have returned 0).

You should check why that doesn't happen - what does ppc_elfv2_elf_make_msymbol_special do for this symbol?

Is this a "real" symbol, or is it one of the synthetic symbols generated by BFD?  In the latter case, either ...make_msybol_special doesn't handle those correctly, or the symbol is synthesized using wrong flags.
Comment 5 Tom de Vries 2022-11-23 16:16:56 UTC
(In reply to Ulrich Weigand from comment #4)
> This fix seems wrong.  The symbol should have been marked as having no local
> entry point (i.e. fun.minsym->target_flag_1 () should have returned 0).
> 
> You should check why that doesn't happen - what does
> ppc_elfv2_elf_make_msymbol_special do for this symbol?
> 
> Is this a "real" symbol, or is it one of the synthetic symbols generated by
> BFD?  In the latter case, either ...make_msybol_special doesn't handle those
> correctly, or the symbol is synthesized using wrong flags.

Thanks for the comments, that's very helpful.

It is a synthetic symbol, and AFAIU the problem is the cast from asymbol* to elf_symbol_type*.  In ppc64_elf_get_synthetic_symtab we have:
...
2577                  size += plt_count * sizeof (asymbol);
...
so we only allocate an asymbol.

This fixes the test-case:
...
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index cc5a26431ba..5aeb4e849d5 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -1632,6 +1632,8 @@ ppc_linux_core_read_description (struct gdbarch *gdbarch,
 static void
 ppc_elfv2_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
 {
+  if ((sym->flags & BSF_SYNTHETIC) != 0)
+    return;
   elf_symbol_type *elf_sym = (elf_symbol_type *)sym;
 
   /* If the symbol is marked as having a local entry point, set a target

...

Now the question is whether there are any synthetic symbols which still need ppc_elfv2_elf_make_msymbol_special to do something, for instance when sym->udata.p != NULL, as in ppc64_elf_make_msymbol_special.
Comment 6 Carl E Love 2022-11-23 16:37:10 UTC
FYI
I do not see the failure on Power 10, gcc (GCC) 12.2.1 20220819 (Red Hat 12.2.1-2), Fedora release 36 (Thirty Six). With mainline gdb
commit 31c1130f35e0ef800ea4d92224a72872ffe4a5db (HEAD -> master, origin/master, origin/HEAD)
Author: GDB Administrator <gdbadmin@sourceware.org>
Date:   Tue Nov 22 00:00:39 2022 +0000

    Automatic date update in version.in



I do not see the failure on Power 10, gcc (GCC) 11.2.1 20220127 (Red Hat 11.2.1-9), Red Hat Enterprise Linux release 9.0 (Plow), with mainline gdb
commit 8db533e7d6d28db1be0ae4c95ddea7aa3a6224c8 (HEAD -> master, origin/master, origin/HEAD)
Author: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
Date:   Wed Nov 23 11:58:31 2022 +0100

    gdb/arm: Include FType bit in EXC_RETURN pattern on v8m


The failure does occur on Power 9, gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0,NAME="Ubuntu"  VERSION="20.04.5 LTS (Focal Fossa)" with mainline gdb
commit 8db533e7d6d28db1be0ae4c95ddea7aa3a6224c8 (HEAD -> master, origin/master, origin/HEAD)
Author: Torbjörn SVENSSON <torbjorn.svensson@foss.st.com>
Date:   Wed Nov 23 11:58:31 2022 +0100

    gdb/arm: Include FType bit in EXC_RETURN pattern on v8m
Comment 7 Ulrich Weigand 2022-11-23 17:03:20 UTC
(In reply to Tom de Vries from comment #5)

> Now the question is whether there are any synthetic symbols which still need
> ppc_elfv2_elf_make_msymbol_special to do something, for instance when
> sym->udata.p != NULL, as in ppc64_elf_make_msymbol_special.

No, with ELFv2 the only synthetic symbols are related to PLT handling (the PLT stubs and the __glink_PLTresolve trampoline), and none of those have a local entry point.

With ELFv1, there are synthetic symbols for the "dot" symbols (i.e. the real symbol "func" points to the function descriptor, and the synthetic symbol ".func" points to the associated function text).  But with ELFv1 there are no local entry points, so we don't need to handle those.

Your fix looks good to me.
Comment 8 Carl E Love 2022-11-23 20:43:55 UTC
I tested the fix on both Power 10 systems.  No regressions were found.

The fix was tested on the Power 9 system.  It fixed the test with no additional test failures.  

Looks good to me.
Comment 10 Sourceware Commits 2022-11-28 09:50:08 UTC
The master branch has been updated by Tom de Vries <vries@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=2650ea9730e31fc5c9111afc1a689dbca76707f5

commit 2650ea9730e31fc5c9111afc1a689dbca76707f5
Author: Tom de Vries <tdevries@suse.de>
Date:   Mon Nov 28 10:50:03 2022 +0100

    [gdb/tdep] Fix gdb.base/msym-bp-shl.exp for ppc64le
    
    With test-case gdb.base/msym-bp-shl.exp on powerpc64le-linux, I run into:
    ...
    (gdb) PASS: gdb.base/msym-bp-shl.exp: debug=0: before run: break foo
    info breakpoint^M
    Num     Type           Disp Enb Address            What^M
    1       breakpoint     keep y   <MULTIPLE>         ^M
    1.1                         y   0x00000000000008d4 <foo+12>^M
    1.2                         y   0x0000000000000a34 crti.S:88^M
    (gdb) FAIL: gdb.base/msym-bp-shl.exp: debug=0: before run: info breakpoint
    ...
    
    The problem is that the prologue skipper walks from foo@plt at 0xa28 to 0xa34:
    ...
    0000000000000a28 <foo@plt>:
     a28:   c0 ff ff 4b     b       9e8 <__glink_PLTresolve>
    
    Disassembly of section .fini:
    
    0000000000000a2c <_fini>:
     a2c:   02 00 4c 3c     addis   r2,r12,2
     a30:   d4 74 42 38     addi    r2,r2,29908
     a34:   a6 02 08 7c     mflr    r0
    ...
    
    This is caused by ppc_elfv2_elf_make_msymbol_special which marks foo@plt as
    having a local entry point, due to incorrectly accessing an asymbol struct
    using a (larger) elf_symbol_type.
    
    Fix this by simply ignoring artificial symbols in
    ppc_elfv2_elf_make_msymbol_special.
    
    Tested on powerpc64le.
    
    Approved-By: Ulrich Weigand <uweigand@de.ibm.com>
    Reviewed-By: Carl Love <cel@us.ibm.com>
    Tested-By: Carl Love <cel@us.ibm.com>
    PR tdep/29814
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29814
Comment 11 Tom de Vries 2022-11-28 09:51:32 UTC
Fixed by commit in previous comment.