Commit 36eec9dc authored by Anders Blomdell's avatar Anders Blomdell
Browse files

Changed signature indices to use __attribute__((constructor)) instead of

linker section tricks. Fallback is to manually call the init function of
each labcomm module.
parent b415dd0d
......@@ -36,3 +36,5 @@ lib/c/liblabcomm.so.1
lib/c/test/test_labcomm_pthread_scheduler
lib/c/liblabcomm_plain_c.so.1
lib/c/test/test_signature_plain_c
test/test_signature_numbers
lib/c/test/test_signature_numbers
......@@ -201,14 +201,8 @@ aspect C_CodeGen {
}
public void Program.C_emitC(C_env env) {
env.print("#if ! defined(LABCOMM_GEN_CODE) && ");
env.println("! defined(LABCOMM_GEN_SIGNATURE)");
env.println("#define LABCOMM_GEN_CODE");
env.println("#define LABCOMM_GEN_SIGNATURE");
env.println("#endif");
env.println("#if defined(LABCOMM_GEN_CODE)");
for (int i = 0; i < getNumDecl(); i++) {
getDecl(i).C_emitSignatureBitsAndForward(env);
getDecl(i).C_emitSignature(env);
getDecl(i).C_emitDecoder(env);
getDecl(i).C_emitDecoderRegisterHandler(env);
getDecl(i).C_emitDecoderIoctl(env);
......@@ -217,12 +211,7 @@ aspect C_CodeGen {
getDecl(i).C_emitEncoderIoctl(env);
getDecl(i).C_emitSizeof(env);
}
env.println("#endif");
env.println("#if defined(LABCOMM_GEN_SIGNATURE)");
for (int i = 0; i < getNumDecl(); i++) {
getDecl(i).C_emitSignature(env);
}
env.println("#endif");
C_emitConstructor(env);
}
}
......@@ -880,16 +869,16 @@ aspect C_EncoderIoctl {
aspect C_Signature {
public void ASTNode.C_emitSignatureBitsAndForward(C_env env) {
public void ASTNode.C_emitSignature(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitSignaturBitsAndForwarde(C_env env)" +
".C_emitSignature(C_env env)" +
" not declared");
}
public void Decl.C_emitSignatureBitsAndForward(C_env env) {
public void Decl.C_emitSignature(C_env env) {
}
public void SampleDecl.C_emitSignatureBitsAndForward(C_env env) {
public void SampleDecl.C_emitSignature(C_env env) {
env.println("static unsigned char signature_bytes_" +
env.prefix + getName() + "[] = {");
SignatureList signature = signature();
......@@ -908,30 +897,49 @@ aspect C_Signature {
}
}
env.println("};");
env.println("LABCOMM_DECLARE_SIGNATURE(labcomm_signature_" +
env.prefix + getName() + ");");
env.println("struct labcomm_signature labcomm_signature_" +
env.prefix + getName() + " = {");
env.indent();
env.println("LABCOMM_SAMPLE, \"" + getName() + "\",");
env.println("(int (*)(struct labcomm_signature *, void *))labcomm_sizeof_" +
env.prefix + getName() + ",");
env.println("sizeof(signature_bytes_" + env.prefix + getName() + "),");
env.println("signature_bytes_" + env.prefix + getName() + ",");
env.println("0");
env.unindent();
env.println(" };");
}
public void ASTNode.C_emitSignature(C_env env) {
public void ASTNode.C_emitConstructor(C_env env) {
throw new Error(this.getClass().getName() +
".C_emitSignature(C_env env)" +
".C_emitConstructor(C_env env)" +
" not declared");
}
public void Decl.C_emitSignature(C_env env) {
}
public void SampleDecl.C_emitSignature(C_env env) {
env.println("LABCOMM_DECLARE_SIGNATURE(labcomm_signature_" +
env.prefix + getName() + ") = {");
public void Program.C_emitConstructor(C_env env) {
env.println("LABCOMM_CONSTRUCTOR void init_" +
env.prefix + "_signatures(void)");
env.println("{");
env.indent();
env.println("LABCOMM_SAMPLE, \"" + getName() + "\",");
env.println("(int (*)(struct labcomm_signature *, void *))labcomm_sizeof_" +
env.prefix + getName() + ",");
env.println("sizeof(signature_bytes_" + env.prefix + getName() + "),");
env.println("signature_bytes_" + env.prefix + getName());
env.println("static int initialized = 0;");
env.println("if (initialized == 0) {");
env.indent();
env.println("initialized = 1;");
for (int i = 0; i < getNumDecl(); i++) {
getDecl(i).C_emitConstructor(env);
}
env.unindent();
env.println(" };");
env.println("}");
env.unindent();
env.println("}");
}
public void Decl.C_emitConstructor(C_env env) {
}
public void SampleDecl.C_emitConstructor(C_env env) {
env.println("labcomm_set_local_index(&labcomm_signature_" +
env.prefix + getName() + ");");
}
......
......@@ -4,22 +4,19 @@ CC=gcc
#CFLAGS=-g -Wall -Werror -O3 -I. -Itest -DLABCOMM_ENCODER_LINEAR_SEARCH
CFLAGS=-g -Wall -Werror -O3 -I. -Itest
LDFLAGS=-L.
#LDLIBS_TEST=-Tlabcomm.linkscript -lcunit -llabcomm
LDLIBS_TEST=-llabcomm -Tlabcomm.linkscript -lrt
LDLIBS_TEST_PLAIN_C=-llabcomm_plain_c -lrt
OBJS_PLAIN_C=labcomm_memory.o \
labcomm_default_error_handler.o \
labcomm_default_memory.o \
labcomm_default_scheduler.o \
labcomm_time.o labcomm_scheduler.o \
labcomm_encoder.o labcomm_decoder.o \
labcomm.o \
labcomm_dynamic_buffer_writer.o \
labcomm_fd_reader.o labcomm_fd_writer.o \
labcomm_pthread_scheduler.o
OBJS=$(OBJS_PLAIN_C) \
labcomm_signature_gnu_ld_tricks.o
LDLIBS_TEST=-llabcomm -lrt
OBJS=labcomm_memory.o \
labcomm_error.o \
labcomm_default_error_handler.o \
labcomm_default_memory.o \
labcomm_default_scheduler.o \
labcomm_time.o labcomm_scheduler.o \
labcomm_encoder.o labcomm_decoder.o \
labcomm.o \
labcomm_dynamic_buffer_writer.o \
labcomm_fd_reader.o labcomm_fd_writer.o \
labcomm_pthread_scheduler.o
#FIXME: labcomm_mem_reader.o labcomm_mem_writer.o
LABCOMM_JAR=../../compiler/labComm.jar
......@@ -27,7 +24,7 @@ LABCOMM=java -jar $(LABCOMM_JAR)
TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding \
test_labcomm_pthread_scheduler \
test_signature_plain_c
test_signature_numbers
#
#FIXME: test_labcomm test_labcomm_errors
TEST_DIR=test
......@@ -51,21 +48,14 @@ endif
.PHONY: all run-test clean distclean
all: liblabcomm.a liblabcomm_plain_c.a \
liblabcomm.so.1 liblabcomm_plain_c.so.1
all: liblabcomm.a liblabcomm.so.1
liblabcomm.a: $(OBJS)
ar -r $@ $^
liblabcomm_plain_c.a: $(OBJS_PLAIN_C)
ar -r $@ $^
liblabcomm.so.1: $(OBJS:%.o=%.pic.o)
gcc -shared -Wl,-soname,$@ -o $@ $^ -lc -lrt
liblabcomm_plain_c.so.1: $(OBJS_PLAIN_C:%.o=%.pic.o)
gcc -shared -Wl,-soname,$@ -o $@ $^ -lc -lrt
labcomm.o : labcomm.c labcomm.h labcomm_private.h
labcomm_fd_reader_writer.o : labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h labcomm.h labcomm_private.h
......@@ -89,22 +79,9 @@ $(TEST_DIR)/%.o: $(TEST_DIR)/%.c
$(CC) $(CFLAGS) -o $@ -c $<
.PRECIOUS: $(TEST_DIR)/%
$(TEST_DIR)/%: $(TEST_DIR)/%.o liblabcomm.a
$(TEST_DIR)/%: $(TEST_DIR)/%.o
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(LDLIBS_TEST)
$(TEST_DIR)/test_signature_plain_c_index.o: \
labcomm_signature_plain_c.c \
$(TEST_DIR)/gen/generated_encoding.c \
$(TEST_DIR)/gen/another_encoding.h \
$(TEST_DIR)/gen/another_encoding.c
$(CC) $(CFLAGS) -o $@ -c $< \
-DALL_LABCOMM_FILES=\"test/test_signature_plain_c.h\"
$(TEST_DIR)/test_signature_plain_c: \
$(TEST_DIR)/test_signature_plain_c.o \
$(TEST_DIR)/test_signature_plain_c_index.o
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS_TEST_PLAIN_C)
$(TEST_DIR)/gen:
mkdir -p $@
......@@ -142,8 +119,6 @@ clean:
distclean: clean
$(RM) liblabcomm.so.1
$(RM) liblabcomm.a
$(RM) liblabcomm_plain_c.a
$(RM) liblabcomm_plain_c.so.1
# Extra dependencies
$(TEST_DIR)/test_labcomm_basic_type_encoding.o: labcomm_private.h
......@@ -151,9 +126,12 @@ $(TEST_DIR)/test_labcomm_basic_type_encoding.o: labcomm_private.h
$(TEST_DIR)/test_labcomm_generated_encoding.o: labcomm_private.h
$(TEST_DIR)/test_labcomm_generated_encoding.o: $(TEST_DIR)/gen/generated_encoding.h
$(TEST_DIR)/test_labcomm_generated_encoding : $(TEST_DIR)/gen/generated_encoding.o
$(TEST_DIR)/test_labcomm: $(TEST_GEN_DIR)/test_sample.o
$(TEST_DIR)/test_signature_plain_c.o: $(TEST_DIR)/gen/another_encoding.h
$(TEST_DIR)/test_signature_plain_c.o: $(TEST_DIR)/gen/generated_encoding.h
$(TEST_DIR)/test_signature_numbers.c: $(TEST_DIR)/gen/another_encoding.h
$(TEST_DIR)/test_signature_numbers.c: $(TEST_DIR)/gen/generated_encoding.h
$(TEST_DIR)/test_signature_numbers: $(TEST_DIR)/gen/another_encoding.o
$(TEST_DIR)/test_signature_numbers: $(TEST_DIR)/gen/generated_encoding.o
labcomm_fd_reader.o: labcomm_private.h
labcomm_fd_writer.o: labcomm_private.h
labcomm_dynamic_buffer_writer.o: labcomm_private.h
......@@ -239,3 +239,24 @@ void *labcomm_signature_array_ref(struct labcomm_memory *memory,
return NULL;
}
}
static int local_index = 0x40;
void labcomm_set_local_index(struct labcomm_signature *signature)
{
if (signature->index != 0) {
labcomm_error_fatal_global(LABCOMM_ERROR_SIGNATURE_ALREADY_SET,
"%s", signature->name);
}
signature->index = local_index;
local_index++;
}
int labcomm_get_local_index(struct labcomm_signature *signature)
{
if (signature->index == 0) {
labcomm_error_fatal_global(LABCOMM_ERROR_SIGNATURE_NOT_SET,
"%s", signature->name);
}
return signature->index;
}
......@@ -42,6 +42,7 @@ struct labcomm_signature {
int (*encoded_size)(struct labcomm_signature *, void *); // void * == encoded_sample *
int size;
unsigned char *signature;
int index;
int cached_encoded_size; // -1 if not initialized or type is variable size
};
......
......@@ -23,7 +23,6 @@
#include <errno.h>
#include "labcomm.h"
#include "labcomm_private.h"
#include "labcomm_signature.h"
#include "labcomm_ioctl.h"
#include "labcomm_dynamic_buffer_writer.h"
......@@ -369,7 +368,7 @@ int labcomm_internal_decoder_ioctl(struct labcomm_decoder *d,
int result;
int local_index, remote_index;
local_index = labcomm_signature_local_index(signature);
local_index = labcomm_get_local_index(signature);
labcomm_scheduler_data_lock(d->scheduler);
remote_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
d->local,
......@@ -393,7 +392,7 @@ int labcomm_internal_decoder_register(
struct sample_entry *entry;
reader_alloc(d);
local_index = labcomm_signature_local_index(signature);
local_index = labcomm_get_local_index(signature);
if (local_index <= 0) { goto out; }
labcomm_reader_start(d->reader, d->reader->action_context,
local_index, 0, signature,
......
......@@ -22,7 +22,6 @@
#include <errno.h>
#include "labcomm.h"
#include "labcomm_signature.h"
#include "labcomm_private.h"
#include "labcomm_ioctl.h"
......@@ -78,7 +77,7 @@ int labcomm_internal_encoder_register(
int result = -EINVAL;
int index, *done, err, i;
index = labcomm_signature_local_index(signature);
index = labcomm_get_local_index(signature);
labcomm_scheduler_writer_lock(e->scheduler);
if (signature->type != LABCOMM_SAMPLE) { goto out; }
if (index <= 0) { goto out; }
......@@ -115,7 +114,7 @@ int labcomm_internal_encode(
int result;
int index;
index = labcomm_signature_local_index(signature);
index = labcomm_get_local_index(signature);
labcomm_scheduler_writer_lock(e->scheduler);
result = labcomm_writer_start(e->writer, e->writer->action_context,
index, signature, value);
......@@ -160,7 +159,7 @@ int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder,
int result = -ENOTSUP;
int index;
index = labcomm_signature_local_index(signature);
index = labcomm_get_local_index(signature);
result = labcomm_writer_ioctl(encoder->writer,
encoder->writer->action_context,
index, signature, action, va);
......
/*
labcomm_signature.h -- signature handling.
labcomm_error.c -- labcomm error handling
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
......@@ -19,5 +19,14 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "labcomm.h"
int labcomm_signature_local_index(struct labcomm_signature *s);
#include <stdlib.h>
#include <stdio.h>
#include "labcomm_error.h"
void labcomm_error_fatal_global(enum labcomm_error error,
char *format,
...)
{
fprintf(stderr, "Fatal error %d\n", error);
exit(1);
}
......@@ -30,10 +30,24 @@ enum labcomm_error {
struct labcomm_error_handler;
void labcomm_error_warning(struct labcomm_error_handler *e,
enum labcomm_error,
char *format,
...);
void labcomm_error_fatal_global(enum labcomm_error error,
char *format,
...);
#endif
#ifdef LABCOMM_ERROR
LABCOMM_ERROR(LABCOMM_ERROR_SIGNATURE_ALREADY_SET,
"Signature has already been set")
LABCOMM_ERROR(LABCOMM_ERROR_SIGNATURE_NOT_SET,
"Signature has not been set")
LABCOMM_ERROR(LABCOMM_ERROR_ENC_NO_REG_SIGNATURE,
"Encoder has no registration for this signature")
LABCOMM_ERROR(LABCOMM_ERROR_ENC_BUF_FULL,
......
......@@ -62,11 +62,12 @@
#define LABCOMM_USER 0x40
/*
*
* Macro to automagically call constructors in modules compiled
* with the labcomm compiler. If __attribute__((constructor)) is
* not supported, these calls has to be done first in main program.
*/
#ifndef LABCOMM_DECLARE_SIGNATURE
#define LABCOMM_DECLARE_SIGNATURE(name) \
struct labcomm_signature __attribute__((section("labcomm"),aligned(1))) name
#ifndef LABCOMM_CONSTRUCTOR
#define LABCOMM_CONSTRUCTOR __attribute__((constructor))
#endif
/*
......@@ -487,4 +488,10 @@ void *labcomm_signature_array_ref(struct labcomm_memory * memory,
for (name.data = (kind *)name.data, /* typechecking no-op */ \
var = name.first ; var < name.last ; var++)
/* Give signature a free local index, this may not be used concurrently */
void labcomm_set_local_index(struct labcomm_signature *signature);
/* Get the local index for a signature */
int labcomm_get_local_index(struct labcomm_signature *s);
#endif
/*
labcomm_signature_gnu_ld_tricks.c -- signature handling.
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
This file is part of LabComm.
LabComm is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
LabComm is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
#include "labcomm.h"
#include "labcomm_signature.h"
#include "labcomm_private.h"
extern struct labcomm_signature labcomm_first_signature;
extern struct labcomm_signature labcomm_last_signature;
int labcomm_signature_local_index(struct labcomm_signature *s)
{
int result = -ENOENT;
if (&labcomm_first_signature <= s && s < &labcomm_last_signature) {
result = (int)(s - &labcomm_first_signature) + LABCOMM_USER;
}
return result;
}
/*
labcomm_signature_plain_c.c -- signature handling.
Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
This file is part of LabComm.
LabComm is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
LabComm is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define LABCOMM_DECLARE_SIGNATURE(name) \
struct labcomm_signature __attribute__((aligned(1))) name
#include <errno.h>
#include "labcomm.h"
#include "labcomm_signature.h"
#include "labcomm_private.h"
/* NB: We need to mimic forward declarations done in generated code */
LABCOMM_DECLARE_SIGNATURE(labcomm_sentinel_1);
#define LABCOMM_GEN_CODE
#include ALL_LABCOMM_FILES
#undef LABCOMM_GEN_CODE
LABCOMM_DECLARE_SIGNATURE(labcomm_sentinel_2);
/* NB: We need to force our sentinels out of bss segment, hence -1 */
LABCOMM_DECLARE_SIGNATURE(labcomm_sentinel_1) = { -1, NULL, NULL, 0, NULL};
#define LABCOMM_GEN_SIGNATURE
#include ALL_LABCOMM_FILES
#undef LABCOMM_GEN_SIGNATURE
LABCOMM_DECLARE_SIGNATURE(labcomm_sentinel_2) = { -1, NULL, NULL, 0, NULL};
int labcomm_signature_local_index(struct labcomm_signature *s)
{
int result = -ENOENT;
struct labcomm_signature *labcomm_first_signature;
struct labcomm_signature *labcomm_last_signature;
if (&labcomm_sentinel_1 < &labcomm_sentinel_2) {
labcomm_first_signature = &labcomm_sentinel_1;
labcomm_last_signature = &labcomm_sentinel_2;
} else {
labcomm_first_signature = &labcomm_sentinel_2;
labcomm_last_signature = &labcomm_sentinel_1;
}
if (labcomm_first_signature <= s && s < labcomm_last_signature) {
result = (int)(s - labcomm_first_signature) + LABCOMM_USER - 1;
}
return result;
}
INPUT(liblabcomm.so.1)
/* Hack to get a link error with (hopefully) useful information if not linked
with -Tlabcomm.linkscript */
"You need to link with '-Tlabcomm.linkscript'"+=1;
/*INPUT(liblabcomm.a)*/
#include <stdlib.h>
#include <stdio.h>
#include "labcomm_private.h"
#include "test/gen/another_encoding.h"
#include "test/gen/generated_encoding.h"
extern int labcomm_signature_local_index(struct labcomm_signature *s);
static void info(char *name, char *full_name,
struct labcomm_signature *signature) {
printf("%s %s %p -> %d\n", name, full_name, signature,
labcomm_signature_local_index(signature));
if (labcomm_signature_local_index(signature) < 0x40) {
labcomm_get_local_index(signature));
if (labcomm_get_local_index(signature) < 0x40) {
exit(1);
}
};
......
#include "gen/generated_encoding.c"
#include "gen/another_encoding.c"
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