📄 image.cc
字号:
/**********
* 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 + -