From: Jan Vrany Date: Fri, 28 Nov 2025 13:47:02 +0000 (+0000) Subject: gdb: update is_addr_in_objfile to support "dynamic" objfiles X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ffa404804e7865460c965d0fbded64c20314b8c7;p=thirdparty%2Fbinutils-gdb.git gdb: update is_addr_in_objfile to support "dynamic" objfiles While working with objfiles in Python I noticed that gdb.Progspace.objfile_for_address () does not return "dynamic" objfiles created by (for example) GDB's JIT reader API. This is because is_addr_in_objfile() checks if a given address falls into any (mappped) section of that objfile. However objfiles created by JIT reader API do not have sections. To solve this issue, this commit updates is_addr_in_objfile() to also check if the address fall into any compunit in that objfile. It does so only if the objfile has no sections. --- diff --git a/gdb/objfiles.c b/gdb/objfiles.c index 0d166ceec4c..5c5b04c6458 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -1084,14 +1084,28 @@ is_addr_in_objfile (CORE_ADDR addr, const struct objfile *objfile) if (objfile == NULL) return false; - for (obj_section &osect : objfile->sections ()) + if (objfile->sections_start == nullptr) { - if (section_is_overlay (&osect) && !section_is_mapped (&osect)) - continue; + /* Objfiles created dynamically by the JIT reader API (and possibly by + other means too) do not have sections. For such "dynamic" objfiles + walk over all compunits and check if any of them contains given + ADDR. */ + for (const compunit_symtab &cu : objfile->compunits ()) + if (cu.contains (addr)) + return true; + } + else + { + for (obj_section &osect : objfile->sections ()) + { + if (section_is_overlay (&osect) && !section_is_mapped (&osect)) + continue; - if (osect.contains (addr)) - return true; + if (osect.contains (addr)) + return true; + } } + return false; } diff --git a/gdb/objfiles.h b/gdb/objfiles.h index 0dd3fafac03..f65f3bde930 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -476,7 +476,7 @@ public: /* A range adapter that makes it possible to iterate over all compunits in one objfile. */ - compunit_symtab_range compunits () + compunit_symtab_range compunits () const { auto begin = compunit_symtab_iterator (compunit_symtabs.begin ()); auto end = compunit_symtab_iterator (compunit_symtabs.end ()); diff --git a/gdb/symtab.c b/gdb/symtab.c index 701aa5d0007..5754d944b6c 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -513,6 +513,14 @@ compunit_symtab::symbol_at_address (CORE_ADDR addr) const /* See symtab.h. */ +bool +compunit_symtab::contains (CORE_ADDR addr) const +{ + return blockvector ()->contains (addr); +} + +/* See symtab.h. */ + compunit_symtab::compunit_symtab (struct objfile *objfile, const char *name_) : m_objfile (objfile), diff --git a/gdb/symtab.h b/gdb/symtab.h index 33cf0a6c229..45aca07bc36 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -1964,6 +1964,9 @@ struct compunit_symtab : intrusive_list_node for ADDR are considered. */ struct symbol *symbol_at_address (CORE_ADDR addr) const; + /* True if ADDR is in this compunit_symtab, false otherwise. */ + bool contains (CORE_ADDR addr) const; + /* Object file from which this symtab information was read. */ struct objfile *m_objfile; diff --git a/gdb/testsuite/gdb.base/jit-reader.exp b/gdb/testsuite/gdb.base/jit-reader.exp index cd844ca75d2..df2dd74a6ab 100644 --- a/gdb/testsuite/gdb.base/jit-reader.exp +++ b/gdb/testsuite/gdb.base/jit-reader.exp @@ -234,6 +234,15 @@ proc jit_reader_test {} { gdb_test "python print( \[o for o in gdb.objfiles() if o.filename.startswith('<< JIT compiled code')\]\[0\].build_id )" \ "None" \ "python gdb.Objfile.build_id" + + # Check that Progspace.objfile_for_address () finds "jitted" + # objfile + gdb_test "frame 0" \ + "#0 $hex in jit_function_stack_mangle ()$any" \ + "select frame 0" + gdb_test "python print( gdb.current_progspace().objfile_for_address(gdb.parse_and_eval('\$pc')) )" \ + ">>" \ + "python gdb.Progspace.objfile_for_address" } } }