72 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			72 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| This file contains a summary of the bugs/features/inconsistencies
 | |
| Robbert and Ed found while making the linker usable for the 68000 and amoeba.
 | |
| 
 | |
| There is something wrong with the way the combination of
 | |
| assembler and linker handle bss.
 | |
| In the original (Duk's) the assembler translated .space and, worse, .align
 | |
| to a sequence of zero's. If this sequence was at the end of a segment
 | |
| within a module the assembler didn't put zero in the segment but sets
 | |
| os_flen to the amount of space initialized before the zero space
 | |
| and os_size to the segements size. (os_size - os_flen) is then the
 | |
| size of the space filled by zeroes.
 | |
| For the sake of clarity, let us call 0...os_flen-1 initialized space
 | |
| and os_flen..os_size-1 uninitialized space.
 | |
| Now the linker, it does a nasty trick. It gathers the uninitialized space
 | |
| of all modules within a segment and puts it consequtively at the end
 | |
| of the segment. I think that I understand the reason: This way you can keep
 | |
| your resultant a.out smaller and you don't need a special bss segment
 | |
| (a la unix). But it is incorrect, the net effect is that the .align's
 | |
| at the end of segments within a module do have the desired effect,
 | |
| the space thus allocated is removed to 'higher spheres' thereby
 | |
| leaving the first items of that segment in the inmediatly following
 | |
| modules at unaligned boundaries.
 | |
| What should be done is that the linker leaves the initialized and
 | |
| the unitialized code alone and regards the whole a a chunk that can be
 | |
| relocated. Only producing a difference of os_size and os_flen for
 | |
| the zeroes at the very end of the segment. Thereby collapsing all
 | |
| .space (and .align) commands into zero space only if they
 | |
| are in consequtive modules at the end of the segment, with modules
 | |
| NOT containing any initialized data.
 | |
| I already, ad-hoc, changed the code of the assembler to producing 'hard'
 | |
| zeroes when aligning. The trick could also be done for .space
 | |
| but is a bit harder here.
 | |
| The reason: .space is also used to allocate space in the BSS segment
 | |
| if that produced zeroes in the a.out file (0..bss_size) we would
 | |
| have a.out files that are far too large.
 | |
| This feature of the linker also caused weird effects for names that
 | |
| are defined as the very last in a section within a module, without
 | |
| any data (initialized or uninitialezed) after it.
 | |
| The names a regarded as pointing into the uninitialized space and
 | |
| thus relocated to the end of the section.
 | |
| The sequence
 | |
| 	.sect .data
 | |
| begdata:
 | |
| 	.sect ....
 | |
| in an head_em.s resulted in the relocation of begdata to the END
 | |
| of the .data segment.
 | |
| 
 | |
| Another problem form the commons:
 | |
| 1 - Local commons are not handled by led and not produced by as.
 | |
|     using .comm for unitialized data is not correct because (from C)
 | |
|     two uninitialized static declarations for the same name in
 | |
|     different modules will be handled as external commons and thus
 | |
|     be overlayed.
 | |
| 2 - The commons are allocated at the very end of the first pass, after the
 | |
|     initialezed data has been allocated in the segments. The order on which
 | |
|     the commons are allocated seems to be random. That way it is impossible
 | |
|     to produce a label that is guaranteed to point to the last byte (+1)
 | |
|     of a segment containing commons.
 | |
|     The currently used trick is to declare an extra segment after the
 | |
|     segment containing the commons. The first bytre in this segment
 | |
|     inmediatly follows the commons and can be used as _end or endbss.
 | |
| 
 | |
| The archiver (aal) with the automatic ranlib is buggy.
 | |
| The only thing that seems to work at the moment is creation of a fresh
 | |
| archive.
 | |
| replacing/adding/deleting modules is likely to produce libraries
 | |
| with incorrect ranlib entries.
 | |
| The major troublemaker seems to be the extra padding byte at the end
 | |
| of odd sized modules.
 | |
| 
 | |
| Led should return a non-zero value when it has found Undefined symbols
 | |
| or has another reason for not being able to produce a correct output file.
 |