diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2017-05-25 16:54:31 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2017-05-26 12:32:02 -0400 |
commit | b9940f0e0d7b5b4fae497cc80d14948a091d71c2 (patch) | |
tree | 298cfa831794e04980424932a4a03e8f387f689f /src | |
parent | f91a49c65d3ea7dd4679b192d8421f621f057304 (diff) | |
download | kutter-b9940f0e0d7b5b4fae497cc80d14948a091d71c2.tar.gz kutter-b9940f0e0d7b5b4fae497cc80d14948a091d71c2.tar.xz kutter-b9940f0e0d7b5b4fae497cc80d14948a091d71c2.zip |
build: Avoid linker magic in compile_time_request.c unique id generation
Avoid generating unique ids via memory locations and linker scripts.
Instead, generate them using code produced by buildcommands.py.
Utilize gcc's ability to perform static string comparisons at compile
time to produce a unique id for each unique string.
This fixes a build failure on ARM introduced in 142b92b8. It also
reduces the complexity of the build.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/command.c | 13 | ||||
-rw-r--r-- | src/command.h | 51 | ||||
-rw-r--r-- | src/ctr.h | 17 | ||||
-rw-r--r-- | src/declfunc.lds.S | 7 |
4 files changed, 43 insertions, 45 deletions
diff --git a/src/command.c b/src/command.c index 44de070d..f96cee62 100644 --- a/src/command.c +++ b/src/command.c @@ -112,7 +112,7 @@ static uint8_t in_sendf; // Encode a message and transmit it void -_sendf(uint8_t parserid, ...) +_sendf(const struct command_encoder *ce, ...) { if (readb(&in_sendf)) // This sendf call was made from an irq handler while the main @@ -120,8 +120,7 @@ _sendf(uint8_t parserid, ...) return; writeb(&in_sendf, 1); - const struct command_encoder *cp = &command_encoders[parserid]; - uint8_t max_size = READP(cp->max_size); + uint8_t max_size = READP(ce->max_size); char *buf = console_get_output(max_size + MESSAGE_MIN); if (!buf) goto done; @@ -129,10 +128,10 @@ _sendf(uint8_t parserid, ...) if (max_size) { char *maxend = &p[max_size]; va_list args; - va_start(args, parserid); - uint8_t num_params = READP(cp->num_params); - const uint8_t *param_types = READP(cp->param_types); - *p++ = READP(cp->msg_id); + va_start(args, ce); + uint8_t num_params = READP(ce->num_params); + const uint8_t *param_types = READP(ce->param_types); + *p++ = READP(ce->msg_id); while (num_params--) { if (p > maxend) goto error; diff --git a/src/command.h b/src/command.h index 180031e5..609becd9 100644 --- a/src/command.h +++ b/src/command.h @@ -1,10 +1,9 @@ #ifndef __COMMAND_H #define __COMMAND_H -#include <stdarg.h> // va_list -#include <stddef.h> // size_t +#include <stddef.h> #include <stdint.h> // uint8_t -#include "compiler.h" // __section +#include "ctr.h" // DECL_CTR // Declare a function to run when the specified command is received #define DECL_COMMAND(FUNC, MSG) \ @@ -25,7 +24,7 @@ // Declare a message type and transmit it. #define sendf(FMT, args...) \ - _sendf(_DECL_PARSER(FMT) , ##args) + _sendf(_DECL_ENCODER(FMT) , ##args ) // Shut down the machine (also declares a static string to transmit) #define shutdown(msg) \ @@ -34,7 +33,8 @@ sched_try_shutdown(_DECL_STATIC_STR(msg)) // command.c -void _sendf(uint8_t parserid, ...); +struct command_encoder; +void _sendf(const struct command_encoder *ce, ...); // out/compile_time_request.c (auto generated file) struct command_encoder { @@ -50,41 +50,30 @@ enum { PT_uint32, PT_int32, PT_uint16, PT_int16, PT_byte, PT_string, PT_progmem_buffer, PT_buffer, }; -extern const struct command_encoder command_encoders[]; extern const struct command_parser * const command_index[]; extern const uint8_t command_index_size; extern const uint8_t command_identify_data[]; extern const uint32_t command_identify_size; +const struct command_encoder *ctr_lookup_encoder(const char *str); +const struct command_encoder *ctr_lookup_output(const char *str); +uint8_t ctr_lookup_static_string(const char *str); -// Compiler glue for DECL_COMMAND macros above. #define _DECL_COMMAND(FUNC, FLAGS, MSG) \ - char __PASTE(_DECLS_ ## FUNC ## _, __LINE__) [] \ - __visible __section(".compile_time_request") \ - = "_DECL_COMMAND " __stringify(FUNC) " " __stringify(FLAGS) " " MSG; \ - void __visible FUNC(uint32_t*) + DECL_CTR("_DECL_COMMAND " __stringify(FUNC) " " __stringify(FLAGS) " " MSG) -#define _DECL_CONSTANT(NAME, VALUE) \ - char __PASTE(_DECLC_ ## NAME ## _, __LINE__) [] \ - __visible __section(".compile_time_request") \ - = "_DECL_CONSTANT " __stringify(NAME) " " __stringify(VALUE) +#define _DECL_CONSTANT(NAME, VALUE) \ + DECL_CTR("_DECL_CONSTANT " __stringify(NAME) " " __stringify(VALUE)) -// Create a compile time request and return a unique (incrementing id) -// for that request. -#define _DECL_REQUEST_ID(REQUEST, ID_SECTION) ({ \ - static char __PASTE(_DECLS_, __LINE__)[] \ - __section(".compile_time_request") = REQUEST; \ - asm volatile("" : : "i"(__PASTE(_DECLS_, __LINE__))); \ - static char __PASTE(_DECLI_, __LINE__) \ - __section(".compile_time_request." ID_SECTION); \ - (size_t)&__PASTE(_DECLI_, __LINE__); }) +#define _DECL_ENCODER(FMT) ({ \ + DECL_CTR("_DECL_ENCODER " FMT); \ + ctr_lookup_encoder(FMT); }) -#define _DECL_PARSER(FMT) \ - _DECL_REQUEST_ID("_DECL_PARSER " FMT, "parsers") +#define _DECL_OUTPUT(FMT) ({ \ + DECL_CTR("_DECL_OUTPUT " FMT); \ + ctr_lookup_output(FMT); }) -#define _DECL_OUTPUT(FMT) \ - _DECL_REQUEST_ID("_DECL_OUTPUT " FMT, "parsers") - -#define _DECL_STATIC_STR(FMT) \ - _DECL_REQUEST_ID("_DECL_STATIC_STR " FMT, "static_strings") +#define _DECL_STATIC_STR(MSG) ({ \ + DECL_CTR("_DECL_STATIC_STR " MSG); \ + ctr_lookup_static_string(MSG); }) #endif // command.h diff --git a/src/ctr.h b/src/ctr.h new file mode 100644 index 00000000..3396644c --- /dev/null +++ b/src/ctr.h @@ -0,0 +1,17 @@ +#ifndef __CTR_H +#define __CTR_H +// Definitions for creating compile time requests. The DECL_CTR macro +// produces requests (text strings) that are placed in a special +// section of the intermediate object files. The requests are then +// extracted during the build and passed to scripts/buildcommand.py. +// The scripts/buildcommand.py code then generates +// out/compile_time_request.c from these requests. + +#include "compiler.h" // __section + +// Declare a compile time request +#define DECL_CTR(REQUEST) \ + static char __PASTE(_DECLS_, __LINE__)[] __attribute__((used)) \ + __section(".compile_time_request") = (REQUEST) + +#endif // ctr.h diff --git a/src/declfunc.lds.S b/src/declfunc.lds.S index 1f178643..ba564bbf 100644 --- a/src/declfunc.lds.S +++ b/src/declfunc.lds.S @@ -24,11 +24,4 @@ SECTIONS DECLWRAPPER(taskfuncs) DECLWRAPPER(initfuncs) DECLWRAPPER(shutdownfuncs) - - .compile_time_request.static_strings 0 (INFO) : { - *( .compile_time_request.static_strings ) - } - .compile_time_request.parsers 0 (INFO) : { - *( .compile_time_request.parsers ) - } } |