194 lines
5.6 KiB
Plaintext
Executable File
194 lines
5.6 KiB
Plaintext
Executable File
/* Linker script for DOS executables with separate data and text segments.
|
|
Partly derived from dos-exe-small.ld in newlib-ia16 and elks-separate.ld. */
|
|
|
|
OUTPUT_FORMAT(binary)
|
|
|
|
DOS_PSP = 0x60;
|
|
MEMOFS = DOS_PSP * 16 - SIZEOF(.msdos_mz_hdr);
|
|
|
|
/* these GROUPs play the same role as GROUPS (segments) in OMF */
|
|
PGROUP = (MEMOFS + LOADADDR(.ptext)) / 16;
|
|
LGROUP = (MEMOFS + LOADADDR(.ltext)) / 16;
|
|
DGROUP = (MEMOFS + LOADADDR(.data)) / 16;
|
|
_DosDataSeg = DGROUP;
|
|
TGROUP = (MEMOFS + LOADADDR(.text)) / 16;
|
|
IGROUP = (MEMOFS + LOADADDR(.itext)) / 16;
|
|
I_GROUP = (MEMOFS + LOADADDR(.idata)) / 16;
|
|
|
|
INITSIZE = SIZEOF(.itext) + SIZEOF(.idata) + SIZEOF(.ibss);
|
|
|
|
SECTIONS
|
|
{
|
|
/* Fabricate a .exe header here. Although libbfd does have an
|
|
"i386msdos" back-end which produces an "MZ" exe header, it cannot do
|
|
certain things (yet). */
|
|
.msdos_mz_hdr : {
|
|
/* Signature. */
|
|
SHORT (0x5a4d)
|
|
/* Bytes in last 512-byte page. */
|
|
SHORT (LOADADDR (.ibss) % 512)
|
|
/* Total number of 512-byte pages. */
|
|
SHORT (ALIGN(LOADADDR (.ibss), 512) / 512)
|
|
/* Relocation entries. */
|
|
SHORT ((__msdos_mz_rel_end - __msdos_mz_rel_start) / 4)
|
|
/* Header size in paragraphs. */
|
|
SHORT (SIZEOF(.msdos_mz_hdr) / 16)
|
|
/* Minimum extra paragraphs. */
|
|
SHORT (ALIGN(SIZEOF (.ibss) + SIZEOF(.istack), 16) / 16)
|
|
/* Maximum extra paragraphs. */
|
|
SHORT (0xffff)
|
|
/* Initial %ss. */
|
|
SHORT (LOADADDR (.istack) / 16 )
|
|
/* Initial %sp. */
|
|
SHORT (LOADADDR (.istack) % 16 + SIZEOF(.istack))
|
|
/* Padding for Checksum (unused) and initial cs:ip (0:0) */
|
|
. = 0x18;
|
|
/* Relocation table offset. */
|
|
SHORT (. + 4)
|
|
/* Overlay number */
|
|
SHORT (0)
|
|
/* Relocations */
|
|
HIDDEN (__msdos_mz_rel_start = .);
|
|
*(.msdos_mz_reloc .msdos_mz_reloc.*)
|
|
HIDDEN (__msdos_mz_rel_end = .);
|
|
/* Padding */
|
|
. = ALIGN (16);
|
|
}
|
|
|
|
/* Target PSP section. */
|
|
.ptext 0 : AT (SIZEOF(.msdos_mz_hdr)) {
|
|
*(PSP)
|
|
}
|
|
|
|
/* Target low data+text sections. */
|
|
.ltext 0 : AT (LOADADDR(.ptext) + SIZEOF(.ptext)) {
|
|
*(_IRQTEXT)
|
|
*(_LOWTEXT)
|
|
*(_IO_TEXT)
|
|
*(_IO_FIXED_DATA)
|
|
}
|
|
|
|
/* Target data sections. */
|
|
.data 0 : AT (ALIGN(LOADADDR(.ltext) + SIZEOF(.ltext), 16)) {
|
|
*(_FIXED_DATA)
|
|
*(_BSS)
|
|
*(EXCLUDE_FILE (config.obj iasmsupt.obj *init*.obj iprf.obj main.obj) .bss)
|
|
*(_DATA)
|
|
*(EXCLUDE_FILE (config.obj iasmsupt.obj *init*.obj iprf.obj main.obj) .data)
|
|
*(_DATAEND)
|
|
*(CONST)
|
|
*(CONST2)
|
|
*(EXCLUDE_FILE (config.obj iasmsupt.obj *init*.obj iprf.obj main.obj) .rodata)
|
|
*(EXCLUDE_FILE (config.obj iasmsupt.obj *init*.obj iprf.obj main.obj) .rodata.*)
|
|
*(DYN_DATA)
|
|
ASSERT(. <= 0xfff8,
|
|
"Error: too large for a small-model .exe file.");
|
|
}
|
|
|
|
/* Target text sections. */
|
|
.text 0 : AT (ALIGN(LOADADDR(.data) + SIZEOF(.data), 16)) {
|
|
*(HMA_TEXT_START)
|
|
*(HMA_TEXT)
|
|
_call_intr = CALL_INTR;
|
|
_res_DosExec = RES_DOSEXEC;
|
|
_res_read = RES_READ;
|
|
_strlen = STRLEN;
|
|
_fstrlen = FSTRLEN;
|
|
_strlen = STRLEN;
|
|
_fstrcmp = FSTRCMP;
|
|
_strchr = STRCHR;
|
|
_fstrchr = FSTRCHR;
|
|
_fmemchr = FMEMCHR;
|
|
_strcpy = STRCPY;
|
|
_fmemcpy = FMEMCPY;
|
|
_fstrcpy = FSTRCPY;
|
|
_memcpy = MEMCPY;
|
|
_fmemset = FMEMSET;
|
|
_memset = MEMSET;
|
|
_memcmp = MEMCMP;
|
|
_fmemcmp = FMEMCMP;
|
|
_network_redirector_mx = NETWORK_REDIRECTOR_MX;
|
|
_execrh = EXECRH;
|
|
_share_check = SHARE_CHECK;
|
|
_share_open_check = SHARE_OPEN_CHECK;
|
|
_share_close_file = SHARE_CLOSE_FILE;
|
|
_share_access_check = SHARE_ACCESS_CHECK;
|
|
_share_lock_unlock = SHARE_LOCK_UNLOCK;
|
|
_call_nls = CALL_NLS;
|
|
_fl_reset = FL_RESET;
|
|
_fl_diskchanged = FL_DISKCHANGED;
|
|
_fl_format = FL_FORMAT;
|
|
_fl_read = FL_READ;
|
|
_fl_write = FL_WRITE;
|
|
_fl_verify = FL_VERIFY;
|
|
_fl_setdisktype = FL_SETDISKTYPE;
|
|
_fl_setmediatype = FL_SETMEDIATYPE;
|
|
_fl_readkey = FL_READKEY;
|
|
_fl_lba_ReadWrite = FL_LBA_READWRITE;
|
|
_floppy_change = FLOPPY_CHANGE;
|
|
_ReadPCClock = READPCCLOCK;
|
|
_WritePCClock = WRITEPCCLOCK;
|
|
_WriteATClock = WRITEATCLOCK;
|
|
*(EXCLUDE_FILE (config.obj iasmsupt.obj *init*.obj iprf.obj main.obj) .text)
|
|
*(HMA_TEXT_END)
|
|
ASSERT(. <= 0x10000,
|
|
"Error: too large for a small-model .exe file.");
|
|
}
|
|
|
|
/* Target init text sections. */
|
|
.itext 0 : AT (LOADADDR(.text) + SIZEOF(.text)) {
|
|
*(INIT_TEXT_START)
|
|
*(INIT_TEXT)
|
|
_init_execrh = INIT_EXECRH;
|
|
_init_memset = INIT_MEMSET;
|
|
_init_fmemset = INIT_FMEMSET;
|
|
_init_memcmp = INIT_MEMCMP;
|
|
_init_fmemcmp = INIT_FMEMCMP;
|
|
_init_memcpy = INIT_MEMCPY;
|
|
_init_fmemcpy = INIT_FMEMCPY;
|
|
_init_strcpy = INIT_STRCPY;
|
|
_init_strlen = INIT_STRLEN;
|
|
_init_strchr = INIT_STRCHR;
|
|
_UMB_get_largest = UMB_GET_LARGEST;
|
|
_init_call_intr = INIT_CALL_INTR;
|
|
_read = READ;
|
|
_init_DosOpen = INIT_DOSOPEN;
|
|
_close = CLOSE;
|
|
_dup2 = DUP2;
|
|
_lseek = LSEEK;
|
|
_allocmem = ALLOCMEM;
|
|
_init_PSPSet = INIT_PSPSET;
|
|
_init_DosExec = INIT_DOSEXEC;
|
|
_init_setdrive = INIT_SETDRIVE;
|
|
_init_switchar = INIT_SWITCHAR;
|
|
_keycheck = KEYCHECK;
|
|
_set_DTA = SET_DTA;
|
|
_DetectXMSDriver = DETECTXMSDRIVER;
|
|
_init_call_XMScall = INIT_CALL_XMSCALL;
|
|
__EnableA20 = _ENABLEA20;
|
|
__DisableA20 = _DISABLEA20;
|
|
*(.text)
|
|
*(INIT_TEXT_END)
|
|
ASSERT(. <= 0x10000,
|
|
"Error: too large for a small-model .exe file.");
|
|
}
|
|
|
|
/* Target init data sections. */
|
|
.idata 0 : AT (LOADADDR(.itext) + SIZEOF(.itext)) {
|
|
*(ID_B)
|
|
*(.data)
|
|
*(.rodata) *(.rodata.*)
|
|
*(ID_E)
|
|
}
|
|
.ibss (NOLOAD) : AT (LOADADDR(.idata) + SIZEOF(.idata)) {
|
|
*(IB_B)
|
|
*(.bss)
|
|
*(IB_E)
|
|
}
|
|
.istack 0 (NOLOAD) : AT (LOADADDR(.ibss) + SIZEOF(.ibss)) {
|
|
*(_STACK)
|
|
. = 0x1000;
|
|
}
|
|
/DISCARD/ : { *(.*) }
|
|
}
|