public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Alan Modra <amodra@gmail.com>
To: binutils@sourceware.org
Subject: objdump --disassemble=sym peculiarities
Date: Tue, 2 Apr 2024 09:14:23 +1030	[thread overview]
Message-ID: <Zgs4x0UQEuxblziu@squeak.grove.modra.org> (raw)

Given this testcase:
 .text
 mov $x1,%eax
f1:
 mov $f1,%eax
 .type f1,@function
 .size f1,.-f1

 mov $x2,%eax
f2:
 mov $f2,%eax
 .type f2,@function
 .size f2,.-f2+0x1000 #bad size

objdump --reloc --disassemble=f1 prints
00000000 <f1-0x5>:
   0:	b8 00 00 00 00       	mov    $0x0,%eax

and objdump --reloc --disassemble=f2 prints
0000000f <f2>:
   f:	b8 0f 00 00 00       	mov    $0xf,%eax
			10: R_386_32	.text

It seems for f1 we get the insn before f1 and no reloc whereas, post
159daa36fa, f2 is disassembled correctly.  Some analysis says that
find_symbol_for_address may return a symbol past the current address,
and reloc skipping is broken.  Fix both of these problems.

	* objdump.c (disassemble_jumps, disassemble_bytes): Replace
        relppp with relpp, ie. don't update caller's rel_pp.  Adjust
        calls.
	(disassemble_section): Skip over relocs inside loop rather
        than before loop.  Revert 7e538762c2c1.  If given a symbol,
	don't start disassembling until its address is reached.
	Correct end of function calculation.

