Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Joel Brobecker <brobecker@adacore.com>
To: David Albert <davidbalbert@gmail.com>
Cc: gdb-patches <gdb-patches@sourceware.org>
Subject: Re: [PATCH] Scan for Mach-O start address in LC_MAIN and properly check bfd_mach_o_scan_start_address's return value
Date: Mon, 19 Nov 2012 04:48:00 -0000	[thread overview]
Message-ID: <20121119044750.GB9964@adacore.com> (raw)
In-Reply-To: <CAKYxTUadUr9GUqMHAA3JdASDfwuEFzS9txT+aXQSQjro+iwx8w@mail.gmail.com>

On Sun, Nov 18, 2012 at 11:13:21PM -0500, David Albert wrote:
> Last week there was a change comitted to GDB that added support for
> the new Mach-O load commands in OS X 10.8. I have two related changes
> that I've included in a patch below.
> 
> 1) On December 7th of last year, bfd_mach_o_scan_start_address was
> changed to return a bfd_boolean, but no change was made to the code
> that checks its return value in bfd_mach_o_scan. This means that
> bfd_mach_o_scan always assumes that bfd_mach_o_scan_start_address
> succeeds. This patch fixes that.
> 
> 2) The start address can now be found in LC_MAIN in addition to
> LC_THREAD and LC_UNIXTHREAD. I've updated
> bfd_mach_o_scan_start_address to reflect this. I moved the call to
> bfd_mach_o_flatten_sections to before bfd_mach_o_scan_start_address,
> because the code that gets the start address from LC_MAIN relies on
> nsects being set.
> 
> I've never submitted a patch to GDB before, so please let me know if
> there are things I can fix. I also have a few notes:
> 
> - I used the latest version of Apple's GDB 6.3 fork (gdb-1822) as a
> reference for some of my research. The changes I made are quite small
> (most of the patch consists of placing a block of existing code inside
> an if statement), but parts of the patch are similar to what I found
> in Apple's fork. The code is simple enough that there are not really
> many ways to solve the problem, but I want to make sure there aren't
> issues with copyright or licensing.
> 
> - The one thing I'm not sure of is line 4047 which reads `if
> (mdata->nsects > 1)`. This is the same check found in Apple's GDB
> fork, however it's unclear why we'd need two or more sections, given
> that we only use the first section to calculate the start address. I
> thought about changing it, but I wanted to get the opinion of someone
> who knows more about Mach-O than I do.
> 
> - I didn't run the test suite because it wasn't clear what parts of
> the suite I should run. I tested it manually and didn't find any
> regressions.

Hi David,

It's nice to see people interested in hacking on Darwin. Changes
in bfd/ should be sent to binutils, however. You can also Cc:
Tristan Gingold, to make sure you catch his attention.


> 
> Best,
> -David
> 
> diff --git a/bfd/ChangeLog b/bfd/ChangeLog
> index c25ceb9..4e5ff3a 100644
> --- a/bfd/ChangeLog
> +++ b/bfd/ChangeLog
> @@ -1,3 +1,10 @@
> +2012-11-18  David Albert  <davidbalbert@gmail.com>
> +
> +	* mach-o.c (bfd_mach_o_scan): Properly check return value of
> +	bfd_mach_o_scan_start_address.
> +	(bfd_mach_o_scan_start_address): Also search for start address in
> +	BFD_MACH_O_LC_MAIN.
> +
>  2012-11-16  Joey Ye  <joey.ye@arm.com>
> 
>  	* elf32-arm.c (elf32_arm_final_link_relocate,
> diff --git a/bfd/mach-o.c b/bfd/mach-o.c
> index e44cf6d..4546540 100644
> --- a/bfd/mach-o.c
> +++ b/bfd/mach-o.c
> @@ -3970,66 +3970,89 @@ bfd_mach_o_scan_start_address (bfd *abfd)
>  {
>    bfd_mach_o_data_struct *mdata = bfd_mach_o_get_data (abfd);
>    bfd_mach_o_thread_command *cmd = NULL;
> +  bfd_mach_o_main_command *main_cmd = NULL;
>    unsigned long i;
> 
>    for (i = 0; i < mdata->header.ncmds; i++)
> -    if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
> -        (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
> -      {
> -        cmd = &mdata->commands[i].command.thread;
> -        break;
> -      }
> -
> -  if (cmd == NULL)
> -    return FALSE;
> +    {
> +      if ((mdata->commands[i].type == BFD_MACH_O_LC_THREAD) ||
> +          (mdata->commands[i].type == BFD_MACH_O_LC_UNIXTHREAD))
> +        {
> +          cmd = &mdata->commands[i].command.thread;
> +          break;
> +        }
> +      else if (mdata->commands[i].type == BFD_MACH_O_LC_MAIN)
> +        {
> +          main_cmd = &mdata->commands[i].command.main;
> +          break;
> +        }
> +    }
> 
> -  /* FIXME: create a subtarget hook ?  */
> -  for (i = 0; i < cmd->nflavours; i++)
> +  if (cmd)
>      {
> -      if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
> -	  && (cmd->flavours[i].flavour
> -	      == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
> -	{
> -	  unsigned char buf[4];
> +      /* FIXME: create a subtarget hook ?  */
> +      for (i = 0; i < cmd->nflavours; i++)
> +        {
> +          if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_I386)
> +              && (cmd->flavours[i].flavour
> +                  == (unsigned long) BFD_MACH_O_x86_THREAD_STATE32))
> +            {
> +              unsigned char buf[4];
> 
> -	  if (bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET) != 0
> -              || bfd_bread (buf, 4, abfd) != 4)
> -	    return FALSE;
> +              if (bfd_seek (abfd, cmd->flavours[i].offset + 40, SEEK_SET) != 0
> +                  || bfd_bread (buf, 4, abfd) != 4)
> +                return FALSE;
> 
> -	  abfd->start_address = bfd_h_get_32 (abfd, buf);
> -	}
> -      else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
> -	       && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE))
> -	{
> -	  unsigned char buf[4];
> +              abfd->start_address = bfd_h_get_32 (abfd, buf);
> +            }
> +          else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC)
> +                   && (cmd->flavours[i].flavour ==
> BFD_MACH_O_PPC_THREAD_STATE))
> +            {
> +              unsigned char buf[4];
> 
> -	  if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
> -              || bfd_bread (buf, 4, abfd) != 4)
> -	    return FALSE;
> +              if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
> +                  || bfd_bread (buf, 4, abfd) != 4)
> +                return FALSE;
> 
> -	  abfd->start_address = bfd_h_get_32 (abfd, buf);
> -	}
> -      else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
> -               && (cmd->flavours[i].flavour == BFD_MACH_O_PPC_THREAD_STATE64))
> -        {
> -          unsigned char buf[8];
> +              abfd->start_address = bfd_h_get_32 (abfd, buf);
> +            }
> +          else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_POWERPC_64)
> +                   && (cmd->flavours[i].flavour ==
> BFD_MACH_O_PPC_THREAD_STATE64))
> +            {
> +              unsigned char buf[8];
> 
> -          if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
> -              || bfd_bread (buf, 8, abfd) != 8)
> -            return FALSE;
> +              if (bfd_seek (abfd, cmd->flavours[i].offset + 0, SEEK_SET) != 0
> +                  || bfd_bread (buf, 8, abfd) != 8)
> +                return FALSE;
> 
> -          abfd->start_address = bfd_h_get_64 (abfd, buf);
> -        }
> -      else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
> -               && (cmd->flavours[i].flavour == BFD_MACH_O_x86_THREAD_STATE64))
> -        {
> -          unsigned char buf[8];
> +              abfd->start_address = bfd_h_get_64 (abfd, buf);
> +            }
> +          else if ((mdata->header.cputype == BFD_MACH_O_CPU_TYPE_X86_64)
> +                   && (cmd->flavours[i].flavour ==
> BFD_MACH_O_x86_THREAD_STATE64))
> +            {
> +              unsigned char buf[8];
> 
> -          if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8),
> SEEK_SET) != 0
> -              || bfd_bread (buf, 8, abfd) != 8)
> -            return FALSE;
> +              if (bfd_seek (abfd, cmd->flavours[i].offset + (16 * 8),
> SEEK_SET) != 0
> +                  || bfd_bread (buf, 8, abfd) != 8)
> +                return FALSE;
> 
> -          abfd->start_address = bfd_h_get_64 (abfd, buf);
> +              abfd->start_address = bfd_h_get_64 (abfd, buf);
> +            }
> +        }
> +    }
> +  else if (main_cmd)
> +    {
> +      bfd_vma text_address = 0;
> +
> +      if (mdata->nsects > 1)
> +        {
> +          bfd_mach_o_section *text_sect = mdata->sections[0];
> +          if (text_sect)
> +            {
> +              text_address = text_sect->addr - text_sect->offset;
> +              abfd->start_address = main_cmd->entryoff + text_address;
> +              return TRUE;
> +            }
>          }
>      }
> 
> @@ -4121,10 +4144,11 @@ bfd_mach_o_scan (bfd *abfd,
>  	}
>      }
> 
> -  if (bfd_mach_o_scan_start_address (abfd) < 0)
> +  bfd_mach_o_flatten_sections (abfd);
> +
> +  if (!bfd_mach_o_scan_start_address (abfd))
>      return FALSE;
> 
> -  bfd_mach_o_flatten_sections (abfd);
>    return TRUE;
>  }

-- 
Joel


  reply	other threads:[~2012-11-19  4:48 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-19  4:13 David Albert
2012-11-19  4:48 ` Joel Brobecker [this message]
2012-11-19  5:03   ` David Albert
2012-11-19  5:06     ` Andrew Pinski
2012-11-19  5:18       ` David Albert
2012-11-19 16:28 ` Tom Tromey
2012-11-23 19:58   ` David Albert

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=20121119044750.GB9964@adacore.com \
    --to=brobecker@adacore.com \
    --cc=davidbalbert@gmail.com \
    --cc=gdb-patches@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