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 {
* The entity is defined outside the compilation unit but potentially used
* 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;
/**
......
......@@ -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
*/
static void dump_size_type(size_t size) {
static void dump_size_type(size_t size)
{
switch (size) {
case 1:
be_emit_cstring("\t.byte\t");
......@@ -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);
}
static void emit_common(const ir_entity *ent)
static void emit_common(const ir_entity *entity)
{
const char *name = get_entity_ld_name(ent);
unsigned size = get_type_size_bytes(get_entity_type(ent));
unsigned alignment = get_effective_entity_alignment(ent);
const char *name = get_entity_ld_name(entity);
unsigned size = get_type_size_bytes(get_entity_type(entity));
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) {
case OBJECT_FILE_FORMAT_MACH_O:
......@@ -1276,6 +1288,7 @@ static void dump_global(be_gas_decl_env_t *env, const ir_entity *ent)
ident *ld_ident = get_entity_ld_ident(ent);
unsigned alignment = get_effective_entity_alignment(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
* the assembler/linker generates */
......@@ -1288,17 +1301,29 @@ static void dump_global(be_gas_decl_env_t *env, const ir_entity *ent)
be_dbg_variable(ent);
switch (visibility) {
case ir_visibility_external:
/* nothing to do for externally defined values */
if (get_entity_visibility(ent) == ir_visibility_external)
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))
panic("alignment not a power of 2");
if (section == GAS_SECTION_BSS &&
(get_entity_linkage(ent) & IR_LINKAGE_MERGE)) {
if (get_entity_visibility(ent) != ir_visibility_default) {
panic("merge link semantic not supported for local/extern entities");
if (get_entity_visibility(ent) == ir_visibility_external) {
panic("merge link semantic not supported for extern entities");
}
emit_common(ent);
return;
......@@ -1334,7 +1359,7 @@ static void dump_global(be_gas_decl_env_t *env, const ir_entity *ent)
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_write_line();
} else if(entity_has_compound_ent_values(ent)) {
......
......@@ -417,6 +417,7 @@ int tr_vrfy(void)
int res = no_error;
ir_type *constructors;
ir_type *destructors;
ir_type *thread_locals;
int i;
static ident *empty = NULL;
......@@ -427,23 +428,32 @@ int tr_vrfy(void)
constructors = get_segment_type(IR_SEGMENT_CONSTRUCTORS);
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,
"entity without LINKAGE_HIDDEN_USER in constructors is pointless",
1);
/* Mach-O doesn't like labels in this section */
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);
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,
"entity without LINKAGE_HIDDEN_USER in destructors is pointless",
1);
/* Mach-O doesn't like labels in this section */
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;
......
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