diff --git a/binutils/objdump.c b/binutils/objdump.c
index 8293387558f..68da543e905 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -2946,7 +2946,7 @@ disassemble_jumps (struct disassemble_info * inf,
 		   bfd_vma                   start_offset,
 		   bfd_vma                   stop_offset,
 		   bfd_vma		     rel_offset,
-		   arelent ***               relppp,
+		   arelent **                relpp,
 		   arelent **                relppend)
 {
   struct objdump_disasm_info *aux;
@@ -2988,11 +2988,11 @@ disassemble_jumps (struct disassemble_info * inf,
       if (inf->disassembler_needs_relocs
 	  && (bfd_get_file_flags (aux->abfd) & EXEC_P) == 0
 	  && (bfd_get_file_flags (aux->abfd) & DYNAMIC) == 0
-	  && *relppp < relppend)
+	  && relpp < relppend)
 	{
 	  bfd_signed_vma distance_to_rel;
 
-	  distance_to_rel = (**relppp)->address - (rel_offset + addr_offset);
+	  distance_to_rel = (*relpp)->address - (rel_offset + addr_offset);
 
 	  /* Check to see if the current reloc is associated with
 	     the instruction that we are about to disassemble.  */
@@ -3205,7 +3205,7 @@ disassemble_bytes (struct disassemble_info *inf,
 		   bfd_vma start_offset,
 		   bfd_vma stop_offset,
 		   bfd_vma rel_offset,
-		   arelent ***relppp,
+		   arelent **relpp,
 		   arelent **relppend)
 {
   struct objdump_disasm_info *aux;
@@ -3377,13 +3377,13 @@ disassemble_bytes (struct disassemble_info *inf,
 	      if (inf->disassembler_needs_relocs
 		  && (bfd_get_file_flags (aux->abfd) & EXEC_P) == 0
 		  && (bfd_get_file_flags (aux->abfd) & DYNAMIC) == 0
-		  && *relppp < relppend)
+		  && relpp < relppend)
 		{
 		  bfd_signed_vma distance_to_rel;
 		  int max_reloc_offset
 		    = aux->abfd->arch_info->max_reloc_offset_into_insn;
 
-		  distance_to_rel = ((**relppp)->address - rel_offset
+		  distance_to_rel = ((*relpp)->address - rel_offset
 				     - addr_offset);
 
 		  insn_size = 0;
@@ -3427,7 +3427,7 @@ disassemble_bytes (struct disassemble_info *inf,
 			  && distance_to_rel < insn_size / (int) opb))
 		    {
 		      inf->flags |= INSN_HAS_RELOC;
-		      aux->reloc = **relppp;
+		      aux->reloc = *relpp;
 		    }
 		}
 
@@ -3600,14 +3600,14 @@ disassemble_bytes (struct disassemble_info *inf,
 	    need_nl = true;
 	}
 
-      while ((*relppp) < relppend
-	     && (**relppp)->address < rel_offset + addr_offset + octets / opb)
+      while (relpp < relppend
+	     && (*relpp)->address < rel_offset + addr_offset + octets / opb)
 	{
 	  if (dump_reloc_info || dump_dynamic_reloc_info)
 	    {
 	      arelent *q;
 
-	      q = **relppp;
+	      q = *relpp;
 
 	      if (wide_output)
 		putchar ('\t');
@@ -3665,7 +3665,7 @@ disassemble_bytes (struct disassemble_info *inf,
 	      printf ("\n");
 	      need_nl = false;
 	    }
-	  ++(*relppp);
+	  ++relpp;
 	}
 
       if (need_nl)
@@ -3809,12 +3809,6 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
   if (sorted_symcount > 1)
     qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
 
-  /* Skip over the relocs belonging to addresses below the
-     start address.  */
-  while (rel_pp < rel_ppend
-	 && (*rel_pp)->address < rel_offset + addr_offset)
-    ++rel_pp;
-
   printf (_("\nDisassembly of section %s:\n"), sanitize_string (section->name));
 
   /* Find the nearest symbol forwards from our current position.  */
@@ -3846,6 +3840,12 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
       bfd_vma nextstop_offset;
       bool insns;
 
+      /* Skip over the relocs belonging to addresses below the
+	 start address.  */
+      while (rel_pp < rel_ppend
+	     && (*rel_pp)->address < rel_offset + addr_offset)
+	++rel_pp;
+
       addr = section->vma + addr_offset;
       addr = ((addr & ((sign_adjust << 1) - 1)) ^ sign_adjust) - sign_adjust;
 
@@ -3912,17 +3912,11 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
 
 	      /* We are not currently printing.  Check to see
 		 if the current symbol matches the requested symbol.  */
-	      if (streq (name, paux->symbol))
+	      if (streq (name, paux->symbol)
+		  && bfd_asymbol_value (sym) <= addr)
 		{
 		  do_print = true;
 
-		  /* Skip over the relocs belonging to addresses below the
-		     symbol address.  */
-		  const bfd_vma sym_offset = bfd_asymbol_value (sym) - section->vma;
-		  while (rel_pp < rel_ppend &&
-		   (*rel_pp)->address - rel_offset < sym_offset)
-			  ++rel_pp;
-
 		  loop_until = next_sym;
 		  if (sym->flags & BSF_FUNCTION)
 		    {
@@ -3932,13 +3926,14 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
 			{
 			  bfd_size_type fsize =
 			    ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
-			  if (addr_offset + fsize > addr_offset
-			      && addr_offset + fsize <= stop_offset)
+			  bfd_vma fend =
+			    bfd_asymbol_value (sym) - section->vma + fsize;
+			  if (fend > addr_offset && fend <= stop_offset)
 			    {
 			      /* Sym is a function symbol with a valid
 				 size associated with it.  Disassemble
 				 to the end of the function.  */
-			      stop_offset = addr_offset + fsize;
+			      stop_offset = fend;
 			      loop_until = stop_offset_reached;
 			    }
 			}
@@ -4046,11 +4041,9 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
 	      objdump_print_symname (abfd, &di, sym);
 
 	      /* Fetch jump information.  */
-	      detected_jumps = disassemble_jumps
-		(pinfo, paux->disassemble_fn,
-		 addr_offset, nextstop_offset,
-		 rel_offset, &rel_pp, rel_ppend);
-
+	      detected_jumps = disassemble_jumps (pinfo, paux->disassemble_fn,
+						  addr_offset, nextstop_offset,
+						  rel_offset, rel_pp, rel_ppend);
 	      /* Free symbol name.  */
 	      free (sf.buffer);
 	    }
@@ -4058,7 +4051,7 @@ disassemble_section (bfd *abfd, asection *section, void *inf)
 	  /* Add jumps to output.  */
 	  disassemble_bytes (pinfo, paux->disassemble_fn, insns, data,
 			     addr_offset, nextstop_offset,
-			     rel_offset, &rel_pp, rel_ppend);
+			     rel_offset, rel_pp, rel_ppend);
 
 	  /* Free jumps.  */
 	  while (detected_jumps)

-- 
Alan Modra
Australia Development Lab, IBM

                 reply	other threads:[~2024-04-01 22:44 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Zgs4x0UQEuxblziu@squeak.grove.modra.org \
    --to=amodra@gmail.com \
    --cc=binutils@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).