summaryrefslogtreecommitdiff
path: root/lib/mipsobj.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mipsobj.cpp')
-rw-r--r--lib/mipsobj.cpp538
1 files changed, 269 insertions, 269 deletions
diff --git a/lib/mipsobj.cpp b/lib/mipsobj.cpp
index 97663e6..233c5c5 100644
--- a/lib/mipsobj.cpp
+++ b/lib/mipsobj.cpp
@@ -1,269 +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);
-}
+#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);
+}