public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/3] What to do with objfiles with no .text section?
@ 2020-05-19 16:14 Simon Marchi
  2020-05-19 16:14 ` [RFC PATCH 1/3] gdb: remove symfile_find_segment_sections and part of init_objfile_sect_indices Simon Marchi
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Simon Marchi @ 2020-05-19 16:14 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [RFC PATCH 1/3] gdb: remove symfile_find_segment_sections and part of init_objfile_sect_indices
  2020-05-19 16:14 [RFC PATCH 0/3] What to do with objfiles with no .text section? Simon Marchi
@ 2020-05-19 16:14 ` Simon Marchi
  2020-05-19 16:14 ` [RFC PATCH 2/3] gdb: fix a few spots to not assume that we have a .text section Simon Marchi
  2020-05-19 16:14 ` [RFC PATCH 3/3] gdb: add test for shared library without " Simon Marchi
  2 siblings, 0 replies; 4+ messages in thread
From: Simon Marchi @ 2020-05-19 16:14 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

See explanation in the cover letter.
---
 gdb/symfile.c | 84 +--------------------------------------------------
 1 file changed, 1 insertion(+), 83 deletions(-)

diff --git a/gdb/symfile.c b/gdb/symfile.c
index 946443f07a89..62ad704f27d3 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -106,8 +106,6 @@ static int simple_read_overlay_table (void);
 
 static int simple_overlay_update_1 (struct obj_section *);
 
-static void symfile_find_segment_sections (struct objfile *objfile);
-
 /* List of all available sym_fns.  On gdb startup, each object file reader
    calls add_symtab_fns() to register information on each format it is
    prepared to read.  */
@@ -280,7 +278,6 @@ static void
 init_objfile_sect_indices (struct objfile *objfile)
 {
   asection *sect;
-  int i;
 
   sect = bfd_get_section_by_name (objfile->obfd, ".text");
   if (sect)
@@ -297,42 +294,6 @@ init_objfile_sect_indices (struct objfile *objfile)
   sect = bfd_get_section_by_name (objfile->obfd, ".rodata");
   if (sect)
     objfile->sect_index_rodata = sect->index;
-
-  /* This is where things get really weird...  We MUST have valid
-     indices for the various sect_index_* members or gdb will abort.
-     So if for example, there is no ".text" section, we have to
-     accomodate that.  First, check for a file with the standard
-     one or two segments.  */
-
-  symfile_find_segment_sections (objfile);
-
-  /* Except when explicitly adding symbol files at some address,
-     section_offsets contains nothing but zeros, so it doesn't matter
-     which slot in section_offsets the individual sect_index_* members
-     index into.  So if they are all zero, it is safe to just point
-     all the currently uninitialized indices to the first slot.  But
-     beware: if this is the main executable, it may be relocated
-     later, e.g. by the remote qOffsets packet, and then this will
-     be wrong!  That's why we try segments first.  */
-
-  for (i = 0; i < objfile->section_offsets.size (); i++)
-    {
-      if (objfile->section_offsets[i] != 0)
-	{
-	  break;
-	}
-    }
-  if (i == objfile->section_offsets.size ())
-    {
-      if (objfile->sect_index_text == -1)
-	objfile->sect_index_text = 0;
-      if (objfile->sect_index_data == -1)
-	objfile->sect_index_data = 0;
-      if (objfile->sect_index_bss == -1)
-	objfile->sect_index_bss = 0;
-      if (objfile->sect_index_rodata == -1)
-	objfile->sect_index_rodata = 0;
-    }
 }
 
 /* The arguments to place_section.  */
@@ -629,7 +590,7 @@ addr_info_make_relative (section_addr_info *addrs, bfd *abfd)
    of how to represent it for fast symbol reading.  This is the default
    version of the sym_fns.sym_offsets function for symbol readers that
    don't need to do anything special.  It allocates a section_offsets table
