X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=object.c;h=fe107434f9c835538a4bbe8dce2a4233d5f1a413;hp=f100e4ae18fd1a95a8c9fc3e903231fd3c7f614a;hb=HEAD;hpb=bf4dbb2860116dd1d0fd934b28a16f9eb15cd7fd diff --git a/object.c b/object.c index f100e4a..6dbf9c5 100644 --- a/object.c +++ b/object.c @@ -1,7 +1,7 @@ // -// RMAC - Reboot's Macro Assembler for all Atari computers +// RMAC - Renamed Macro Assembler for all Atari computers // OBJECT.C - Writing Object Files -// Copyright (C) 199x Landon Dyer, 2011-2019 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2022 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -62,7 +62,6 @@ See left. 4 & 5 If these bits are set to 0 (PF_PRIVATE), the processes' static void WriteLOD(void); static void WriteP56(void); - // // Add entry to symbol table (in ALCYON mode) // If 'globflag' is 1, make the symbol global @@ -157,34 +156,73 @@ uint8_t * AddSymEntry(register uint8_t * buf, SYM * sym, int globflag) return buf; } - // // Add an entry to the BSD symbol table // +// From stab.def (https://sites.uclouvain.be/SystInfo/usr/include/bits/stab.def.html): +/* +_________________________________________________ +| 00 - 1F are not dbx stab symbols | +| In most cases, the low bit is the EXTernal bit| + +| 00 UNDEF | 02 ABS | 04 TEXT | 06 DATA | +| 01 |EXT | 03 |EXT | 05 |EXT | 07 |EXT | + +| 08 BSS | 0A INDR | 0C FN_SEQ | 0E WEAKA | +| 09 |EXT | 0B | 0D WEAKU | 0F WEAKT | + +| 10 WEAKD | 12 COMM | 14 SETA | 16 SETT | +| 11 WEAKB | 13 | 15 | 17 | + +| 18 SETD | 1A SETB | 1C SETV | 1E WARNING| +| 19 | 1B | 1D | 1F FN | +*/ uint8_t * AddBSDSymEntry(uint8_t * buf, SYM * sym, int globflag) { chptr = buf; // Point to buffer for depositing longs - D_long(strindx); // Deposit the symbol string index + if (sym->sname) + { + D_long(strindx); // Deposit the symbol string index + } + else + { + D_long(0); // Deposit special NULL string index + } uint16_t w1 = sym->sattr; // Obtain symbol attributes uint32_t z = 0; // Initialize resulting symbol flags - if (w1 & EQUATED) + if (sym->stype == DBGSYM) { - z = 0x02000000; // Set equated flag + // Debug symbols hard-code the a.out symbol type in the st_type field + // and can include additional type-specific data in the a.out symbol + // "other" and "description" fields, both packed into this same dword. + z = sym->st_type << 24; + z |= sym->st_other << 16; + z |= sym->st_desc; } else { + // Translate rmac symbol attributes to an a.out symbol type. + if (w1 & EQUATED) + { + z = 0x02000000; // Set equated flag + } + + // If a symbol is both EQUd and flagged as TBD then we let the latter + // take precedence. Otherwise the linker will not even bother trying to + // relocate the address during link time. + switch (w1 & TDB) { case TEXT: z = 0x04000000; break; // Set TEXT segment flag case DATA: z = 0x06000000; break; // Set DATA segment flag case BSS : z = 0x08000000; break; // Set BSS segment flag } - } - if (globflag) - z |= 0x01000000; // Set global flag if requested + if (globflag) + z |= 0x01000000; // Set global flag if requested + } D_long(z); // Deposit symbol attribute z = sym->svalue; // Obtain symbol value @@ -196,15 +234,17 @@ uint8_t * AddBSDSymEntry(uint8_t * buf, SYM * sym, int globflag) z += sect[DATA].sloc; // If BSS add DATA segment size D_long(z); // Deposit symbol value - strcpy(strtable + strindx, sym->sname); - strindx += strlen(sym->sname) + 1; // Incr string index incl null terminate + if (sym->sname) + { + strcpy(strtable + strindx, sym->sname); + strindx += strlen(sym->sname) + 1; // Incr string index incl null terminate + } buf += 12; // Increment buffer to next record symsize += 12; // Increment symbol table size return buf; } - // // Add entry to ELF symbol table; if `globflag' is 1, make the symbol global // @@ -222,7 +262,7 @@ uint8_t * AddELFSymEntry(uint8_t * buf, SYM * sym, int globflag) if (w1 & DEFINED) { if (globflag) // Export the symbol - st_info |= 16; //STB_GLOBAL (1<<4) + st_info |= 16; // STB_GLOBAL (1<<4) } else if (w1 & (GLOBAL | REFERENCED)) st_info |= 16; @@ -230,7 +270,7 @@ uint8_t * AddELFSymEntry(uint8_t * buf, SYM * sym, int globflag) D_byte(st_info); D_byte(0); // st_other - uint16_t st_shndx = 0xFFF1; // Assume absolute (equated) number + uint16_t st_shndx = SHN_ABS; // Assume absolute (equated) number if (w1 & TEXT) st_shndx = elfHdrNum[ES_TEXT]; @@ -238,8 +278,13 @@ uint8_t * AddELFSymEntry(uint8_t * buf, SYM * sym, int globflag) st_shndx = elfHdrNum[ES_DATA]; else if (w1 & BSS) st_shndx = elfHdrNum[ES_BSS]; - else if (globflag) - st_shndx = 0; // Global, not absolute + else if (globflag && !(w1 & DEFINED) && (w1 & REFERENCED)) + { + st_shndx = SHN_UNDEF; + } // If the symbol is global then probably we + // don't need to do anything (probably) + // since we set STB_GLOBAL in st_info above. + // Unless we need to set it to SHN_COMMON? D_word(st_shndx); @@ -250,7 +295,6 @@ uint8_t * AddELFSymEntry(uint8_t * buf, SYM * sym, int globflag) return buf + 0x10; } - // // Helper function for ELF output // @@ -271,7 +315,6 @@ int DepositELFSectionHeader(uint8_t * ptr, uint32_t name, uint32_t type, uint32_ return 40; } - // // Deposit an entry in the Section Header string table // @@ -286,7 +329,6 @@ printf("DepositELFSHSTEntry: s = \"%s\"\n", s); return strSize + 1; } - // // Deposit a symbol table entry in the ELF Symbol Table // @@ -303,7 +345,6 @@ uint32_t DepositELFSymbol(uint8_t * ptr, uint32_t name, uint32_t addr, uint32_t return 16; } - // // Write an object file to the passed in file descriptor // N.B.: Return value is ignored... @@ -327,7 +368,9 @@ int WriteObject(int fd) // Write requested object file... if ((obj_format == BSD) || ((obj_format == ALCYON) && (prg_flag == 0))) - { + { + ch_size = 0; + // Force BSD format (if it was ALCYON format) obj_format = BSD; @@ -336,9 +379,9 @@ int WriteObject(int fd) printf("Total : %d bytes\n", sect[TEXT].sloc + sect[DATA].sloc + sect[BSS].sloc); } - sy_assign(NULL, NULL); // Assign index numbers to the symbols + AssignSymbolNos(NULL, NULL); // Assign index numbers to the symbols tds = sect[TEXT].sloc + sect[DATA].sloc; // Get size of TEXT and DATA segment - buf = malloc(0x800000); // Allocate 8MB object file image memory + buf = malloc(0x800000); // Allocate 8MB object file image memory if (buf == NULL) { @@ -398,7 +441,7 @@ int WriteObject(int fd) // Point to start of symbol table p = buf + BSDHDRSIZE + tds + trsize + drsize; - sy_assign(p, AddBSDSymEntry); // Build symbol and string tables + AssignSymbolNos(p, AddBSDSymEntry); // Build symbol and string tables chptr = buf + 0x10; // Point to sym table size hdr entry D_long(symsize); // Write the symbol table size @@ -425,6 +468,8 @@ int WriteObject(int fd) } else if (obj_format == ALCYON) { + ch_size = 0; + if (verb_flag) { if (prg_flag) @@ -435,7 +480,8 @@ int WriteObject(int fd) // 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; + // (To clarify: 28 bytes is the size of an extended symbol) + uint32_t symbolMaxSize = AssignSymbolNos(NULL, NULL) * 28; // Alloc memory for header + text + data, symbol and relocation // information construction. @@ -475,8 +521,8 @@ int WriteObject(int fd) // Construct symbol table and update the header entry, if necessary if (prg_flag > 1) { - // sy_assign with AddSymEntry updates symsize (stays 0 otherwise) - sy_assign(buf + HDRSIZE + tds, AddSymEntry); + // AssignSymbolNos with AddSymEntry updates symsize (stays 0 otherwise) + AssignSymbolNos(buf + HDRSIZE + tds, AddSymEntry); chptr = buf + 0x0E; // Point to symbol table size entry D_long(symsize); @@ -732,7 +778,7 @@ for(int j=0; jchnext) + { + memcpy(p, cp->chptr, cp->ch_size); + p += cp->ch_size; + } + } + if (MarkABSImage(buf, tds, sect[TEXT].sloc, TEXT) != OK) // Do TEXT relocation table + { + return ERROR; + } + if (MarkABSImage(buf, tds, sect[TEXT].sloc, DATA) != OK) // Do DATA relocation table + { + return ERROR; + } + + // Write out the header + text & data + symbol table (if any) + unused = write(fd, buf, tds); + + } return 0; } - static void WriteLOD(void) { D_printf("_START %s 0000 0000 0000 RMAC %01i.%01i.%01i\n\n", firstfname, MAJOR, MINOR, PATCH); @@ -889,7 +983,6 @@ static void WriteLOD(void) D_printf("\n_END %.4X\n", dsp_orgmap[0].orgadr); } - static void WriteP56(void) { for(DSP_ORG * l=&dsp_orgmap[0]; l