예제 #1
0
int decl_interposable(decl *d)
{
	/*
	 * Match gcc's -fsemantic-interposition default, where:
	 *
	 * -fpic -fpie -fsemantic-interposition function-visibility  |  can-inline-non-static function?
	 *   0     0              0                 default                     yes (-fno-pic)
	 *   0     0              1                 default                     yes (-fno-pic)
	 *   0     1              0                 default                     yes (-fno-pic)
	 *   0     1              1                 default                     yes (-fno-pic)
	 *   0     0              0             protected/hidden                yes (-fno-pic)
	 *   0     0              1             protected/hidden                yes (-fno-pic)
	 *   0     1              0             protected/hidden                yes (-fno-pic)
	 *   0     1              1             protected/hidden                yes (-fno-pic)
	 *
	 *   1     1              1             protected/hidden                yes (-fvisibility=protected/hidden)
	 *   1     1              0             protected/hidden                yes (-fvisibility=protected/hidden)
	 *   1     0              1             protected/hidden                yes (-fvisibility=protected/hidden)
	 *   1     0              0             protected/hidden                yes (-fvisibility=protected/hidden)
	 *
	 *   1     1              1                 default                     yes (-fpie)
	 *   1     1              0                 default                     yes (-fpie)
	 *   1     0              1                 default                     no
	 *   1     0              0                 default                     yes (-fno-semantic-interposition)
	 *
	 * -fno-pic: -fsemantic-interposition and -fvisibility=... have no effect
	 *
	 * -fpic:    We can inline non-static, default-visibility functions when
	 *           -fno-semantic-interposition is set otherwise, the ELF abi says a
	 *           non-static default-visibility function may be overridden.
	 */
	if(!cc1_fopt.pic && !cc1_fopt.pie)
		return 0; /* not compiling for interposable shared library */

	if(cc1_fopt.pie && decl_defined(d, 0))
		return 0; /* pie, this is the main program, can't have its symbols interposed */

	switch(decl_linkage(d)){
		case linkage_internal:
		case linkage_none:
			return 0; /* static decl, fixed */
		case linkage_external:
			break;
	}

	switch(decl_visibility(d)){
		case VISIBILITY_DEFAULT:
			break;
		case VISIBILITY_PROTECTED:
			return 0; /* symbol visible, but not interposable by contract */
		case VISIBILITY_HIDDEN:
			return 0; /* symbol not visible, so not interposable */
	}

	/* extern decls (that aren't explicitly visibility-attributed) are interposable */
	if(!decl_defined(d, 0))
		return 1;

	return cc1_fopt.semantic_interposition;
}
예제 #2
0
int decl_needs_GOTPLT(decl *d)
{
	/* need to differentiate:
	 * extern int x; // always pic (aka x@GOTPCREL(%rip))
	 *
	 * __attribute__((visibility("hidden/protected")))
	 * extern int x; // pic but we can avoid the GOT, e.g. x(%rip)
	 *
	 * int x = 3; // pic, must go via GOT
	 *
	 * -fno-semantic-interposition / -fpie
	 * int x = 3; // pic, can avoid the GOT because it's effectively hidden/protected
	 *
	 * -fno-semantic-interposition / -fno-pie (but -fpic)
	 * extern int x; // pic, must use GOT as we don't know if it's in our module
	 */

	if(!cc1_fopt.pic && !cc1_fopt.pie)
		return 0;

	if(decl_linkage(d) == linkage_internal)
		return 0;

	if(cc1_fopt.pie){
		/* gcc acts as if variables are always local/accessible without the GOT in pie-code */
		int is_var = 0; /* !type_is(d->ref, type_func) */

		if((is_var || decl_defined(d, 0)) && !attribute_present(d, attr_weak))
			return 0;
	}

	switch(decl_visibility(d)){
		case VISIBILITY_DEFAULT:
			break;
		case VISIBILITY_HIDDEN:
		case VISIBILITY_PROTECTED:
			return 0;
	}

	return 1;
}
예제 #3
0
파일: asm.c 프로젝트: 8l/ucc-c-compiler
void asm_declare_decl_init(decl *d)
{
	enum section_type sec;

	if((d->store & STORE_MASK_STORE) == store_extern){
		asm_predeclare_extern(d);
		return;
	}

	sec = type_is_const(d->ref) ? SECTION_RODATA : SECTION_DATA;

	if(d->bits.var.init.dinit && !decl_init_is_zero(d->bits.var.init.dinit)){
		asm_nam_begin(sec, d);
		asm_declare_init(sec, d->bits.var.init.dinit, d->ref);
		asm_out_section(sec, "\n");

	}else if(d->bits.var.init.compiler_generated && fopt_mode & FOPT_COMMON){
		const char *common_prefix = "comm ";

		/* section doesn't matter */
		sec = SECTION_BSS;

		if(decl_linkage(d) == linkage_internal){
			if(AS_SUPPORTS_LOCAL_COMMON){
				asm_out_section(sec, ".local %s\n", decl_asm_spel(d));
			}else{
				common_prefix = "zerofill __DATA,__bss,";
			}
		}

		asm_out_section(sec, ".%s%s,%u,%u\n",
				common_prefix,
				decl_asm_spel(d), decl_size(d), decl_align(d));

	}else{
		/* always resB, since we use decl_size() */
		asm_nam_begin(SECTION_BSS, d);
		asm_reserve_bytes(SECTION_BSS, decl_size(d));
	}
}
예제 #4
0
int decl_unused_and_internal(decl *d)
{
	/* need to check every clone of the decl */
	decl *i;
	int used = 0;

	for(i = d; i; i = i->proto){
		if(i->flags & DECL_FLAGS_USED){
			used = 1;
			goto fin;
		}
	}
	for(i = d; i; i = i->impl){
		if(i->flags & DECL_FLAGS_USED){
			used = 1;
			goto fin;
		}
	}

fin:
	return !used && decl_linkage(d) != linkage_external;
}