-   for the objectfile OBJFILE and stuffs ADDR into all of the offsets.  */
+   for the object file OBJFILE and stuffs ADDR into all of the offsets.  */
 
 void
 default_symfile_offsets (struct objfile *objfile,
@@ -3697,49 +3658,6 @@ symfile_map_offsets_to_segments (bfd *abfd,
   return 1;
 }
 
-static void
-symfile_find_segment_sections (struct objfile *objfile)
-{
-  bfd *abfd = objfile->obfd;
-  int i;
-  asection *sect;
-  struct symfile_segment_data *data;
-
-  data = get_symfile_segment_data (objfile->obfd);
-  if (data == NULL)
-    return;
-
-  if (data->num_segments != 1 && data->num_segments != 2)
-    {
-      free_symfile_segment_data (data);
-      return;
-    }
-
-  for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
-    {
-      int which = data->segment_info[i];
-
-      if (which == 1)
-	{
-	  if (objfile->sect_index_text == -1)
-	    objfile->sect_index_text = sect->index;
-
-	  if (objfile->sect_index_rodata == -1)
-	    objfile->sect_index_rodata = sect->index;
-	}
-      else if (which == 2)
-	{
-	  if (objfile->sect_index_data == -1)
-	    objfile->sect_index_data = sect->index;
-
-	  if (objfile->sect_index_bss == -1)
-	    objfile->sect_index_bss = sect->index;
-	}
-    }
-
-  free_symfile_segment_data (data);
-}
-
 /* Listen for free_objfile events.  */
 
 static void
-- 
2.26.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [RFC PATCH 2/3] gdb: fix a few spots to not assume that we have a .text section
  2020-05-19 16:14 [RFC PATCH 0/3] What to do with objfiles with no .text section? Simon Marchi
  2020-05-19 16:14 ` [RFC PATCH 1/3] gdb: remove symfile_find_segment_sections and part of init_objfile_sect_indices Simon Marchi
@ 2020-05-19 16:14 ` Simon Marchi
  2020-05-19 16:14 ` [RFC PATCH 3/3] gdb: add test for shared library without " Simon Marchi
  2 siblings, 0 replies; 4+ messages in thread
From: Simon Marchi @ 2020-05-19 16:14 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

Following the previous patch, it's possible for objfile::sect_index_text
to have the -1 value, if the objfile has no .text section.  Trying to
debug a program that uses such a library leads to failed assertions,
because of using objfile::text_section_offset and SECT_OFF_TEXT.

This patch fixes enough of these spots so that I'm able to do "start"
and "backtrace" a program that uses a library with no .text section, to
illustrate what kinds of fixes would be needed to make GDB not assume
that .text is always present.

In the DWARF reader, sometimes it is enough to move the call to
text_section_offset in a narrower code path.  Sometimes, we need to do a
bit more work to identify the correct section, like in
add_partial_symbol.  In symab functions that do lookup by pc, we need to
skip the objfiles that don't have any text.
---
 gdb/dwarf2/read.c | 175 +++++++++++++++++++++++++++++-----------------
 gdb/objfiles.h    |   3 +-
 gdb/psympriv.h    |  13 ++++
 gdb/psymtab.c     |   7 +-
 gdb/symfile.c     |   7 +-
 5 files changed, 130 insertions(+), 75 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 719051bc5b2f..77bffc2b5e5a 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -7327,7 +7327,6 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
   struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
   struct gdbarch *gdbarch = objfile->arch ();
   struct dwarf2_per_cu_data *per_cu = cu->per_cu;
-  CORE_ADDR baseaddr;
   CORE_ADDR best_lowpc = 0, best_highpc = 0;
   dwarf2_psymtab *pst;
   enum pc_bounds_kind cu_bounds_kind;
@@ -7356,8 +7355,6 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
   /* This must be done before calling dwarf2_build_include_psymtabs.  */
   pst->dirname = dwarf2_string_attr (comp_unit_die, DW_AT_comp_dir, cu);
 
-  baseaddr = objfile->text_section_offset ();
-
   dwarf2_find_base_address (comp_unit_die, cu);
 
   /* Possibly set the default values of LOWPC and HIGHPC from
@@ -7366,6 +7363,7 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
 					 &best_highpc, cu, pst);
   if (cu_bounds_kind == PC_BOUNDS_HIGH_LOW && best_lowpc < best_highpc)
     {
+      CORE_ADDR baseaddr = objfile->text_section_offset ();
       CORE_ADDR low
 	= (gdbarch_adjust_dwarf2_addr (gdbarch, best_lowpc + baseaddr)
 	   - baseaddr);
@@ -7407,12 +7405,18 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
 	  best_highpc = highpc;
 	}
     }
-  pst->set_text_low (gdbarch_adjust_dwarf2_addr (gdbarch,
-						 best_lowpc + baseaddr)
-		     - baseaddr);
-  pst->set_text_high (gdbarch_adjust_dwarf2_addr (gdbarch,
-						  best_highpc + baseaddr)
-		      - baseaddr);
+
+  if (best_lowpc != 0 || best_highpc != 0)
+    {
+      CORE_ADDR baseaddr = objfile->text_section_offset ();
+
+      pst->set_text_low (gdbarch_adjust_dwarf2_addr (gdbarch,
+						     best_lowpc + baseaddr)
+			 - baseaddr);
+      pst->set_text_high (gdbarch_adjust_dwarf2_addr (gdbarch,
+						      best_highpc + baseaddr)
+			  - baseaddr);
+    }
 
   end_psymtab_common (objfile, pst);
 
@@ -8239,6 +8243,27 @@ partial_die_full_name (struct partial_die_info *pdi,
 							   pdi->name, 0, cu));
 }
 
+/* Find in which section of ABFD the address ADDR falls.  Return the index of
+   such section, or -1 if no section matches.  */
+
+static int
+find_bfd_section_for_address (bfd *abfd, CORE_ADDR addr)
+{
+  for (asection *sec = abfd->sections; sec != nullptr; sec = sec->next)
+    {
+      if ((bfd_section_flags (sec) & SEC_ALLOC) == 0)
+	continue;
+
+      CORE_ADDR start = bfd_section_vma (sec);
+      CORE_ADDR end = start + bfd_section_size (sec);
+
+      if (addr >= start && addr < end)
+	return sec->index;
+    }
+
+  return -1;
+}
+
 static void
 add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 {
@@ -8248,9 +8273,6 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
   struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR addr = 0;
   const char *actual_name = NULL;
-  CORE_ADDR baseaddr;
-
-  baseaddr = objfile->text_section_offset ();
 
   gdb::unique_xmalloc_ptr<char> built_actual_name
     = partial_die_full_name (pdi, cu);
@@ -8273,31 +8295,37 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
     {
     case DW_TAG_inlined_subroutine:
     case DW_TAG_subprogram:
-      addr = (gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + baseaddr)
-	      - baseaddr);
-      if (pdi->is_external
-	  || cu->language == language_ada
-	  || (cu->language == language_fortran
-	      && pdi->die_parent != NULL
-	      && pdi->die_parent->tag == DW_TAG_subprogram))
-	{
-          /* Normally, only "external" DIEs are part of the global scope.
-             But in Ada and Fortran, we want to be able to access nested
-             procedures globally.  So all Ada and Fortran subprograms are
-             stored in the global scope.  */
-	  where = psymbol_placement::GLOBAL;
-	}
-      else
-	where = psymbol_placement::STATIC;
+      {
+	CORE_ADDR baseaddr = objfile->text_section_offset ();
+
+	addr = (gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + baseaddr)
+		- baseaddr);
+	if (pdi->is_external
+	    || cu->language == language_ada
+	    || (cu->language == language_fortran
+		&& pdi->die_parent != NULL
+		&& pdi->die_parent->tag == DW_TAG_subprogram))
+	  {
+	    /* Normally, only "external" DIEs are part of the global scope.
+	       But in Ada and Fortran, we want to be able to access nested
+	       procedures globally.  So all Ada and Fortran subprograms are
+	       stored in the global scope.  */
+	    where = psymbol_placement::GLOBAL;
+	  }
+	else
+	  where = psymbol_placement::STATIC;
 
-      psymbol.domain = VAR_DOMAIN;
-      psymbol.aclass = LOC_BLOCK;
-      psymbol.ginfo.section = SECT_OFF_TEXT (objfile);
-      psymbol.ginfo.value.address = addr;
+	psymbol.domain = VAR_DOMAIN;
+	psymbol.aclass = LOC_BLOCK;
+	psymbol.ginfo.section
+	  = find_bfd_section_for_address (objfile->obfd, addr);
+	psymbol.ginfo.value.address = addr;
+
+	if (pdi->main_subprogram && actual_name != NULL)
+	  set_objfile_main_name (objfile, actual_name, cu->language);
+	break;
+      }
 
-      if (pdi->main_subprogram && actual_name != NULL)
-	set_objfile_main_name (objfile, actual_name, cu->language);
-      break;
     case DW_TAG_constant:
       psymbol.domain = VAR_DOMAIN;
       psymbol.aclass = LOC_STATIC;
@@ -8337,7 +8365,8 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 	    {
 	      psymbol.domain = VAR_DOMAIN;
 	      psymbol.aclass = LOC_STATIC;
-	      psymbol.ginfo.section = SECT_OFF_TEXT (objfile);
+	      psymbol.ginfo.section
+		= find_bfd_section_for_address (objfile->obfd, addr);
 	      psymbol.ginfo.value.address = addr;
 	      where = psymbol_placement::GLOBAL;
 	    }
@@ -8353,9 +8382,12 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 
 	  psymbol.domain = VAR_DOMAIN;
 	  psymbol.aclass = LOC_STATIC;
-	  psymbol.ginfo.section = SECT_OFF_TEXT (objfile);
 	  if (has_loc)
-	    psymbol.ginfo.value.address = addr;
+	    {
+	      psymbol.ginfo.section
+		= find_bfd_section_for_address (objfile->obfd, addr);
+	      psymbol.ginfo.value.address = addr;
+	    }
 	  where = psymbol_placement::STATIC;
 	}
       break;
@@ -9637,12 +9669,9 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
   struct gdbarch *gdbarch = objfile->arch ();
   CORE_ADDR lowpc, highpc;
   struct compunit_symtab *cust;
-  CORE_ADDR baseaddr;
   struct block *static_block;
   CORE_ADDR addr;
 
-  baseaddr = objfile->text_section_offset ();
-
   /* Clear the list here in case something was left over.  */
   cu->method_list.clear ();
 
@@ -9669,18 +9698,30 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
      it, by scanning the DIE's below the compilation unit.  */
   get_scope_pc_bounds (cu->dies, &lowpc, &highpc, cu);
 
-  addr = gdbarch_adjust_dwarf2_addr (gdbarch, highpc + baseaddr);
+  if (lowpc != -1 && highpc != 0)
+    {
+      CORE_ADDR baseaddr = objfile->text_section_offset ();
+      addr = gdbarch_adjust_dwarf2_addr (gdbarch, highpc + baseaddr);
+    }
+  else
+    addr = 0;
+
   static_block = cu->get_builder ()->end_symtab_get_static_block (addr, 0, 1);
 
-  /* If the comp unit has DW_AT_ranges, it may have discontiguous ranges.
-     Also, DW_AT_ranges may record ranges not belonging to any child DIEs
-     (such as virtual method tables).  Record the ranges in STATIC_BLOCK's
-     addrmap to help ensure it has an accurate map of pc values belonging to
-     this comp unit.  */
-  dwarf2_record_block_ranges (cu->dies, static_block, baseaddr, cu);
+  if (objfile->sect_index_text != -1)
+    {
+      CORE_ADDR baseaddr = objfile->text_section_offset ();
+
+      /* If the comp unit has DW_AT_ranges, it may have discontiguous ranges.
+	 Also, DW_AT_ranges may record ranges not belonging to any child DIEs
+	 (such as virtual method tables).  Record the ranges in STATIC_BLOCK's
+	 addrmap to help ensure it has an accurate map of pc values belonging to
+	 this comp unit.  */
+      dwarf2_record_block_ranges (cu->dies, static_block, baseaddr, cu);
+    }
 
-  cust = cu->get_builder ()->end_symtab_from_static_block (static_block,
-						    SECT_OFF_TEXT (objfile),
+  cust = cu->get_builder ()->end_symtab_from_static_block
+    (static_block, objfile->sect_index_text != -1 ? SECT_OFF_TEXT (objfile) : -1,
 						    0);
 
   if (cust != NULL)
@@ -10845,18 +10886,18 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   CORE_ADDR highpc = ((CORE_ADDR) 0);
   struct attribute *attr;
   struct die_info *child_die;
-  CORE_ADDR baseaddr;
 
   prepare_one_comp_unit (cu, die, cu->language);
-  baseaddr = objfile->text_section_offset ();
 
   get_scope_pc_bounds (die, &lowpc, &highpc, cu);
 
-  /* If we didn't find a lowpc, set it to highpc to avoid complaints
-     from finish_block.  */
-  if (lowpc == ((CORE_ADDR) -1))
-    lowpc = highpc;
-  lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
+  if (lowpc != ((CORE_ADDR) -1))
+    {
+      CORE_ADDR baseaddr = objfile->text_section_offset ();
+      lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
+    }
+  else
+    lowpc = 0;
 
   file_and_directory fnd = find_file_and_directory (die, cu);
 
@@ -20154,8 +20195,7 @@ static void
 dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
 		      const int decode_for_pst_p, CORE_ADDR lowpc)
 {
-  const gdb_byte *line_ptr, *extended_end;
-  const gdb_byte *line_end;
+  const gdb_byte *extended_end;
   unsigned int bytes_read, extended_len;
   unsigned char op_code, extended_op;
   CORE_ADDR baseaddr;
@@ -20167,10 +20207,17 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
      the line number program).  */
   bool record_lines_p = !decode_for_pst_p;
 
-  baseaddr = objfile->text_section_offset ();
+  const gdb_byte *line_ptr = lh->statement_program_start;
+  const gdb_byte *line_end = lh->statement_program_end;
+
+  /* It's possible for the object file to have no .text section (which makes
+     calling objfile->text_section_offset below invalid) and a .debug_line
+     section with an empty line number program.  If so, just return early
+     to avoid calling text_section_offset.  */
+  if (line_ptr == line_end)
+    return;
 
-  line_ptr = lh->statement_program_start;
-  line_end = lh->statement_program_end;
+  baseaddr = objfile->text_section_offset ();
 
   /* Read the statement sequences until there's nothing left.  */
   while (line_ptr < line_end)
@@ -20590,13 +20637,10 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
   const char *name;
   struct attribute *attr = NULL;
   struct attribute *attr2 = NULL;
-  CORE_ADDR baseaddr;
   struct pending **list_to_add = NULL;
 
   int inlined_func = (die->tag == DW_TAG_inlined_subroutine);
 
-  baseaddr = objfile->text_section_offset ();
-
   name = dwarf2_name (die, cu);
   if (name)
     {
@@ -20668,6 +20712,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	  if (attr != nullptr)
 	    {
 	      CORE_ADDR addr;
+	      CORE_ADDR baseaddr = objfile->text_section_offset ();
 
 	      addr = attr->value_as_address ();
 	      addr = gdbarch_adjust_dwarf2_addr (gdbarch, addr + baseaddr);
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index 0b47bd0c1e2f..de495c16ec27 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -114,7 +114,8 @@ struct entry_info
   /* The unrelocated value we should use for this objfile entry point.  */
   CORE_ADDR entry_point;
 
-  /* The index of the section in which the entry point appears.  */
+  /* The index of the section in which the entry point appears.  If -1, we
+     don't know / couldn't find the section.  */
   int the_bfd_section_index;
 
   /* Set to 1 iff ENTRY_POINT contains a valid value.  */
diff --git a/gdb/psympriv.h b/gdb/psympriv.h
index 6f0307e05b78..46e546b61e7e 100644
--- a/gdb/psympriv.h
+++ b/gdb/psympriv.h
@@ -158,24 +158,32 @@ struct partial_symtab
   /* Return the raw low text address of this partial_symtab.  */
   CORE_ADDR raw_text_low () const
   {
+    gdb_assert (text_low_valid);
+
     return m_text_low;
   }
 
   /* Return the raw high text address of this partial_symtab.  */
   CORE_ADDR raw_text_high () const
   {
+    gdb_assert (text_high_valid);
+
     return m_text_high;
   }
 
   /* Return the relocated low text address of this partial_symtab.  */
   CORE_ADDR text_low (struct objfile *objfile) const
   {
+    gdb_assert (text_low_valid);
+
     return m_text_low + objfile->text_section_offset ();
   }
 
   /* Return the relocated high text address of this partial_symtab.  */
   CORE_ADDR text_high (struct objfile *objfile) const
   {
+    gdb_assert (text_high_valid);
+
     return m_text_high + objfile->text_section_offset ();
   }
 
@@ -193,6 +201,11 @@ struct partial_symtab
     text_high_valid = 1;
   }
 
+  /* Return true if this partial symtab has some text (code) parts.  */
+  bool has_text () const
+  {
+    return text_low_valid && text_high_valid;
+  }
 
   /* Chain of all existing partial symtabs.  */
 
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 1fce7a398384..3073cccfa364 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -306,7 +306,8 @@ find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc,
      that is not a partial_symtab, which doesn't end well.  */
 
   if (objfile->partial_symtabs->psymtabs != NULL
-      && objfile->partial_symtabs->psymtabs_addrmap != NULL)
+      && objfile->partial_symtabs->psymtabs_addrmap != NULL
+      && objfile->sect_index_text != -1)
     {
       CORE_ADDR baseaddr = objfile->text_section_offset ();
 
@@ -356,7 +357,7 @@ find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc,
      debug info type in single OBJFILE.  */
 
   for (partial_symtab *pst : require_partial_symbols (objfile, true))
-    if (!pst->psymtabs_addrmap_supported
+    if (!pst->psymtabs_addrmap_supported && pst->has_text ()
 	&& pc >= pst->text_low (objfile) && pc < pst->text_high (objfile))
       {
 	struct partial_symtab *best_pst;
@@ -2127,7 +2128,7 @@ maintenance_check_psymtabs (const char *ignore, int from_tty)
 	cust = ps->get_compunit_symtab ();
 
 	/* First do some checks that don't require the associated symtab.  */
-	if (ps->text_high (objfile) < ps->text_low (objfile))
+	if (ps->has_text () && ps->text_high (objfile) < ps->text_low (objfile))
 	  {
 	    printf_filtered ("Psymtab ");
 	    puts_filtered (ps->filename);
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 62ad704f27d3..63db2bc7875e 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -808,7 +808,6 @@ init_entry_point_info (struct objfile *objfile)
     {
       struct obj_section *osect;
       CORE_ADDR entry_point =  ei->entry_point;
-      int found;
 
       /* Make certain that the address points at real code, and not a
 	 function descriptor.  */
@@ -821,8 +820,8 @@ init_entry_point_info (struct objfile *objfile)
 	 symbol table.  */
       ei->entry_point
 	= gdbarch_addr_bits_remove (objfile->arch (), entry_point);
+      ei->the_bfd_section_index = -1;
 
-      found = 0;
       ALL_OBJFILE_OSECTIONS (objfile, osect)
 	{
 	  struct bfd_section *sect = osect->the_bfd_section;
@@ -833,13 +832,9 @@ init_entry_point_info (struct objfile *objfile)
 	    {
 	      ei->the_bfd_section_index
 		= gdb_bfd_section_index (objfile->obfd, sect);
-	      found = 1;
 	      break;
 	    }
 	}
-
-      if (!found)
-	ei->the_bfd_section_index = SECT_OFF_TEXT (objfile);
     }
 }
 
-- 
2.26.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [RFC PATCH 3/3] gdb: add test for shared library without .text section
  2020-05-19 16:14 [RFC PATCH 0/3] What to do with objfiles with no .text section? Simon Marchi
  2020-05-19 16:14 ` [RFC PATCH 1/3] gdb: remove symfile_find_segment_sections and part of init_objfile_sect_indices Simon Marchi
  2020-05-19 16:14 ` [RFC PATCH 2/3] gdb: fix a few spots to not assume that we have a .text section Simon Marchi
@ 2020-05-19 16:14 ` Simon Marchi
  2 siblings, 0 replies; 4+ messages in thread
From: Simon Marchi @ 2020-05-19 16:14 UTC (permalink / raw)
  To: gdb-patches; +Cc: Simon Marchi

This is just a raw test to help test the previous patch.
---
 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 +++++++++++++++++++++
 3 files changed, 38 insertions(+)
 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

diff --git a/gdb/testsuite/gdb.base/solib-no-text-lib.c b/gdb/testsuite/gdb.base/solib-no-text-lib.c
new file mode 100644
index 000000000000..b0d865137ad2
--- /dev/null
+++ b/gdb/testsuite/gdb.base/solib-no-text-lib.c
@@ -0,0 +1 @@
+int hello = 1;
diff --git a/gdb/testsuite/gdb.base/solib-no-text-main.c b/gdb/testsuite/gdb.base/solib-no-text-main.c
new file mode 100644
index 000000000000..15e093704f76
--- /dev/null
+++ b/gdb/testsuite/gdb.base/solib-no-text-main.c
@@ -0,0 +1,7 @@
+/* Defined in the shared library.  */
+extern int hello;
+
+int main (void)
+{
+  return hello;
+}
diff --git a/gdb/testsuite/gdb.base/solib-no-text.exp b/gdb/testsuite/gdb.base/solib-no-text.exp
new file mode 100644
index 000000000000..b8de1e76e192
--- /dev/null
+++ b/gdb/testsuite/gdb.base/solib-no-text.exp
@@ -0,0 +1,30 @@
+# Library file.
+set libname "solib-no-text-lib"
+set srcfile_lib ${srcdir}/${subdir}/${libname}.c
+set binfile_lib [standard_output_file ${libname}.so]
+set lib_flags {debug ldflags=-nodefaultlibs ldflags=-nostdlib}
+
+# Binary file.
+set testfile "solib-no-text-main"
+set srcfile ${srcdir}/${subdir}/${testfile}.c
+set binfile [standard_output_file ${testfile}]
+set bin_flags [list debug shlib=${binfile_lib}]
+
+if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} ${lib_flags}] != "" } {
+    untested "failed to compile shared library"
+    return -1
+}
+
+if { [gdb_compile ${srcfile} ${binfile} executable ${bin_flags}] != "" } {
+    untested "failed to compile executable"
+    return -1
+}
+
+clean_restart ${binfile}
+
+# `message` is important here, if there's an internal error, it will produce a
+# failure.
+runto main message
+
+gdb_test "print hello"
+gdb_test "bt"
-- 
2.26.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-05-19 16:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-19 16:14 [RFC PATCH 0/3] What to do with objfiles with no .text section? Simon Marchi
2020-05-19 16:14 ` [RFC PATCH 1/3] gdb: remove symfile_find_segment_sections and part of init_objfile_sect_indices Simon Marchi
2020-05-19 16:14 ` [RFC PATCH 2/3] gdb: fix a few spots to not assume that we have a .text section Simon Marchi
2020-05-19 16:14 ` [RFC PATCH 3/3] gdb: add test for shared library without " Simon Marchi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).