#ifndef __OBJELF_H__
#define __OBJELF_H__

/* =================================================================
 *
 *      objelf.h
 *
 * ================================================================= 
 * ####ECOSGPLCOPYRIGHTBEGIN####                                     
 * -------------------------------------------                       
 * This file is part of eCos, the Embedded Configurable Operating System.
 * Copyright (C) 2005, 2008 Free Software Foundation, Inc.           
 * Copyright (C) 2005, 2008 eCosCentric Limited                      
 *
 * eCos is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 or (at your option) any later
 * version.                                                          
 *
 * eCos is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.                                                 
 *
 * You should have received a copy of the GNU General Public License 
 * along with eCos; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.     
 *
 * As a special exception, if other files instantiate templates or use
 * macros or inline functions from this file, or you compile this file
 * and link it with other works to produce a work based on this file,
 * this file does not by itself cause the resulting work to be covered by
 * the GNU General Public License. However the source code for this file
 * must still be made available in accordance with section (3) of the GNU
 * General Public License v2.                                        
 *
 * This exception does not invalidate any other reasons why a work based
 * on this file might be covered by the GNU General Public License.  
 * -------------------------------------------                       
 * ####ECOSGPLCOPYRIGHTEND####                                       
 * =================================================================
 * #####DESCRIPTIONBEGIN####
 * 
 *  Author(s):    nickg, Anthony Tonizzo (atonizzo@gmail.com)
 *  Contributors: nickg@ecoscentric.com
 *  Date:         2005-05-13
 *  Purpose:      
 *  Description:  
 *               
 * ####DESCRIPTIONEND####
 * 
 * =================================================================
 */

//==============================================================================

#include <cyg/objloader/objload.h>

//==============================================================================

extern char *cyg_ldr_last_error;

//==============================================================================

typedef struct CYG_LDR_ELF_OBJECT
{
    CYG_ADDRWORD                        ptr;

    size_t    (*read)(struct CYG_LDR_ELF_OBJECT*, size_t, void*);
    cyg_int32 (*seek)(struct CYG_LDR_ELF_OBJECT*, cyg_uint32);
    cyg_int32 (*close)(struct CYG_LDR_ELF_OBJECT*);

    // This is the absolute address in memory where the object resides.
    Elf32_Ehdr*   p_elfhdr;

    // Start of the section header.
    Elf32_Shdr*   p_sechdr;

    cyg_int32     hdrndx_symtab;
    cyg_int32     hdrndx_strtab;

    cyg_uint32    **sections;

} CYG_LDR_ELF_OBJECT;

//==============================================================================
// Debug functions.

//#undef CYGPKG_OBJLOADER_DEBUG_LEVEL
//#define CYGPKG_OBJLOADER_DEBUG_LEVEL 3

#if CYGPKG_OBJLOADER_DEBUG_LEVEL != 0
#define ELFDEBUG(a) diag_printf(a)
#else
#define ELFDEBUG(a)
#endif

#if CYGPKG_OBJLOADER_DEBUG_LEVEL > 0
void       cyg_ldr_print_section_data(CYG_LDR_ELF_OBJECT *);
void       cyg_ldr_print_symbol_names(CYG_LDR_ELF_OBJECT *);
void       cyg_ldr_print_rel_names(CYG_LDR_ELF_OBJECT *);
#endif

#if CYGPKG_OBJLOADER_DEBUG_LEVEL > 2
#define ol_diag( __fmt, ... ) diag_printf("OL: %30s[%3d]: " __fmt, __FUNCTION__, __LINE__, ## __VA_ARGS__ );
#define ol_dump_buf( __addr, __size ) diag_dump_buf( __addr, __size )
#else
#define ol_diag( __fmt, ... )
#define ol_dump_buf( __addr, __size )
#endif

//==============================================================================
// Internal functions

cyg_uint32 *cyg_ldr_load_elf_section(CYG_LDR_ELF_OBJECT *, cyg_uint32);
void        cyg_ldr_delete_elf_section(CYG_LDR_ELF_OBJECT *, cyg_uint32);
cyg_uint32 *cyg_ldr_section_address(CYG_LDR_ELF_OBJECT *, cyg_uint32);
void*       cyg_ldr_scan_file(CYG_LDR_ELF_OBJECT *);
cyg_int32   cyg_ldr_relocate_section(CYG_LDR_ELF_OBJECT *, cyg_uint32, cyg_uint32);
void*       cyg_ldr_symbol_address(CYG_LDR_ELF_OBJECT *, cyg_uint32);
void*       cyg_ldr_external_address(CYG_LDR_ELF_OBJECT *, cyg_uint32);

//==============================================================================
// The following value is returned from cyg_ldr_symbol_address(), and
// other functions, to indicate that a symbol has not been found. It's
// value is set to cyg_ldr_symbol_address since this is an address
// internal to the object loader that no module or application symbol
// can have.

#define     SYM_VALUE_UNKNOWN ((cyg_uint32)&cyg_ldr_symbol_address)

//==============================================================================
// Relocator interface

void      cyg_ldr_flush_cache(void);
cyg_int32 cyg_ldr_relocate(cyg_int32, cyg_uint32, cyg_uint32, cyg_int32);

// Flags values:

#define CYG_LDR_FLAG_RELA       (1<<0)          // RELA relocation

//==============================================================================                             
#endif
