[PATCH 1/4] objdump: New feature display of global variable information based on DWARF info section

Jan Beulich jbeulich@suse.com
Fri Aug 22 07:30:29 GMT 2025
On 19.08.2025 04:12, Guillaume VACHERIAS wrote:
> --- a/binutils/doc/binutils.texi
> +++ b/binutils/doc/binutils.texi
> @@ -2294,6 +2294,7 @@ objdump [@option{-a}|@option{--archive-headers}]
>          [@option{-WN}|@option{--dwarf=no-follow-links}]
>          [@option{-wD}|@option{--dwarf=use-debuginfod}]
>          [@option{-wE}|@option{--dwarf=do-not-use-debuginfod}]
> +        [@option{-Y}|@option{--map-file}]
>          [@option{-L}|@option{--process-links}]
>          [@option{--ctf=}@var{section}]
>          [@option{--sframe=}@var{section}]
> @@ -2540,6 +2541,12 @@ for specification with @option{-b} or @option{-m}.
>  Display information for section @var{name}.  This option may be
>  specified multiple times.
>  
> +@item -Y
> +@itemx --map-file
> +Display global variable information. This option only works when the object
> +file is compiled with debug option. Useful to track the location and the
> +type of all global variables in the passed object file.

I don't think "map-file" properly expresses what the option does. "map-globals"
maybe? Or, if it's really only variables and not also functions,
"map-global-vars"?

I'm further unconvinced we want to consume a (relatively) precious single-letter
option here.

And then, is "compiled with debug option" precise enough? You rely on it being
Dwarf, yet more precisely Dwarf2 or newer?

> --- a/binutils/dwarf.c
> +++ b/binutils/dwarf.c
> @@ -1162,6 +1162,141 @@ display_block (unsigned char *data,
>    return data;
>  }
>  
> +static int
> +get_location_expression (int die_tag,
> +			 unsigned long attribute,
> +			 unsigned char * data,
> +			 unsigned int pointer_size,
> +			 unsigned int offset_size,
> +			 int dwarf_version,
> +			 uint64_t length,
> +			 uint64_t die_offset,
> +			 uint64_t cu_offset,
> +			 struct dwarf_section * section)
> +{
> +  unsigned op;
> +  uint64_t uvalue = 0;
> +  int64_t svalue;
> +  unsigned char *end = data + length;
> +  int need_frame_base = 0;
> +
> +  while (data < end)
> +    {
> +      op = *data++;
> +
> +      switch (op)
> +	{
> +	case DW_OP_addr:
> +	  SAFE_BYTE_GET_AND_INC (uvalue, data, pointer_size, end);
> +	  break;

Like you have it here, ...

> @@ -2432,6 +2567,53 @@ display_lang (uint64_t uvalue)
>      }
>  }
>  
> +static void
> +insert_element_in_list (enum dwarf_tag dw_tag,
> +		       enum dwarf_attribute dw_attr ATTRIBUTE_UNUSED,
> +		       uint64_t die_offset ATTRIBUTE_UNUSED,
> +		       uint64_t *uvalue ATTRIBUTE_UNUSED,
> +		       int64_t *svalue ATTRIBUTE_UNUSED,
> +		       const unsigned char *data ATTRIBUTE_UNUSED)
> +{
> +  /* TODO: Retrieve attributes information from
> +     below dwarf entries tag.  */
> +  switch (dw_tag)
> +    {
> +      /* Base type.  */
> +      case DW_TAG_base_type:

... please also align case labels here with the opening figure brace.
Then again, ...

> +	break;
> +      /* typedef.  */
> +      case DW_TAG_typedef:
> +	break;
> +      /* enumeration.  */
> +      case DW_TAG_enumerator:
> +	break;
> +      case DW_TAG_enumeration_type:
> +	break;
> +      /* Array type.  */
> +      case DW_TAG_subrange_type:
> +	break;
> +      case DW_TAG_array_type:
> +	break;
> +      /* Memnber type.  */
> +      case DW_TAG_member:
> +	break;
> +      /* Structure type.  */
> +      case DW_TAG_structure_type:
> +      /* Union type.  */
> +      case DW_TAG_union_type:
> +	break;
> +      case DW_TAG_const_type:
> +      case DW_TAG_volatile_type:
> +      case DW_TAG_pointer_type:
> +	break;
> +      case DW_TAG_variable:
> +	break;
> +      default:
> +	break;
> +    }
> +}

... what use is this when all cases merely have "break"?

> @@ -2448,7 +2630,10 @@ read_and_display_attr_value (unsigned long attribute,
>  			     struct dwarf_section *section,
>  			     struct cu_tu_set *this_set,
>  			     char delimiter,
> -			     int level)
> +			     int level,
> +			     int do_var_map,

bool?

> @@ -3487,7 +3810,10 @@ read_and_display_attr (unsigned long attribute,
>  		       int do_loc,
>  		       struct dwarf_section *section,
>  		       struct cu_tu_set *this_set,
> -		       int level)
> +		       int level,
> +		       int do_var_map,

Again.

> @@ -3750,6 +4077,8 @@ read_bases (abbrev_entry *   entry,
>     and we do not want to display anything to the user.
>     If do_types is TRUE, we are processing a .debug_types section instead of
>     a .debug_info section.
> +   If do_var_map is TRUE, we are processing a .debug_types section without
> +   displaying anything to the user yet.
>     The information displayed is restricted by the values in DWARF_START_DIE
>     and DWARF_CUTOFF_LEVEL.
>     Returns TRUE upon success.  Otherwise an error or warning message is
> @@ -3760,7 +4089,8 @@ process_debug_info (struct dwarf_section * section,
>  		    void *file,
>  		    enum dwarf_section_display_enum abbrev_sec,
>  		    bool do_loc,
> -		    bool do_types)
> +		    bool do_types,
> +		    bool do_var_map)

This is getting unwieldy: At call sites it is entirely impossible to tell
apart the three booleans. I think this wants switching to an unsigned int
flags parameter, with suitable #define-s to use at call and use sites.
(Such would probably want to be a separate prereq patch.)

> --- a/binutils/objdump.c
> +++ b/binutils/objdump.c
> @@ -138,6 +138,7 @@ static bool color_output = false;	/* --visualize-jumps=color.  */
>  static bool extended_color_output = false; /* --visualize-jumps=extended-color.  */
>  static int process_links = false;       /* --process-links.  */
>  static int show_all_symbols;            /* --show-all-symbols.  */
> +static bool dump_map_file;		/* -Y, --map-file.  */

Please use blank padding, like adjacent lines do.

> @@ -327,6 +328,8 @@ usage (FILE *stream, int status)
>    -WE --dwarf=do-not-use-debuginfod\n\
>                             When following links, do not query debuginfod servers\n"));
>  #endif
> +  fprintf (stream, _("\
> +  -Y, --map-file	   Display memory mapping of global variables\n"));

Same here.

Jan


More information about the Binutils mailing list