Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Mar 2012 17:18:48 -0700
From:      Chuck Swiger <cswiger@mac.com>
To:        kaltheat@googlemail.com
Cc:        freebsd-questions@freebsd.org
Subject:   Re: Which compiler compiled system?
Message-ID:  <E0F66E4F-7CC9-4CC3-9A0F-AC5710ED47F9@mac.com>
In-Reply-To: <20120312194545.GA14584@->
References:  <20120312194545.GA14584@->

next in thread | previous in thread | raw e-mail | index | archive | help
On Mar 12, 2012, at 12:45 PM, kaltheat@googlemail.com wrote:
> Is there a way to determine whether a FreeBSD-system was compiled with gcc or clang?
> I thought of some libs or so that might significantly differ.

It's fairly easy to determine whether assembly code was compiled with gcc or clang from idioms they use-- GCC emits .ascii for strings and then adds a trailing null; clang uses .asciz, for example.  From that you can also figure out whether a particular executable or shared library was compiled with one or the other-- gcc is doing a leaf frame caller optimization, where it leave / jmp to puts() (using the stack frame allocated for main()), whereas clang is doing normal stack frame handling of %rpb and explicit return.

Regards,
-- 
-Chuck

% cat h.c
#include <stdio.h>

int main() {
    puts("Hello, world!\n");
}
% gcc -S -O2 -o h-gcc.s h.c
% clang -S -O2 -o h-clang.s h.c
% cat h-gcc.s
	.cstring
LC0:
	.ascii "Hello, world!\12\0"
	.text
	.align 4,0x90
.globl _main
_main:
LFB3:
	pushq	%rbp
LCFI0:
	movq	%rsp, %rbp
LCFI1:
	leaq	LC0(%rip), %rdi
	leave
	jmp	_puts
LFE3:
	.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame1:
	.set L$set$0,LECIE1-LSCIE1
	.long L$set$0
LSCIE1:
	.long	0x0
	.byte	0x1
	.ascii "zR\0"
	.byte	0x1
	.byte	0x78
	.byte	0x10
	.byte	0x1
	.byte	0x10
	.byte	0xc
	.byte	0x7
	.byte	0x8
	.byte	0x90
	.byte	0x1
	.align 3
LECIE1:
.globl _main.eh
_main.eh:
LSFDE1:
	.set L$set$1,LEFDE1-LASFDE1
	.long L$set$1
LASFDE1:
	.long	LASFDE1-EH_frame1
	.quad	LFB3-.
	.set L$set$2,LFE3-LFB3
	.quad L$set$2
	.byte	0x0
	.byte	0x4
	.set L$set$3,LCFI0-LFB3
	.long L$set$3
	.byte	0xe
	.byte	0x10
	.byte	0x86
	.byte	0x2
	.byte	0x4
	.set L$set$4,LCFI1-LCFI0
	.long L$set$4
	.byte	0xd
	.byte	0x6
	.align 3
LEFDE1:
	.subsections_via_symbols

% cat h-clang.s
	.section	__TEXT,__text,regular,pure_instructions
	.globl	_main
	.align	4, 0x90
_main:                                  ## @main
Leh_func_begin0:
## BB#0:
	pushq	%rbp
Ltmp0:
	movq	%rsp, %rbp
Ltmp1:
	leaq	L_.str(%rip), %rdi
	callq	_puts
	xorl	%eax, %eax
	popq	%rbp
	ret
Leh_func_end0:

	.section	__TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
	.asciz	 "Hello, world!\n"

	.section	__TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame0:
Lsection_eh_frame0:
Leh_frame_common0:
Lset0 = Leh_frame_common_end0-Leh_frame_common_begin0 ## Length of Common Information Entry
	.long	Lset0
Leh_frame_common_begin0:
	.long	0                       ## CIE Identifier Tag
	.byte	1                       ## DW_CIE_VERSION
	.asciz	 "zR"                   ## CIE Augmentation
	.byte	1                       ## CIE Code Alignment Factor
	.byte	120                     ## CIE Data Alignment Factor
	.byte	16                      ## CIE Return Address Column
	.byte	1                       ## Augmentation Size
	.byte	16                      ## FDE Encoding = pcrel
	.byte	12                      ## DW_CFA_def_cfa
	.byte	7                       ## Register
	.byte	8                       ## Offset
	.byte	144                     ## DW_CFA_offset + Reg (16)
	.byte	1                       ## Offset
	.align	3
Leh_frame_common_end0:
	.globl	_main.eh
_main.eh:
Lset1 = Leh_frame_end0-Leh_frame_begin0 ## Length of Frame Information Entry
	.long	Lset1
Leh_frame_begin0:
Lset2 = Leh_frame_begin0-Leh_frame_common0 ## FDE CIE offset
	.long	Lset2
Ltmp2:                                  ## FDE initial location
	.quad	Leh_func_begin0-Ltmp2
Lset3 = Leh_func_end0-Leh_func_begin0   ## FDE address range
	.quad	Lset3
	.byte	0                       ## Augmentation size
	.byte	4                       ## DW_CFA_advance_loc4
Lset4 = Ltmp0-Leh_func_begin0
	.long	Lset4
	.byte	14                      ## DW_CFA_def_cfa_offset
	.byte	16                      ## Offset
	.byte	134                     ## DW_CFA_offset + Reg (6)
	.byte	2                       ## Offset
	.byte	4                       ## DW_CFA_advance_loc4
Lset5 = Ltmp1-Ltmp0
	.long	Lset5
	.byte	13                      ## DW_CFA_def_cfa_register
	.byte	6                       ## Register
	.align	3
Leh_frame_end0:

.subsections_via_symbols

...and here's a disassembly of main() from gcc:

_main:
0000000100000f10	pushq	%rbp
0000000100000f11	movq	%rsp,%rbp
0000000100000f14	leaq	0x00000039(%rip),%rdi
0000000100000f1b	leave
0000000100000f1c	jmp	0x100000f28	; symbol stub for: _puts

...and clang:

_main:
0000000100000f10	pushq	%rbp
0000000100000f11	movq	%rsp,%rbp
0000000100000f14	leaq	0x00000039(%rip),%rdi
0000000100000f1b	callq	0x100000f2a	; symbol stub for: _puts
0000000100000f20	xorl	%eax,%eax
0000000100000f22	popq	%rbp
0000000100000f23	ret




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?E0F66E4F-7CC9-4CC3-9A0F-AC5710ED47F9>