From mint-bounce@lists.fishpool.fi Tue Feb 5 10:56:43 2008 Message-ID: <47A885A7.2070403@freesbee.fr> Date: Tue, 05 Feb 2008 16:49:59 +0100 From: =?ISO-8859-1?Q?Vincent_Rivi=E8re?= User-Agent: Thunderbird 2.0.0.9 (Windows/20071031) MIME-Version: 1.0 To: mint Subject: Re: [MiNT] Alignment References: <4798E197.6050500@freesbee.fr> In-Reply-To: <4798E197.6050500@freesbee.fr> Content-Type: text/plain; charset=ISO-8859-1; format=flowed X-ecartis-version: Ecartis v1.0.0 Sender: mint-bounce@lists.fishpool.fi Errors-to: mint-bounce@lists.fishpool.fi X-original-sender: vincent.riviere@freesbee.fr Precedence: bulk List-help: List-unsubscribe: List-Id: X-List-ID: List-subscribe: List-owner: List-post: Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by mail.sparemint.org id m15FugTP032370 More information about alignment and compatibility issues. The only important alignment for compatibility is the one used by GCC. It has always been 2 for MiNT (but it is 4 for other m68k platforms). The GCC alignment is important for (at least) 2 things: 1) Structure members alignment. This is crucial for compatibility. If a program (or LDG dynamic library) expects to find some data at a specific offset, of course it will crash if the data is not exactly at the same place. 2) Aligning global variables to the specified alignment for performance purpose. Because the current GCC alignment is 2, the variables of type "long" of "structure containing longs" may or may not be aligned on 4-byte boundaries. The alignment of the global variables is a performance issue, but not a compatibility problem. Then at the binutils level: gas takes in input an asm source file, assemble it without modifying any offset (regardless to the binutils alignment), then it generates sections (.text, .data) with the following characteristics : 1) The section is marked as needing to be aligned on the "binutils alignment". This rule will have to be respected by the linker. 2) The section size is adjusted in order to be a multiple of the "binutils alignment". Thanks to that, when the linker will append another section coming from another .o file just after it, the alignment will be respected. What happens in the binutils-2.13 for MiNT ? GCC generates 2-byte aligned code. Then gas uses a 4-byte alignment. It is totally useless: only the first global variable will respect that alignment. The following ones will only respect what was generated by GCC: alignment on 2. Then ld links all the .o files, and respect their (bogus) alignment. Then the OS load the executable in memory. If the OS loads the executable to a multiple of 4, the linker alignment will be respected. But if the OS loads the executable to a multiple of 2 only, all that alignment stuff will be totally useless ! I remember I saw such things on my STe with TOS 1.62, but I need to make further tests. A quick summary : 1) GCC must respect the hardcoded "GCC alignment" 2) gas must produce .o files in respect to the alignment requested by GCC. 3) ld must produce executable files in respect to the alignment requested by every .o file. 4) The OS must respect the alignment of the executable files when loading them into memory. If any of the above points is not respected, all that "performance alignment" tweaking will be useless. You can see the alignements with the binutils objdump command: $ m68k-atari-mint-objdump -h hello.o hello.o: file format a.out-zero-big Sections: Idx Name Size VMA LMA File off Algn 0 .text 000000aa 00000000 00000000 00000020 2**1 CONTENTS, ALLOC, LOAD, RELOC, CODE 1 .data 00000008 000000aa 000000aa 000000ca 2**1 CONTENTS, ALLOC, LOAD, DATA 2 .bss 00000000 000000b2 000000b2 00000000 2**1 ALLOC $ m68k-atari-mint-objdump -h hello.tos hello.tos: file format a.out-mintprg Sections: Idx Name Size VMA LMA File off Algn 0 .text 0000bed6 000000e4 000000e4 00000100 2**1 CONTENTS, ALLOC, LOAD, CODE 1 .data 000005ac 0000bfba 0000bfba 0000bfd6 2**1 CONTENTS, ALLOC, LOAD, DATA 2 .bss 00000b86 0000c566 0000c566 00000000 2**1 ALLOC The column "Algn" indicates the alignment. Note that the notation "**" indicates "power". So "2**1" is 2, and "2**2" is 4. For MiNT exectuables (without virtual memory - sigh), the VMA address is the offset of the section in memory, relative to the start of the .text segment. The VMA address of the .text segment in executables is e4 instead of 00 because of the size of the extended MiNT header. Note the name of the .o file format. It is not actually saved into the a.out object files, it is hardcoded into the binutils (!). So objdump-2.13 will always display "a.out-mint", and objdump-2.18 will always display "a.out-zero-big" I specially improved the objdump tool in binutils 2.18. It's output is now 100% accurate. -- Vincent Rivière