Add section with (incomplete) checking for mach-o

This commit is contained in:
Christoffer Lerno
2021-08-18 20:07:38 +02:00
committed by Christoffer Lerno
parent b4be829c71
commit 232632b74e
6 changed files with 74 additions and 6 deletions

View File

@@ -362,6 +362,10 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl)
// TODO fix name
LLVMValueRef old = decl->backend_ref;
decl->backend_ref = LLVMAddGlobal(c->module, LLVMTypeOf(init_value), decl->extname ?: decl->external_name);
if (decl->section)
{
LLVMSetSection(decl->backend_ref, decl->section);
}
llvm_set_alignment(decl->backend_ref, alignment);
LLVMValueRef failable_ref = decl->var.failable_ref;

View File

@@ -9,6 +9,46 @@
static bool sema_analyse_struct_union(Context *context, Decl *decl);
static bool sema_check_section(Context *context, Decl *decl, Attr *attr)
{
const char *section_string = attr->expr->const_expr.string.chars;
decl->section = section_string;
// No restrictions except for MACH-O
if (platform_target.object_format != OBJ_FORMAT_MACHO)
{
return true;
}
scratch_buffer_clear();
StringSlice slice = strtoslice(section_string);
StringSlice segment = strnexttok(&slice, ',');
StringSlice section = strnexttok(&slice, ',');
StringSlice attrs = strnexttok(&slice, ',');
StringSlice stub_size_str = strnexttok(&slice, ',');
if (slice.len)
{
SEMA_ERROR(attr->expr, "Too many parts to the Mach-o section description.");
}
slicetrim(&segment);
if (segment.len == 0)
{
SEMA_ERROR(attr->expr, "The segment is missing, did you type it correctly?");
return false;
}
slicetrim(&section);
if (section.len == 0)
{
SEMA_ERROR(attr->expr, "Mach-o requires 'segment,section' as the format, did you type it correctly?");
return false;
}
if (section.len > 16)
{
SEMA_ERROR(attr->expr, "Mach-o requires the section to be at the most 16 characters, can you shorten it?");
return false;
}
// TODO improve checking
return true;
}
static bool sema_check_unique_parameters(Decl **decls)
{
STable *table = &global_context.scratch_table;
@@ -300,10 +340,6 @@ static bool sema_analyse_struct_union(Context *context, Decl *decl)
had = decl->extname != NULL;
decl->extname = attr->expr->const_expr.string.chars;
break;
case ATTRIBUTE_SECTION:
had = decl->section != NULL;
decl->section = attr->expr->const_expr.string.chars;
break;
case ATTRIBUTE_ALIGN:
had = decl->alignment != 0;
decl->alignment = attr->alignment;
@@ -994,7 +1030,7 @@ static inline bool sema_analyse_func(Context *context, Decl *decl)
break;
case ATTRIBUTE_SECTION:
had = decl->section != NULL;
decl->section = attr->expr->const_expr.string.chars;
if (!sema_check_section(context, decl, attr)) return decl_poison(decl);
break;
case ATTRIBUTE_ALIGN:
had = decl->alignment != 0;
@@ -1228,7 +1264,7 @@ static inline bool sema_analyse_global(Context *context, Decl *decl)
break;
case ATTRIBUTE_SECTION:
had = decl->section != NULL;
decl->section = attr->expr->const_expr.string.chars;
if (!sema_check_section(context, decl, attr)) return decl_poison(decl);
break;
case ATTRIBUTE_ALIGN:
had = decl->alignment != 0;

View File

@@ -430,6 +430,7 @@ static inline StringSlice strtoslice(const char *data)
{
return (StringSlice) { data, strlen(data) };
}
void slicetrim(StringSlice *slice);
#define MAX(_a, _b) ({ \
typeof(_a) __a__ = (_a); \

View File

@@ -42,6 +42,23 @@ StringSlice strnexttok(StringSlice *slice, char separator)
return result;
}
void slicetrim(StringSlice *slice)
{
size_t i;
for (i = 0; i < slice->len; i++)
{
if (slice->ptr[i] != ' ') break;
}
slice->ptr += i;
slice->len -= i;
for (i = slice->len; i > 0; i--)
{
if (slice->ptr[i - 1] != ' ') break;
}
slice->len = i;
}
char *strcopy(const char *start, size_t len)
{
char *buffer = malloc_arena(len + 1);

View File

@@ -158,6 +158,8 @@ class Issues:
if (line.startswith("warning:")):
print("TODO" + line)
exit(-1)
elif (line.startswith("target:")):
self.arch = line[7:].strip()
elif (line.startswith("error:")):
line = line[6:].strip()
self.errors[self.current_file.filename + ":%d" % (self.line + self.current_file.line_offset)] = line

View File

@@ -0,0 +1,8 @@
// #target: x64-darwin
int foo @section("foo, 12345678901234567 "); // #error: Mach-o requires the section to be at the most 16 characters
int bar @section("foo, "); // #error: Mach-o requires 'segment,section' as the format, did you type it correctly?
int baz @section("foo"); // #error: Mach-o requires 'segment,section' as the format, did you type it correctly?
int abc @section("foo,b,c,d,e,f"); // #error: Too many parts to the Mach-o section description.
int def @section("foo,b,c,d");