//
-// 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-2021 Reboot and Friends
// RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
// Source utilised with the kind permission of Landon Dyer
//
w |= AL_EXTERN | AL_GLOBAL; // Common symbol
w &= ~AL_BSS; // They're not BSS in Alcyon object files
}
- else if (w1 & DEFINED)
+
+ if (w1 & DEFINED)
{
if (globflag) // Export the symbol
w |= AL_GLOBAL;
{
z = 0x02000000; // Set equated flag
}
- else
+
+ // If a symbol is both EQUd and flagged as TBD then we let
+ // the later take precedence. Otherwise the linker will not even
+ // bother trying to relocate the address during link time
+
+ switch (w1 & TDB)
{
- 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
- }
+ 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)
register WORD w1 = sym->sattr;
- if (w1 & COMMON)
- {
- //w |= AL_EXTERN | AL_GLOBAL; // common symbol
- //w &= ~AL_BSS; // they're not BSS in Alcyon object files
- }
- else if (w1 & DEFINED)
+ 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;
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];
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);
//
int WriteObject(int fd)
{
- LONG t; // Scratch long
LONG tds; // TEXT & DATA segment size
int i; // Temporary int
CHUNK * cp; // Chunk (for gather)
uint8_t * buf; // Scratch area
uint8_t * p; // Temporary ptr
LONG trsize, drsize; // Size of relocations
- long unused; // For supressing 'write' warnings
+ uint32_t unused; // For supressing 'write' warnings
if (verb_flag)
{
// 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;
}
else if (obj_format == ALCYON)
{
+ ch_size = 0;
+
if (verb_flag)
{
if (prg_flag)
// Assign index numbers to the symbols, get # of symbols (we assume
// that all symbols can potentially be extended, hence the x28)
+ // (To clarify: 28 bytes is the size of an extended symbol)
uint32_t symbolMaxSize = sy_assign(NULL, NULL) * 28;
// Alloc memory for header + text + data, symbol and relocation
sy_assign(buf + HDRSIZE + tds, AddSymEntry);
chptr = buf + 0x0E; // Point to symbol table size entry
D_long(symsize);
+
+ if (verb_flag)
+ printf("Symbol table: %d bytes\n", symsize);
}
// Write out the header + text & data + symbol table (if any)
else
WriteP56();
- // Write all the things |o/
- ssize_t unused = write(fd, buf, chptr - buf);
+ // Write all the things \o/
+ unused = write(fd, buf, chptr - buf);
if (buf)
free(buf);
}
+ else if (obj_format == RAW)
+ {
+ if (!org68k_active)
+ {
+ return error("cannot output absolute binary without a starting address (.org or command line)");
+ }
+
+ // Alloc memory for text + data construction.
+ tds = sect[TEXT].sloc + sect[DATA].sloc;
+ buf = malloc(tds);
+ chptr = buf;
+ // Construct text and data segments; fixup relocatable longs;
+ // finally write the text + data
+
+ p = buf;
+ objImage = buf; // Set global object image pointer
+
+ for (i = TEXT; i <= DATA; i++)
+ {
+ for (cp = sect[i].sfcode; cp != NULL; cp = cp->chnext)
+ {
+ 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;
}