12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244 |
- // Written by Julien Muchembled.
- // Fixed by Romain Lievin for Linux.
- // Further modifications by Sebastian Reichelt, Kevin Kofler and Paul Froissart.
- // Copyright (c) 2001-2002. All rights reserved.
- // default: don't include AmigaOS support
- //#define SUPPORT_AMIGA
- // This needs to be defined BEFORE including obj2ti.h, since it is used in
- // that header.
- #include "obj2ti.h"
- // default: don't print out extra debugging information
- //#define TEXT_DEBUG
- #ifdef TEXT_DEBUG
- # define DEBUG_PRINT(str...) (printf (str))
- #else
- # define DEBUG_PRINT(str...)
- #endif
- // default: catch symbols with unknown class
- #define CHECK_SYMBOLS
- #define MAX_VAR_SIZE 65517
- __inline unsigned short br2 (void *pp)
- {
- unsigned char *p = (unsigned char *) pp;
- return ((unsigned short) p[0] << 8) + (unsigned short) p[1];
- }
- __inline unsigned long br4 (void *pp)
- {
- unsigned char *p = (unsigned char *) pp;
- return ((unsigned long) p[0] << 24) + ((unsigned long) p[1] << 16)
- + ((unsigned long) p[2] << 8) + (unsigned long) p[3];
- }
- __inline void bw2 (void *pp, unsigned short w)
- {
- unsigned char *p = (unsigned char *) pp;
- *p++ = (unsigned char)(w>>8);
- *p = (unsigned char) w;
- }
- __inline void bw4 (void *pp, unsigned long dw)
- {
- unsigned char *p = (unsigned char *) pp;
- *p++ = (unsigned char)(dw>>24);
- *p++ = (unsigned char)(dw>>16);
- *p++ = (unsigned char)(dw>>8);
- *p = (unsigned char) dw;
- }
- __inline void ba4 (void *p, unsigned long dw)
- { bw4 (p, br4 (p) + dw); }
- __inline unsigned short lr2 (void *pp)
- {
- unsigned char *p = (unsigned char *) pp;
- return (unsigned short) p[0] + ((unsigned short) p[1] << 8);
- }
- __inline unsigned long lr4 (void *pp)
- {
- unsigned char *p = (unsigned char *) pp;
- return (unsigned long) p[0] + ((unsigned long) p[1] << 8)
- + ((unsigned long) p[2] << 16) + ((unsigned long) p[3] << 24);
- }
- __inline void lw2 (void *pp, unsigned short w)
- {
- unsigned char *p = (unsigned char *) pp;
- *p++ = (unsigned char) w;
- *p = (unsigned char)(w>>8);
- }
- __inline void lw4 (void *pp, unsigned long dw)
- {
- unsigned char *p = (unsigned char *) pp;
- *p++ = (unsigned char) dw;
- *p++ = (unsigned char)(dw>>=8);
- *p++ = (unsigned char)(dw>>=8);
- *p = (unsigned char)(dw>>8);
- }
- __inline void la4 (void *p, unsigned long dw)
- { lw4 (p, lr4 (p) + dw); }
- void Object::AllocExt (int CurHunk, Import **Imp16, Import **Imp32, Export **Exports)
- {
- if (Hunk[CurHunk].nImp16)
- *Imp16 = Hunk[CurHunk].Imp16 = new Import[Hunk[CurHunk].nImp16];
- if (Hunk[CurHunk].nImp32)
- *Imp32 = Hunk[CurHunk].Imp32 = new Import[Hunk[CurHunk].nImp32];
- if (Hunk[CurHunk].nExports)
- *Exports = Hunk[CurHunk].Exports = new Export[Hunk[CurHunk].nExports];
- }
- #ifdef SUPPORT_AMIGA
- ObjErr Object::ReadAmiga ()
- {
- int CurHunk=-1; unsigned long *am = o32, size, *Ext[3]={NULL,NULL,NULL};
- bBadExport = true;
- for (size=Size>>2; size>0; size--) {
- DWORD n, HunkType = br4(am++);
- n = br4 (am);
- switch (HunkType) {
- default: return OBJERR_HunkType;
- case HunkUnit:
- case HunkName:
- case HunkDbg:
- size -= ++n; am += n;
- case HunkEnd: break;
- case HunkCode:
- if (CodeHunk >= 0) return OBJERR_NbScns;
- else {
- CodeHunk = ++CurHunk;
- Hunk[CurHunk].size = n << 2;
- Hunk[CurHunk].o32 = ++am;
- am += n; size -= n+1;
- } break;
- case HunkData:
- if (DataHunk >= 0) return OBJERR_NbScns;
- else {
- DataHunk = ++CurHunk;
- Hunk[CurHunk].size = n << 2;
- Hunk[CurHunk].o32 = ++am;
- am += n; size -= n+1;
- } break;
- case HunkBSS:
- if (BSSHunk >= 0) return OBJERR_NbScns;
- else Hunk[BSSHunk = ++CurHunk].size = n << 2, am++, size--;
- break;
- case HunkR16:
- fprintf (stderr, "Warning: 16-bit relocations are unsupported.\n");
- for (; size>0 && n; n=br4 (am))
- n += 2, am += n, size -= n;
- am++; size--; break;
- case HunkR32:
- if (CurHunk < 0) return OBJERR_R32Hunk;
- else {
- for (; size>0 && n; n=br4 (am)) {
- DWORD k = br4 (++am);
- if (k < 3 && !Hunk[CurHunk].R32[k]) {
- unsigned long *R32;
- Hunk[CurHunk].nR32[k] = n;
- Hunk[CurHunk].R32[k] = R32 = new unsigned long [n];
- for (am++; n--; size--) *R32++ = br4 (am++);
- size -= 2;
- } else return OBJERR_R32Hunk;
- } am++; size--;
- } break;
- case HunkExt:
- if (CurHunk < 0 || Ext[CurHunk]) return OBJERR_ExtHunk;
- else {
- unsigned char type; unsigned long nExtRefs=0, nImports=0;
- Ext[CurHunk] = am;
- do {
- n = (br4 (am) & 0xFFFFFF) + 1;
- switch (type = *(unsigned char *)am++) {
- default: return OBJERR_ExtType;
- case TypeEnd: break;
- case TypeImport32:
- Hunk[CurHunk].nImp32++;
- case TypeImport16:
- case TypeImport16Alt:
- am += n; size -= n;
- n = br4 (am-1);
- nImports++;
- case TypeExport:
- am += n; size -= n; nExtRefs++;
- } } while (size-- > 0 && type != TypeEnd);
- if (!nExtRefs) Ext[CurHunk] = NULL;
- else {
- Hunk[CurHunk].nExports = nExtRefs - nImports;
- Hunk[CurHunk].nImp16 = nImports - Hunk[CurHunk].nImp32;
- } } } }
- if (size) return OBJERR_Size;
- if (CurHunk < 0) return OBJERR_NbScns;
- nscns = CurHunk+1;
- for (CurHunk=0; (unsigned int)CurHunk<nscns; CurHunk++)
- if ((am = Ext[CurHunk])) {
- unsigned char type;
- Import *Imp16, *Imp32; Export *Exports;
- AllocExt (CurHunk, &Imp16, &Imp32, &Exports);
- while ((type = *(unsigned char *)am) != TypeEnd) {
- unsigned long *rlc, n = br4 (am++) & 0xFFFFFF;
- switch (type) {
- case TypeImport32:
- Imp32->name = (char *)am;
- am += n; n = br4 (am++);
- Imp32->nrlcs = n;
- Imp32->rlc = rlc = new unsigned long [n];
- while (n--) *rlc++ = br4 (am++);
- Imp32++;
- break;
- case TypeImport16:
- case TypeImport16Alt:
- Imp16->name = (char *)am;
- am += n; n = br4 (am++);
- Imp16->nrlcs = n;
- Imp16->rlc = rlc = new unsigned long [n];
- while (n--) *rlc++ = br4 (am++);
- Imp16++;
- break;
- case TypeExport:
- Exports->name = (char *)am; am += n;
- //Exports->size = 0;
- Exports->value = br4 (am++);
- Exports++;
- } } }
- return OBJERR_OK;
- }
- #endif
- char *Object::COFF_ReadName (SYMENT *sym, char *Str)
- {
- return br4 (sym->e.e.e_zeroes) ?
- sym->e.e_name :
- &Str[br4 (sym->e.e.e_offset)];
- }
- ObjErr Object::ReadCOFF ()
- {
- int CurHunk=BSSHunk=0; SCNHDR *scn = (SCNHDR *)&o8[sizeof(FILHDR)];
- RELOC *Relocs[2]; unsigned short nrlcs[2];
- unsigned long i, nSyms, s_vaddr[3];
- nscns = br2 (filhdr->f_nscns);
- if (nscns < 3) return OBJERR_NbScns;
- if (nscns > 3) {
- fprintf (stderr, "Warning: More than 3 COFF sections. Excess sections ignored.\n");
- nscns = 3;
- }
- if (br2 (filhdr->f_opthdr)) return OBJERR_OptHdr;
- s_vaddr[0] = 0;
- for (i=0; i<nscns; i++)
- switch (br4 (scn[i].s_flags) & (STYP_TEXT | STYP_DATA | STYP_BSS)) {
- default: return OBJERR_ScnType;
- case STYP_TEXT | STYP_DATA:
- case STYP_TEXT:
- if (CodeHunk >= 0) return OBJERR_NbScns;
- else {
- Relocs[CurHunk] = (RELOC *)&o8[br4 (scn[i].s_relptr)];
- nrlcs[CurHunk] = br2 (scn[i].s_nreloc);
- Hunk[CodeHunk = ++CurHunk].o8 = &o8[br4 (scn[i].s_scnptr)];
- Hunk[CurHunk].size = br4 (scn[i].s_size);
- s_vaddr[CurHunk] = br4 (scn[i].s_vaddr);
- }
- break;
- case STYP_BSS:
- // This program can only work properly if the BSS section is the last
- // one.
- if (CurHunk != (int) nscns - 1) return OBJERR_NbScns;
- else {
- // Objcopy produces real BSS sections, while the GNU assembler
- // simply leaves an empty section.
- // Both versions will work here, since the relocs are different
- // (section 0 (none) vs. section 3).
- Hunk[0].size = br4 (scn[i].s_size);
- // This is just a stupid number which has to be subtracted from all
- // relocs.
- s_vaddr[0] = br4 (scn[i].s_vaddr);
- }
- break;
- case STYP_DATA:
- if (DataHunk >= 0) return OBJERR_NbScns;
- else {
- Relocs[CurHunk] = (RELOC *)&o8[br4 (scn[i].s_relptr)];
- nrlcs[CurHunk] = br2 (scn[i].s_nreloc);
- Hunk[DataHunk = ++CurHunk].o8 = &o8[br4 (scn[i].s_scnptr)];
- Hunk[CurHunk].size = br4 (scn[i].s_size);
- s_vaddr[CurHunk] = br4 (scn[i].s_vaddr);
- }
- break;
- }
- SYMENT *sym, *Sym = (SYMENT *)&o8[br4 (filhdr->f_symptr)];
- char *Str = (char *)&Sym[nSyms = br4 (filhdr->f_nsyms)];
- struct SYMNFO {
- unsigned char ok;
- unsigned char R32;
- unsigned char IsBSSSymbol;
- unsigned short hunk;
- struct {
- unsigned short n16;
- unsigned short n32;
- } Hunk[2];
- } *SymNfo = (SYMNFO *)_alloca (nSyms*sizeof(SYMNFO));
- unsigned long *R32[2][3];
- memset (&R32, 0, sizeof (R32)); memset (SymNfo, 0, nSyms*sizeof(SYMNFO));
- /************************************\
- | Basic symbol and relocation info |
- \************************************/
- // Read in the symbol table and build the SymNfo table with additional
- // information.
- // FIXME: Imported symbols shouldn't be considered as exports as well.
- for (sym=Sym,i=0; i<nSyms; sym++,i++) {
- DEBUG_PRINT ("Symbol %ld: Type 0x%lx; Section %ld; Value 0x%lx\n", (long) i, (long) (br2 (sym->e_sclass)), (long) (short) (br2 (sym->e_scnum)), (long) (br4 (sym->e_value)));
- #ifdef CHECK_SYMBOLS
- switch (br2 (sym->e_sclass)) {
- // All non-standard symbols are not 'ok'.
- case 0x200:
- case 0x201:
- case 0x300:
- case 0x301:
- #endif
- { unsigned int hunk = br2 (sym->e_scnum);
- if (hunk == nscns) {
- // It is a symbol in the BSS section, as objcopy produces them.
- // This program assumes that the BSS section is the last one.
- // This could be greatly simplified if we assume that there is
- // always just one single symbol (called '.bss') at the start of
- // the BSS section.
- SymNfo[i].IsBSSSymbol = 1;
- SymNfo[i].R32 = 1;
- ba4 (sym->e_value, (DWORD)-(long)s_vaddr[0]);
- }
- if (hunk >= nscns) hunk = 0;
- Hunk[SymNfo[i].hunk = hunk].nExports++;
- SymNfo[i].ok = 1;
- }
- #ifdef CHECK_SYMBOLS
- }
- #endif
- }
- // Here the number of imports and relocations is read in. No relocation is
- // actually done.
- for (CurHunk=1; (unsigned int)CurHunk<nscns; CurHunk++) {
- unsigned short j; RELOC *rlc = Relocs[CurHunk-1];
- for (j=nrlcs[CurHunk-1]; j; rlc++,j--) {
- unsigned long i = br4 (rlc->r_symndx);
- sym = &Sym[i];
- if (SymNfo[i].ok) {
- unsigned long value = br4 (sym->e_value);
- DEBUG_PRINT ("Reloc %ld: Type 0x%lx; Section %ld; Address 0x%lx\n", (long) (nrlcs[CurHunk-1] - j + 1), (long) (br2 (rlc->r_type)), (long) CurHunk, (long) (long) (br4 (rlc->r_vaddr)));
- DEBUG_PRINT (" Symbol %ld (%s)\n", (long) i, COFF_ReadName (sym, Str));
- switch (br2 (rlc->r_type)) {
- default:
- return OBJERR_RlcType;
- case 0x10:
- case 0x13:
- DEBUG_PRINT (" 16-bit reloc\n");
- if (!value && !SymNfo[i].hunk) {
- DEBUG_PRINT (" Normal reloc: Section %ld; Address 0x%lx\n", (long) SymNfo[i].hunk, (long) (br4 (sym->e_value)));
- if (!SymNfo[i].Hunk[CurHunk-1].n16++) Hunk[CurHunk].nImp16++;
- }
- break;
- case 0x11:
- case 0x14:
- // Warning: BSSHunk is 0.
- // And 0 is also used for imported symbols, which don't have a
- // section they reside in.
- // Luckily however, we can decide by looking at the value:
- // If it's 0, it's an import, like a ROM_CALL or RAM_CALL.
- // Otherwise, we have a BSS entry. The value then marks the size
- // of the entry, in bytes.
- // That means we simply replace the value by an offset into the
- // BSS section (plus s_vaddr, because COFF requires it). Since
- // this offset can be 0 for the first symbol in the BSS section,
- // we sign a special flag.
- if (SymNfo[i].hunk==0) {
- DEBUG_PRINT (" Symbol has section 0\n");
- DEBUG_PRINT (" Value: %ld (marked as BSS: %ld)\n", (long) value, (long) SymNfo[i].IsBSSSymbol);
- if (value || SymNfo[i].IsBSSSymbol) {
- DEBUG_PRINT (" Inserting reloc into BSS section (0)\n");
- Hunk[CurHunk].nR32[0]++;
- if (!SymNfo[i].R32) {
- unsigned long blocksize = value;
- SymNfo[i].R32 = 1;
- SymNfo[i].IsBSSSymbol = 1;
- bw4 (sym->e_value, value = s_vaddr[0] + Hunk[0].size);
- Hunk[0].size += blocksize;
- DEBUG_PRINT (" New BSS size: %ld\n", (long) Hunk[0].size);
- DEBUG_PRINT (" New value for symbol: %ld\n", (long) value);
- }
- } else {
- DEBUG_PRINT (" Adding import\n");
- if (!SymNfo[i].Hunk[CurHunk-1].n32++) Hunk[CurHunk].nImp32++;
- }
- } else {
- DEBUG_PRINT (" Normal reloc: Section %ld; Address 0x%lx\n", (long) SymNfo[i].hunk, (long) (br4 (sym->e_value)));
- Hunk[CurHunk].nR32[SymNfo[i].hunk]++;
- SymNfo[i].R32 = 1;
- } }
- } else {
- fprintf (stderr, "Warning: Removing reloc to unsupported symbol '%s'.\n", COFF_ReadName (sym, Str));
- } } }
- /*****************************************************\
- | Allocation of export, import, and relocation tables |
- \*****************************************************/
- // All tables are built up using the results from the counting above.
- Export *Exports[3]={NULL,NULL,NULL};
- unsigned long **Imp16rlc[3], **Imp32rlc[3];
- for (i=0; i<nscns; i++) {
- Import *Imp16=NULL, *Imp32=NULL;
- // Allocate imports and exports for hunk i using its nImp16 etc. values.
- AllocExt (i, &Imp16, &Imp32, &Exports[i]);
- if (i) {
- unsigned int n16=0, n32=0;
- unsigned long j, **pImp16rlc, **pImp32rlc;
- pImp16rlc = Imp16rlc[i] = Hunk[i].nImp16 ? new unsigned long *[Hunk[i].nImp16] : NULL;
- pImp32rlc = Imp32rlc[i] = Hunk[i].nImp32 ? new unsigned long *[Hunk[i].nImp32] : NULL;
- for (sym=Sym,j=0; j<nSyms; sym++,j++)
- if (!SymNfo[j].hunk) {
- if (SymNfo[j].Hunk[i-1].n16) {
- Imp16->name = COFF_ReadName (sym, Str);
- Imp16->nrlcs = SymNfo[j].Hunk[i-1].n16;
- Imp16->rlc = *pImp16rlc++ = new unsigned long [Imp16->nrlcs];
- Imp16++; SymNfo[j].Hunk[i-1].n16 = ++n16;
- }
- if (SymNfo[j].Hunk[i-1].n32) {
- Imp32->name = COFF_ReadName (sym, Str);
- Imp32->nrlcs = SymNfo[j].Hunk[i-1].n32;
- Imp32->rlc = *pImp32rlc++ = new unsigned long [Imp32->nrlcs];
- Imp32++; SymNfo[j].Hunk[i-1].n32 = ++n32;
- } }
- // Allocate the relocation tables.
- for (j=0; j<nscns; j++) if (Hunk[i].nR32[j])
- R32[i-1][j] = Hunk[i].R32[j] = new unsigned long [Hunk[i].nR32[j]];
- } }
- /******************************\
- | Initialization of all tables |
- \******************************/
- // Initialize export tables.
- for (sym=Sym,i=0; i<nSyms; sym++,i++)
- if (SymNfo[i].ok) {
- Exports[SymNfo[i].hunk]->name = COFF_ReadName (sym, Str);
- Exports[SymNfo[i].hunk]->value = br4 (sym->e_value);
- Exports[SymNfo[i].hunk]++;
- }
- // Initialize import and relocation tables, and relocate.
- for (CurHunk=1; (unsigned int)CurHunk<nscns; CurHunk++) {
- unsigned long j; RELOC *rlc = Relocs[CurHunk-1];
- for (j=nrlcs[CurHunk-1]; j; rlc++,j--) {
- unsigned long i = br4 (rlc->r_symndx);
- if (SymNfo[i].ok) {
- int k; unsigned long ofs;
- ofs = br4 (rlc->r_vaddr) - s_vaddr[CurHunk];
- switch (br2 (rlc->r_type)) {
- case 0x10:
- case 0x13:
- if ((k = SymNfo[i].Hunk[CurHunk-1].n16))
- *Imp16rlc[CurHunk][k-1]++ = ofs;
- break;
- case 0x11:
- case 0x14:
- if (SymNfo[i].R32) {
- *R32[CurHunk-1][SymNfo[i].hunk]++ = ofs;
- DEBUG_PRINT ("Relocating 32 bits at offset 0x%lx in section %ld\n", (long) ofs, (long) CurHunk);
- DEBUG_PRINT (" Old value: 0x%lx\n", (long) br4 (&Hunk[CurHunk].o8[ofs]));
- ba4 (&Hunk[CurHunk].o8[ofs], (SymNfo[i].IsBSSSymbol ? br4 (Sym[i].e_value) : 0) + ((DWORD)-(long)s_vaddr[SymNfo[i].hunk]));
- DEBUG_PRINT (" New value: 0x%lx\n", (long) br4 (&Hunk[CurHunk].o8[ofs]));
- } else if ((k = SymNfo[i].Hunk[CurHunk-1].n32))
- *Imp32rlc[CurHunk][k-1]++ = ofs;
- } } }
- Delete (Imp16rlc[CurHunk]);
- Delete (Imp32rlc[CurHunk]);
- }
- return OBJERR_OK;
- }
- ObjErr Object::Read (char *FileName)
- {
- long size = 0;
- FILE *f = fopen (FileName, "rb");
- if (!f) return OBJERR_Open;
- fseek (f, 0, SEEK_END);
- Size = ftell (f); rewind (f);
- if ((o0 = malloc (Size)))
- size = fread (o0, 1, Size, f);
- fclose (f);
- if (!o0) return OBJERR_Mem;
- if (size != Size) return OBJERR_Read;
- switch (br2 (o0)) {
- #ifdef SUPPORT_AMIGA
- case 0:
- ObjFmt = OBJFMT_Amiga;
- return ReadAmiga ();
- #endif
- case 0x150:
- ObjFmt = OBJFMT_COFF;
- return ReadCOFF ();
- }
- return OBJERR_Unknown;
- }
- void Object::MergeImp (
- unsigned long nImp1, Import * Imp1,
- unsigned long &nImp2, Import * &Imp2,
- unsigned long size)
- {
- unsigned long n; Import *imp2 = Imp2;
- for (n=0; n<nImp2; imp2++,n++) {
- unsigned long k, *rlc = imp2->rlc;
- for (k=imp2->nrlcs; k--; rlc++) *rlc += size;
- Import *imp1 = Imp1;
- for (k=nImp1; k--; imp1++)
- if (!strcmp (imp1->name, imp2->name)) {
- unsigned long i, j;
- i = imp1->nrlcs; j = imp2->nrlcs;
- rlc = new unsigned long [i+j];
- memcpy (rlc, imp1->rlc, i * sizeof (long));
- memcpy (&rlc[i], imp2->rlc, j * sizeof (long));
- Delete (imp1->rlc); Delete (imp2->rlc);
- imp1->rlc = rlc; imp1->nrlcs += j;
- if (!--nImp2) Delete (Imp2);
- else {
- memmove (imp2, imp2+1, (nImp2-n--) * sizeof (Import));
- imp2--;
- } break;
- } }
- }
- void Object::Merge2 (
- unsigned long &n1, void * &p1,
- unsigned long &n2, void * &p2,
- unsigned long SizeOf)
- {
- if (n2) {
- unsigned char *p = new unsigned char [(n1+n2)*SizeOf];
- memcpy (p, p1, n1 * SizeOf);
- memcpy (&p[n1*SizeOf], p2, n2 * SizeOf);
- DeleteCast (unsigned char **, p1);
- DeleteCast (unsigned char **, p2);
- n1 += n2; n2 = 0;
- p1 = p;
- }
- }
- void Object::Merge (int &First, int &Second)
- {
- int first, second;
- if ((unsigned int)(second=Second) < nscns) {
- if ((unsigned int)(first=First) < nscns) {
- int hunk; unsigned long size = Hunk[first].size;
- for (hunk=0; hunk<(int)nscns; hunk++) if (hunk != second) {
- unsigned long i, *R32 = Hunk[second].R32[hunk];
- for (i=Hunk[second].nR32[hunk]; i--; R32++) *R32 += size;
- }
- MergeImp (
- Hunk[first].nImp16, Hunk[first].Imp16,
- Hunk[second].nImp16, Hunk[second].Imp16,
- size);
- MergeImp (
- Hunk[first].nImp32, Hunk[first].Imp32,
- Hunk[second].nImp32, Hunk[second].Imp32,
- size);
- {
- unsigned long i; Export *exp = Hunk[second].Exports;
- for (i=Hunk[second].nExports; i--; exp++) exp->value += size;
- }
- for (hunk=0; hunk<(int)nscns; hunk++) {
- unsigned long i, j, *R32_1, *R32_2;
- i = Hunk[hunk].nR32[first]; j = Hunk[hunk].nR32[second];
- Hunk[hunk].nR32[first] += j; Hunk[hunk].nR32[second] = 0;
- R32_1 = new unsigned long [i+j];
- memcpy (R32_1, Hunk[hunk].R32[first], i*sizeof(long));
- Delete (Hunk[hunk].R32[first]);
- Hunk[hunk].R32[first] = R32_1; R32_1 += i;
- R32_2 = Hunk[hunk].R32[second];
- for (; j--; R32_1++) {
- ba4 (&Hunk[hunk].o8[*R32_1 = *R32_2++], size);
- if (hunk == second) *R32_1 += size;
- }
- Delete (Hunk[hunk].R32[second]);
- }
- for (hunk=0; hunk<(int)nscns; hunk++) if (hunk != second) {
- unsigned long i, j, *R32;
- i = Hunk[first].nR32[hunk]; j = Hunk[second].nR32[hunk];
- Hunk[first].nR32[hunk] += j; Hunk[second].nR32[hunk] = 0;
- R32 = new unsigned long [i+j];
- memcpy (R32, Hunk[first].R32[hunk], i*sizeof(long));
- memcpy (&R32[i], Hunk[second].R32[hunk], j*sizeof(long));
- Delete (Hunk[first].R32[hunk]);
- Delete (Hunk[second].R32[hunk]);
- Hunk[first].R32[hunk] = R32;
- }
- Merge2 (Hunk[first].nImp16, (void * &) Hunk[first].Imp16, Hunk[second].nImp16, (void * &) Hunk[second].Imp16, sizeof (Import));
- Merge2 (Hunk[first].nImp32, (void * &) Hunk[first].Imp32, Hunk[second].nImp32, (void * &) Hunk[second].Imp32, sizeof (Import));
- Merge2 (Hunk[first].nExports, (void * &) Hunk[first].Exports, Hunk[second].nExports, (void * &) Hunk[second].Exports, sizeof (Export));
- unsigned size2 = Hunk[second].size;
- Hunk[first].size += size2; Hunk[second].size = 0;
- unsigned char *o8 = new unsigned char [size + size2];
- memcpy (o8, Hunk[first].o0, size);
- memcpy (&o8[size], Hunk[second].o0, size2);
- if (Hunk[second].DelDat)
- DeleteCast (unsigned char **, Hunk[second].o0);
- if (Hunk[first].DelDat)
- DeleteCast (unsigned char **, Hunk[first].o0);
- else Hunk[first].DelDat = true;
- Hunk[first].o8 = o8;
- } else First = second, Second = first;
- }
- }
- #define CONFLICT "%s is incompatible with %s"
- TI68kErr TI68k::Conflict (TI68kType Type2)
- {
- if (szErr) {
- Delete (szErr[TI68kERR_Conflict-1]);
- char *msg = szErr[TI68kERR_Conflict-1] = new char [
- sizeof(CONFLICT) - 4
- + strlen(szTI68kType[Type2-1])
- + strlen(szTI68kType[Type-1])];
- sprintf (msg, CONFLICT, szTI68kType[Type2-1], szTI68kType[Type-1]);
- } return TI68kERR_Conflict;
- }
- void TI68k::UndefRef (Import *imp)
- {
- fprintf (stderr, "Error: %lu undefined reference(s) to '%s'.\n", imp->nrlcs, imp->name);
- }
- enum { RAM32, eRAM32, RAM16, eRAM16, ROM, LIBS };
- TI68kErr TI68k::MakeDoorsOS ()
- {
- bool bErr=false; Import *imp;
- int i, *lens, n16, n32, *ndx, nExtra16=0, nLibs=LIBS, nRAM16=0;
- n16 = (signed)Hunk[CodeHunk].nImp16;
- n32 = (signed)Hunk[CodeHunk].nImp32;
- lens = (int *)_alloca (n32 * sizeof (int));
- ndx = (int *)_alloca (n32 * sizeof (int));
- for (imp=Hunk[CodeHunk].Imp32,i=0; i<n32; imp++,i++) {
- char *p = strrchr (&imp->name[1], '@');
- if ((!p) && ((*imp->name)!='_') && strncmp(imp->name,"L__",3)) {
- p = strstr (&imp->name[1], "__");
- }
- if (p) {
- lens[i] = p - imp->name;
- if (lens[i] > 8 && strncmp (imp->name, "_extraramaddr@", 14))
- lens[i] = 0;
- } else if (!strncmp (imp->name, "_RAM_CALL_", 10)
- || !strncmp (imp->name, "_ROM_CALL_", 10))
- lens[i] = 9;
- else if (!strncmp (imp->name, "_extraramaddr_", 14))
- lens[i] = 13;
- else lens[i] = 0;
- if (!lens[i]) UndefRef (imp), bErr = true;
- else {
- int j; Import *imp2 = Hunk[CodeHunk].Imp32;
- for (j=0; j<i; imp2++, j++)
- if (lens[i] == lens[j])
- if (!strncmp (imp2->name, imp->name, lens[i]))
- lens[i] = -lens[i], ndx[i] = ndx[j], j = i;
- if (j == i) {
- if (lens[i] <= 8) ndx[i] = nLibs++;
- else switch (imp->name[2]) {
- case 'A': ndx[i] = RAM32; break;
- case 'O': ndx[i] = ROM; break;
- default: ndx[i] = eRAM32;
- } } } }
- for (imp = Hunk[CodeHunk].Imp16,i=0; i<n16; imp++, i++) {
- if (!strncmp (imp->name, "_extraramaddr", 13)) nExtra16++;
- else if (!strncmp (imp->name, "_RAM_CALL_", 10)) nRAM16++;
- else UndefRef (imp), bErr = true;
- }
- if (bErr) return TI68kERR_DoorsOSUndef;
- struct LibRef {
- unsigned short ord, nrlcs;
- unsigned long *rlc;
- } **Refs = (LibRef **)_alloca (nLibs * sizeof (LibRef *));
- struct Lib {
- char name[9];
- unsigned char minVersion /*__attribute__ ((packed))*/;
- union {
- unsigned short nRefs;
- unsigned short nExps;
- };
- union {
- LibRef *Refs;
- unsigned short *Exps;
- };
- } Exp, *Libs = (Lib *)_alloca (nLibs * sizeof (Lib));
- memset (Libs, 0, nLibs * sizeof (Lib));
- Libs[RAM16].nRefs = nRAM16; Libs[eRAM16].nRefs = nExtra16;
- struct {
- unsigned short code, comment, main, exit, extra;
- } Ofs = { 0, 0, 0, 0, 0};
- unsigned short HeaderSize = 40 + (nLibs-LIBS) * 12 + 2 *
- (unsigned short)(Hunk[CodeHunk].nR32[CodeHunk] + Hunk[CodeHunk].nR32[BSSHunk]);
- if (!(Hunk[BSSHunk].size)) HeaderSize-=6;
- for (imp=Hunk[CodeHunk].Imp32,i=0; i<n32; imp++,i++) {
- if (lens[i] > 0 && ndx[i] >= LIBS)
- strncpy (Libs[ndx[i]].name, imp->name, lens[i]);
- Libs[ndx[i]].nRefs++;
- }
- if (Libs[ROM].nRefs) HeaderSize += 2;
- if (Libs[RAM32].nRefs || Libs[eRAM32].nRefs
- || Libs[RAM16].nRefs || Libs[eRAM16].nRefs)
- HeaderSize += 2;
- for (i=0; i<nLibs; i++) {
- Libs[i].Refs = Refs[i]
- = (LibRef *)_alloca (Libs[i].nRefs * sizeof (LibRef));
- HeaderSize += Libs[i].nRefs * 4;
- }
- for (imp=Hunk[CodeHunk].Imp32,i=0; i<n32; imp++,i++) {
- char *p; LibRef **refs = &Refs[ndx[i]];
- (*refs)->ord = (unsigned short)
- strtoul (&imp->name[abs(lens[i])+(((imp->name[abs(lens[i])]=='_')&&(imp->name[abs(lens[i])+1]=='_'))?2:1)], &p, 16);
- HeaderSize += ((*refs)->nrlcs = (unsigned short) imp->nrlcs) * 2;
- (*refs)->rlc = imp->rlc; (*refs)++;
- }
- nRAM16 = nExtra16 = 0;
- for (imp = Hunk[CodeHunk].Imp16,i=0; i<n16; imp++, i++) {
- LibRef *refs; int len; char *p;
- if (!strncmp (imp->name, "_RAM_CALL_", 10))
- len = 10, refs = &Libs[RAM16].Refs[nRAM16++];
- else len = 14, refs = &Libs[eRAM16].Refs[nExtra16++];
- refs->ord = (unsigned short)strtoul (&imp->name[len], &p, 16);
- if (*p) UndefRef (imp), bErr = true;
- HeaderSize += (refs->nrlcs = (unsigned short) imp->nrlcs) * 2;
- refs->rlc = imp->rlc;
- }
- if (bErr) return TI68kERR_DoorsOSUndef;
- Export *exp = Hunk[CodeHunk].Exports; Exp.nRefs = 0;
- for (i=(int)Hunk[CodeHunk].nExports; i--; exp++) {
- if (!strcmp (exp->name, "_comment"))
- Ofs.comment = (unsigned short)exp->value;
- else if (!strcmp (exp->name, "_main"))
- Ofs.main = (unsigned short)exp->value;
- else if (!strcmp (exp->name, "_exit"))
- Ofs.exit = (unsigned short)exp->value;
- else if (!strcmp (exp->name, "_extraram"))
- Ofs.extra = (unsigned short)exp->value;
- else {
- char *p = strrchr (&exp->name[1], '@');
- if ((!p) && ((*exp->name)!='_') && strncmp(exp->name,"L__",3)) {
- p = strstr (&exp->name[1], "__");
- }
- if (p) {
- if (!strncmp(p+((*p=='_')?2:1),"version",7)) {
- int len = p - exp->name;
- if (len > 8) return TI68kERR_BadExport;
- unsigned long j = strtoul (p+((*p=='_')?9:8), &p, 16);
- if ((*p) || (j > 255ul)) return TI68kERR_BadExport; else {
- for (int ii=0; ii<nLibs; ii++) {
- if (!strncmp(Libs[ii].name,exp->name,len)) Libs[ii].minVersion=j;
- }
- }} else {
- int len = p - exp->name;
- if (len > 8) return TI68kERR_BadExport;
- if (!Exp.nRefs) {
- strncpy (Exp.name, exp->name, len);
- Exp.name[len] = 0;
- } else if (strncmp (Exp.name, exp->name, len))
- return TI68kERR_BadExport;
- Exp.nRefs++;
- }
- } } }
- if (Exp.nRefs) {
- HeaderSize += 4 + 2 * Exp.nRefs;
- Exp.Refs = (LibRef *)_alloca (Exp.nRefs * sizeof (short));
- memset (Exp.Refs, -1, Exp.nRefs * sizeof (short));
- exp = Hunk[CodeHunk].Exports;
- for (i=(int)Hunk[CodeHunk].nExports; i--; exp++) {
- char *p = strrchr (&exp->name[1], '@');
- if ((!p) && ((*exp->name)!='_') && strncmp(exp->name,"L__",3)) {
- p = strstr (&exp->name[1], "__");
- if (p) p++;
- }
- if (p++) {
- if (strncmp(p,"version",7)) {
- unsigned long j = strtoul (p, &p, 16);
- if (*p || j >= Exp.nExps || (short)Exp.Exps[j] != -1)
- return TI68kERR_BadExport;
- Exp.Exps[j] = (unsigned short)exp->value;
- }
- } } }
- union {
- void *o0;
- unsigned char *o8;
- unsigned short *o16;
- unsigned long *o32;
- };
- Ofs.code = HeaderSize + (Type == TI68k_68kP ? sizeof (PrgmStub) : sizeof (LibStub));
- o8 = dat = new unsigned char [size = Ofs.code + Hunk[CodeHunk].size + 3];
- bw2 (o16++, 0x6100);
- bw2 (o16++, HeaderSize-2);
- bw4 (o32++, ('6'<<24)+('8'<<16)+('k'<<8)+(Type==TI68k_68kP?'P':'L'));
- *o16++ = 0;
- bw2 (o16++, Ofs.comment ? Ofs.comment + Ofs.code : 0);
- bw2 (o16++, Type == TI68k_68kP ? Ofs.main + Ofs.code : 0);
- bw2 (o16++, Ofs.exit ? Ofs.exit + Ofs.code : 0);
- bw2 (o16++, Flags);
- *o16++ = 0; *o32++ = 0;
- bw2 (o16++, Ofs.extra ? Ofs.extra + Ofs.code : 0);
- bw2 (o16++, nLibs-LIBS);
- for (i=LIBS; i<nLibs; o8+=10,i++)
- memcpy (o0, Libs[i].name, 10);
- for (i=LIBS; i<nLibs; i++) {
- int j = Libs[i].nRefs; bw2 (o16++, --j);
- LibRef *Refs = Libs[i].Refs;
- do {
- bw2 (o16++, Refs->ord);
- unsigned long *rlc = Refs->rlc;
- unsigned short k=Refs++->nrlcs;
- while (k--) bw2 (o16++, Ofs.code + (unsigned short)*rlc++);
- *o16++ = 0;
- } while (j--);
- }
- if (!Libs[ROM].nRefs) *o16++ = 0;
- else {
- bw2 (o16++, (unsigned short)-1);
- int j = Libs[ROM].nRefs; bw2 (o16++, --j);
- LibRef *Refs = Libs[ROM].Refs;
- do {
- bw2 (o16++, Refs->ord);
- unsigned long *rlc = Refs->rlc;
- unsigned short k=Refs++->nrlcs;
- while (k--) bw2 (o16++, Ofs.code + (unsigned short)*rlc++);
- *o16++ = 0;
- } while (j--);
- }
- i = Libs[RAM32].nRefs + Libs[eRAM32].nRefs
- + Libs[RAM16].nRefs + Libs[eRAM16].nRefs;
- if (!i--) *o16++ = 0;
- else {
- bw2 (o16++, (unsigned short)-1); bw2 (o16++, i);
- for (i=RAM32; i<=eRAM16; i++) {
- int j; LibRef *Refs = Libs[i].Refs;
- for (j=Libs[i].nRefs; j; j--) {
- bw2 (o16++, Refs->ord + (unsigned short)(i<<14));
- unsigned long *rlc = Refs->rlc;
- unsigned short k=Refs++->nrlcs;
- while (k--) bw2 (o16++, Ofs.code + (unsigned short)*rlc++);
- *o16++ = 0;
- } } }
- unsigned long *R32 = Hunk[CodeHunk].R32[CodeHunk];
- for (i=(int)Hunk[CodeHunk].nR32[CodeHunk]; i; i--)
- bw2 (o16++, Ofs.code + (unsigned short)*R32++);
- *o16++ = 0;
- if (Hunk[BSSHunk].size) {
- bw2 (&dat[0x14], (unsigned short)(o8-dat));
- bw4 (o32++, Hunk[BSSHunk].size);
- R32 = Hunk[CodeHunk].R32[BSSHunk];
- for (i=(int)Hunk[CodeHunk].nR32[BSSHunk]; i; i--)
- bw2 (o16++, Ofs.code + (unsigned short)*R32++);
- *o16++ = 0;
- } else bw2 (&dat[0x14], (unsigned short)0);
- if (Exp.nRefs) {
- bw2 (&dat[0x16], (unsigned short)(o8-dat));
- bw2 (o16++, Exp.nRefs);
- for (i=0; i<Exp.nRefs; i++)
- bw2 (o16++, Ofs.code + (unsigned short)Exp.Exps[i]);
- *o16++ = 0;
- }
- if (Type == TI68k_68kP)
- memcpy (o0, PrgmStub, sizeof (PrgmStub)), o8 += sizeof (PrgmStub);
- else memcpy (o0, LibStub, sizeof (LibStub)), o8 += sizeof (LibStub);
- memcpy (o0, Hunk[CodeHunk].o0, Hunk[CodeHunk].size);
- o8 += Hunk[CodeHunk].size;
- R32 = Hunk[CodeHunk].R32[CodeHunk];
- for (i=(int)Hunk[CodeHunk].nR32[CodeHunk]; i; i--)
- ba4 (&dat[Ofs.code+(unsigned short)*R32++], Ofs.code);
- *o16++ = 0; *o8 = 0xF3;
- return TI68kERR_OK;
- }
- bool TI68k::NostubImp (unsigned long n, Import *imp)
- {
- if (!n) return false;
- for (; n--; imp++) UndefRef (imp);
- return true;
- }
- TI68kErr TI68k::MakeNostub ()
- {
- if (BSSHunk >= 0) if (Hunk[BSSHunk].size) {
- Hunk[BSSHunk].o8 = new unsigned char [Hunk[BSSHunk].size];
- Hunk[BSSHunk].DelDat = true;
- memset (Hunk[BSSHunk].o8, 0, Hunk[BSSHunk].size);
- Merge (CodeHunk, BSSHunk);
- }
- if (!NostubImp (Hunk[CodeHunk].nImp16, Hunk[CodeHunk].Imp16)
- && !NostubImp (Hunk[CodeHunk].nImp32, Hunk[CodeHunk].Imp32)) {
- unsigned long n = Hunk[CodeHunk].nR32[CodeHunk];
- unsigned long *R32 = Hunk[CodeHunk].R32[CodeHunk];
- size = Hunk[CodeHunk].size + 4 * n + 3;
- dat = new unsigned char [size];
- memcpy (dat, Hunk[CodeHunk].o0, Hunk[CodeHunk].size);
- unsigned short *o16 = (unsigned short *)&dat[size-1];
- *(unsigned char *)o16-- = 0xF3;
- for (; n--; R32++) {
- bw2 (o16--, (unsigned short)*R32);
- bw2 (o16--, (unsigned short)br4 (&dat[*R32]));
- } *o16 = 0;
- return TI68kERR_OK;
- } else return TI68kERR_NostubUndef;
- }
- bool TI68k::ExtImp (unsigned long n, Import *imp)
- {
- if (!n) return false;
- for (; n--; imp++) UndefRef (imp);
- return true;
- }
- char *OutputName2=0;
- bool InList(char *str, char *list) {
- if (!*list) return true;
- while (*list)
- if (!strcmp(str,list)) return true;
- else while (*list++);
- return false;
- }
- void maj_conv(char *s) {
- char c;
- while ((c=*s++))
- if (c>='A' && c<='Z')
- memmove(s+1,s,strlen(s)+1), *s='-';
- }
- TI68kErr TI68k::MakeExt ()
- {
- /* TODO (?) : BSS aren't supported */
- if (BSSHunk >= 0) if (Hunk[BSSHunk].size) {
- Hunk[BSSHunk].o8 = new unsigned char [Hunk[BSSHunk].size];
- Hunk[BSSHunk].DelDat = true;
- memset (Hunk[BSSHunk].o8, 0, Hunk[BSSHunk].size);
- Merge (CodeHunk, BSSHunk);
- }
- char *ExportList;
- FILE *ex_fp=fopen("export.dat","rb");
- if (!ex_fp) ExportList="";
- else ExportList = new char [300000], fread(ExportList,300000,1,ex_fp), fclose(ex_fp);
- FILE *def_fp=fopen("deflt.txt","a+");
- unsigned long nExp = 0, szExpN = 0;
- int n=Hunk[CodeHunk].nExports; Export *exp = Hunk[CodeHunk].Exports;
- unsigned long *expOffs = new unsigned long [n]; char **expName = new char * [n];
- for (; n--; exp++) {
- if (InList(exp->name, ExportList)) {
- char buf[200];
- sprintf(buf,"%s.ref",exp->name);
- maj_conv(buf);
- FILE *fp=fopen(buf,"w");
- if (!fp) { printf("Couldn't open '%s' !\n",buf); return TI68kERR_Unknown; }
- sprintf(buf,"%s.ext",OutputName2);
- fputs(buf,fp);
- fclose(fp);
- if (def_fp) fprintf(def_fp,"#var %s\n",exp->name);
- expOffs[nExp] = exp->value, expName[nExp] = exp->name,
- szExpN += strlen(exp->name)+1, nExp++;
- }
- }
- if (def_fp) fclose(def_fp);
- unsigned long nRef0 = 0, nRef = 0, nImp = 0, szImpN = 0; int i;
- int n32=Hunk[CodeHunk].nImp32, n16=Hunk[CodeHunk].nImp16;
- Import *imp32 = Hunk[CodeHunk].Imp32, *imp16 = Hunk[CodeHunk].Imp16, *imp;
- for (n=n16,imp=imp16; n--; imp++)
- nRef0+=imp->nrlcs+1;
- for (n=n32,imp=imp32; n--; imp++)
- nRef0+=imp->nrlcs+1;
- unsigned long *impOffs = new unsigned long [nRef0];
- char **impName = new char * [n16+n32];
- for (n=n16,imp=imp16; n--; imp++) {
- for (i=imp->nrlcs;i--;)
- impOffs[nRef] = imp->rlc[i]-2, nRef++;
- impOffs[nRef] = -2ul, nRef++;
- impName[nImp] = imp->name, szImpN += strlen(imp->name)+1, nImp++;
- }
- for (n=n32,imp=imp32; n--; imp++) {
- for (i=imp->nrlcs;i--;)
- impOffs[nRef] = imp->rlc[i], nRef++;
- impOffs[nRef] = -2ul, nRef++;
- impName[nImp] = imp->name, szImpN += strlen(imp->name)+1, nImp++;
- }
- unsigned long nInt = Hunk[CodeHunk].nR32[CodeHunk];
- unsigned long *R32 = Hunk[CodeHunk].R32[CodeHunk];
- size = (2+Hunk[CodeHunk].size) + (2*nInt+2) + (2*nExp+2+szExpN) + (szExpN&1) + (2*nRef+2+szImpN) + (szImpN&1) + (2);
- dat = new unsigned char [size];
- memset (dat, 0, size);
- unsigned char *p8 = dat;
- #define w16(x) (bw2(p8,(unsigned short)(x)), p8+=2)
- w16(2+Hunk[CodeHunk].size);
- memcpy (p8, Hunk[CodeHunk].o0, Hunk[CodeHunk].size), p8+=Hunk[CodeHunk].size;
- /* Relocation section */
- for (n=nInt; n--; R32++) {
- w16(2+(unsigned short)*R32);
- }
- w16(0);
- /* Export section */
- for (n=nExp;n--;)
- w16(2+expOffs[n]);
- w16(0);
- for (n=nExp;n--;)
- strcpy((char *)p8, expName[n]), p8+=strlen(expName[n])+1;
- if (szExpN&1) *p8++=0;
- /* Import section */
- for (i=0;i<(int)nRef;i++)
- w16(2+impOffs[i]);
- w16(0);
- for (i=0;i<(int)nImp;i++)
- strcpy((char *)p8, impName[i]), p8+=strlen(impName[i])+1;
- if (szImpN&1) *p8++=0;
- /* BSS section */
- w16(0);
- #ifndef NDEBUG
- if (p8!=&dat[size]) { printf("Size mismatch!\n"); return TI68kERR_Unknown; }
- #endif
- return TI68kERR_OK;
- }
- TI68kErr TI68k::Make ()
- {
- int hunk;
- for (hunk=0; hunk<3; hunk++) {
- unsigned long i; Export *exp = Hunk[hunk].Exports;
- for (i=Hunk[hunk].nExports; i; exp++,i--) {
- if (!strcmp (exp->name, szTI68kType[TI68k_68kL-1])) {
- if (Type == TI68k_none) Type = TI68k_68kL;
- else return Conflict (TI68k_68kL);
- }
- else if (!strcmp (exp->name, szTI68kType[TI68k_68kP-1])) {
- if (Type == TI68k_none) Type = TI68k_68kP;
- else if (Type != TI68k_nostub)
- return Conflict (TI68k_68kP);
- }
- else if (!strcmp (exp->name, szTI68kType[TI68k_ext-1])) {
- if (Type == TI68k_none) Type = TI68k_ext;
- else
- return Conflict (TI68k_ext);
- }
- else if (!strcmp (exp->name, szTI68kType[TI68k_nostub-1])) {
- if (Type == TI68k_none || Type == TI68k_68kP)
- Type = TI68k_nostub;
- else if (Type != TI68k_nostub_dll)
- return Conflict (TI68k_nostub);
- }
- else if (!strcmp (exp->name, szTI68kType[TI68k_nostub_dll-1])) {
- if (Type == TI68k_none || Type == TI68k_68kP || Type == TI68k_nostub)
- Type = TI68k_nostub_dll;
- else return Conflict (TI68k_nostub_dll);
- }
- else if (!strcmp (exp->name, szTI68kType[TI68k_prosit-1]))
- return TI68kERR_prosit;
- else if (!strcmp (exp->name, "_ti89"))
- Output89 = 1;
- else if (!strcmp(exp->name, "_ti92plus"))
- Output92p = 1;
- else if (!strncmp(exp->name, "_flag_", 6))
- Flags |= 1 << strtoul (&exp->name[6], NULL, 10);
- else if (!strncmp(exp->name, "_version", 6))
- LibVersion = strtoul (&exp->name[8], NULL, 16);
- else if (bBadExport
- && strcmp (exp->name, "_comment")
- && strcmp (exp->name, "_exit")
- && strcmp (exp->name, "_extraram")) {
- char *p = strrchr (&exp->name[1], '@');
- if (p) if (p[1]) {
- strtoul (&p[1], &p, 16);
- if (*p) p = NULL;
- }
- if (!p) return TI68kERR_BadExport;
- } } }
- if (!Output89 && !Output92p && Type!=TI68k_ext) return TI68kERR_NoOutput;
- Merge (CodeHunk, DataHunk);
- switch (Type) {
- case TI68k_ext:
- return MakeExt ();
- case TI68k_nostub:
- case TI68k_nostub_dll:
- return MakeNostub ();
- default:
- return MakeDoorsOS ();
- }
- return TI68kERR_Unknown;
- }
- TI68kErr TI68k::DoSave (char *FileName, char *ext, char *Header, unsigned long HeaderSize, unsigned short chksum)
- {
- if (strlen (FileName) + strlen (ext) < _MAX_PATH) {
- unsigned char buf[2]; char FullName[_MAX_PATH]; FILE *f;
- f = fopen (strcat (strcpy (FullName, FileName), ext), "wb");
- if (HeaderSize) fwrite (Header, 1, HeaderSize, f);
- bw2 (buf, (unsigned short)size);
- fwrite (buf, 1, 2, f);
- fwrite (dat, 1, size, f);
- if (HeaderSize) lw2 (buf, chksum), fwrite (buf, 1, 2, f);
- fclose (f);
- }
- return TI68kERR_OK;
- }
- TI68kErr TI68k::Save (char *FileName, bool outputbin, bool quiet)
- {
- static char Header[]=
- "**TI92P*\001\0main\0\0\0\0"
- "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
- "\001\0R\0\0\0\0\0\0\0\0\0\0\0!\0\0\0\0\0\0\0¥Z\0\0\0";
- #define HeaderSize (sizeof (Header))
- char AMSname[9], *p; unsigned short chksum;
- if (GetExeSize () > MAX_VAR_SIZE)
- return TI68kERR_TooLarge;
- AMSname[8] = 0; p = strrchr (FileName, '\\');
- _strlwr (strncpy (AMSname, p ? p + 1 : FileName, 8));
- strncpy (&Header[0x40], AMSname, 8);
- lw4 (&Header[0x4C], size + HeaderSize + 4);
- if (outputbin || Type == TI68k_nostub_dll || Type == TI68k_ext) {
- if (Type == TI68k_nostub_dll && !outputbin)
- DoSave (FileName, ".ndl", NULL, 0, 0);
- else if (Type == TI68k_ext && !outputbin)
- DoSave (FileName, ".ext", NULL, 0, 0);
- else
- DoSave (FileName, ".bin", NULL, 0, 0);
- if (!quiet) {
- if (Output89) printf ("Linked for TI-89\n");
- if (Output92p) printf ("Linked for TI-92 Plus\n");
- }
- } else {
- chksum = LOBYTE (size) + HIBYTE (size);
- unsigned long i;
- for (i=0; i<size; i++) chksum += (unsigned short)dat[i];
- if (Output89) DoSave (FileName, ".89z", strncpy (Header, "**TI89**", 8), HeaderSize, chksum);
- if (Output92p) DoSave (FileName, ".9xz", strncpy (Header, "**TI92P*", 8), HeaderSize, chksum);
- }
- return TI68kERR_OK;
- }
- int main (int argc, char **argv)
- {
- bool help, outputbin=false, quiet=false, ver=false;
- int err = 0; char *ObjFile=NULL, *OutputName=NULL;
- TI68kType Type = TI68k_none;
- for (help=!--argc; argc && !err; argc--) {
- char *p = *++argv;
- if (*p++ == '-') {
- do switch (*p++) {
- case 'o':
- if (!OutputName) {
- OutputName = *++argv;
- if (--argc) break;
- }
- default: err = -1; break;
- case '?':
- case 'h': help = true; break;
- case 'O': outputbin = true; break;
- case 'q': quiet = true; break;
- case 'v': ver = true; break;
- case 'x': Type = TI68k_ext; break;
- case '-':
- if (!strcmp (p, "help")) help = true;
- else if (!strcmp (p, "version")) ver = true;
- else if (!strcmp (p, "quiet")) quiet = true;
- else if (!strcmp (p, "outputbin")) outputbin = true;
- else if (!strcmp (p, "output") && !OutputName && --argc) OutputName = *++argv;
- else if (!strcmp (p, "ext")) Type = TI68k_ext;
- else err = -1;
- case 0:
- p = NULL;
- } while (p);
- } else if (ObjFile) err = -1;
- else ObjFile = *argv;
- }
- if (err) {
- fputs ("Invalid command line.\n", stderr);
- help = true;
- } else if (ver) puts (
- "Obj2Ti 1.01f by Julien Muchembled <julien.muchembled@netcourrier.com>\n"
- "Modified by: Romain Lievin <rlievin@mail.com>\n"
- " Sebastian Reichelt <Sebastian@tigcc.ticalc.org>\n"
- " Kevin Kofler <Kevin@tigcc.ticalc.org>\n"
- " and Paul Froissart\n"
- );
- if (help) puts (
- "Usage: obj2ti [options] file\n"
- "Options:\n"
- " -h --help\tDisplay this information\n"
- " -o --output\tFollowed by project name\n"
- " -O --outputbin\tOutput a binary file, not a calc file\n"
- " -q --quiet\tLink without displaying extra verbose information\n"
- " -v --version\tDisplay program version number\n"
- " -x --ext\tOutput a .ext object suitable for GTC\n"
- );
- else if (ObjFile) {
- TI68k *ti = new TI68k (szErr, Type);
- err = ti->Read (ObjFile);
- if (!err) {
- char *ext = strrchr (OutputName2 = ObjFile, '.');
- if (ext && (!strcmp(ext,".o") || !strcmp(ext,".O")))
- *ext = 0;
- err = ti->Make ();
- if (!err) {
- if (!OutputName) {
- char *ext = strrchr (OutputName = ObjFile, '.');
- if (ext) if (!_stricmp (ext, ".o")) *ext = 0;
- } err = ti->Save (OutputName, outputbin, quiet);
- if (!err && !quiet) printf ("Linked %s - Size: %lu bytes\n", OutputName, ti->GetExeSize ());
- } }
- if (err) {
- if (err == TI68kERR_TooLarge)
- fprintf (stderr, "Error: Size of %lu bytes exceeds maximum by %lu.\n", ti->GetExeSize (), ti->GetExeSize () - MAX_VAR_SIZE);
- else if (szErr[err-1])
- fprintf (stderr, "%s.\n", szErr[err-1]);
- }
- delete ti;
- }
- return err;
- }
|