简体   繁体   中英

Getting address of assembly label in C via ARM (using GCC)

Basically, I am trying to find a reliable way to get the length of a C function in bytes.

A few people suggest using the address of the function and the address of another function directly following it. I don't want to use this method, as I don't believe it is reliable. The compiler could move things around, and it just seems a bit hack-ish.

The solution I have come up with is to use two labels at the start and the end of a function. I have declared the lables with:

__asm__ __volatile__("func_start/end:");

Now, my problem is, I am having trouble getting the address of these labels put back into a variable in C.

Here is some code that I have already tried:

unsigned int  addr, len;

__asm__ __volatile__("mov  $func_start, %[address]\n\t"\
                    "mov  $func_end, %[length]\n\t"\
                    : [address]"=r"(addr), [length]"=r"(len));


__asm__ __volatile__("mov  %0, $func_start \n\t"\
                     "mov  %1, $func_end\n\t"\
                    : "=r"(addr), "=r"(len));

Both of these examples give the error "ARM register expected" during compilation. As I am not very experienced with ARM assembly (let alone x86), I'm not sure what's wrong. I have tried to port the following x86 code to ARM:

__asm__ __volatile__("movl  $enc_start, %0\n\t"\
                    "movl  $enc_end, %1\n\t"\
                    : "=r"(addr), "=r"(len));

I'm obviously doing something wrong here. I would greatly appreciate it if someone could explain what I'm doing wrong. I've been stuck on this for a few weeks now. Thanks!

There is no reliable way to get the length of a function because there is no well-defined meaning for length of a function.

AC implementation may in-line a function. It may both in-line the function in some places and provide a non-lined version in another. The function might have code preceding its entry point. The function might have code following its exit point. A function might have multiple exit points. Other routines called might be in-lined inside the function. The function might share code with other functions (eg, two functions that do the same thing except that one performs some slight manipulations on its parameters before beginning might be given two separate entry points to mostly common code). A function might have some code in one place and other code in another place, with code for other functions in between. A function, even if written as a single sequence of code by the compiler, might be broken into blocks and rearranged by the linker. (OS X does this.)

If you wish to persist in spite of the above, you can try:

#include <stdio.h>


static void foo(void)
{
    __asm__ __volatile__("_foo_start:");
    printf("Hello, world.\n");
    __asm__ __volatile__("_foo_end:");
}


int main(void)
{
    extern const char foo_start[], foo_end[];
    printf("Difference = 0x%tx.\n", foo_end - foo_start);
    foo();
    return 0;
}

It is, of course, not supported by the C standard.

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