summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rwxr-xr-xlib/Makefile2
-rw-r--r--lib/mipsdis.cpp7
-rw-r--r--lib/mipsobj.cpp269
3 files changed, 275 insertions, 3 deletions
diff --git a/lib/Makefile b/lib/Makefile
index b3d7399..3adf730 100755
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -3,7 +3,7 @@
CPPFLAGS=-Wall -g -O3 -mcpu=i686 -I../includes -DHAVE_ZLIB -DUSE_CDREADER -DDEBUG `baltisot-config --cflags` `lua-config --include`
CXX=g++
-OBJECTS = cdutils.o lzss.o yazedc.o cdreader.o cdabstract.o isobuilder.o luacd.o mips.o mipsmem.o mipsdis.o mipsdump.o
+OBJECTS = cdutils.o lzss.o yazedc.o cdreader.o cdabstract.o isobuilder.o luacd.o mips.o mipsmem.o mipsdis.o mipsdump.o mipsobj.o
TARGET = lib.a
all: ${TARGET}
diff --git a/lib/mipsdis.cpp b/lib/mipsdis.cpp
index a1b2a68..cbaf9e3 100644
--- a/lib/mipsdis.cpp
+++ b/lib/mipsdis.cpp
@@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* $Id: mipsdis.cpp,v 1.1 2004-01-03 15:04:47 pixel Exp $ */
+/* $Id: mipsdis.cpp,v 1.2 2004-01-26 15:31:55 pixel Exp $ */
#include "mipsdis.h"
#include "mips.h"
@@ -110,6 +110,7 @@ void Disassembler::crawl_code(Uint32 pc) {
while (dis->bheap.size()) {
branched = pc = dis->bheap.top();
dis->bheap.pop();
+ printm(M_STATUS, "Crawling to branch %8.8lX\n", pc);
do {
if (pc >= (0x80000000 + PSXMEM)) {
dis->invalid = true;
@@ -121,7 +122,7 @@ void Disassembler::crawl_code(Uint32 pc) {
}
mm->SetTag(pc, CODE, true);
- printm(M_STATUS, "%8.8lX\r", pc);
+ printm(M_STATUS, "Working at %8.8lX\n", pc);
decode(dis, pc);
pc += 4;
@@ -146,6 +147,7 @@ void Disassembler::mainloop(void) {
infunction = false;
// Crawl the start part.
+ printm(M_STATUS, "Starting crawl at %8.8lX\n", mm->GetPC());
if (!started)
crawl_code();
@@ -157,6 +159,7 @@ void Disassembler::mainloop(void) {
while (dis->fheap.size()) {
pc = dis->fheap.top();
dis->fheap.pop();
+ printm(M_STATUS, "Crawling function %8.8lX\n", pc);
if (mm->GetTag(pc, CODE))
continue;
crawl_code(pc);
diff --git a/lib/mipsobj.cpp b/lib/mipsobj.cpp
new file mode 100644
index 0000000..97663e6
--- /dev/null
+++ b/lib/mipsobj.cpp
@@ -0,0 +1,269 @@
+#include "mipsobj.h"
+
+section::section(const String & _name, int _type) : name(_name), type(_type), datas(0), length(0) { }
+section::section() : name(""), type(-1), datas(0), length(0) { }
+
+section::~section() {
+ if (datas)
+ free(datas);
+}
+
+void section::setname(const String & _name) {
+ name = _name;
+}
+
+void section::settype(int _type) {
+ type = _type;
+}
+
+void section::putdatas(const Uint8 * _datas, int _length) {
+ if (type != BSS) {
+ datas = (Uint8 *) realloc(datas, length + _length);
+ memcpy(datas + length, _datas, _length);
+ }
+ length += _length;
+}
+
+int section::gettype() {
+ return type;
+}
+
+int section::getsize() {
+ return length;
+}
+
+const Uint8 * section::getdatas() {
+ return datas;
+}
+
+void section::putreloc(const String & _symbol, int _type, Uint32 _offset) {
+ struct reloc_t r;
+
+ r.symbol = _symbol;
+ r.type = _type;
+ r.offset = _offset;
+
+ putreloc(r);
+}
+
+void section::putreloc(const struct reloc_t & r) {
+ relocs.push_back(r);
+}
+
+mipsobj::mipsobj() : loaded(false) { }
+
+mipsobj::~mipsobj() { }
+
+void loadELF(Handle * elf) throw (GeneralException) {
+}
+
+#define OBJSIG 0x024b4e4c
+
+#define READNAME(_str, _file) { \
+ char _name[256]; \
+ int _len; \
+ \
+ _len = _file->readU8(); \
+ _file->read(_name, _len); \
+ _name[_len] = 0; \
+ _str = _name; \
+}
+
+void mipsobj::loadOBJ(Handle * obj) throw (GeneralException) {
+ int cursec, len, reloctype, relocexpr, id;
+ bool eof = false;
+ std::map<int, String> secnames;
+ std::map<int, String> symbolnames;
+ Uint8 * datas;
+ struct reloc_t reloc;
+ struct symbol_t symbol;
+ String name;
+
+ while (!eof) {
+ int entryid = obj->readU8();
+
+ switch (entryid) {
+ case 0x00:
+ eof = true;
+ break;
+
+ case 0x02:
+ len = obj->readU16();
+ datas = (Uint8 *) malloc(len);
+
+ obj->read(datas, len);
+ sections[secnames[cursec]].putdatas(datas, len);
+
+ free(datas);
+ break;
+
+ case 0x06:
+ cursec = obj->readU16();
+ break;
+
+ case 0x08:
+ len = obj->readU32();
+
+ sections[secnames[cursec]].putdatas(0, len);
+ break;
+
+ case 0x0a:
+ reloctype = obj->readU8();
+ reloc.offset = obj->readU16();
+
+ switch (reloctype) {
+ case 0x10:
+ reloc.type = R_MIPS_32;
+ break;
+ case 0x4a:
+ reloc.type = R_MIPS_26;
+ break;
+ case 0x52:
+ reloc.type = R_MIPS_HI16;
+ break;
+ case 0x54:
+ reloc.type = R_MIPS_LO16;
+ break;
+ case 0x0a:
+ case 0x26:
+ case 0x28:
+ case 0x64:
+ printm(M_ERROR, "Relocation type %02x not supported.\n", reloctype);
+ exit(-1);
+ break;
+ default:
+ printm(M_ERROR, "Relocation type %02x UNKNOWN! Please send the object to the author.\n", reloctype);
+ exit(-1);
+ }
+
+ relocexpr = obj->readU8();
+
+ switch (relocexpr) {
+ case 0x02:
+ reloc.symbol = symbolnames[obj->readU16()];
+ break;
+ case 0x04:
+ reloc.symbol = secnames[obj->readU16()];
+ break;
+ case 0x00:
+ case 0x0c:
+ case 0x16:
+ case 0x2c:
+ case 0x2e:
+ case 0x30:
+ case 0x32:
+ case 0x36:
+ printm(M_ERROR, "Relocation expression %02x not supported.\n", relocexpr);
+ exit(-1);
+ break;
+ default:
+ printm(M_ERROR, "Relocation expression %02x UNKNOWN! Please mail the author.\n", relocexpr);
+ exit(-1);
+ break;
+ }
+
+ sections[secnames[cursec]].relocs.push_back(reloc);
+
+ break;
+
+ case 0x0c:
+ id = obj->readU16();
+ symbol.section = obj->readU16();
+ symbol.offset = obj->readU32();
+ READNAME(symbol.name, obj);
+ symbol.type = GLOBAL;
+
+ symbolnames[id] = symbol.name;
+
+ break;
+
+ case 0x0e:
+ id = obj->readU16();
+ READNAME(symbol.name, obj);
+ symbol.type = EXTERN;
+
+ symbolnames[id] = symbol.name;
+
+ break;
+
+ case 0x10:
+ id = obj->readU16();
+ obj->readU8();
+ obj->readU16();
+ READNAME(name, obj);
+
+ secnames[id] = name;
+
+ break;
+
+ case 0x12:
+ printm(M_WARNING, "Local symbol not supported.\n");
+ obj->readU16();
+ obj->readU32();
+ READNAME(name, obj);
+ break;
+
+ case 0x1c:
+ printm(M_WARNING, "File number and name not supported.\n");
+ obj->readU16();
+ READNAME(name, obj);
+ break;
+
+ case 0x2e:
+ if ((id = obj->readU8()) != 7) {
+ printm(M_ERROR, "CPU type %i not supported.\n", id);
+ exit(-1);
+ }
+ break;
+
+ case 0x30:
+ printm(M_ERROR, "Constant not supported.\n");
+ exit(-1);
+ break;
+
+ default:
+ printm(M_ERROR, "Object entry type %i UNKNOWN! Please send the object to the author.\n", entryid);
+ exit(-1);
+ break;
+ }
+ }
+}
+
+#define LIBSIG 0x0142494c
+
+void mipsobj::loadLIB(Handle * lib, const String & objname) throw (GeneralException) {
+ char _name[9];
+ String name;
+ int hsize, size, ptr;
+ bool found = false;
+
+ lib->seek(0);
+
+ if (lib->readU32() != LIBSIG) {
+ throw GeneralException("Not a Psy-Q lib file");
+ }
+
+ while (lib->tell() != lib->GetSize()) {
+ ptr = lib->tell();
+
+ lib->read(_name, 8);
+ name = _name;
+ lib->seek(4, SEEK_CUR);
+ hsize = lib->readU32();
+ size = lib->readU32();
+
+ if (objname == name.trim()) {
+ lib->seek(ptr + hsize);
+ found = true;
+ break;
+ }
+
+ lib->seek(ptr + size);
+ }
+
+ if (!found) {
+ throw GeneralException("Object `" + objname + "' not found in archive " + lib->GetName());
+ }
+
+ loadOBJ(lib);
+}