By default gcc will put all writable variables in the .bss section if they are zero-initialized, and otherwise in the .data section. This can be changed with an attribute:
static bool initialized __attribute__(( section(.data) )) = false;
Is there a way to apply this attribute to all the static/writable variables in the program (or at least per source file), instead of annotating each variable one-by-one with the attribute? Note that I do need a .bss section, but only for extern references.
Related
I had a piece of code in IAR.
#if defined (__ICCARM__)
#define __vectors __root const uVectorEntry __vector_table[] # ".intvec"
#define __stack { .ui32Ptr = (uint32_t)Stack + sizeof(Stack) }
typedef union
{
void (*Handler)(void);
uint32_t ui32Ptr;
} uVectorEntry;
#endif
It needs to be redone for GCC.
Everything that after defining along the way is also independent of the compiler.
Perhaps only 1 line #define __vectors __root const uVectorEntry __vector_table[] # ".intvec" requires a reaction.
This is the startap file for stm32f103c8t6 (Cortex-M3).
More precisely a small piece of it.
So __vector_table[] must have 59 elemehts, and it is interrupt vector table.
__vectors is likely used in vector table definition in the form __vectors = { /* vector table elements */ };. Macro definition is as follows:
const uVectorEntry __vector_table[] is standard C declaration for a const table.
__root is an attribute that specifies that this object must not be removed by the compiler or linker even if it might seem unused.
# ".intvec" specifies that __vector_table should be placed in .intvec section by the linker.
__stack is likely used in the vector table to have the end address of stack, to initialize stack pointer at boot time.
To put it shortly, all non-standard parts are there to ensure that vector table is in correct location and is not removed.
If I have a function foo() and use -ffunction-sections, gcc will place foo() inside its own .text.foo section. Is it possible to change the prefix of .text? Such that I get .customName.foo instead of text.foo.
I have the same problem, and I solved it using the section attribute.
The following solution is the simplest but does not create a section for each function (as the -ffunction-section parameter allows to do)
#define AT_FLASH_TEXT_SECTION(var) \
__attribute__((section(".text.flash"))) var
AT_FLASH_TEXT_SECTION(int myFunction(float param1, long param2));
So the function myFunction will appear in the section .text.flash, but also all other functions that are declared using the macro AT_FLASH_TEXT_SECTION.
To get the desired behavior I modified the macro as follows:
#define AT_FLASH_TEXT_SECTION_SYM(var, subsectionName) \
__attribute__((section(".text.flash." #subsectionName))) var
AT_FLASH_TEXT_SECTION_SYM(int myNewFunction(float param1, long param2), myNewFunction);
This is the best solution I've found so far.
Unfortunately, it is error-prone: the function name must be repeated identically in the subsectionName parameter of the AT_FLASH_TEXT_SECTION_SYM macro.
Furthermore, if two c modules contain two static functions with the same name, they will be emitted in the same section, going back to the previous problem.
I hope this helps, and maybe you can find a better solution starting from this.
No, that does not seem possible. See gcc/varasm.c (I haven't run the debugger, but am fairly sure this is the code that computes section names.)
void
default_unique_section (tree decl, int reloc)
{
[...]
switch (categorize_decl_for_section (decl, reloc))
{
case SECCAT_TEXT:
prefix = one_only ? ".t" : ".text";
break;
[...]
name = IDENTIFIER_POINTER (id);
name = targetm.strip_name_encoding (name);
[...]
string = ACONCAT ((linkonce, prefix, ".", name, NULL));
set_decl_section_name (decl, string);
}
Besides, that might be a bad idea, as e.g. linker scripts treat sections based on their names (see ld --verbose). Something like .text.customprefix.foo might be a better choice, but I don't know why you want custom prefices.
As a workaround, you can assign sections manually with the section attribute.
'section ("SECTION-NAME")'
Normally, the compiler places the code it generates in the 'text'
section. Sometimes, however, you need additional sections, or you
need certain particular functions to appear in special sections.
The 'section' attribute specifies that a function lives in a
particular section. For example, the declaration:
extern void foobar (void) __attribute__ ((section ("bar")));
puts the function 'foobar' in the 'bar' section.
I have a code compiled with ghs compiler in which the sections have been defined in c code as
#pragma ghs section data = ".shareddata"
// some c code
#pragma ghs section data = default
how do we define pragmas for sections using gcc for the above thing
In general, gcc discourages the use of pragmas, instead suggesting that you use attributes for both functions and variables.
From the GCC manual ("Declaring Attibutes of Functions"):
Normally, the compiler places the code it generates in the text section. Sometimes, however, you need additional sections, or you need certain particular functions to appear in special sections. The section attribute specifies that a function lives in a particular section. For example, the declaration:
extern void foobar (void) __attribute__ ((section ("bar")));
puts the function foobar in the bar section.
From "Specifying Attributes of Variables"
Normally, the compiler places the objects it generates in sections like data and bss. Sometimes, however, you need additional sections, or you need certain particular variables to appear in special sections, for example to map to special hardware. The section attribute specifies that a variable (or function) lives in a particular section. For example, this small program uses several specific section names:
struct duart a __attribute__ ((section ("DUART_A"))) = { 0 };
struct duart b __attribute__ ((section ("DUART_B"))) = { 0 };
char stack[10000] __attribute__ ((section ("STACK"))) = { 0 };
int init_data __attribute__ ((section ("INITDATA")));
main()
{
/* Initialize stack pointer */
init_sp (stack + sizeof (stack));
/* Initialize initialized data */
memcpy (&init_data, &data, &edata - &data);
/* Turn on the serial ports */
init_duart (&a);
init_duart (&b);
}
Use the section attribute with global variables and not local variables, as shown in the example.
You may use the section attribute with initialized or uninitialized global variables but the linker requires each object be defined once, with the exception that uninitialized variables tentatively go in the common (or bss) section and can be multiply “defined”. Using the section attribute changes what section the variable goes into and may cause the linker to issue an error if an uninitialized variable has multiple definitions. You can force a variable to be initialized with the -fno-common flag or the nocommon attribute.
Some file formats do not support arbitrary sections so the section attribute is not available on all platforms. If you need to map the entire contents of a module to a particular section, consider using the facilities of the linker instead.
I develop using Geany 1.22 and I am having trouble with coloration of C++11 keywords.
Here is my configuration file for .cpp : filetypes.cpp
# For complete documentation of this file, please see Geany's main documentation
[styling]
# foreground;background;bold;italic
default=default
comment=comment
commentline=comment
commentdoc=commentdoc
number=number
word=keyword
word2=keyword2
string=string
character=character
uuid=extra
preprocessor=preprocessor
operator=operator
identifier=default
stringeol=stringeol
# #"verbatim"
verbatim=extra
# (/regex/)
regex=extra
commentlinedoc=commentdoc
commentdockeyword=commentdoc
commentdockeyworderror=commentdoc
globalclass=type
[keywords]
# all items must be in one line
primary=and and_eq asm auto bitand bitor bool break case catch char class compl const const_cast continue default delete do double dynamic_cast else enum explicit export extern false float for friend goto if inline int long mutable namespace new not not_eq operator or or_eq private protected public register reinterpret_cast return short signed sizeof static static_cast struct switch template this throw true try typedef typeid typename union unsigned using virtual void volatile wchar_t while xor xor_eq static_assert decltype
secondary=
# these are some doxygen keywords (incomplete)
docComment=attention author brief bug class code date def enum example exception file fn namespace note param remarks return see since struct throw todo typedef var version warning union
[lexer_properties]
styling.within.preprocessor=1
preprocessor.symbol.$(file.patterns.cpp)=#
preprocessor.start.$(file.patterns.cpp)=if ifdef ifndef
preprocessor.middle.$(file.patterns.cpp)=else elif
preprocessor.end.$(file.patterns.cpp)=endif
[settings]
lexer_filetype=C
# default extension used when saving files
extension=cpp
# the following characters are these which a "word" can contains, see documentation
#wordchars=_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
# if only single comment char is supported like # in this file, leave comment_close blank
comment_open=//
comment_close=
# this is an alternative way, so multiline comments are used
#comment_open=/*
#comment_close=*/
# set to false if a comment character/string should start at column 0 of a line, true uses any
# indentation of the line, e.g. setting to true causes the following on pressing CTRL+d
#command_example();
# setting to false would generate this
# command_example();
# This setting works only for single line comments
comment_use_indent=true
# context action command (please see Geany's main documentation for details)
context_action_cmd=
[build_settings]
# %f will be replaced by the complete filename
# %e will be replaced by the filename without extension
# (use only one of it at one time)
compiler=g++ -Wall -c "%f"
linker=g++ -Wall -o "%e" "%f"
run_cmd="./%e"
If I write :
class MyClass
{
};
to define a new class, then the color of MyClass is set to the color of globalclass (which is the color associated to type)
But when I write in C++11 :
class MyClass final
{
};
then final (and not MyClass) is set to the color of globalclass. If I add final to the list of primary keywords, then it is set to the color of word which is good, but MyClass is still not interpreted as a globalclass.
How to solve that problem ?
The problem seems to be that in C++11, final and override (I suspect you will have the same problem there) are not actually keywords. They are identifiers that only gain special meaning is a specific context. This means that you can't actually "just" give a colour to these identifiers at any time, you need to know their context.
Luckily, however, this C++11 support has all been done for you in Geany 1.23. Unfortunately Geany 1.23 doesn't do it 100% correct either. That is, if one writes int final = 123; then final will be coloured as a keyword (whereas it actually isn't a keyword). So what they actually did is: they added final as a primary keyword, which isn't exactly correct, but it -sort of- works.
So my advice to you is either download the latest version of Geany from this link or try the following configuration file: (from Geany 1.23)
# For complete documentation of this file, please see Geany's main documentation
[styling=C]
[keywords]
# all items must be in one line
primary=alignas alignof and and_eq asm auto bitand bitor bool break case catch char char16_t char32_t class compl const const_cast constexpr continue decltype default delete do double dynamic_cast else enum explicit export extern false final float for friend goto if inline int int8_t int16_t int32_t int64_t long mutable namespace new noexcept not not_eq nullptr operator or or_eq override private protected ptrdiff_t public register reinterpret_cast return short signed sizeof size_t static static_assert static_cast struct switch template this thread_local throw true try typedef typeid typename union unsigned using virtual void volatile wchar_t while xor xor_eq
secondary=
# these are the Doxygen keywords
docComment=a addindex addtogroup anchor arg attention author authors b brief bug c callergraph callgraph category cite class code cond copybrief copydetails copydoc copyright date def defgroup deprecated details dir dontinclude dot dotfile e else elseif em endcode endcond enddot endhtmlonly endif endinternal endlatexonly endlink endmanonly endmsc endrtfonly endverbatim endxmlonly enum example exception extends file fn headerfile hideinitializer htmlinclude htmlonly if ifnot image implements include includelineno ingroup interface internal invariant latexonly li line link mainpage manonly memberof msc mscfile n name namespace nosubgrouping note overload p package page par paragraph param post pre private privatesection property protected protectedsection protocol public publicsection ref related relatedalso relates relatesalso remark remarks result return returns retval rtfonly sa section see short showinitializer since skip skipline snippet struct subpage subsection subsubsection tableofcontents test throw throws todo tparam typedef union until var verbatim verbinclude version warning weakgroup xmlonly xrefitem
[lexer_properties]
styling.within.preprocessor=1
lexer.cpp.track.preprocessor=0
preprocessor.symbol.$(file.patterns.cpp)=#
preprocessor.start.$(file.patterns.cpp)=if ifdef ifndef
preprocessor.middle.$(file.patterns.cpp)=else elif
preprocessor.end.$(file.patterns.cpp)=endif
[settings]
lexer_filetype=C
# default extension used when saving files
extension=cpp
# the following characters are these which a "word" can contains, see documentation
#wordchars=_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
# single comments, like # in this file
comment_single=//
# multiline comments
comment_open=/*
comment_close=*/
# set to false if a comment character/string should start at column 0 of a line, true uses any
# indentation of the line, e.g. setting to true causes the following on pressing CTRL+d
#command_example();
# setting to false would generate this
# command_example();
# This setting works only for single line comments
comment_use_indent=true
# context action command (please see Geany's main documentation for details)
context_action_cmd=
[indentation]
#width=4
# 0 is spaces, 1 is tabs, 2 is tab & spaces
#type=1
[build_settings]
# %f will be replaced by the complete filename
# %e will be replaced by the filename without extension
# (use only one of it at one time)
compiler=g++ -Wall -c "%f"
linker=g++ -Wall -o "%e" "%f"
run_cmd="./%e"
However, I somehow doubt that the above will work without updating to the next version of Geany, because you said that just adding "final" as a primary keyword didn't work for you.
On the other hand, check out the manual on lexer properties if you still want to manually do this.
I hope this helps.
I have scientific simulation code written in C that runs from the command line. The user provides an input model as a set of C subroutines in a model.c file that are then compiled into code at runtime.
Certain model properties are not always relevant for a specific problem but currently the user still needs to provide an empty dummy function for that property in order for the code to compile.
Is it possible to have dummy subroutines for the model properties embedded in the source code that are linked only if the user-provided model.c does not contain a subroutine for that property?
As an example, if model.c contains a subroutine called temperature(), the code should link to that one, rather than the subroutine called temperature() found in src/dummy_function.c. If model.c does not have temperature() the compiler should use the dummy function in src/dummy_function.c.
If possible, I would prefer a solution that does not require preprocessor directives in the model.c file.
Yes you can. Suppose you have simple code in file, say undesym.c:
int
main(void)
{
user_routine();
return 0;
}
Create weak stub in say file fakeone.c
#include "assert.h"
int __attribute__((weak))
user_routine(void)
{
assert(0 == "stub user_routine is not for call");
return 0;
}
Now create "user" function in, say goodone.c
#include "stdio.h"
int
user_routine(void)
{
printf("user_routine Ok\n");
return 0;
}
Now if you will link together gcc undesym.c fakeone.c then a.out will run to assert, but if you will add goodone.c to compilation, like gcc undesym.c fakeone.c goodone.c, then it will prefer strong definition to weak, and will run to message.
You may adopt the same mechanism, defining default functions weak.
Since you say that the user's subroutines are "compiled into the code at runtime", you could use dynamic linking to load a user-provided binary and look for their entry points at runtime. In linux (or any POSIX system), this would be based on dlopen()/dlsym() and look more or less like this:
#include <dlfcn.h>
/* ... */
/* Link the UserModule.so into the executable */
void *user_module = dlopen("UserModule.so", RTLD_NOW);
if (!user_module) {
/* Module could not be loaded, handle error */
}
/* Locate the "temperature" function */
void *temperature_ptr = dlsym(user_module, "temperature"):
if (!temperature_ptr) {
/* Module does not define the "temperature" function */
}
void (*user_temperature)() = (void(*)())temperature_ptr;
/* Call the user function */
user_temperature();
See the dlopen documentation for details. A similar facility is very likely available in whatever OS you're using.