From: Andrew Pinski <pinskia@gmail.com>
To: David Albert <davidbalbert@gmail.com>
Cc: Joel Brobecker <brobecker@adacore.com>,
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 05:06:00 -0000 [thread overview]
Message-ID: <CA+=Sn1n1JHqzozYyS2u4M7gt1TuaQBGL9vC6Cf0ERx3PePnmjA@mail.gmail.com> (raw)
In-Reply-To: <CAKYxTUYa4Bx+GjChG97LH3w1a3jX3x3ejuzJf9tQfc4mL0HtnA@mail.gmail.com>
On Sun, Nov 18, 2012 at 9:03 PM, David Albert <davidbalbert@gmail.com> wrote:
> On Sun, Nov 18, 2012 at 11:47 PM, Joel Brobecker <brobecker@adacore.com> wrote:
>> 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.
>
> Thanks, Joel. I'll do this in the morning. If this patch gets pulled
> into binutils, what's the process for getting it in GDB? Does the
> latest BFD just get merged into GDB every now and then or does it have
> to be shepherded through by someone?
Right now gdb and binutils share the same cvs repo so there is nothing
special to do.
Thanks,
Andrew
>
> Thanks,
> -David
>
>>
>>
>>>
>>> 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
next prev parent reply other threads:[~2012-11-19 5:06 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
2012-11-19 5:03 ` David Albert
2012-11-19 5:06 ` Andrew Pinski [this message]
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='CA+=Sn1n1JHqzozYyS2u4M7gt1TuaQBGL9vC6Cf0ERx3PePnmjA@mail.gmail.com' \
--to=pinskia@gmail.com \
--cc=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