X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=object.c;h=bee4fd60febb432fb79f91465a13b3e6fe6494af;hp=3cae5479de5cbfca362f74ba6537720e661db3e8;hb=bdbf34766f4d074a5933eb1326fe4ce03d249e10;hpb=052be802baa4836564801c780b1d432cfe17c576 diff --git a/object.c b/object.c index 3cae547..bee4fd6 100644 --- a/object.c +++ b/object.c @@ -1,18 +1,19 @@ // -// RMAC - Reboot's Macro Assembler for the Atari Jaguar Console System +// RMAC - Reboot's Macro Assembler for all Atari computers // OBJECT.C - Writing Object Files -// Copyright (C) 199x Landon Dyer, 2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2019 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // #include "object.h" +#include "6502.h" +#include "direct.h" #include "error.h" #include "mark.h" #include "riscasm.h" #include "sect.h" #include "symbol.h" -extern void m6502obj(int ofd); //#define DEBUG_ELF @@ -57,7 +58,7 @@ See left. 4 & 5 If these bits are set to 0 (PF_PRIVATE), the processes' // -// Add entry to symbol table +// Add entry to symbol table (in ALCYON mode) // If 'globflag' is 1, make the symbol global // If in .PRG mode, adjust symbol values for fake link // @@ -66,6 +67,7 @@ uint8_t * AddSymEntry(register uint8_t * buf, SYM * sym, int globflag) // Copy symbol name to buffer (first 8 chars or less) register uint8_t * s = sym->sname; register int i; + uint32_t extra = 0; for(i=0; i<8 && *s; i++) *buf++ = *s++; @@ -73,6 +75,31 @@ uint8_t * AddSymEntry(register uint8_t * buf, SYM * sym, int globflag) while (i++ < 8) *buf++ = '\0'; + register uint16_t w1 = sym->sattr; + register uint16_t w = AL_DEFINED | tdb_tab[w1 & TDB]; + + if (prg_flag == 3) + { + // Extended symbol - Check to see if symbol is larger than 8 characters + // and write an extra 14 characters where the next symbol would be. + // Modify the flag word for this + if (*s) + { + //printf("%s '%i' - will write extended symbol\n", sym->sname,s[0]); + uint8_t *buf2 = buf + 6; + + for(i=8; i<8+14 && *s; i++) + *buf2++ = *s++; + + while (i++ < 8 + 14) + *buf2++ = '\0'; + + symsize += 14; + w |= 0x48; + extra = 14; + } + } + // // Construct and deposit flag word // @@ -83,9 +110,6 @@ uint8_t * AddSymEntry(register uint8_t * buf, SYM * sym, int globflag) // o exports (DEFINED) are AL_GLOBAL // o imports (~DEFINED) are AL_EXTERN // - register uint16_t w1 = sym->sattr; - register uint16_t w = AL_DEFINED | tdb_tab[w1 & TDB]; - if (w1 & EQUATED) // Equated w |= AL_EQUATED; @@ -104,7 +128,7 @@ uint8_t * AddSymEntry(register uint8_t * buf, SYM * sym, int globflag) SETBE16(buf, 0, w); buf += 2; - register uint32_t z = sym->svalue; + register uint32_t z = (uint32_t)sym->svalue; if (prg_flag) // Relocate value in .PRG segment { @@ -120,6 +144,9 @@ uint8_t * AddSymEntry(register uint8_t * buf, SYM * sym, int globflag) SETBE32(buf, 0, z); // Deposit symbol value buf += 4; + symsize += 14; + buf += extra; + return buf; } @@ -177,6 +204,7 @@ uint8_t * AddBSDSymEntry(uint8_t * buf, SYM * sym, int globflag) uint8_t * AddELFSymEntry(uint8_t * buf, SYM * sym, int globflag) { chptr = buf; + ch_size = 0; D_long(strindx); // st_name D_long(sym->svalue); // st_value D_long(0); // st_size @@ -227,6 +255,7 @@ uint8_t * AddELFSymEntry(uint8_t * buf, SYM * sym, int globflag) int DepositELFSectionHeader(uint8_t * ptr, uint32_t name, uint32_t type, uint32_t flags, uint32_t addr, uint32_t offset, uint32_t size, uint32_t link, uint32_t info, uint32_t addralign, uint32_t entsize) { chptr = ptr; + ch_size = 0; D_long(name); D_long(type); D_long(flags); @@ -262,6 +291,7 @@ printf("DepositELFSHSTEntry: s = \"%s\"\n", s); uint32_t DepositELFSymbol(uint8_t * ptr, uint32_t name, uint32_t addr, uint32_t size, uint8_t info, uint8_t other, uint16_t shndx) { chptr = ptr; + ch_size = 0; D_long(name); D_long(addr); D_long(size); @@ -284,7 +314,6 @@ int WriteObject(int fd) CHUNK * cp; // Chunk (for gather) uint8_t * buf; // Scratch area uint8_t * p; // Temporary ptr - LONG ssize; // Size of symbols LONG trsize, drsize; // Size of relocations long unused; // For supressing 'write' warnings @@ -306,9 +335,9 @@ int WriteObject(int fd) printf("Total : %d bytes\n", sect[TEXT].sloc + sect[DATA].sloc + sect[BSS].sloc); } - ssize = sy_assign(NULL, NULL); // Assign index numbers to the symbols + sy_assign(NULL, NULL); // Assign index numbers to the symbols tds = sect[TEXT].sloc + sect[DATA].sloc; // Get size of TEXT and DATA segment - buf = malloc(0x600000); // Allocate 6mb object file image memory + buf = malloc(0x800000); // Allocate 8MB object file image memory if (buf == NULL) { @@ -316,7 +345,7 @@ int WriteObject(int fd) return ERROR; } - memset(buf, 0, 0x600000); // Clear allocated memory + memset(buf, 0, 0x800000); // Clear allocated memory objImage = buf; // Set global object image pointer strtable = malloc(0x200000); // Allocate 2MB string table buffer @@ -395,49 +424,34 @@ int WriteObject(int fd) if (verb_flag) { if (prg_flag) - { printf("TOS header : 28 bytes\n"); - printf("Total : %d bytes\n", 28 + sect[TEXT].sloc + sect[DATA].sloc + sect[BSS].sloc); - } - else - { - printf("Total : %d bytes\n", sect[TEXT].sloc + sect[DATA].sloc + sect[BSS].sloc); - } - } - // Compute size of symbol table; assign numbers to the symbols... - ssize = 0; + printf("Total : %d bytes\n", sect[TEXT].sloc + sect[DATA].sloc + sect[BSS].sloc + (prg_flag ? 28 : 0)); + } - // As we grabbed BSD *and* Alcyon in prg_flag == 0 mode, this is *always* - // false... :-P - if (prg_flag != 1) - ssize = sy_assign(NULL, NULL) * 14; + // Assign index numbers to the symbols, get # of symbols (we assume + // that all symbols can potentially be extended, hence the x28) + uint32_t symbolMaxSize = sy_assign(NULL, NULL) * 28; // Alloc memory for header + text + data, symbol and relocation // information construction. - t = tds = sect[TEXT].sloc + sect[DATA].sloc; - - if (t < ssize) - t = ssize; - - // Is there any reason to do this this way??? - buf = malloc(t + HDRSIZE); - buf += HDRSIZE; + tds = sect[TEXT].sloc + sect[DATA].sloc; + buf = malloc(HDRSIZE + tds + symbolMaxSize); // Build object file header just before the text+data image - chptr = buf - HDRSIZE; // -> base of header + chptr = buf; // -> base of header D_word(0x601A); // 00 - magic number D_long(sect[TEXT].sloc); // 02 - TEXT size D_long(sect[DATA].sloc); // 06 - DATA size D_long(sect[BSS].sloc); // 0A - BSS size - D_long(ssize); // 0E - symbol table size + D_long(0); // 0E - symbol table size (filled later) D_long(0); // 12 - stack size (unused) D_long(PRGFLAGS); // 16 - PRGFLAGS D_word(0); // 1A - relocation information exists // Construct text and data segments; fixup relocatable longs in .PRG // mode; finally write the header + text + data - p = buf; + p = buf + HDRSIZE; for(i=TEXT; i<=DATA; i++) { @@ -450,19 +464,22 @@ int WriteObject(int fd) // Do a first pass on the Alcyon image, if in PRG mode if (prg_flag) - MarkImage(buf, tds, sect[TEXT].sloc, 0); + MarkImage(buf + HDRSIZE, tds, sect[TEXT].sloc, 0); - unused = write(fd, buf - HDRSIZE, tds + HDRSIZE); - - // Construct and write symbol table - if (prg_flag != 1) + // Construct symbol table and update the header entry, if necessary + if (prg_flag > 1) { - sy_assign(buf, AddSymEntry); - unused = write(fd, buf, ssize); + // sy_assign with AddSymEntry updates symsize (stays 0 otherwise) + sy_assign(buf + HDRSIZE + tds, AddSymEntry); + chptr = buf + 0x0E; // Point to symbol table size entry + D_long(symsize); } + // Write out the header + text & data + symbol table (if any) + unused = write(fd, buf, HDRSIZE + tds + symsize); + // Construct and write relocation information; the size of it changes if - // we're writing a RELMODed executable. + // we're writing a RELMODed executable. N.B.: Destroys buffer! tds = MarkImage(buf, tds, sect[TEXT].sloc, 1); unused = write(fd, buf, tds); } @@ -473,7 +490,7 @@ int WriteObject(int fd) if (buf == NULL) { - error("cannot allocate object file memory (in BSD mode)"); + error("cannot allocate object file memory (in ELF mode)"); return ERROR; } @@ -483,7 +500,7 @@ int WriteObject(int fd) if (strtable == NULL) { - error("cannot allocate string table memory (in BSD mode)"); + error("cannot allocate string table memory (in ELF mode)"); return ERROR; } @@ -520,7 +537,7 @@ int WriteObject(int fd) { elfHdrNum[ES_TEXT] = shstIndex; shstTab[ES_TEXT] = shstSize; - shstSize += DepositELFSHSTEntry(&shstPtr, "TEXT"); + shstSize += DepositELFSHSTEntry(&shstPtr, ".text"); shstIndex++; numEntries++; } @@ -529,7 +546,7 @@ int WriteObject(int fd) { elfHdrNum[ES_DATA] = shstIndex; shstTab[ES_DATA] = shstSize; - shstSize += DepositELFSHSTEntry(&shstPtr, "DATA"); + shstSize += DepositELFSHSTEntry(&shstPtr, ".data"); shstIndex++; numEntries++; } @@ -538,7 +555,7 @@ int WriteObject(int fd) { elfHdrNum[ES_BSS] = shstIndex; shstTab[ES_BSS] = shstSize; - shstSize += DepositELFSHSTEntry(&shstPtr, "BSS"); + shstSize += DepositELFSHSTEntry(&shstPtr, ".bss"); shstIndex++; numEntries++; } @@ -619,7 +636,7 @@ for(int j=0; j 0) { - headerSize += DepositELFSectionHeader(headers + headerSize, shstTab[ES_TEXT], 1, 6, 0, elfSize, sect[TEXT].sloc, 0, 0, 2, 0); + headerSize += DepositELFSectionHeader(headers + headerSize, shstTab[ES_TEXT], 1, 6, 0, elfSize, sect[TEXT].sloc, 0, 0, largestAlign[0], 0); for(CHUNK * cp=sect[TEXT].sfcode; cp!=NULL; cp=cp->chnext) { @@ -636,7 +653,7 @@ for(int j=0; j 0) { - headerSize += DepositELFSectionHeader(headers + headerSize, shstTab[ES_DATA], 1, 3, 0, elfSize, sect[DATA].sloc, 0, 0, 1, 0); + headerSize += DepositELFSectionHeader(headers + headerSize, shstTab[ES_DATA], 1, 3, 0, elfSize, sect[DATA].sloc, 0, 0, largestAlign[1], 0); for(CHUNK * cp=sect[DATA].sfcode; cp!=NULL; cp=cp->chnext) { @@ -651,7 +668,7 @@ for(int j=0; j 0) { - headerSize += DepositELFSectionHeader(headers + headerSize, shstTab[ES_BSS], 8, 3, 0, elfSize, sect[BSS].sloc, 0, 0, 2, 0); + headerSize += DepositELFSectionHeader(headers + headerSize, shstTab[ES_BSS], 8, 3, 0, elfSize, sect[BSS].sloc, 0, 0, largestAlign[2], 0); } int textrelLoc = headerSize; @@ -752,11 +769,11 @@ for(int j=0; j