summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndreas Fried <andreas.fried@kit.edu>2020-09-23 14:11:49 +0200
committerAndreas Fried <andreas.fried@kit.edu>2020-10-12 18:02:50 +0200
commit0098d766265b322c10e8545385c0bbbedb1bb0d8 (patch)
tree9b433a62a8ffa46d374be4abab85ee1935d82eea
parente702b61837ab8ad3c828da1decb2df726e0bd2a9 (diff)
Add custom_section attribute to entities.
-rw-r--r--include/libfirm/typerep.h13
-rw-r--r--ir/be/begnuas.c27
-rw-r--r--ir/tr/entity.c22
-rw-r--r--ir/tr/entity_t.h26
4 files changed, 88 insertions, 0 deletions
diff --git a/include/libfirm/typerep.h b/include/libfirm/typerep.h
index c04952d..8c297cb 100644
--- a/include/libfirm/typerep.h
+++ b/include/libfirm/typerep.h
@@ -300,6 +300,19 @@ FIRM_API void set_entity_ld_ident(ir_entity *ent, ident *ld_ident);
/** Returns the mangled name of the entity as a string. */
FIRM_API const char *get_entity_ld_name(const ir_entity *ent);
+/**
+ * If this entity should be placed in a custom binary section, returns
+ * the section's name. If this entity should be placed in the default
+ * section, returns NULL.
+ */
+ident *get_entity_custom_section_ident(const ir_entity *ent);
+
+/** Returns the custom section name as a string. */
+const char *get_entity_custom_section_name(const ir_entity *ent);
+
+/** Sets the custom section name. Set to NULL to use the default section. */
+void set_entity_custom_section_ident(ir_entity *ent, ident *id);
+
/** returns 1 if the entity has an ld_ident set explicitely */
FIRM_API int entity_has_ld_ident(const ir_entity *entity);
diff --git a/ir/be/begnuas.c b/ir/be/begnuas.c
index 17f7adf..4b3ddd1 100644
--- a/ir/be/begnuas.c
+++ b/ir/be/begnuas.c
@@ -142,6 +142,19 @@ static const elf_sectioninfo_t elf_sectioninfos[] = {
static void emit_section_sparc(be_gas_section_t section,
const ir_entity *entity)
{
+ if (entity) {
+ char *custom_section = get_entity_custom_section_name(entity);
+ if (custom_section) {
+ current_section = (be_gas_section_t) -1;
+
+ be_emit_cstring("\t.section\t\"");
+ be_emit_string(custom_section);
+ be_emit_cstring("\"\n");
+ be_emit_write_line();
+ return;
+ }
+ }
+
if (current_section == section && !(section & GAS_SECTION_FLAG_COMDAT))
return;
current_section = section;
@@ -185,6 +198,19 @@ static void emit_section_sparc(be_gas_section_t section,
static void emit_section_elf_coff(be_gas_section_t const section, ir_entity const *const entity)
{
+ if (entity) {
+ char *custom_section = get_entity_custom_section_name(entity);
+ if (custom_section) {
+ current_section = (be_gas_section_t) -1;
+
+ be_emit_cstring("\t.section\t");
+ be_emit_string(custom_section);
+ be_emit_char('\n');
+ be_emit_write_line();
+ return;
+ }
+ }
+
if (current_section == section && !(section & GAS_SECTION_FLAG_COMDAT))
return;
current_section = section;
@@ -252,6 +278,7 @@ static void emit_section_elf_coff(be_gas_section_t const section, ir_entity cons
static void emit_section(be_gas_section_t const section, ir_entity const *const entity)
{
if (is_macho()) {
+ assert(get_entity_custom_section_ident(entity) == NULL);
emit_section_macho(section);
} else if (be_gas_elf_variant == ELF_VARIANT_SPARC) {
emit_section_sparc(section, entity);
diff --git a/ir/tr/entity.c b/ir/tr/entity.c
index 2e82dce..d9ef2da 100644
--- a/ir/tr/entity.c
+++ b/ir/tr/entity.c
@@ -39,6 +39,7 @@ static ir_entity *intern_new_entity(ir_type *owner, ir_entity_kind kind,
res->firm_tag = k_entity;
res->name = name;
res->ld_name = name;
+ res->custom_section = NULL;
res->type = type;
res->owner = owner;
res->kind = kind;
@@ -280,6 +281,27 @@ const char *(get_entity_ld_name)(const ir_entity *ent)
return _get_entity_ld_name(ent);
}
+ident *(get_entity_custom_section_ident)(const ir_entity *ent)
+{
+ assert(ent->firm_tag == k_entity);
+ return ent->custom_section;
+}
+
+const char *(get_entity_custom_section_name)(const ir_entity *ent)
+{
+ assert(ent->firm_tag == k_entity);
+ if (ent->custom_section)
+ return get_id_str(ent->custom_section);
+ else
+ return NULL;
+}
+
+void (set_entity_custom_section_ident)(ir_entity *ent, ident *id)
+{
+ assert(ent->firm_tag == k_entity);
+ ent->custom_section = id;
+}
+
int entity_has_ld_ident(const ir_entity *entity)
{
return entity->ld_name != NULL;
diff --git a/ir/tr/entity_t.h b/ir/tr/entity_t.h
index a205d8d..b62c1f2 100644
--- a/ir/tr/entity_t.h
+++ b/ir/tr/entity_t.h
@@ -28,6 +28,9 @@
#define get_entity_owner(ent) _get_entity_owner(ent)
#define get_entity_ld_ident(ent) _get_entity_ld_ident(ent)
#define get_entity_ld_name(ent) _get_entity_ld_name(ent)
+#define get_entity_custom_section_ident(ent) _get_entity_custom_section_ident(ent)
+#define get_entity_custom_section_name(ent) _get_entity_custom_section_name(ent)
+#define set_entity_custom_section_ident(ent) _set_entity_custom_section_ident(ent)
#define get_entity_type(ent) _get_entity_type(ent)
#define get_entity_linkage(ent) _get_entity_linkage(ent)
#define get_entity_volatility(ent) _get_entity_volatility(ent)
@@ -179,6 +182,8 @@ struct ir_entity {
ident *ld_name; /**< Unique name of this entity, i.e., the mangled
name. May be NULL to indicate that a default
mangling based on the name should happen */
+ ident *custom_section; /**< If non-NULL, this entity should be placed into
+ the binary section given here. */
ir_type *type; /**< The type of this entity */
ir_type *owner; /**< The compound type (e.g. class type) this
entity belongs to. */
@@ -281,6 +286,27 @@ static inline const char *_get_entity_ld_name(const ir_entity *ent)
return get_id_str(get_entity_ld_ident(ent));
}
+static inline ident *_get_entity_custom_section_ident(const ir_entity *ent)
+{
+ assert(ent->firm_tag == k_entity);
+ return ent->custom_section;
+}
+
+static inline const char *_get_entity_custom_section_name(const ir_entity *ent)
+{
+ assert(ent->firm_tag == k_entity);
+ if (ent->custom_section)
+ return get_id_str(ent->custom_section);
+ else
+ return NULL;
+}
+
+static inline void _set_entity_custom_section_ident(ir_entity *ent, ident *id)
+{
+ assert(ent->firm_tag == k_entity);
+ ent->custom_section = id;
+}
+
static inline ir_type *_get_entity_type(const ir_entity *ent)
{
assert(ent->firm_tag == k_entity);