[ARM]__weak的⽤法
debug的时候,忽然发现这个函数没有函数实现的地⽅,只有函数的调⽤和声明。
仔细看了看这个函数的定义,前⾯居然有⼀个__weak,得,查查看看__weak是⼲什么的吧。
⾛后⾯是从ARM⽹站搜到的,偶也!
读完之后呢,⼤概总结两点:
1. 带__weak的函数,不⼀定⾮得有函数实现。有就最好了,当non-weak⼀样处理。如果没有函数实现,请看第⼆点。
2. 如果没有函数实现体,linker会把这个函数处理成nop或者BL到下⼀条语句。
真的是这样吗?得⾃⼰动⼿看看才⾏,实践出真知嘛!罗德巴赫伺候
看到了吧,那个⾼亮的2039⾏有两个nop出现,到底是不是我们那个函数呢?去代码看看喽!
果然,2039⾏正是我们那个朝思暮想的函数。
好啦,到此为⽌,休息⼀会!
exists的用法------------------------------------------------------------------------------------------------------------------------------
///
How does __weak work?
Applies to: ,
Answer
The ARM compilation tools support the concept of "weak" references and definitions. These can provide additional flexibility in the way the linker includes various (typically library) functions and variables in a build.
Weak references
If the linker can not resolve normal (non-weak) references to symbols included in the link, it will attempt to do so by finding the symbol in a library, and report an error if it can not. Once such a refer
ence has been resolved, the section it is resolved to is marked as used, so will not later be removed by the linker as an unused section. Each non-weak reference must be resolved by exactly one definition (if there are multiple definitions, the linker will also report an error).
Function or variable declarations in C source files can be marked with the__weak qualifier. As with extern, this qualifier tells the compiler that a function or variable is declared in another compilation unit (source file). As the definition of this
function/variable may not be available to compiler, it creates a (weak) reference to be resolved by the linker.
The compiler will not load an object from a library in order to resolve a weak reference. It will only be able to resolve the weak reference if the definition will be included in the image for other reasons. The weak reference will not cause the linker to mark the section containing the definition as used, so it may be removed by the linker as unused. The definition may already exist in the image for several reasons:
1. The symbol is strongly referenced somewhere else in the code.
2. The symbol definition exists in the same ELF section as a symbol definition that is included for any of these reasons*.
3. The symbol definition is in a section that has been specified using --keep, or contains an ENTRY point.
4. The symbol definition is in an object file included in the link (not a libary unless the object within the library has been
explicitly included on the link line), and the--no_remove option is used.
In summary, a weak reference will be resolved if the definition is already included in the image, but will not affect whether or not that definition is included.
An unresolved weak function call will be replaced either with a NOP (no-operation instruction), or a BL (Branch with link instruction) to the following instruction - effectively the function call just does not happen.
Example usage:
A library contains a function foo(), that will be called in some builds of an application but not in others. If it is used,init_foo() must be called first. Weak references can be used to "automate" the call to init_foo().
The library can define init_foo() and foo() in the the same ELF section*. The application initialisation code should
call init_foo()weakly. Now if the application includes foo() for any reason, it will also include init_foo() and this will be called from the initialisation code. In any builds that do not include foo(), the call to init_foo()will be removed by the linker.
In this scenario, there is no need to rebuild the initialisation code between builds that include foo() and don't include foo(). There is also no possibility of accidentally building an application with a version of the initialisation code that does not
call init_foo(), and other parts of the application that call foo().
foo.c (typically built into a library):
void init_foo()
{
// Some initialisation code
}
void foo()
{
// A function that is included in some builds
// and requires init_foo() to be called first.
}
init.c:
__weak void init_foo(void);
int main(void)
{
init_foo();
// Rest of code that may make calls foo() directly or indirectly.
}
Weak references can also be generated by the assembler:
init.s:
IMPORT init_foo WEAK
AREA init, CODE, readonly
BL init_foo
;Rest of code
END
Weak Definitions
A function definition (or EXPORT ed label in assembler) can also be marked as weak, as can a variable definition. In this case, a weak symbol definition is created in the object file.
A weak definition can be used to resolve any reference to that symbol in the same way as a normal definition. However, if another (non-weak) definition of that symbol exists in the build, the linker will use that definition instead of the weak definition, and not produce an error due to multiply-defined symbols.
///
------------------------------------------------------------------------------------------------------------------------------
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论