Commit bfd8bf38 authored by Matthias Braun's avatar Matthias Braun
Browse files

support for local common symbols (whatever that is good for); introduce...

support for local common symbols (whatever that is good for); introduce ir_visibility_private (not tested yet as they don't occur in C)

[r27109]
parent 9b4c6a21
...@@ -94,7 +94,15 @@ typedef enum { ...@@ -94,7 +94,15 @@ typedef enum {
* The entity is defined outside the compilation unit but potentially used * The entity is defined outside the compilation unit but potentially used
* here. * here.
*/ */
ir_visibility_external ir_visibility_external,
/**
* This has the same semantic as visibility_local. Additionally the symbol is
* completely hidden from the linker (it only appears in the assembly).
* While visibility_local is probably still visible to debuggers,
* visibility_private symbols aren't and probably won't appear in the object
* files
*/
ir_visibility_private
} ir_visibility; } ir_visibility;
/** /**
......
...@@ -480,7 +480,8 @@ static void do_dump_atomic_init(be_gas_decl_env_t *env, ir_node *init) ...@@ -480,7 +480,8 @@ static void do_dump_atomic_init(be_gas_decl_env_t *env, ir_node *init)
* *
* @param size the size in bytes * @param size the size in bytes
*/ */
static void dump_size_type(size_t size) { static void dump_size_type(size_t size)
{
switch (size) { switch (size) {
case 1: case 1:
be_emit_cstring("\t.byte\t"); be_emit_cstring("\t.byte\t");
...@@ -1218,11 +1219,22 @@ static be_gas_section_t determine_section(be_gas_decl_env_t *env, ...@@ -1218,11 +1219,22 @@ static be_gas_section_t determine_section(be_gas_decl_env_t *env,
panic("Couldn't determine section for %+F?!?", entity); panic("Couldn't determine section for %+F?!?", entity);
} }
static void emit_common(const ir_entity *ent) static void emit_common(const ir_entity *entity)
{ {
const char *name = get_entity_ld_name(ent); const char *name = get_entity_ld_name(entity);
unsigned size = get_type_size_bytes(get_entity_type(ent)); unsigned size = get_type_size_bytes(get_entity_type(entity));
unsigned alignment = get_effective_entity_alignment(ent); unsigned alignment = get_effective_entity_alignment(entity);
ir_visibility visibility = get_entity_visibility(entity);
if (visibility == ir_visibility_local
|| visibility == ir_visibility_private) {
/* counter the visibility_global effect of .comm
* ... and to be honest I have no idea what local common symbols
* are good for...
*/
be_emit_irprintf("\t.local %s\n", name);
be_emit_write_line();
}
switch (be_gas_object_file_format) { switch (be_gas_object_file_format) {
case OBJECT_FILE_FORMAT_MACH_O: case OBJECT_FILE_FORMAT_MACH_O:
...@@ -1272,10 +1284,11 @@ static void dump_indirect_symbol(const ir_entity *entity, be_gas_section_t secti ...@@ -1272,10 +1284,11 @@ static void dump_indirect_symbol(const ir_entity *entity, be_gas_section_t secti
*/ */
static void dump_global(be_gas_decl_env_t *env, const ir_entity *ent) static void dump_global(be_gas_decl_env_t *env, const ir_entity *ent)
{ {
ir_type *type = get_entity_type(ent); ir_type *type = get_entity_type(ent);
ident *ld_ident = get_entity_ld_ident(ent); ident *ld_ident = get_entity_ld_ident(ent);
unsigned alignment = get_effective_entity_alignment(ent); unsigned alignment = get_effective_entity_alignment(ent);
be_gas_section_t section = determine_section(env, ent); be_gas_section_t section = determine_section(env, ent);
ir_visibility visibility = get_entity_visibility(ent);
/* we already emitted all methods. Except for the trampolines which /* we already emitted all methods. Except for the trampolines which
* the assembler/linker generates */ * the assembler/linker generates */
...@@ -1288,17 +1301,29 @@ static void dump_global(be_gas_decl_env_t *env, const ir_entity *ent) ...@@ -1288,17 +1301,29 @@ static void dump_global(be_gas_decl_env_t *env, const ir_entity *ent)
be_dbg_variable(ent); be_dbg_variable(ent);
/* nothing to do for externally defined values */ switch (visibility) {
if (get_entity_visibility(ent) == ir_visibility_external) case ir_visibility_external:
/* nothing to do for externally defined values */
return; return;
case ir_visibility_private:
/* mangle name so the assembler doesn't export the symbol
* TODO: this is probably a bit broken, since the backends probably don't
* mangle themselfes when outputting these symbols... */
ld_ident = id_mangle3(".L", ld_ident, "");
break;
case ir_visibility_local:
case ir_visibility_default:
/* nothing todo (leave the cases here to avoid compiler warnings) */
break;
}
if (!is_po2(alignment)) if (!is_po2(alignment))
panic("alignment not a power of 2"); panic("alignment not a power of 2");
if (section == GAS_SECTION_BSS && if (section == GAS_SECTION_BSS &&
(get_entity_linkage(ent) & IR_LINKAGE_MERGE)) { (get_entity_linkage(ent) & IR_LINKAGE_MERGE)) {
if (get_entity_visibility(ent) != ir_visibility_default) { if (get_entity_visibility(ent) == ir_visibility_external) {
panic("merge link semantic not supported for local/extern entities"); panic("merge link semantic not supported for extern entities");
} }
emit_common(ent); emit_common(ent);
return; return;
...@@ -1334,7 +1359,7 @@ static void dump_global(be_gas_decl_env_t *env, const ir_entity *ent) ...@@ -1334,7 +1359,7 @@ static void dump_global(be_gas_decl_env_t *env, const ir_entity *ent)
be_emit_write_line(); be_emit_write_line();
} }
if (section == GAS_SECTION_BSS || section == GAS_SECTION_TLS_BSS) { if (entity_is_null(ent)) {
be_emit_irprintf("\t.zero %u\n", get_type_size_bytes(type)); be_emit_irprintf("\t.zero %u\n", get_type_size_bytes(type));
be_emit_write_line(); be_emit_write_line();
} else if(entity_has_compound_ent_values(ent)) { } else if(entity_has_compound_ent_values(ent)) {
......
...@@ -417,6 +417,7 @@ int tr_vrfy(void) ...@@ -417,6 +417,7 @@ int tr_vrfy(void)
int res = no_error; int res = no_error;
ir_type *constructors; ir_type *constructors;
ir_type *destructors; ir_type *destructors;
ir_type *thread_locals;
int i; int i;
static ident *empty = NULL; static ident *empty = NULL;
...@@ -427,23 +428,32 @@ int tr_vrfy(void) ...@@ -427,23 +428,32 @@ int tr_vrfy(void)
constructors = get_segment_type(IR_SEGMENT_CONSTRUCTORS); constructors = get_segment_type(IR_SEGMENT_CONSTRUCTORS);
for (i = get_compound_n_members(constructors)-1; i >= 0; --i) { for (i = get_compound_n_members(constructors)-1; i >= 0; --i) {
ir_entity *entity = get_compound_member(constructors, i); const ir_entity *entity = get_compound_member(constructors, i);
ASSERT_AND_RET(get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER, ASSERT_AND_RET(get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER,
"entity without LINKAGE_HIDDEN_USER in constructors is pointless", "entity without LINKAGE_HIDDEN_USER in constructors is pointless",
1); 1);
/* Mach-O doesn't like labels in this section */ /* Mach-O doesn't like labels in this section */
ASSERT_AND_RET(get_entity_ld_ident(entity), ASSERT_AND_RET(get_entity_ld_ident(entity),
"entity in constructors should have ld_ident ''", 1); "entity in constructors should have ld_ident=''", 1);
} }
destructors = get_segment_type(IR_SEGMENT_DESTRUCTORS); destructors = get_segment_type(IR_SEGMENT_DESTRUCTORS);
for (i = get_compound_n_members(destructors)-1; i >= 0; --i) { for (i = get_compound_n_members(destructors)-1; i >= 0; --i) {
ir_entity *entity = get_compound_member(destructors, i); const ir_entity *entity = get_compound_member(destructors, i);
ASSERT_AND_RET(get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER, ASSERT_AND_RET(get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER,
"entity without LINKAGE_HIDDEN_USER in destructors is pointless", "entity without LINKAGE_HIDDEN_USER in destructors is pointless",
1); 1);
/* Mach-O doesn't like labels in this section */ /* Mach-O doesn't like labels in this section */
ASSERT_AND_RET(get_entity_ld_ident(entity), ASSERT_AND_RET(get_entity_ld_ident(entity),
"entity in destructors should have ld_ident ''", 1); "entity in destructors should have ld_ident=''", 1);
}
thread_locals = get_segment_type(IR_SEGMENT_THREAD_LOCAL);
for (i = get_compound_n_members(thread_locals)-1; i >= 0; --i) {
const ir_entity *entity = get_compound_member(thread_locals, i);
/* this is odd and should not be allowed I think */
ASSERT_AND_RET(!is_method_entity(entity),
"method in THREAD_LOCAL segment", 1);
ASSERT_AND_RET(!(get_entity_linkage(entity) & IR_LINKAGE_MERGE),
"IR_LINKAGE_MERGE currently not support for thread locals", 1);
} }
return res; return res;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment