📄 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 + -