简体   繁体   中英

Can I get the address of a singleton during compile or link time from gcc?

I am working on a embedded project and ask me, if it is possible to get the address of a singleton class during compile or link time.

To create my singleton, I use the following code and would be interested in the address of instance .

class A
{
    public:
    static A& get()
    {
        static A instance;
        return instance;
}:

What I want to do, is of course changing the value from outside using a debug probe, but not using a real debug session.

Best regards Andreas

Without signficant knowledge of exactly what development tools, hardware architecture, etc, you are using, it's very hard to say exactly what you should do, but it's typically possible to assign certain variables to a specific data-segment or functions in a specific code-segment, and then in the linking phase assign a specific address to that segment.

For example you can use the gcc section attribute :

int init_data __attribute__ ((section ("INITDATA")));

or

MyObj obj __attribute__((section ("BATTERY_BACKED")));

and then use the same section name in a linker script that places it to the "right" address.

Most (reasonable) embedded toolchains will support this in some manner, but exactly how it is done varies quite a lot.

Another option is to use placement new :

MyObj *obj = new ((void *)0x11220000) MyObj(args);

You can use placement-new with a buffer whose address is available at compile or link time.

#include <new>

extern unsigned char placeA[];

class A {
public:
    static A& get()
    {
        static A *p_instance;
        if(!p_instance) {
            p_instance = new(placeA) A();
        }
        return *p_instance;
    }
};

unsigned char placeA[sizeof(A)] __attribute__ ((aligned (__BIGGEST_ALIGNMENT__)));

Usually debug probes only see physical addresses while user applications only operate on virtual addresses, which change all the times the application is loaded, so no linker trick will work. You didn't say which OS you use but I guess it's Linux. If so, you can do something like this: reserve yourself a scratchpad memory area you know the physical address of and which is not used by the OS. For example if your SoC has an embedded static memory, use that, if not just ask you local Linux expert how to reserve a page of RAM into the kernel memory configuration.

Then look at this article to understand how to map a physical address into the virtual memory space of your application:

how to access kernel space from user space(in linux)?

After getting the virtual address of the scratchpad area your application can read/write there whatever it wants. The debug probe will be able to to read/write into the same area with the physical address.

Not exactly sure if this is what you're trying to do, but using "-S" with gcc will stop everything after the compile stage. That way you can dive into the assembly code and evaluate your variables. Here is the man page excerpt:

If you only want some of the stages of compilation, you can use -x (or
filename suffixes) to tell gcc where to start,
and one of the options -c, -S, or -E to say where gcc is to stop.  Note that
some combinations (for example, -x cpp-output -E) instruct gcc to do nothing at all.

-c  Compile or assemble the source files, but do not link.  The linking stage simply is not done.  The ultimate
    output is in the form of an object file for each source file.

    By default, the object file name for a source file is made by replacing the suffix .c, .i, .s, etc., with .o.

    Unrecognized input files, not requiring compilation or assembly, are ignored.

-S  Stop after the stage of compilation proper; do not assemble.  The output is in the form of an assembler code file
    for each non-assembler input file specified.

    By default, the assembler file name for a source file is made by replacing the suffix .c, .i, etc., with .s.

    Input files that don't require compilation are ignored.

-E  Stop after the preprocessing stage; do not run the compiler proper.  The output is in the form of preprocessed
    source code, which is sent to the standard output.

    Input files which don't require preprocessing are ignored.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM