123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- | Fargo 0.2.1 Library Header
- | The format of this header is documented in some old (Fargo 0.2.3 or earlier)
- | versions of Fargo.txt.
- | Here's some additional information:
- /*
- The bytes in the Fargo >=0.2.1 relocation table have the following meaning
- (NOTE: all numbers below are hexadecimal!):
- The offset starts at the end of the Fargo header - 6 bytes. (For some
- reason... The smallest encodable difference is 4 bytes, not 6.)
- 00: end of list
- 01-7F: add 004-100 (2(value+1)) to the previous offset to get the new one
- 80-BF: add 04-22 (2(nibble_value+2)). (Note that 01-7F can be used for
- that purpose as well if you are a lazy linker author. :-) But the
- nibble-encoding saves some space, so you'd better use it.)
- The bytes have the following values (the most significant nibble is
- the first one):
- Byte 1: n+6 (2+6=8 .. 5+6=B), first data nibble
- Byte 2: 2 data nibbles
- ...
- Byte n: 2 data nibbles
- Note that n = ([total number of data nibbles] + 1) / 2. It follows
- that the total number of data nibbles must be odd and >=3. Use
- byte-encoding (01-7F) otherwise (for all data if the number is <=2,
- for the last data nibble only if it is even and >=4). It also must
- not exceed 9 (5*2-1), in which case you need to split it up.
- C0-FF: the byte starts a full word: 0xC000+difference
- add 2(difference+0x81) to the previous offset to get the new one
- FFFF is special: it adds 0x80FC to the offset, but the computation
- does not stop here, instead another delta is added
- (NOTE: numbers below are decimal unless prefixed by "0x"!)
- In pseudo-code, this means:
- offset=26-6; // header size - 6
- for each (byte) {
- switch (byte) {
- case 0: stop;
- case 0x01..0x7f:
- offset+=2*(byte+1);
- dump(offset);
- break;
- case 0x80..0xbf:
- n=(byte>>4)-6;
- offset+=2*((byte&7)+2);
- dump(offset);
- for(i=1;i<n;i++) {
- offset+=2*((byte>>4)+2);
- dump(offset);
- offset+=2*((byte&7)+2);
- dump(offset);
- }
- case 0xc0..0xff:
- complete the word;
- if (word==0xFFFF) {
- offset+=0x80FC;
- } else {
- offset+=2*(word-(0xC000-0x81));
- dump(offset);
- }
- }
- }
- Another thing which changed since the old format is that the BSS size is encoded
- as a word, not as a longword, and that there is no relocation table at all if
- the size is 0.
- The export table is not compressed, only the reloc, BSS and import tables
- are.
- */
- .xdef __fargo_library_header,__fargo_program_signature,__fargo_fixed_header_end,__ld_insert_fargo_exports,__ld_fargo021_relocs_ref,__ld_fargo021_bss_refs_ref,__ld_fargo021_libs_ref
- | Fixed Fargo library header.
- .section _stl1,"d"
- __fargo_library_header:
- __fargo_program_signature:
- .word 0x0032
- .ascii "EXE DLL "
- __fargo_reloc_count_pos:
- .word 0
- __fargo_reloc_table_pos:
- .word __ld_insert_fargo021_relocs-__fargo_program_signature+2
- __fargo_bss_table_pos:
- .word __ld_insert_fargo021_bss_refs-__fargo_program_signature+2
- __fargo_import_table_pos:
- .word __ld_insert_fargo021_libs-__fargo_program_signature+2
- __fargo_export_table_pos:
- .word __fargo_library_export_table-__fargo_program_signature+2
- __fargo_library_name_pos:
- .word _library-__fargo_program_signature+2
- | The reference address for compressed relocs is located here.
- __ld_fargo021_relocs_ref:
- __ld_fargo021_bss_refs_ref:
- __ld_fargo021_libs_ref:
- __fargo_flags:
- .word 1 | Fargo 0.2.1 format
- __fargo_fixed_header_end:
- | Relocation table is auto-generated by __ld_insert_fargo021_relocs.
- | The format for the reloc table is as follows:
- | A compressed reloc table (see above).
- | BSS table is auto-generated by __ld_insert_fargo021_bss_refs.
- | The format for the BSS table is as follows:
- | 2 bytes: BSS size
- | If non-zero:
- | A compressed reloc table (see above).
- | Fargo library import table is auto-generated by __ld_insert_fargo021_libs.
- | The format for the library table is as follows:
- | 2 bytes: number of libraries
- | For each library...
- | 2 bytes: offset to the library name
- | For each imported function..
- | A compressed (see below) offset of the function index in the library from
- | than the previous one. The base offset is -1.
- | 1 byte: 01-7F: offset (1 byte) OR 80-FF: first byte of (offset+0x8000)
- | If 80-FF:
- | 1 byte: second byte of (offset+0x8000)
- | A compressed reloc table (see above).
- | 1 byte: 0
- | 1 byte: 0 (Yes, there is a redundant null-terminator! Needed only if at least 1 library.)
- | Fargo library export table.
- .section _stl2,"d"
- __fargo_library_export_table:
- __fargo_export_count_pos:
- .word __ld_export_count
- __ld_insert_fargo_exports:
- | The format for the export table is as follows:
- | For each export...
- | 2 bytes: offset into the program
|