Playing with __ attributes__ (I)

Time:2022-6-5

preface

In some codes, we can often see the following function modifiers:

__attribute__((constructor)) static void foo(void) {
    //...
}
void f(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.6,obsoleted=10.7)));

origin

In GNU C, we can use function attributes(Function attribute)Define specific compiler optimizations, compiler checks, memory management, code generation, call return transformations for our functions.
For example:noreturnUsed to specify that the function has no return value.formatParameter used to specify that there is a print encoding style in the function parameter.

Many attributes are platform related. For example, many platforms supportinterrupt, but the specific use must comply with the register usage specification of a specific platform.

__declspec(dllimport) It is a common declaration used to declare functions imported from dynamic libraries under windows.

Function properties using__attribute__As a declaration keyword, followed by double parentheses(())Specify a specific attribute, using commas,Interval multiple attributes. For details, seeAttribute Syntax

Common function properties

constructor

The modified function will be called when loading binary. The call stack in MacOS is as follows:

    frame #1: 0x00007fff5fc12d0b dyld`ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) + 265
    frame #2: 0x00007fff5fc12e98 dyld`ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) + 40
    frame #3: 0x00007fff5fc0f891 dyld`ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 305
    frame #4: 0x00007fff5fc0f718 dyld`ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 138
    frame #5: 0x00007fff5fc0f989 dyld`ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) + 75
    frame #6: 0x00007fff5fc02245 dyld`dyld::initializeMainExecutable() + 187
    frame #7: 0x00007fff5fc05c19 dyld`dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) + 2669
    frame #8: 0x00007fff5fc01276 dyld`dyldbootstrap::start(macho_header const*, int, char const**, long, macho_header const*, unsigned long*) + 512
    frame #9: 0x00007fff5fc01036 dyld`_dyld_start + 54

The calling order of multiple constructor functions is determined by the declaration order

destructor

Similarly, it is called at the end of the program.

constructor && destructor with PRIORITY

Syntax:__attribute__((destructor (PRIORITY)))
PRIORITYThe lower the priority, the earlier the call
For example:

void begin_0 (void) __attribute__((constructor (101)));
void end_0 (void) __attribute__((destructor (101)));
void begin_1 (void) __attribute__((constructor (102)));
void end_1 (void) __attribute__((destructor (102)));
void begin_2 (void) __attribute__((constructor (103)));
void end_2 (void) __attribute__((destructor (103)));

Operation results:

begin_0 ()
begin_1 ()
begin_2 ()
end_2 ()
end_1 ()
end_0 ()

returns_nonnull

Tells the compiler that the return value must never be null

alias (“target”)

Define aliases for functions

other

Except function properties(Function Attributes)AndVariable Attributes, Type Attributes, Label Attributes, Enumerator AttributesEtc

Clang has special attributes for IOS,Poke here. More details in next issue

Reference reading

1
2

Originally written in segmentfaultlink