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

📄 image.cc

📁 这是著名的TCPMP播放器在WINDWOWS,和WINCE下编译通过的源程序.笔者对其中的LIBMAD库做了针对ARM MPU的优化. 并增加了词幕功能.
💻 CC
📖 第 1 页 / 共 2 页
字号:
/**********
 * Copyright (c) 2004 Greg Parker.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY GREG PARKER ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 **********/

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <fcntl.h>

#include "elf.h"
#include "got.h"
#include "swap.h"
#include "image.h"
#include "section.h"
#include "complain.h"
#include "symboltable.h"
#include "stringtable.h"

#ifndef O_BINARY
#define O_BINARY 0
#endif

// Max Palm resource size (actually 65505 for 3.0+)
// Note: this number must be in sync with peal.c.
#define RESOURCE_MAX 65400

// .prc header (68K-swapped!)
typedef struct {
    char name[32];
    uint16_t attr;
    uint16_t version;
    uint32_t created;
    uint32_t modified;
    uint32_t backup;
    uint32_t modnum;
    uint32_t appinfo;
    uint32_t sortinfo;
    char type[4];
    char creator[4];
    uint32_t uidseed;
    uint32_t nextlist;
    uint16_t count;
} __attribute__((packed,aligned(1))) prc_header;


// .prc resource header (68K-swapped!)
typedef struct {
    char type[4];
    uint16_t id;
    uint32_t offset;
} __attribute__((packed,aligned(1))) res_header;

void Image::allocate_sections()
{
    Elf32_Shdr *shdr = (Elf32_Shdr *)(mContents + mEhdr.e_shoff);
    mSections.resize(mEhdr.e_shnum);
    for (int i = 0; i < mEhdr.e_shnum; i++) {
        Elf32_Shdr *s = (Elf32_Shdr *)((uint8_t *)shdr+i*mEhdr.e_shentsize);
        Elf32_Word type = swap32(s->sh_type);
        sectionPointers.push_back(s);

        switch (type) {
        case SHT_NULL: 
        case SHT_PROGBITS:
        case SHT_NOBITS:
            mSections[i] = new Section(*this);
            break;
        case SHT_SYMTAB:
            mSections[i] = new SymbolTable(*this);
            break;
        case SHT_STRTAB:
            mSections[i] = new StringTable(*this);
            break;
        case SHT_REL:
            // nothing to do
            break;
        default:
            unimplemented("unrecognized section type %d\n", type);
            break;
        }
    }
}
    
void Image::read_sections()
{
    // strtabs
    for (unsigned int i = 0; i < sectionPointers.size(); i++) {
        Elf32_Shdr *s = sectionPointers[i];
        Elf32_Word type = swap32(s->sh_type);
        if (type == SHT_STRTAB) {
            mSections[i]->read(s);
            if (i == mEhdr.e_shstrndx) sectionNames = (StringTable *)mSections[i];
        }
    }
    

    // null
    for (unsigned int i = 0; i < sectionPointers.size(); i++) {
        Elf32_Shdr *s = sectionPointers[i];
        Elf32_Word type = swap32(s->sh_type);
        if (type == SHT_NULL) {
            mSections[i]->read(s);
        }
    }


    // allocated
    for (unsigned int i = 0; i < sectionPointers.size(); i++) {
        Elf32_Shdr *s = sectionPointers[i];
        Elf32_Word type = swap32(s->sh_type);
        if (type == SHT_PROGBITS  ||  type == SHT_NOBITS) {
            mSections[i]->read(s);
            if (!mGOT  &&  mSections[i]->name() == ".got") {
                delete mSections[i];
                mGOT = new GOT(*this);
                mSections[i] = mGOT;
                mGOT->read(s);
            }
        }
    }
    
    
    // symtab
    for (unsigned int i = 0; i < sectionPointers.size(); i++) {
        Elf32_Shdr *s = sectionPointers[i];
        Elf32_Word type = swap32(s->sh_type);
        if (type == SHT_SYMTAB) {
            mSections[i]->read(s);
            mSymtab = (SymbolTable *)mSections[i];
        }
    }
    
    
    // relocations
    for (unsigned int i = 0; i < sectionPointers.size(); i++) {
        Elf32_Shdr *s = sectionPointers[i];
        Elf32_Word type = swap32(s->sh_type);
        if (type == SHT_REL) {
            mSections[swap32(s->sh_info)]->applyRelocations(s);
        }
    }
}


Image::Image(uint8_t *buf)
{
    mContents = buf;
    memcpy(&mEhdr, mContents, sizeof(mEhdr));
    swap_ehdr(&mEhdr);

    sectionNames = NULL;
    mGOT = NULL;
    mSymtab = NULL;

    // Perform some sanity checks against the ELF header
    
    if (!IS_ELF(mEhdr)) {
        error("not an ELF file (bad magic number)");
    }

    if (mEhdr.e_ident[EI_CLASS] != ELFCLASS32) {
        error("not a 32-bit ELF file");
    }

    if (mEhdr.e_ident[EI_DATA] != ELFDATA2LSB) {
        error("not a little-endian ELF file");
    }

    if (mEhdr.e_ident[EI_VERSION] != EV_CURRENT) {
        error("not a version %d ELF file", EV_CURRENT);
    }

    if (mEhdr.e_ident[EI_OSABI] != ELFOSABI_ARM) {
        error("not an ARM ABI ELF file");
    }

    if (mEhdr.e_type != ET_EXEC) {
        error("not an executable ELF file");
    }

    if (mEhdr.e_machine != EM_ARM) {
        error("not an ARM machine ELF file");
    }

    if (mEhdr.e_version != EV_CURRENT) {
        error("not a version %d ELF file", EV_CURRENT);
    }


    // Allocate all sections. They must all be allocated before any are 
    // read because of cyclic references. 

    allocate_sections();


    // Read all sections.

    read_sections();
}


void Image::addSectionGlobals()
{
    vector<Section *>::iterator iter;
    for (iter = mSections.begin(); iter != mSections.end(); ++iter) 
    {
        Section *section = *iter;
        if (section  &&  (section->type() == SHT_NOBITS  ||  
                          section->type() == SHT_PROGBITS)) 
        {
            Symbol *sym = section->baseSymbol();
            mSymtab->addSymbol(sym);
        }
    }
}

void Image::trimSections(void)
{
    vector<Section *> newSections;

    for (unsigned int i = 0; i < mSections.size(); i++) {
        Section *s = mSections[i];
        if (!s) continue;
        uint32_t type = s->type();

        // elided: relocs, strtabs other than main strtab
        if (!(type == SHT_NULL  ||  type == SHT_SYMTAB  ||  
              type == SHT_NOBITS  ||  type == SHT_PROGBITS))
            continue;
        // elided: useless named sections
        if (s->name() == ".disposn"  ||  s->name() == ".got.plt"  ||  
            s->name() == ".comment"  ||  
            0 == strncmp(s->name().c_str(), ".debug", 6)  ||
            0 == strncmp(s->name().c_str(), ".debu.", 6))
            continue;

⌨️ 快捷键说明

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