kong.internal.image_reflect

proxy generatator - maps 32/64 bit backends and endian conversion

Template : reflect

example:

mixin (reflect!("Ehdr", ["Elf32_Ehdr", "Elf64_Ehdr"],
"e_type",
"e_machine",
"e_version",

etc...

));


Generated code:

    struct Ehdr
    {
        union { 
            Elf32_Ehdr* __Elf32_Ehdr__;
            Elf64_Ehdr* __Elf64_Ehdr__;

            void* address; 
            void* __R3FL3CTtyp31d__; // used by image_interface.link to identify proxy structs.
        }

        short type;
        extern(C) void* function(void* dst, void* src, size_t n) copy;

        static const ushort[][] offset = [[Elf32_Ehdr.e_type.offsetof, ...], [Elf64_Ehdr.e_type.offsetof, ...]];
        static const ushort[][] size   = [[Elf32_Ehdr.e_type.sizeof, ...], [Elf64_Ehdr.e_type.sizeof, ...]]; 

        enum { e_type, e_machine, ... };

        uint64_t opIndex(int i)
        {
            uint64_t val;

            copy(&val, address + offset[type][i], size[type][i]);
            return val;
        }

        void opIndexAssign(uint64_t val, int i)
            { copy(address + offset[type][i], &val, size[type][i]); }
    
        ushort tsize()
            { return t_size[type]; }
    }
}

Common case intialization:

* image_interface.link and related normally take care of this
// endian swap
extern (C)
void*
swpcpy(void* dst, void* src, size_t n)
{
    for (int i = 0; i < n; ++i)
        (cast(ubyte*)dst)[i] = (cast(ubyte*)src)[n - i - 1];

    return dst;
}


void
reflect_init(alias a)(int type, bool endian)
{
    a.type    = type;
    a.address = xxx;

    if (endian)
         a.copy = cast(copy_callback) &swpcpy;
    else a.copy = cast(copy_callback) &memcpy;
}