/*!
    @page jitpage JIT and special case DWARF

    @tableofcontents html 2

    @section noobject Reading DWARF not in an object file

    If the DWARF you work with is in standard object
    files (Elf, PE, MacOS) then you can ignore
    this section entirely. All that this section
    describes is used, but it's already done for
    you in functions in the library: @see dwarf_init_path
    @link dwarf_init_path_dl @endlink @see dwarf_init_b and
    @see dwarf_finish .

    This section describes how to use calls
    @see dwarf_object_init_b @see dwarf_object_finish .

    These functions are useful if someone is doing
    just-in-time
    compilation, and someone working on the code
    wants to debug this on-the-fly code in a situation
    where nothing can be written to disc, but DWARF
    can be constructed in memory.

    For a simple example of this with DWARF in
    local arrays
    @see jitreader

    But the @e libdwarf feature can be useful in a variety of
    circumstances.

    For example, the DWARF data were kept
    in simple files of bytes on the internet.
    Or on the local net. Or if files can
    be written locally each section could be kept
    in a simple stream of bytes in the local
    file system.

    Another example is a non-standard file system,
    or file format, with the intent of obfuscating
    the file or the DWARF.

    For this to work the code generator must generate standard DWARF.

    Overall the idea is a simple one: You write
    a small handful of functions and supply
    function pointers and code implementing the
    functions.  These are part of your application
    or library, not part of @e libdwarf.
    Your code accesses the data in whatever way
    applies and you write code that provides
    the interfaces so standard @e libdwarf can access
    your DWARF content.

    You set up a little bit of data with that code
    (described below)
    and then you have essentially written the
    dwarf_init_path equivalent and you can access
    compilation units, line tables etc and
    the standard @e libdwarf function calls simply work.

    Data you need to create involves the following types.
    What follows describes how to fill them in
    and how to make them work for you.

    @code
    typedef struct Dwarf_Obj_Access_Interface_a_s
        Dwarf_Obj_Access_Interface_a;
    struct Dwarf_Obj_Access_Interface_a_s {
        void                             *ai_object;
        const Dwarf_Obj_Access_Methods_a *ai_methods;
    };

    typedef struct Dwarf_Obj_Access_Methods_a_s
        Dwarf_Obj_Access_Methods_a
    struct Dwarf_Obj_Access_Methods_a_s {
        int    (*om_get_section_info)(void* obj,
            Dwarf_Half                  section_index,
            Dwarf_Obj_Access_Section_a* return_section,
            int                       * error);
        Dwarf_Small      (*om_get_byte_order)(void* obj);
        Dwarf_Small      (*om_get_length_size)(void* obj);
        Dwarf_Small      (*om_get_pointer_size)(void* obj);
        Dwarf_Unsigned   (*om_get_filesize)(void* obj);
        Dwarf_Unsigned   (*om_get_section_count)(void* obj);
        int              (*om_load_section)(void* obj,
            Dwarf_Half    section_index,
            Dwarf_Small** return_data,
            int         * error);
        int              (*om_relocate_a_section)(void* obj,
            Dwarf_Half  section_index,
            Dwarf_Debug dbg,
            int        *error);
    };

    typedef struct Dwarf_Obj_Access_Section_a_s
        Dwarf_Obj_Access_Section_a
    struct Dwarf_Obj_Access_Section_a_s {
        const char*    as_name;
        Dwarf_Unsigned as_type;
        Dwarf_Unsigned as_flags;
        Dwarf_Addr     as_addr;
        Dwarf_Unsigned as_offset;
        Dwarf_Unsigned as_size;
        Dwarf_Unsigned as_link;
        Dwarf_Unsigned as_info;
        Dwarf_Unsigned as_addralign;
        Dwarf_Unsigned as_entrysize;
    };
    @endcode

    @subsection objaccessinterface Describing the Interface

    @b struct struct Dwarf_Obj_Access_Interface_a_s

    Your code must create and fill in this struct's two
    pointer members.  Libdwarf needs these to access
    your DWARF data.
    You pass a pointer to this filled-in struct
    to @b dwarf_object_init_b.  When it is time
    to conclude all access to the created Dwarf_Debug
    call @b dwarf_object_finish .
    Any allocations you made in setting these things up
    you must then free after calling @b dwarf_object_finish .

    @b ai_object

    Allocate a local struct (@e libdwarf will not
    touch this struct and will not know
    anything of its contents). You will need one
    of these for each Dwarf_Debug you open.
    Put a pointer to this into ai_object.
    Then fill in all the data you need to access information
    you will pass back via the ai_methods functions.
    In the description of the methods functions
    described later here, this pointer
    is named @b obj .

    @b ai_methods

    Usually you allocate a static structure
    and fill it in with function pointers
    (to functions you write).
    Then put a pointer to the static structure
    into this field.

    @subsection objaccesssection Describing A Section

    @b Dwarf_Obj_Access_Section_a:

    The set of fields here is a set that is sufficient
    to describe a single object section to @e libdwarf.
    Your implementation of a @b om_get_section_info
    must simply fill in a few fields (leaving most zero)
    for @e libdwarf for the section indexed.
    The fields here are standard Elf,
    and for most you can just fill in the value zero.
    For section index zero as_name should be set to
    an empty string (see below about section index numbers).

    @b as_name: Here you set a section name via the pointer.
    The section names must be names as defined in the DWARF
    standard, so if such do not appear in your data
    you have to create the strings yourself.

    @b as_type: Just fill in zero.

    @b as_flags: Just fill in zero.

    @b as_addr: Fill in the address, in local memory,
    where the bytes of the section are.

    @b as_offset: Just fill in zero.

    @b as_size: Fill in the size, in bytes,
    of the section you are telling @e libdwarf about.

    @b as_link: Just fill in zero.

    @b as_info: Just fill in zero.

    @b as_addralign:Just fill in zero.

    @b as_entrysize: Just fill in one.

    @subsection objaccessmethods Function Pointers

    @b struct Dwarf_Obj_Access_Methods_a_s:

    The functions @e libdwarf needs to access object data
    are declared here.
    Usually the struct is statically defined
    and the function pointers are set at
    compile time.
    You must implement these functions based on
    your knowledge of how the actual data is
    represented and where to get it.

    Each has a first-parameter of @b obj
    which is a struct you define to hold data you need
    to implement this set of functions. You refer to
    it
    When @e libdwarf calls your set of functions (these
    described now) it passes the ai_object pointer
    you provided to these functions as @b obj parameter .

    This is the final part of your work for @e libdwarf.
    In the source file with your code you will be
    allocating data, making a provision for
    an array (real or conceptual) for per-section data,
    and returning values @e libdwarf needs.
    Note that the section array should include
    an index zero with all zero field values.
    That means interesting fields start with index one.
    This special case of index zero
    Elf is required and matches the standard Elf object format.

    Notice that the @b error argument, where applicable,
    is an int* .  Error codes passed back are DW_DLE codes
    and @b dwarf_errmsg_by_number may be used (by your
    code) to get the standard error string for that error.

    @b om_get_section_info

    @code
    Get address, size, and name info about a section.

    Parameters
    obj            -  Your data
    section_index  - Zero-based index.
    return_section - Pointer to a structure in which
        section info will be placed.   Caller must
        provide a valid pointer to a structure area.
        The structure's contents will be overwritten
        by the call to get_section_info.
    error          - A pointer to an integer in which an error
        code may be stored.

    Return
    DW_DLV_OK       - Everything ok.
    DW_DLV_ERROR    - Error occurred. Use 'error' to determine the
        @e libdwarf defined error.
    DW_DLV_NO_ENTRY - No such section.
    @endcode

    @b om_get_byte_order

    This retrieves data you put into your @b ai_object
    struct that you filled out.

    @code
    Get from your @b ai_object whether the object
    file represented by this interface is big-endian
    (DW_END_big) or little endian (DW_END_little).

    Parameters
    obj  -  Your data

    Return
    Endianness of object, DW_END_big or DW_END_little.
    @endcode

    @b om_get_length_size

    This retrieves data you put into your @b ai_object
    struct that you filled out.

    @code
    Get the size of a length field in the underlying object file.
    @e libdwarf currently supports * 4 and 8 byte sizes, but may
    support larger in the future.
    Perhaps the return type should be an enumeration?

    Parameters
    obj  -  Your data

    Return
    Size of length. Cannot fail.
    @endcode

    @b om_get_pointer_size

    This retrieves data you put into your @b ai_object
    struct that you filled out.

    @code
    Get the size of a pointer field in the underlying object file.
    @e libdwarf currently supports  4 and 8 byte sizes.
    Perhaps the return type should be an enumeration?

    Return
    Size of pointer. Cannot fail.  */
    @endcode

    @b om_get_filesize

    This retrieves data you put into your @b ai_object
    struct that you filled out.

    @code
    Parameters
    obj  -  Your data

    Return
    Must return a value at least as large as any section @e libdwarf
    might read.  Returns a value that is a sanity check on
    offsets @e libdwarf reads for this DWARF set.  It need not be
    a tight bound.
    @endcode

    @b om_get_section_count

    This retrieves data you put into your @b ai_object
    struct that you filled out.

    @code
    Get the number of sections in the object file, including
    the index zero section with no content.

    Parameters
    obj  -  Your data

    Return
    Number of sections.
    @endcode

    @b om_load_section

    This retrieves data you put into your @b ai_object
    struct that you filled out.

    Get a pointer to an array of bytes that
    are the section content.

    @code
    Get a pointer to an array of bytes that
    represent the section.

    Parameters
    obj           -  Your data
    section_index - Zero-based section index.
    return_data   - Place the address of this section
        content into  *return_data .
    error         - Pointer to an integer for returning
        libdwarf-defined error numbers.

    Return
    DW_DLV_OK       - No error.
    DW_DLV_ERROR    - Error. Use 'error' to indicate
        a libdwarf-defined error number.
    DW_DLV_NO_ENTRY - No such section.  */
    @endcode

    @b om_relocate_a_section

    @code
    Leave this pointer NULL.
    If relocations are required it is probably simpler
    for you do to them yourself n your
    implementation of @b om_load_section .
    Any relocations this function pointer
    is to use must be in standard Elf
    relocation (32 or 64 bit) form and must be
    in an appropriately named Elf relocation section.

    Parameters
    obj  -  Your data
    section_index - Zero-based index of the
        section to be relocated.
    error - Pointer to an integer for returning libdwarf-defined
        error numbers.

    Return
    DW_DLV_OK - No error.
    DW_DLV_ERROR - Error. Use 'error' to indicate
        a libdwarf-defined
        error number.
    DW_DLV_NO_ENTRY - No such section.
    @endcode

*/