Re: [RFC-v5] Fix .text section offset for windows DLL (was Calling __stdcall functions in the inferior)

Pedro Alves
2012-12-13T11:49:58Z

On 12/13/2012 11:07 AM, Pedro Alves wrote:
>> > Pedro,
>> > you are right that my just committed patch does not
>> > fix the issue for windows gdbserver...
>> > So your idea to share the new function between gdb and gdbserver
>> > seemed indeed appealing, but when I looked at the new function pe_text_section_offset
>> > it doesn't seem so easy to me to remove bfd dependency...

It actually looks quite easy to me.

>> >
>> > I will try to come up with a fix for gdbserver,
>> > but I am not sure it will be soon...
> Thanks.

> CORE_ADDR
> pe_text_section_offset (struct bfd *abfd)
>
> {
> unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
> unsigned long export_rva, export_size, nsections, secptr, expptr;
> unsigned long exp_funcbase;
> unsigned char *expdata, *erva;
> unsigned long name_rvas, ordinals, nexp, ordbase;
> char *dll_name;
> int is_pe64 = 0;
> int is_pe32 = 0;
> char const *target;
>
> if (!abfd)
> return DEFAULT_COFF_PE_TEXT_SECTION_OFFSET;
>
> target = bfd_get_target (abfd);
>
> is_pe64 = (strcmp (target, "pe-x86-64") == 0
> || strcmp (target, "pei-x86-64") == 0);
> is_pe32 = (strcmp (target, "pe-i386") == 0
> || strcmp (target, "pei-i386") == 0
> || strcmp (target, "pe-arm-wince-little") == 0
> || strcmp (target, "pei-arm-wince-little") == 0);
>
> if (!is_pe32 && !is_pe64)
> {
> /* This is not a recognized PE format file. Abort now, because
> the code is untested on anything else. *FIXME* test on
> further architectures and loosen or remove this test. */
> return DEFAULT_COFF_PE_TEXT_SECTION_OFFSET;
> }

Just drop all these is_pe64/is_pe32 checks. They're not really necessary.

> /* Get pe_header, optional header and numbers of sections. */
> pe_header_offset = pe_get32 (abfd, 0x3c);
> opthdr_ofs = pe_header_offset + 4 + 20;
> nsections = pe_get16 (abfd, pe_header_offset + 4 + 2);
> secptr = (pe_header_offset + 4 + 20 +
> pe_get16 (abfd, pe_header_offset + 4 + 16));
>
> /* Get the rva and size of the export section. */
> for (i = 0; i < nsections; i++)
> {
> char sname[8];
> unsigned long secptr1 = secptr + 40 * i;
> unsigned long vaddr = pe_get32 (abfd, secptr1 + 12);
>
> bfd_seek (abfd, (file_ptr) secptr1, SEEK_SET);
> bfd_bread (sname, (bfd_size_type) 8, abfd);
> if (strcmp (sname, ".text") == 0)
> return vaddr;
> }

All the bfd_seek/bfd_bread calls can be trivially replaced
by the equivalent Win32 file handling functions -- note how
win32_add_one_solib already has a handy handle open.
We can just make handle_load_dll not add the 0x1000 itself,
but leave win32_add_one_solib to do it instead. Alternatively, to
make the code portable and usable from GDB, use fopen/fread, etc.
instead.

> return DEFAULT_COFF_PE_TEXT_SECTION_OFFSET;
> }

--
Pedro Alves