diff options
author | pixel <pixel> | 2005-12-02 11:28:26 +0000 |
---|---|---|
committer | pixel <pixel> | 2005-12-02 11:28:26 +0000 |
commit | ce887d66a761c7b84ba8011d8bc47e3c83bb5488 (patch) | |
tree | 4b714d940bcd460e0bc6371ee223267f13fdc935 /lib/binwriter-elf.cpp | |
parent | 9ecacd862cd0f6e1041a668d626862ed49d2e8a1 (diff) |
Adding PSx-Patcher to the tree.
Diffstat (limited to 'lib/binwriter-elf.cpp')
-rw-r--r-- | lib/binwriter-elf.cpp | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/lib/binwriter-elf.cpp b/lib/binwriter-elf.cpp new file mode 100644 index 0000000..81755d7 --- /dev/null +++ b/lib/binwriter-elf.cpp @@ -0,0 +1,144 @@ +/* + * PSX-Tools Bundle Pack + * Copyright (C) 2002-2005 Nicolas "Pixel" Noble + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* $Id: binwriter-elf.cpp,v 1.1 2005-12-02 11:28:27 pixel Exp $ */ + +#include "binwriter-elf.h" +#include "binary-elf.h" + +#ifdef WORDS_BIGENDIAN +static void sw32(u32 & x) { + x = (x >> 24) | ((x >> 8) & 0x0000ff00) | ((x << 8) & 0x00ff0000) | (x << 24); +} +static void sw16(u16 & x) { + x = (x >> 8) | ((x << 8); +} +#else +#define sw32(x) while(0) +#define sw16(x) while(0) +#endif + +static u8 elf_ident[] = { + 0x7F, 0x45, 0x4C, 0x46, 0x01, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +// works only with align == 2^n +static Uint32 align_it(Uint32 address, int align) { + if (address & (--align)) { + address |= align; + address++; + } + + return address; +} + +void BinWriter_elf::dump(Handle * elf) { + struct elf_header_t weh; + struct elf_pheader_t weph; + int i; + std::vector<struct SectionOut>::iterator iter; + Uint32 offset = 0x1000; + + for (i = 0; i < 16; i++) { + weh.e_ident.raw[i] = elf_ident[i]; + } + weh.e_type = 2; + weh.e_machine = 8; + weh.e_version = 1; + weh.e_phoff = sizeof(weh); + weh.e_shoff = 0; + weh.e_flags = 0; + weh.e_ehsize = sizeof(weh); + weh.e_phentsize = sizeof(weph); + weh.e_phnum = sections.size(); + weh.e_shoff = 0; + weh.e_shnum = 0; + weh.e_shentsize = 0; + weh.e_entry = epc; + weh.e_shstrndx = 0; + + sw16(weh.e_type); + sw16(weh.e_machine); + sw32(weh.e_version); + sw32(weh.e_entry); + sw32(weh.e_phoff); + sw32(weh.e_shoff); + sw32(weh.e_flags); + sw16(weh.e_ehsize); + sw16(weh.e_phentsize); + sw16(weh.e_phnum); + sw16(weh.e_shentsize); + sw16(weh.e_shnum); + sw16(weh.e_shstrndx); + + elf->write(&weh, sizeof(weh)); + + + for (iter = sections.begin(); iter != sections.end(); iter++) { + weph.type = PT_LOAD; + weph.flags = PF_R | PF_W | PF_X; + weph.offset = offset; + weph.vaddr = iter->base; + weph.paddr = iter->base; + weph.filesz = iter->real_size; + weph.memsz = iter->whole_size; + weph.align = 0x1000; + + offset += iter->real_size; + offset = align_it(offset, 0x1000); + + sw32(weph.type); + sw32(weph.flags); + sw32(weph.offset); + sw32(weph.vaddr); + sw32(weph.paddr); + sw32(weph.filesz); + sw32(weph.memsz); + sw32(weph.align); + + elf->write(&weph, sizeof(weph)); + } + + offset = 0x1000; + + for (iter = sections.begin(); iter != sections.end(); iter++) { + elf->seek(offset); + if (iter->data) { + elf->write(iter->data, iter->real_size); + offset += iter->real_size; + } else { + offset++; + } + offset = align_it(offset, 0x1000); + } +} + +#if 0 +static Uint32 elf_hash(const unsigned char * name) { + Uint31 h = 0, g; + + while (*name) { + h = (h << 4) + *name++; + if ((g = h & 0xf0000000) + h ^= g >> 24; + h &= ~g; + } +} +#endif |