[Mono-dev] Howto Marshal IntPtr to Elf32_Phdr[] ?

Quandary quandary82 at hailmail.net
Mon Mar 28 08:01:13 EDT 2011


So what you're saying is that

System.Runtime.InteropServices.UnmanagedType.LPStructArray
is inexistant, so there can be no
[MarshalAs(UnmanagedType.LPStructArray)]

Basically, one could add a property at the end and rename the IntPtr 
variable ?
Or would that shift the offsets ?

In which case the next question would be whether there exists a

[MarshalAs(UnmanagedType.Ignore)]

attribute that I could prefix the property with.


Am 28.03.2011 09:29, schrieb Tom Spink:
> Hi,
>
>> Still I was hoping for a less-hackish method via MarshalAs.
> Unfortunately, MarshalAs almost helps you out, by giving you a
> SizeParamIndex property, to indicate to the marshaller which parameter
> to get size information from when marshalling an LPArray.  But - this
> is only for methods (that have a signature with a parameter indicating
> the size of the array), not for structures, so it doesn't really help.
>
>> sounds awfully x86 specific, maybe even x86-32 specific
> Well, it's just pointer arithmetic - your not actually manipulating
> memory here, or doing anything clever at all.  You're just reading
> from a certain location.  It's up to the API how it presents the
> memory - in this case, a C-style array, which is compiler specific not
> platform specific.
>
>> [MarshalAs(UnmanagedType.LPStr)]
> Good point on marshalling your string, with LPStr.  I was going to
> mention it - but forgot.
>
>
> On 27 March 2011 22:20, Quandary<quandary82 at hailmail.net>  wrote:
>> Hi Tom,
>>
>> Thank you, that works.
>>
>> Still I was hoping for a less-hackish method via MarshalAs.
>>
>> address + j * sizeof(mystruct_t)
>> sounds awfully x86 specific, maybe even x86-32 specific
>> But then again, so is struct Elf32_Phdr the way I did it.
>>
>>
>> As a side-note to other potential users:
>> If I/you apply
>> [MarshalAs(UnmanagedType.LPStr)]
>> to
>> public System.IntPtr dlpi_name;
>> and instead call it
>> public string dlpi_name;
>> then I needn't marshall it in the callback.
>>
>>
>> Kind regards
>>
>> Stefan
>>
>>
>> On 03/27/2011 06:23 PM, Tom Spink wrote:
>>> Hi Quandry,
>>>
>>> You've almost got it - you just need to do a bit of pointer arithmetic.
>>>
>>> In your for loop, you've got this:
>>>
>>> ///
>>> for (j = 0; j<  info.dlpi_phnum; j++)
>>>              Console.WriteLine("\t\t header {0}: address={1}\n", j, 22);
>>> ///
>>>
>>> Not sure what that 22 is... but if you do this:
>>>
>>> ///
>>> for (int j = 0; j<  info.dlpi_phnum; j++) {
>>>      var ptr = new IntPtr(info.dlpi_phdr.ToInt64() + (j *
>>> Marshal.SizeOf(typeof(Elf32_Phdr))));
>>>      var hdr = (Elf32_Phdr)Marshal.PtrToStructure(ptr, typeof(Elf32_Phdr));
>>>
>>>      Console.WriteLine("\t\t header {0}: address={1}: offset={2}\n", j,
>>> info.dlpi_phdr, hdr.p_offset);
>>> }
>>> ///
>>>
>>> Inside your for loop, you've now got the 'hdr' variable, which is the
>>> Elf32_Phdr struct of the 'current element' in the array.  This works
>>> because info.dlpi_phdr is a pointer to the base address of the array -
>>> where the array is just a sequential list of Elf32_Phdr structures.
>>> So, by taking the base address, then adding on the index into the
>>> array (multiplied by the size of the array's element type), you'll get
>>> the base address of that particular element.  Once you've got this
>>> base address, all you have to do is marshal that pointer, to the right
>>> structure type.
>>>
>>> Also, make sure you mark your structures with the following attribute:
>>>
>>> [StructLayout(LayoutKind.Sequential)]
>>>
>>> Hope this helps!
>>>
>>> -- Tom
>>>
>>> On 27 March 2011 16:43, Quandary<quandary82 at hailmail.net>  wrote:
>>>> Hi everyone,
>>>>
>>>> I have a problem with dl_iterate_phdr.
>>>> (man 3 dl_iterate_phdr)
>>>>
>>>> You find the (till now unanswered) question on stackoverflow, I'm not
>>>> inclined to retype everything here again, so below the link:
>>>> http://stackoverflow.com/questions/5447282/c-howto-marshal-intptr-to-an-array-of-struct
>>>>
>>>> In a nutshell, the problem is the struct dl_phdr_info you see below.
>>>>
>>>> It seems I need to Marshal
>>>> public System.IntPtr dlpi_phdr;
>>>> to
>>>> public Elf32_Phdr[] dlpi_phdr;
>>>> somehow.
>>>>
>>>> Or maybe I did translate it to managed code the wrong way.
>>>> Can anybody have a look at it ?
>>>>
>>>> All necessary code/structs to get the sample running you find on the
>>>> stackoverflow link.
>>>>
>>>>
>>>> Here's the C struct:
>>>>
>>>>   struct dl_phdr_info {
>>>>             ElfW(Addr)        dlpi_addr;  /* Base address of object */
>>>>             const char       *dlpi_name;  /* (Null-terminated) name of
>>>>                                              object */
>>>>             const ElfW(Phdr) *dlpi_phdr;  /* Pointer to array of
>>>>                                              ELF program headers
>>>>                                              for this object */
>>>>             ElfW(Half)        dlpi_phnum; /* # of items in dlpi_phdr */
>>>>         };
>>>>
>>>> Here's my C# translation of the above struct:
>>>>
>>>>    public struct dl_phdr_info
>>>>      {
>>>>          public System.UInt32 dlpi_addr; /* Base address of object */
>>>>
>>>>          // TODO: String, MarshalAs Pointer
>>>>          public System.IntPtr dlpi_name;  /* (Null-terminated) name of
>>>> object*/
>>>>
>>>>          /* Pointer to array of ELF program headers for this object */
>>>>          public System.IntPtr dlpi_phdr; // Hackish, cannot read it, but then
>>>> at least the rest works
>>>>
>>>>          // This way it throws an exception at runtime.
>>>>
>>>> //[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStruct)]
>>>>          //public Elf32_Phdr[] dlpi_phdr;
>>>>
>>>>          public System.UInt16  dlpi_phnum; /* # of items in 'dlpi_phdr' */
>>>>      }
>>>>
>>>>
>>>> _______________________________________________
>>>> Mono-devel-list mailing list
>>>> Mono-devel-list at lists.ximian.com
>>>> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>>>>
>>>>
>>>
>>
>
>



More information about the Mono-devel-list mailing list