#ifndef DRD64_HEADER_LIBGOBLIN_TYPE
#define DRD64_HEADER_LIBGOBLIN_TYPE
-#include"drd64_libgoblin.h"
+/*=====================================================================*/
+/*
+typedef union {
+ int i_obj_id;
+ Byte *pb_info;
+} LibGoblin_ObjInfo_Link;
+*/
-#define LIBGOBLIN_BINFO_TYPE_NONE 0x00
-#define LIBGOBLIN_BINFO_TYPE_ELF 0x01
-#define LIBGOBLIN_BINFO_TYPE_ELF64 0x64
-#define LIBGOBLIN_BINFO_TYPE_ELF32 0x32
+/*=====================================================================*/
+typedef struct {
+ Byte *pb_dwinfo;
+ int i_obj_id;
+} LibGoblin_Index_DWARFInfo;
-#define IsBinfoType_Elf64(n) \
- ((LIBGOBLIN_BINFO_TYPE_ELF64==((n)->b_type)) ? 0x01 : 0x00)
-#define IsBinfoType_Elf32(n) \
- ((LIBGOBLIN_BINFO_TYPE_ELF32==((n)->b_type)) ? 0x01 : 0x00)
-#define LIBGOBLIN_BINFO_ENDIAN_NONE 0x00
-#define LIBGOBLIN_BINFO_ENDIAN_LITTLE 0x01
-#define LIBGOBLIN_BINFO_ENDIAN_BIG 0x02
+/*=====================================================================*/
+typedef struct {
+ Byte *pb_sechdr;
+ Byte *pb_data; // FileLocation (Offset)
+ Word w_index;
+ Ptr ptr_addr;
+ QWord qw_size;
+ QWord qw_flag;
+ QWord qw_entsize;
+ char *pstr_secname;
+ int i_binfile;
-#define LIBGOBLIN_BINFO_SECTION_TEXT 0x00
-#define LIBGOBLIN_BINFO_SECTION_DATA 0x01
-#define LIBGOBLIN_BINFO_SECTION_BSS 0x02
+ int i_objid;
+} LibGoblin_SectionInfo;
-#define LIBGOBLIN_BINFO_PHASE_INIT 0x00
-#define LIBGOBLIN_BINFO_PHASE_ALLOCED 0x01
-#define LIBGOBLIN_BINFO_PHASE_BINREAD 0x02
-#define LIBGOBLIN_BINFO_PHASE_ANALYZED 0x03
-#define LIBGOBLIN_BINFO_MAXFILES 3
-#define LIBGOBLIN_BINFO_FILE_EXEC 0
-#define LIBGOBLIN_BINFO_FILE_CORE 1
-#define LIBGOBLIN_BINFO_FILE_DEBUG 2
+/*=====================================================================*/
+/*typedef struct {
+ Ptr ptr_address; // Object Address
+ DWord dw_size; // Object Size (Address Range)
+ char *pstr_name; // Object Name (Param./Func./etc...)
+ //DWord dw_srcid; // SourceInfo struct ID
+ DWord dw_next;
+ Byte b_elf_flags;
+ Word w_secid; // SectionInfo ItemIndex belong with this object.
+} LibGoblin_AddressInfo ****OLD**** ;*/
-#define LIBGOBLIN_BINFO_FILE_MMAP (DWord)0x01
-#define LIBGOBLIN_BINFO_FILE_EXTALLOC (DWord)0x02
-#define LIBGOBLIN_BINFO_FILE_INTALLOC (DWord)0x04
-
-#define LIBGOBLIN_ELF_SEC_ID_TEXT 0x00
-#define LIBGOBLIN_ELF_SEC_ID_TEXT_INIT 0x01
-#define LIBGOBLIN_ELF_SEC_ID_TEXT_FINI 0x02
-#define LIBGOBLIN_ELF_SEC_ID_DATA 0x03
-#define LIBGOBLIN_ELF_SEC_ID_BSS 0x04
-#define LIBGOBLIN_ELF_SEC_ID_GOT 0x05
-#define LIBGOBLIN_ELF_SEC_ID_GOT_PLT 0x06
-#define LIBGOBLIN_ELF_SEC_ID_PLT 0x07
-#define LIBGOBLIN_ELF_SEC_ID_REL_PLT 0x08
-#define LIBGOBLIN_ELF_SEC_ID_RELA_PLT 0x09
-#define LIBGOBLIN_ELF_SEC_ID_SHSTRTAB 0x0a
-#define LIBGOBLIN_ELF_SEC_ID_STRTAB 0x0b
-#define LIBGOBLIN_ELF_SEC_ID_SYMTAB 0x0c
-#define LIBGOBLIN_ELF_SEC_ID_DTORS 0x0d
-#define LIBGOBLIN_ELF_SEC_ID_CTORS 0x0e
-#define LIBGOBLIN_ELF_SEC_ID_DYNAMIC 0x0f
-#define LIBGOBLIN_ELF_SEC_ID_DYNSTR 0x10
-#define LIBGOBLIN_ELF_SEC_ID_DYNSYM 0x11
-#define LIBGOBLIN_ELF_SEC_ID_EH_FRAME 0x12
-#define LIBGOBLIN_ELF_SEC_ID_EH_FRAME_HDR 0x13
-#define LIBGOBLIN_ELF_SEC_ID_COMMENT 0x14
-#define LIBGOBLIN_ELF_SEC_ID_GNU_VERSION 0x15
-#define LIBGOBLIN_ELF_SEC_ID_GNU_VERSION_R 0x16
-#define LIBGOBLIN_ELF_SEC_ID_RODATA 0x17
-#define LIBGOBLIN_ELF_SEC_ID_NOTE_ABI_TAG 0x18
-#define LIBGOBLIN_ELF_SEC_ID_HASH 0x19
-#define LIBGOBLIN_ELF_SEC_ID_INTERP 0x1a
-#define LIBGOBLIN_ELF_SEC_ID_JCR 0x1b
-#define LIBGOBLIN_ELF_SEC_ID_DEBUG_ABBREV 0x1c
-#define LIBGOBLIN_ELF_SEC_ID_DEBUG_INFO 0x1d
-#define LIBGOBLIN_ELF_SEC_ID_DEBUG_LINE 0x1e
-#define LIBGOBLIN_ELF_SEC_ID_DEBUG_ARANGES 0x1f
-#define LIBGOBLIN_ELF_SEC_ID_DEBUG_FRAME 0x20
-#define LIBGOBLIN_ELF_SEC_ID_DEBUG_LOC 0x21
-#define LIBGOBLIN_ELF_SEC_ID_DEBUG_PUBNAMES 0x22
-
-#define LIBGOBLIN_ELF_SEC_ID_DEFAULT_MAX 0x22
-#define LIBGOBLIN_ELF_SEC_ID_MAX 0x3f
-
-#define LIBGOBLIN_ELF_SEC_STR_TEXT ".text"
-#define LIBGOBLIN_ELF_SEC_STR_TEXT_INIT ".init"
-#define LIBGOBLIN_ELF_SEC_STR_TEXT_FINI ".fini"
-#define LIBGOBLIN_ELF_SEC_STR_DATA ".data"
-#define LIBGOBLIN_ELF_SEC_STR_BSS ".bss"
-#define LIBGOBLIN_ELF_SEC_STR_GOT ".got"
-#define LIBGOBLIN_ELF_SEC_STR_GOT_PLT ".got.plt"
-#define LIBGOBLIN_ELF_SEC_STR_PLT ".plt"
-#define LIBGOBLIN_ELF_SEC_STR_REL_PLT ".rel.plt"
-#define LIBGOBLIN_ELF_SEC_STR_RELA_PLT ".rela.plt"
-#define LIBGOBLIN_ELF_SEC_STR_SHSTRTAB ".shstrtab"
-#define LIBGOBLIN_ELF_SEC_STR_STRTAB ".strtab"
-#define LIBGOBLIN_ELF_SEC_STR_SYMTAB ".symtab"
-#define LIBGOBLIN_ELF_SEC_STR_DTORS ".dtors"
-#define LIBGOBLIN_ELF_SEC_STR_CTORS ".ctors"
-#define LIBGOBLIN_ELF_SEC_STR_DYNAMIC ".dynamic"
-#define LIBGOBLIN_ELF_SEC_STR_DYNSTR ".dynstr"
-#define LIBGOBLIN_ELF_SEC_STR_DYNSYM ".dynsym"
-#define LIBGOBLIN_ELF_SEC_STR_EH_FRAME ".eh_frame"
-#define LIBGOBLIN_ELF_SEC_STR_EH_FRAME_HDR ".eh_frame_hdr"
-#define LIBGOBLIN_ELF_SEC_STR_COMMENT ".comment"
-#define LIBGOBLIN_ELF_SEC_STR_GNU_VERSION ".gnu.version"
-#define LIBGOBLIN_ELF_SEC_STR_GNU_VERSION_R ".gnu.version_r"
-#define LIBGOBLIN_ELF_SEC_STR_RODATA ".rodata"
-#define LIBGOBLIN_ELF_SEC_STR_NOTE_ABI_TAG ".note.ABI-tag"
-#define LIBGOBLIN_ELF_SEC_STR_HASH ".hash"
-#define LIBGOBLIN_ELF_SEC_STR_INTERP ".interp"
-#define LIBGOBLIN_ELF_SEC_STR_JCR ".jcr"
-#define LIBGOBLIN_ELF_SEC_STR_DEBUG_ABBREV ".debug_abbrev"
-#define LIBGOBLIN_ELF_SEC_STR_DEBUG_INFO ".debug_info"
-#define LIBGOBLIN_ELF_SEC_STR_DEBUG_LINE ".debug_line"
-#define LIBGOBLIN_ELF_SEC_STR_DEBUG_ARANGES ".debug_aranges"
-#define LIBGOBLIN_ELF_SEC_STR_DEBUG_FRAME ".debug_frame"
-#define LIBGOBLIN_ELF_SEC_STR_DEBUG_LOC ".debug_loc"
-#define LIBGOBLIN_ELF_SEC_STR_DEBUG_PUBNAMES ".debug_pubnames"
+
+/*=====================================================================*/
+#define OBJINFO_STATUS_INVALID 0x00000000
+#define OBJINFO_STATUS_VALID 0x00000001 // bit 0
+#define OBJINFO_STATUS_DYNAMIC 0x00000002 // bit 1
+#define OBJINFO_STATUS_RESOLV1 0x00000004 // bit 2 (Specified BinaryInfo & Index)
+//#define OBJINFO_STATUS_RESOLV2 0x00000008 // bit 3 (Loaded .so)
+#define OBJINFO_STATUS_REL 0x00000100
+#define OBJINFO_STATUS_SOLVED 0x00001000
+
+#define OBJINFO_TYPE_NULL 0x00
+#define OBJINFO_TYPE_MASTER 0x01
+#define OBJINFO_TYPE_PROGRAM 0x02
+#define OBJINFO_TYPE_PROGHDR 0x03
+#define OBJINFO_TYPE_SECTION 0x04
+#define OBJINFO_TYPE_OBJFILE 0x05
+#define OBJINFO_TYPE_TYPE_MULTI 0x06
+#define OBJINFO_TYPE_TYPE_SINGLE 0x07
+#define OBJINFO_TYPE_TYPEDEF 0x08
+#define OBJINFO_TYPE_FUNCTION 0x09
+#define OBJINFO_TYPE_OBJECT 0x0a
+#define OBJINFO_TYPE_COMMON 0x0b
+#define OBJINFO_TYPE_TLS 0x0c
+#define OBJINFO_TYPE_REL 0x0d
+#define OBJINFO_TYPE_NONE 0x7f
+
+typedef struct {
+ int i_id;
+ Byte b_type;
+ DWord dw_status;
+
+ // Address & Memory-Range Info ----
+ struct {
+ Ptr ptr_addr; // Object Address
+ // [Section] sh_addr - Address in memory image.
+ // [Symbol ] st_value - Symbol value.
+ QWord qw_size; // Object Size (Address Range)
+ // [Symbol ] st_size - Size of associated object.
+ } addr;
+
+ // Address Order Link ---
+ struct {
+ int i_next_id; // Next Address ObjectInfo
+ int i_prev_id; // Prev Address ObjectInfo
+ } addrlink;
+
+ // Group(Parent-Child) Order Link ---
+ struct {
+ int i_parent_id; // Parent ObjectInfo
+ int i_child_topid; // Child Top ObjectInfo
+ int i_prev_id;
+ int i_next_id; // Next
+ } grplink;
+
+ // Type Link ---
+ struct {
+ int i_prev_id;
+ int i_next_id;
+ } typelink;
+
+ // File Info ---
+ struct {
+ int i_binfile;
+ void *pv_offset;
+ // [Section] sh_offset - Offset in file.
+ QWord qw_size;
+ } file;
+
+ // ObjectInfo (DATA) ---
+ char *pstr_name; // Object Name (Param./Func./etc...)
+ // [Section] = sh_name - Section name (index into the section header string table).
+ // [Symbol ] = st_name - String table index of name.
+ DWord dw_hash;
+
+ union {
+ Byte b_data[128];
+
+ // for OBJINFO_TYPE_PROGRAM
+ struct {
+ int i_binfo_id;
+ } program;
+
+ // for OBJINFO_TYPE_PROGHDR
+ struct {
+ DWord dw_type; // Entry type.
+ DWord dw_flags; // Access permission flags.
+ QWord qw_align; // Alignment in memory and file.
+ void *pv_proghdr; // Program Header Pointer
+ } proghdr;
+
+ // for OBJINFO_TYPE_SECTION
+ struct {
+ QWord qw_flag; // sh_flags - Section flags.
+ QWord qw_align; // sh_addralign - Alignment in bytes.
+ QWord qw_entsize; // sh_entsize - Size of each entry in section.
+ DWord dw_type; // sh_type - Section type.
+ DWord dw_link; // sh_link - Index of a related section.
+ DWord dw_info; // sh_info - Depends on section type.
+ void *pv_sechdr;
+ } section;
+
+ // for OBJINFO_TYPE_OBJFILE
+ struct {
+ int i_objid_parent;
+ int i_abbrevs;
+ DWARF_AbbrevEntry *p_abbrev;
+ LibGoblin_DWARF_Info_CUHeader t_cuheader;
+ } objfile;
+
+ struct {
+ DWord dw_size;
+ Byte b_encoding;
+ Byte b_bit_offset;
+ Byte b_bit_size;
+ Byte b_endianity;
+ Byte b_addr_class;
+ Byte b_prototyped;
+ } type;
+
+ struct {
+ int i_objid_parent;
+ Byte b_prototyped;
+ Byte b_external;
+ Byte b_inline;
+
+ } function;
+ } info;
+
+ struct {
+ Byte b_type; // st_info - Type and binding information.
+ Byte b_binding; // st_info - Type and binding information.
+ Byte b_visibility; // st_other - Reserved (not used).
+ Word w_secindex; // st_shndx - Section index of symbol.
+ } elfsym;
+
+ struct {
+ int i_binfo_origin;
+ int i_dynsym_index;
+
+ int i_objid_rel;
+ } dynamic;
+
+ struct {
+ int i_objid_origin;
+ } rel;
+
+ struct {
+ Byte *pb_info;
+
+ int i_objid_type;
+ Byte *pb_dwinfo_type;
+ } dwarf;
+
+ int i_secid;
+ int i_srcid; // SourceInfo struct ID
+ DWord dw_srcline;
+
+ Byte b_elf_flags;
+ Word w_secid; // ==OLD== SectionInfo ItemIndex belong with this object.
+
+} LibGoblin_ObjectInfo;
/*=====================================================================*/
typedef struct {
- Byte *pb_sechdr;
- Byte *pb_data;
- char *pstr_secname;
- QWord qw_size;
- int i_fid;
-} LibGoblin_SectionInfo;
+ Ptr ptr_addr;
+ int i_objid;
+} LibGoblin_AddressInfo;
+
+/*=====================================================================*/
+typedef struct {
+ int i_id;
+ DWord dw_hash_filename;
+ DWord dw_hash_localpath;
+ char str_filename[DRD64_MAX_PATH];
+ char str_localpath[DRD64_MAX_PATH];
+ char str_srcpath[DRD64_MAX_PATH]; // for DW_AT_name
+ //char str_buildpath[DRD64_MAX_PATH]; // for DW_AT_comp_dir (Optional)
+
+ int i_bfile_id;
+ struct {
+ int i_abbrevs;
+ DWARF_AbbrevEntry *p_abbrev;
+ } dwarf;
+
+} LibGoblin_SrcFile;
+
/*=====================================================================*/
+#define BINFILE_FLAGMASK_FILE (DWord)0x00000007
+#define BINFILE_FLAG_FILE_MMAP (DWord)0x00000001
+#define BINFILE_FLAG_FILE_EXTALLOC (DWord)0x00000002
+#define BINFILE_FLAG_FILE_INTALLOC (DWord)0x00000004
+
+#define BINFILE_FLAGMASK_RELTYPE (DWord)0x00000010
+#define BINFILE_FLAG_RELTYPE_REL (DWord)0x00000000
+#define BINFILE_FLAG_RELTYPE_RELA (DWord)0x00000010
+
+#define BINFILE_STATUS_NOUSE 0x00
+#define BINFILE_STATUS_CREATE 0x01
+#define BINFILE_STATUS_FILEOPEN 0x02
+#define BINFILE_STATUS_READSECTION 0x03
+
typedef struct {
+ int i_id;
+ int i_refcount;
+
/* Binary-File Info. */
int i_fd;
DWord dw_flag;
- char str_filepath[DRD64_MAX_PATH];
+ Byte b_status;
+
+ // EXEC-program / shared lib. filename (without directry)
+ char str_filename[DRD64_MAX_PATH];
+ char str_localpath[DRD64_MAX_PATH]; // filepath in local machine path.(transported)
+ char str_remotepath[DRD64_MAX_PATH]; // filepath in remote machine path.(local machine is NULL)
+
+ // .dynamic Section - rpath (.so location path - converted real-path)
+ char str_rpath[DRD64_MAX_PATH];
+ // .dynamic Section - runpath (.so location path - converted real-path)
+ char str_runpath[DRD64_MAX_PATH];
+
LibFileType_FileType t_ftype;
/* Binary-File Memory Image Access Info. */
DWord dw_size;
Byte *pb_binary;
+ struct {
+ LibGoblin_SrcFile *p_srcfile;
+ int i_alloc;
+ int i_max;
+ int i_now;
+ } srcfile;
+
+ struct {
+ int i_abbrevs_max;
+ int i_abbrevs_alloc;
+ DWARF_AbbrevEntry *p_abbrev;
+ QWord qw_abbrev_unreadsz;
+
+ LibGoblin_Index_DWARFInfo *p_offset;
+ int i_alloced_offset;
+ int i_max_offset;
+
+ int i_objfiles;
+
+ int i_maxvals;
+ } dwarf;
+
/* Binary-Format Depending Info. (ELF)*/
void *p_elf;
- LibGoblin_SectionInfo t_section[LIBGOBLIN_ELF_SEC_ID_MAX];
+ LibGoblin_SectionInfo t_section[LIBGOBLIN_SECTION_ID_MAX];
+ int i_secindex[LIBGOBLIN_SECTION_ID_MAX];
} LibGoblin_BinaryFile;
+
/*=====================================================================*/
+#define LIBGOBLIN_BINFO_PHASE_INIT 0x00
+#define LIBGOBLIN_BINFO_PHASE_ALLOCED 0x10
+#define LIBGOBLIN_BINFO_PHASE_SETNAME 0x20
+#define LIBGOBLIN_BINFO_PHASE_SETPROG 0x30
+#define LIBGOBLIN_BINFO_PHASE_BINREAD 0x40
+#define LIBGOBLIN_BINFO_PHASE_ELF1READ 0x51
+#define LIBGOBLIN_BINFO_PHASE_ELF2READ 0x52
+#define LIBGOBLIN_BINFO_PHASE_ANALYZED 0x50
+
+#define LIBGOBLIN_BINFO_TYPE_NONE 0x00
+#define LIBGOBLIN_BINFO_TYPE_ELF 0x01
+#define LIBGOBLIN_BINFO_TYPE_ELF64 0x64
+#define LIBGOBLIN_BINFO_TYPE_ELF32 0x32
+
+#define isElf64(n) \
+ ((LIBGOBLIN_BINFO_TYPE_ELF64==((n)->b_type)) ? 0x01 : 0x00)
+#define isElf32(n) \
+ ((LIBGOBLIN_BINFO_TYPE_ELF32==((n)->b_type)) ? 0x01 : 0x00)
+#define IsBinfoType_Elf64(n) \
+ ((LIBGOBLIN_BINFO_TYPE_ELF64==((n)->b_type)) ? 0x01 : 0x00)
+#define IsBinfoType_Elf32(n) \
+ ((LIBGOBLIN_BINFO_TYPE_ELF32==((n)->b_type)) ? 0x01 : 0x00)
+
+#define LIBGOBLIN_BINFO_ENDIAN_NONE 0x00
+#define LIBGOBLIN_BINFO_ENDIAN_LITTLE 0x01
+#define LIBGOBLIN_BINFO_ENDIAN_BIG 0x02
+
+#define LIBGOBLIN_BINFO_SECTION_TEXT 0x00
+#define LIBGOBLIN_BINFO_SECTION_DATA 0x01
+#define LIBGOBLIN_BINFO_SECTION_BSS 0x02
+
+#define LIBGOBLIN_BINFO_MAXFILES 3 // Except FILE_LIBRARY
+#define LIBGOBLIN_BINFO_FILE_EXEC 0
+#define LIBGOBLIN_BINFO_FILE_CORE 1
+#define LIBGOBLIN_BINFO_FILE_DEBUG 2
+#define LIBGOBLIN_BINFO_FILE_LIBRARY -1
+
+#define LIBGOBLIN_DWARF_ATTR_DEF_MAX 0x6f
+#define LIBGOBLIN_DWARF_ATTR_EXT_MAX 53
+#define LIBGOBLIN_DWARF_ATTR_MAX (LIBGOBLIN_DWARF_ATTR_DEF_MAX + LIBGOBLIN_DWARF_ATTR_EXT_MAX)
+
typedef struct {
/* BinaryInfo Struct ID */
int i_id;
/* Debug-Format Depending Info. (DWarf) */
void *p_debug;
- /* Exec. File ===========================================*/
- LibGoblin_BinaryFile t_binfile[3];
+ /* Address Table Info. */
+/*
+ LibGoblin_AddressInfo *p_addrinfo;
+ DWord dw_alloc_addrinfo;
+ DWord dw_max_addrinfo;
+*/
+
+ /* Exec. File Info. */
+ char str_filename[DRD64_MAX_PATH];
+ DWord dw_hash;
+
+ int i_binfile; // binaryFile ID
+ int i_binfile_debug;
+
+ int i_pginfo;
+ int i_binfo_parent;
+ int i_binfo_next;
+
+ PtrValue ptr_loadbase;
+
+ LibGoblin_SectionInfo t_section[LIBGOBLIN_SECTION_ID_MAX];
/* Binary-Format Depending Info. (ELF)*/
//void *p_format;
- LibGoblin_SectionInfo t_section[LIBGOBLIN_ELF_SEC_ID_MAX];
-
-} LibGoblin_BinaryInfo;
+ struct {
+ int i_maxvals;
+ LibGoblin_DWARF_DIEValue *p_infoval;
+
+ int i_extattrs;
+ LibGoblin_DWARF_Attribute t_attr[LIBGOBLIN_DWARF_ATTR_MAX+1];
+ int i_alloc_srctbl;
+ int i_max_srctbl;
+ int *pi_srctbl;
+ } dwarf;
+
+
+} LibGoblin_BinaryInfo;
/*=====================================================================*/
typedef struct {
- Word dw_id;
- Word w_flag;
- Ptr *p_address;
- DWord dw_size;
- DWord dw_srcid;
- DWord dw_name;
- DWord dw_next;
- Word w_secid;
-} LibGoblin_SymbolInfo;
+
+ int i_id;
+
+ // Object Table & Address Table ---
+ struct {
+ LibGoblin_ObjectInfo *p_objinfo;
+ int i_empty; // Empty ObjectInfo Chain Top-ID.
+ int i_alloced; // Alloced ObjectInfo
+ int i_used; // ObjectInfo Items
+ int i_topid; // Top-Ptr ObjectInfo
+
+ } objinfo;
+ LibGoblin_AddressInfo *p_addrinfo;
+
+ Word dw_flag;
+ int i_binfo_id;
+ int i_binfo_id_core;
+
+ /* Address Table Info. */
+ //LibGoblin_AddressInfo *p_addrinfo;
+ //DWord dw_alloc_addrinfo;
+ //DWord dw_max_addrinfo;
+
+
+} LibGoblin_ProgramInfo;
-#endif /* DRD64_HEADER_LIBGOBLIN_SYMINFO*/
+#endif /* DRD64_HEADER_LIBGOBLIN_TYPE*/
/* EOF of drd64_.h ----------------------------------- */