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

Tom Spink tspink at gmail.com
Sun Mar 27 12:23:11 EDT 2011


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
>
>



-- 
Tom Spink


More information about the Mono-devel-list mailing list