Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
3f3a2d31
Commit
3f3a2d31
authored
Feb 12, 2010
by
Matthias Braun
Browse files
correct handling of local commons
[r27139]
parent
3a3cc2a9
Changes
1
Hide whitespace changes
Inline
Side-by-side
ir/be/begnuas.c
View file @
3f3a2d31
...
...
@@ -1302,37 +1302,66 @@ static unsigned get_effective_entity_alignment(const ir_entity *entity)
static
void
emit_common
(
const
ir_entity
*
entity
)
{
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
);
ir_linkage
linkage
=
get_entity_linkage
(
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
);
unsigned
size
=
get_type_size_bytes
(
get_entity_type
(
entity
));
unsigned
alignment
=
get_effective_entity_alignment
(
entity
);
if
(
get_entity_linkage
(
entity
)
&
IR_LINKAGE_WEAK
)
{
emit_weak
(
entity
);
}
switch
(
be_gas_object_file_format
)
{
case
OBJECT_FILE_FORMAT_MACH_O
:
be_emit_cstring
(
"
\t
.lcomm "
);
be_gas_emit_entity
(
entity
);
be_emit_irprintf
(
",%u,%u
\n
"
,
size
,
log2_floor
(
alignment
));
be_emit_write_line
();
return
;
case
OBJECT_FILE_FORMAT_ELF
:
be_emit_cstring
(
"
\t
.comm "
);
be_gas_emit_entity
(
entity
);
be_emit_irprintf
(
",%u,%u
\n
"
,
size
,
alignment
);
be_emit_write_line
();
return
;
case
OBJECT_FILE_FORMAT_COFF
:
be_emit_cstring
(
"
\t
.comm "
);
be_gas_emit_entity
(
entity
);
be_emit_irprintf
(
",%u # %u
\n
"
,
size
,
alignment
);
be_emit_write_line
();
return
;
}
if
(
linkage
&
IR_LINKAGE_WEAK
)
{
panic
(
"invalid object file format"
);
}
static
void
emit_local_common
(
const
ir_entity
*
entity
)
{
unsigned
size
=
get_type_size_bytes
(
get_entity_type
(
entity
));
unsigned
alignment
=
get_effective_entity_alignment
(
entity
);
if
(
get_entity_linkage
(
entity
)
&
IR_LINKAGE_WEAK
)
{
emit_weak
(
entity
);
}
switch
(
be_gas_object_file_format
)
{
case
OBJECT_FILE_FORMAT_MACH_O
:
be_emit_irprintf
(
"
\t
.comm %s,%u,%u
\n
"
,
name
,
size
,
log2_floor
(
alignment
));
be_emit_cstring
(
"
\t
.lcomm "
);
be_gas_emit_entity
(
entity
);
be_emit_irprintf
(
",%u,%u
\n
"
,
size
,
log2_floor
(
alignment
));
be_emit_write_line
();
return
;
case
OBJECT_FILE_FORMAT_ELF
:
be_emit_irprintf
(
"
\t
.comm %s,%u,%u
\n
"
,
name
,
size
,
alignment
);
be_emit_cstring
(
"
\t
.local "
);
be_gas_emit_entity
(
entity
);
be_emit_cstring
(
"
\n
"
);
be_emit_write_line
();
be_emit_cstring
(
"
\t
.comm "
);
be_gas_emit_entity
(
entity
);
be_emit_irprintf
(
",%u,%u
\n
"
,
size
,
alignment
);
be_emit_write_line
();
return
;
case
OBJECT_FILE_FORMAT_COFF
:
be_emit_irprintf
(
"
\t
.comm %s,%u # %u
\n
"
,
name
,
size
,
alignment
);
be_emit_cstring
(
"
\t
.lcomm "
);
be_gas_emit_entity
(
entity
);
be_emit_irprintf
(
",%u # %u
\n
"
,
size
,
alignment
);
be_emit_write_line
();
return
;
}
...
...
@@ -1382,14 +1411,14 @@ void be_gas_emit_entity(const ir_entity *entity)
* @param env the gas output environment
* @param ent the entity to be dumped
*/
static
void
emit_global
(
be_gas_decl_env_t
*
env
,
const
ir_entity
*
ent
)
static
void
emit_global
(
be_gas_decl_env_t
*
env
,
const
ir_entity
*
ent
ity
)
{
ir_type
*
type
=
get_entity_type
(
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
);
ir_linkage
linkage
=
get_entity_linkage
(
ent
);
ir_type
*
type
=
get_entity_type
(
ent
ity
);
ident
*
ld_ident
=
get_entity_ld_ident
(
ent
ity
);
unsigned
alignment
=
get_effective_entity_alignment
(
ent
ity
);
be_gas_section_t
section
=
determine_section
(
env
,
ent
ity
);
ir_visibility
visibility
=
get_entity_visibility
(
ent
ity
);
ir_linkage
linkage
=
get_entity_linkage
(
ent
ity
);
/* block labels are already emittet in the code */
if
(
type
==
firm_code_type
)
...
...
@@ -1400,23 +1429,35 @@ static void emit_global(be_gas_decl_env_t *env, const ir_entity *ent)
if
(
is_Method_type
(
type
)
&&
section
!=
GAS_SECTION_PIC_TRAMPOLINES
)
{
/* functions with graph are already emitted with
* be_gas_emit_function_prolog */
if
(
get_entity_irg
(
ent
)
==
NULL
)
{
emit_visibility
(
ent
);
if
(
get_entity_irg
(
ent
ity
)
==
NULL
)
{
emit_visibility
(
ent
ity
);
}
return
;
}
be_dbg_variable
(
ent
);
be_dbg_variable
(
entity
);
if
(
section
==
GAS_SECTION_BSS
)
{
ir_visibility
visibility
=
get_entity_visibility
(
entity
);
if
(
section
==
GAS_SECTION_BSS
&&
(
linkage
&
IR_LINKAGE_MERGE
))
{
if
(
get_entity_visibility
(
ent
)
==
ir_visibility_external
)
{
switch
(
visibility
)
{
case
ir_visibility_local
:
case
ir_visibility_private
:
emit_local_common
(
entity
);
return
;
case
ir_visibility_default
:
if
(
linkage
&
IR_LINKAGE_MERGE
)
{
emit_common
(
entity
);
return
;
}
break
;
case
ir_visibility_external
:
panic
(
"merge link semantic not supported for extern entities"
);
break
;
}
emit_common
(
ent
);
return
;
}
emit_visibility
(
ent
);
emit_visibility
(
ent
ity
);
if
(
visibility
==
ir_visibility_external
)
{
/* nothing to do for externally defined values */
return
;
...
...
@@ -1425,11 +1466,11 @@ static void emit_global(be_gas_decl_env_t *env, const ir_entity *ent)
if
(
!
is_po2
(
alignment
))
panic
(
"alignment not a power of 2"
);
emit_section
(
section
,
ent
);
emit_section
(
section
,
ent
ity
);
if
(
section
==
GAS_SECTION_PIC_TRAMPOLINES
||
section
==
GAS_SECTION_PIC_SYMBOLS
)
{
emit_indirect_symbol
(
ent
,
section
);
emit_indirect_symbol
(
ent
ity
,
section
);
return
;
}
...
...
@@ -1440,28 +1481,28 @@ static void emit_global(be_gas_decl_env_t *env, const ir_entity *ent)
if
(
be_gas_object_file_format
==
OBJECT_FILE_FORMAT_ELF
&&
be_gas_emit_types
)
{
be_emit_cstring
(
"
\t
.type
\t
"
);
be_gas_emit_entity
(
ent
);
be_gas_emit_entity
(
ent
ity
);
be_emit_cstring
(
", "
);
be_emit_char
(
be_gas_elf_type_char
);
be_emit_cstring
(
"object
\n\t
.size
\t
"
);
\
be_gas_emit_entity
(
ent
);
be_gas_emit_entity
(
ent
ity
);
be_emit_irprintf
(
", %u
\n
"
,
get_type_size_bytes
(
type
));
}
if
(
get_id_str
(
ld_ident
)[
0
]
!=
'\0'
)
{
be_gas_emit_entity
(
ent
);
be_gas_emit_entity
(
ent
ity
);
be_emit_cstring
(
":
\n
"
);
be_emit_write_line
();
}
if
(
entity_is_null
(
ent
))
{
if
(
entity_is_null
(
ent
ity
))
{
be_emit_irprintf
(
"
\t
.zero %u
\n
"
,
get_type_size_bytes
(
type
));
be_emit_write_line
();
}
else
if
(
entity_has_compound_ent_values
(
ent
))
{
emit_compound_graph_init
(
env
,
ent
);
}
else
if
(
entity_has_compound_ent_values
(
ent
ity
))
{
emit_compound_graph_init
(
env
,
ent
ity
);
}
else
{
assert
(
ent
->
initializer
!=
NULL
);
emit_initializer
(
env
,
ent
);
assert
(
ent
ity
->
initializer
!=
NULL
);
emit_initializer
(
env
,
ent
ity
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment