⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loader.cxx

📁 eCos操作系统源码
💻 CXX
📖 第 1 页 / 共 2 页
字号:
        case DT_REL:                    /* address of rel. tbl. w addends */            rel = (Elf32_Rel *)(dynamic->d_un.d_ptr + base);            break;        case DT_RELSZ:                  /* size of DT_REL relocation table */            relsize = dynamic->d_un.d_val;            break;        case DT_RELENT:                 /* size of DT_REL relocation entry */            relent = dynamic->d_un.d_val;            break;        case DT_PLTREL:                 /* PLT referenced relocation entry */            pltrel = dynamic->d_un.d_val;            break;        case DT_DEBUG:                  /* Debug data */            break;                      /* ignore for now */        case DT_TEXTREL:                /* Allow rel. mod. to unwritable seg */            flags |= DF_TEXTREL;            break;        case DT_JMPREL:                 /* add. of PLT's relocation entries */            jmprel = dynamic->d_un.d_ptr + base;            break;        case DT_BIND_NOW:               /* Bind now regardless of env setting */            flags |= DF_BIND_NOW;            break;        case DT_INIT_ARRAY:             /* init array address */            init_array = (Elf32_Addr *)(dynamic->d_un.d_ptr + base);            break;        case DT_FINI_ARRAY:             /* fini array address */            fini_array = (Elf32_Addr *)(dynamic->d_un.d_ptr + base);            break;        case DT_INIT_ARRAYSZ:           /* init array size */            init_array_sz = dynamic->d_un.d_val;            break;        case DT_FINI_ARRAYSZ:           /* fini array size */            fini_array_sz = dynamic->d_un.d_val;            break;        case DT_FLAGS:                  /* flags */            flags |= dynamic->d_un.d_val;            break;        case DT_PREINIT_ARRAY:          /* preinit array address */            pre_init_array = (Elf32_Addr *)(dynamic->d_un.d_ptr + base);            break;        case DT_PREINIT_ARRAYSZ:        /* preinit array size */            pre_init_array_sz = dynamic->d_un.d_val;            break;                    default:            // handle format-specific entries            break;        }    }        CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Get the symbol name from the current object's symbol table, look it// up in the hash tables of the loaded objects, and return its address.CYG_ADDRESS Cyg_LoadObject_Base::get_sym_addr_from_ix( Elf32_Word ix ){    Elf32_Sym *sym = get_sym( ix );    if( sym == NULL ) return 0;    const char *name = get_name( sym->st_name );    // If the symbol has local binding, we must look for    // it in this object only.    if( ELF32_ST_BIND(sym->st_info) == STB_LOCAL )         return hash_lookup_addr( name );    // Otherwise search the loaded objects in load order    return Cyg_Loader::loader->hash_lookup_addr( name );}// -------------------------------------------------------------------------// Lookup the name in our hash table and return the symbol table entryElf32_Sym *Cyg_LoadObject_Base::hash_lookup( const char *name ){    Elf32_Sym *ret = NULL;    if( hash == NULL )    {        error = CYG_LOADERR_NO_HASHTABLE;        return NULL;    }    error = CYG_LOADERR_NO_SYMBOL;        Elf32_Word ix = elf_hash( (const unsigned char *)name );    ix %= hash->nbucket;    // get head of chain    Elf32_Word iy = bucket[ ix ];         while( iy != STN_UNDEF )    {        Elf32_Sym *sym = get_sym( iy );        const char *sname = get_name( sym->st_name );        if( streq( name, sname ) )        {            ret = sym;            error = CYG_LOADERR_NOERROR;            break;        }        iy = chain[ iy ];    }    return ret;}// -------------------------------------------------------------------------// Lookup the given name in our symbol table and return it's value// relocated to our load address.CYG_ADDRESS Cyg_LoadObject_Base::hash_lookup_addr( const char *name ){    Elf32_Sym *sym = hash_lookup( name );    if( sym == NULL )        return CYG_LOADER_NULLSYMADDR;    // Check that this symbol is for a defined object, if its type is    // NOTYPE then it is undefined, here, and we cannot take its address.    // Hopefully it is defined in some other object.        if( ELF32_ST_TYPE(sym->st_info) == STT_NOTYPE )    {        error = CYG_LOADERR_NO_SYMBOL;        return CYG_LOADER_NULLSYMADDR;    }        return sym->st_value + base;}// -------------------------------------------------------------------------// ELF hash function// This is the standard hash function used for indexing the bucket// array in the hash table.unsigned long Cyg_LoadObject_Base::elf_hash( const unsigned char *name ){    unsigned long h = 0, g;    while( *name )    {        h = ( h << 4 ) + *name++;        if( (g = h & 0xf0000000) != 0 )            h ^= g >> 24;        h &= ~g;    }    return h;}// -------------------------------------------------------------------------//Elf32_Sym *Cyg_LoadObject_Base::get_sym( Elf32_Word ix ){    if( symtab == NULL )        return NULL;        return &symtab[ix];}char *Cyg_LoadObject_Base::get_name( Elf32_Word offset ){    if( strtab == NULL || offset > strsize )        return NULL;        return (char *)(&strtab[offset]);}// -------------------------------------------------------------------------// Destructor// -------------------------------------------------------------------------// Cyg_LoadObject_Base destructorCyg_LoadObject_Base::~Cyg_LoadObject_Base(){    CYG_REPORT_FUNCTION();    // empty out segments list    while( !segs.empty() )    {        Cyg_LoaderMemBlock *block = segs.rem_head();        block->free();    }    CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Translate a symbol into its address.void *Cyg_LoadObject_Base::symbol( const char *name ){    CYG_REPORT_FUNCTION();    Elf32_Addr addr = hash_lookup_addr( name );    if( addr == CYG_LOADER_NULLSYMADDR )        addr = 0;        CYG_REPORT_RETVAL( addr );    return (void *)addr;}// -------------------------------------------------------------------------// Start the given executable object runningcyg_code Cyg_LoadObject_Base::exec(int argc, char **argv, char **envv){    CYG_REPORT_FUNCTION();    CYG_REPORT_FUNCARG3XV( argc, argv, envv );    cyg_code error = 0;        CYG_REPORT_RETVAL(error);    return error;}// =========================================================================// Cyg_LoadObject members// -------------------------------------------------------------------------// Apply relocationsvoid Cyg_LoadObject::relocate(){    CYG_REPORT_FUNCTION();    if( rel != NULL )    {        Elf32_Rel *r = rel;        for( int i = relsize; i > 0 && error == 0; i -= relent, r++ )            error = apply_rel( ELF32_R_TYPE(r->r_info),                               ELF32_R_SYM(r->r_info),                               r->r_offset);    }            if( error == 0 && rela != NULL )    {        Elf32_Rela *r = rela;        for( int i = relasize; i > 0 && error == 0; i -= relaent, r++ )            error = apply_rela( ELF32_R_TYPE(r->r_info),                                ELF32_R_SYM(r->r_info),                                r->r_offset,                                r->r_addend);    }        CYG_REPORT_RETURN();}// -------------------------------------------------------------------------// Apply JMPREL relocations for the PLTvoid Cyg_LoadObject::relocate_plt(){    CYG_REPORT_FUNCTION();    if( pltrel == DT_REL )    {        Elf32_Rel *r = (Elf32_Rel *)jmprel;        for( int i = pltrelsz; i > 0 && error == 0; i -= sizeof(Elf32_Rel), r++ )            error = apply_rel( ELF32_R_TYPE(r->r_info),                               ELF32_R_SYM(r->r_info),                               r->r_offset);    }            if( error == 0 && pltrel == DT_RELA )    {        Elf32_Rela *r = (Elf32_Rela *)jmprel;        for( int i = pltrelsz; i > 0 && error == 0; i -= sizeof(Elf32_Rela), r++ )            error = apply_rela( ELF32_R_TYPE(r->r_info),                                ELF32_R_SYM(r->r_info),                                r->r_offset,                                r->r_addend);    }        CYG_REPORT_RETURN();}// =========================================================================// Loader memory allocator default class methods.// The default behaviour of this class is to use malloc/realloc/free// to handle memory.// -------------------------------------------------------------------------Cyg_LoaderMemAlloc::Cyg_LoaderMemAlloc(){    // no initialization needed}// -------------------------------------------------------------------------Cyg_LoaderMemAlloc::~Cyg_LoaderMemAlloc(){    // No destruction needed}// -------------------------------------------------------------------------// Allocate memory of the supplied size and alignment.// size      - size in bytes// alignment - alignment expressed as a power of 2Cyg_LoaderMemBlock *Cyg_LoaderMemAlloc::alloc( cyg_int32 size,                                               cyg_int32 alignment){#if CYGINT_ISO_MALLOC        Cyg_LoaderMemBlock *block;    cyg_uint8 *mem;    cyg_uint32 acsize = sizeof(Cyg_LoaderMemBlock) + size + alignment;    mem = (cyg_uint8 *)::malloc( acsize );    if( mem == NULL )        return NULL;    block = (Cyg_LoaderMemBlock *)mem;    // set up aligned block address    block->address      = (void *)((((CYG_ADDRWORD)mem+sizeof(Cyg_LoaderMemBlock))+alignment) & ~(alignment-1));    block->size         = size;    block->alignment    = alignment;    block->mem          = this;    block->actual_address = (CYG_ADDRESS) mem;    block->actual_size    = acsize;    return block;#else    return 0;#endif    }// -------------------------------------------------------------------------// Reallocate blockCyg_LoaderMemBlock *Cyg_LoaderMemAlloc::realloc( Cyg_LoaderMemBlock *oblock,                                                 cyg_int32 size,                                                 cyg_int32 alignment){#if CYGINT_ISO_MALLOC        Cyg_LoaderMemBlock *block;    cyg_uint8 *mem;    if( alignment == -1 )        alignment = oblock->alignment;        cyg_uint32 acsize = sizeof(Cyg_LoaderMemBlock) + size + alignment;    mem = (cyg_uint8 *)::realloc( (void *)(oblock->actual_address), acsize );    if( mem == NULL )        return NULL;    block = (Cyg_LoaderMemBlock *)mem;    // set up aligned block address    block->address      = (void *)((((CYG_ADDRWORD)mem+sizeof(Cyg_LoaderMemBlock))+alignment) & (alignment-1));    block->size         = size;    block->alignment    = alignment;    block->mem          = this;    block->actual_address = (CYG_ADDRESS) mem;    block->actual_size    = acsize;    return block;#else    return NULL;#endif}    // -------------------------------------------------------------------------// Free a previously allocated memory segment.void Cyg_LoaderMemAlloc::free( Cyg_LoaderMemBlock *block ){#if CYGINT_ISO_MALLOC            ::free( (void *)block->actual_address );#endif    }// =========================================================================// Loader stream functionsCyg_LoaderStream::Cyg_LoaderStream(){}Cyg_LoaderStream::~Cyg_LoaderStream(){}cyg_code Cyg_LoaderStream::get_byte(CYG_BYTE *val){    return CYG_LOADERR_EOF;}cyg_code Cyg_LoaderStream::get_data(CYG_BYTE *addr, CYG_ADDRWORD size){    return CYG_LOADERR_EOF;}cyg_code Cyg_LoaderStream::seek(CYG_ADDRWORD pos){    return CYG_LOADERR_SEEK;    }// =========================================================================// Memory based loader streamCyg_LoaderStream_Mem::Cyg_LoaderStream_Mem( const void *addr, cyg_int32 size ){    base = pos = (CYG_ADDRESS)addr;    end = base + size;}Cyg_LoaderStream_Mem::~Cyg_LoaderStream_Mem(){    // nothing to do}    cyg_code Cyg_LoaderStream_Mem::get_byte(CYG_BYTE *val){    if( pos == end )        return CYG_LOADERR_EOF;    *val = *(CYG_BYTE *)pos;    pos++;        return CYG_LOADERR_NOERROR;}cyg_code Cyg_LoaderStream_Mem::get_data(CYG_BYTE *addr, CYG_ADDRWORD size){    if( pos == end || (pos+size) > end )        return CYG_LOADERR_EOF;    memcpy( (void *)addr, (void *)pos, size );    pos += size;        return CYG_LOADERR_NOERROR;}cyg_code Cyg_LoaderStream_Mem::seek(CYG_ADDRWORD apos){    CYG_ADDRWORD npos = base+apos;        if( npos > end || npos < base )        return CYG_LOADERR_SEEK;    pos = npos;    return CYG_LOADERR_NOERROR;}// =========================================================================// file based loader stream#ifdef CYGPKG_IO_FILEIO#include <unistd.h>Cyg_LoaderStream_File::Cyg_LoaderStream_File( int afd ){    fd = afd;}Cyg_LoaderStream_File::~Cyg_LoaderStream_File(){    // nothing to do    fd = 0;}    cyg_code Cyg_LoaderStream_File::get_byte(CYG_BYTE *val){    ssize_t got = read( fd, (void *)val, 1 );        if( got == 0 )        return CYG_LOADERR_EOF;    return CYG_LOADERR_NOERROR;}cyg_code Cyg_LoaderStream_File::get_data(CYG_BYTE *addr, CYG_ADDRWORD size){    ssize_t got = read( fd, (void *)addr, size );        if( got != (ssize_t)size )        return CYG_LOADERR_EOF;    return CYG_LOADERR_NOERROR;}cyg_code Cyg_LoaderStream_File::seek(CYG_ADDRWORD apos){    off_t npos = lseek( fd, apos, SEEK_SET );        if( npos != apos )        return CYG_LOADERR_SEEK;    return CYG_LOADERR_NOERROR;}#endif// =========================================================================// EOF loader.cxx

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -