- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有两个汇编代码,code1.s
和 code2.s
,我想从这两个代码构建一个可重定位(使用 -fPIC 开关)共享库。
我想要code2.s
调用一个名为myfun1
的函数,它在code1.s
中定义。
当我在 code2.s
中使用 call myfun1@PLT
时,它找到了该函数并且它像一个魅力一样工作但是它使用 PLT 部分来调用这个函数同一个共享库。我想在不遵守 PLT 部分的情况下执行此操作。当我删除 @PLT
时,我得到 myfun1
的 relocation R_X86_64_PC32 against symbol
错误。
如何在不使用 PLT 部分的情况下执行此操作?有什么办法吗?我认为这应该是可行的,因为共享库应该是可重定位的,但不需要它的每个目标文件,因此为什么调用同一个库中的函数应该通过 PLT 部分。
这是我的编译命令:
对于 codeX.s:
gcc -c codeX.s -fPIC -DPIC -o codeX.o
或
gcc -c codeX.s -o codeX.o
对于名为 libcodes.so 的共享库:
gcc -shared -fPIC -DPIC -o libcodes.so code1.o code2.o
正如您可能好奇我为什么这样做一样,我有很多目标文件,每个目标文件都想调用 myfun1
。在这里,我只是让询问技术部分变得更简单。即使我尝试将 myfun1
放入所有 codeX.s
文件中,但我收到多次定义 myfun1
的错误。我不太在意空间,也不太在意是否要将 myfun1
放入所有文件中。
最佳答案
在一个源文件中,您可以只使用两个标签 ( Building .so with recursive function in it ),一个带有 .globl
,另一个没有。但这还不足以跨共享库中的源文件。
结合以下针对也导出的函数的答案仍然有用:一个 .hidden 和一个不是,因此您可以在库中高效地调用。
使用 .globl
和 .hidden
创建一个可以在当前目标文件之外看到的符号,但不能在共享库之外。因此它不受符号插入的影响,也不受同一共享中其他文件的调用图书馆可以直接调用它,而不是通过 PLT 或 GOT。
测试和工作示例:
## foo.S
.globl myfunc
.hidden myfunc
myfunc:
#.globl myfunc_external # optional, a non-hidden symbol at the same addr
#myfunc_external:
ret
## bar.S
.globl bar
bar:
call myfunc
ret
使用 gcc -shared foo.S bar.S -o foo.so
和 objdump -drwC -Mintel foo.so
构建:
Disassembly of section .text:
000000000000024d <myfunc>:
24d: c3 ret
000000000000024e <bar>:
24e: e8 fa ff ff ff call 24d <myfunc> # a direct near call
253: c3 ret
(我实际上也使用 -nostdlib
构建,为了示例目的,通过省略其他函数(如 __do_global_dtors_aux
和 register_tm_clones
来保持反汇编输出干净> 和 .init
部分。)
我认为 Glibc 为此使用 strong 或 weak_alias
( what does the weak_alias function do and where is it defined ),因此来自共享库的调用可以使用普通名称。 Where are syscalls located in glibc source ,例如__chdir
和 chdir
。
例如glibc's printf.c
定义 __printf
并使 printf
成为它的 strong 别名。
io/chdir.c
定义 __chdir
并使 chdir
成为它的 weak 别名。
其中一个 x86-64 memchr asm 实现也使用 strong_alias
宏(在文件底部)。
相关的 GAS 指令是:
没有强别名 GAS 指令。这可能等效于简单的 foo = foo_internal
或等效的 .set foo, foo_internal
。
(TODO:完整的示例和关于强/弱究竟做什么的更多细节。我目前不知道,所以如果我自己没有时间阅读文档,欢迎编辑。 我知道这个东西存在并解决了这个问题,但我不知 Prop 体如何。)
关于在共享库中不使用 PLT 调用另一个目标文件中的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51573771/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!