_fargo021_library_header.s 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. | Fargo 0.2.1 Library Header
  2. | The format of this header is documented in some old (Fargo 0.2.3 or earlier)
  3. | versions of Fargo.txt.
  4. | Here's some additional information:
  5. /*
  6. The bytes in the Fargo >=0.2.1 relocation table have the following meaning
  7. (NOTE: all numbers below are hexadecimal!):
  8. The offset starts at the end of the Fargo header - 6 bytes. (For some
  9. reason... The smallest encodable difference is 4 bytes, not 6.)
  10. 00: end of list
  11. 01-7F: add 004-100 (2(value+1)) to the previous offset to get the new one
  12. 80-BF: add 04-22 (2(nibble_value+2)). (Note that 01-7F can be used for
  13. that purpose as well if you are a lazy linker author. :-) But the
  14. nibble-encoding saves some space, so you'd better use it.)
  15. The bytes have the following values (the most significant nibble is
  16. the first one):
  17. Byte 1: n+6 (2+6=8 .. 5+6=B), first data nibble
  18. Byte 2: 2 data nibbles
  19. ...
  20. Byte n: 2 data nibbles
  21. Note that n = ([total number of data nibbles] + 1) / 2. It follows
  22. that the total number of data nibbles must be odd and >=3. Use
  23. byte-encoding (01-7F) otherwise (for all data if the number is <=2,
  24. for the last data nibble only if it is even and >=4). It also must
  25. not exceed 9 (5*2-1), in which case you need to split it up.
  26. C0-FF: the byte starts a full word: 0xC000+difference
  27. add 2(difference+0x81) to the previous offset to get the new one
  28. FFFF is special: it adds 0x80FC to the offset, but the computation
  29. does not stop here, instead another delta is added
  30. (NOTE: numbers below are decimal unless prefixed by "0x"!)
  31. In pseudo-code, this means:
  32. offset=26-6; // header size - 6
  33. for each (byte) {
  34. switch (byte) {
  35. case 0: stop;
  36. case 0x01..0x7f:
  37. offset+=2*(byte+1);
  38. dump(offset);
  39. break;
  40. case 0x80..0xbf:
  41. n=(byte>>4)-6;
  42. offset+=2*((byte&7)+2);
  43. dump(offset);
  44. for(i=1;i<n;i++) {
  45. offset+=2*((byte>>4)+2);
  46. dump(offset);
  47. offset+=2*((byte&7)+2);
  48. dump(offset);
  49. }
  50. case 0xc0..0xff:
  51. complete the word;
  52. if (word==0xFFFF) {
  53. offset+=0x80FC;
  54. } else {
  55. offset+=2*(word-(0xC000-0x81));
  56. dump(offset);
  57. }
  58. }
  59. }
  60. Another thing which changed since the old format is that the BSS size is encoded
  61. as a word, not as a longword, and that there is no relocation table at all if
  62. the size is 0.
  63. The export table is not compressed, only the reloc, BSS and import tables
  64. are.
  65. */
  66. .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
  67. | Fixed Fargo library header.
  68. .section _stl1,"d"
  69. __fargo_library_header:
  70. __fargo_program_signature:
  71. .word 0x0032
  72. .ascii "EXE DLL "
  73. __fargo_reloc_count_pos:
  74. .word 0
  75. __fargo_reloc_table_pos:
  76. .word __ld_insert_fargo021_relocs-__fargo_program_signature+2
  77. __fargo_bss_table_pos:
  78. .word __ld_insert_fargo021_bss_refs-__fargo_program_signature+2
  79. __fargo_import_table_pos:
  80. .word __ld_insert_fargo021_libs-__fargo_program_signature+2
  81. __fargo_export_table_pos:
  82. .word __fargo_library_export_table-__fargo_program_signature+2
  83. __fargo_library_name_pos:
  84. .word _library-__fargo_program_signature+2
  85. | The reference address for compressed relocs is located here.
  86. __ld_fargo021_relocs_ref:
  87. __ld_fargo021_bss_refs_ref:
  88. __ld_fargo021_libs_ref:
  89. __fargo_flags:
  90. .word 1 | Fargo 0.2.1 format
  91. __fargo_fixed_header_end:
  92. | Relocation table is auto-generated by __ld_insert_fargo021_relocs.
  93. | The format for the reloc table is as follows:
  94. | A compressed reloc table (see above).
  95. | BSS table is auto-generated by __ld_insert_fargo021_bss_refs.
  96. | The format for the BSS table is as follows:
  97. | 2 bytes: BSS size
  98. | If non-zero:
  99. | A compressed reloc table (see above).
  100. | Fargo library import table is auto-generated by __ld_insert_fargo021_libs.
  101. | The format for the library table is as follows:
  102. | 2 bytes: number of libraries
  103. | For each library...
  104. | 2 bytes: offset to the library name
  105. | For each imported function..
  106. | A compressed (see below) offset of the function index in the library from
  107. | than the previous one. The base offset is -1.
  108. | 1 byte: 01-7F: offset (1 byte) OR 80-FF: first byte of (offset+0x8000)
  109. | If 80-FF:
  110. | 1 byte: second byte of (offset+0x8000)
  111. | A compressed reloc table (see above).
  112. | 1 byte: 0
  113. | 1 byte: 0 (Yes, there is a redundant null-terminator! Needed only if at least 1 library.)
  114. | Fargo library export table.
  115. .section _stl2,"d"
  116. __fargo_library_export_table:
  117. __fargo_export_count_pos:
  118. .word __ld_export_count
  119. __ld_insert_fargo_exports:
  120. | The format for the export table is as follows:
  121. | For each export...
  122. | 2 bytes: offset into the program