[RFC PATCH 0/3] What to do with objfiles with no .text section?

Simon Marchi simon.marchi@efficios.com
Tue May 19 16:14:28 GMT 2020


My attention was brought to init_objfile_sect_indices while
investigating PR 25678.  Its job is to set the various `sect_index_*`
fields of struct objfile.  I am questioning what this function does and
should do when a section when the .text section is missing.

Currently, if a library has no .text section but has two segments, then
init_objfile_sect_indices will set `sect_index_text` to some positive
value.  This can be reproduced with:

    $ cat allo.c
    int salut;
    int bonjour = 1;
    const int allo = 2;
    $ gcc allo.c -fPIC -o allo.o -g3 -O0 -c
    $ gcc allo.o -shared -nostdlib -nodefaultlibs -o allo.so
    $ cat test.c
    int main() {}
    $ gcc test.c -Wl,--no-as-needed ./allo.so -g3 -O0

If you debug a.out and break on init_objfile_sect_indices, you'll see that it
(symfile_find_segment_sections, in fact) will set sect_index_text to some
non-`-1` value, in my case 0.  The logic of symfile_find_segment_sections seems
to be: if I can't locate the .text section, I'll set sect_index_text to point
to some other section that is in the first segment.  The offsets of these two
sections should be the same, so it shouldn't matter if sect_index_tex points to
another section.  That relies on the well-known (?) that the first segment
contains the text and rodata, while the second segment contains data and bss.

Even though that's the kind of characteristic that probably doesn't
change often, that heuristic sounds oddly specific.

There is also code in init_objfile_sect_indices that sets all
`sect_index_*` fields to 0 if they are unset and all section offsets are
0.

The problem with all this, as illustrated by bug 25678, is that if an object
file has no .text section and three segments, for example, then it can leave
sect_index_text uninitialized (-1).  This can be reproduced by using the
libtestcase.so attached with the bug:

    $ gcc test.c -Wl,--no-as-needed ./libtestcase.so -g3 -O0

sect_index_text remains -1, while the rest of GDB assumes that it is set to
some valid value, so we hit some assertions.

>From there, I see two possible ways forward:

1. We add more heuristic so that sect_index_text is always set to some
   valid index value.  That does not seem like a good idea to me though:
   while it may be fine with respect to section offsets to make
   sect_index_text point to some other section, it may cause other
   problems down the road to "lie" to GDB that way.
2. Make init_objfile_sect_indices leave sect_index_text as -1 when there
   is no .text section in the objfile.  The rest of GDB needs to be
   adapted to account for that possibility.

I prefer option #2, since it more accurately represents reality,
although I'm a bit afraid it is a rabbit hole.

To demonstrate what this could look like, patch #1 removes the heuristic code
in init_objfile_sect_indices, to only leave the more obvious code that looks up
sections by name.  I'm curious if anybody knows of situations where looking up
sections by name wouldn't be enough.

Here's the patch that introduced this code, maybe it will give some
clues:

  https://sourceware.org/legacy-ml/gdb-patches/2007-05/msg00140.html

Patch #2 does a few fixes to make some parts of GDB aware that sect_index_text
can be -1, and that it means there's no text section.

Simon Marchi (3):
  gdb: remove symfile_find_segment_sections and part of
    init_objfile_sect_indices
  gdb: fix a few spots to not assume that we have a .text section
  gdb: add test for shared library without .text section

 gdb/dwarf2/read.c                           | 175 ++++++++++++--------
 gdb/objfiles.h                              |   3 +-
 gdb/psympriv.h                              |  13 ++
 gdb/psymtab.c                               |   7 +-
 gdb/symfile.c                               |  91 +---------
 gdb/testsuite/gdb.base/solib-no-text-lib.c  |   1 +
 gdb/testsuite/gdb.base/solib-no-text-main.c |   7 +
 gdb/testsuite/gdb.base/solib-no-text.exp    |  30 ++++
 8 files changed, 169 insertions(+), 158 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/solib-no-text-lib.c
 create mode 100644 gdb/testsuite/gdb.base/solib-no-text-main.c
 create mode 100644 gdb/testsuite/gdb.base/solib-no-text.exp

-- 
2.26.2



More information about the Gdb-patches mailing list