针对未定义符号 `ELF' 重新定位 R_X86_64_8;制作PIE对象时不能使用 [英] relocation R_X86_64_8 against undefined symbol `ELF' can not be used when making a PIE object
问题描述
把它放在汽油里:
.text.globl 主主要的:异或 %eax, %eaxlea str(%rip), %rdi调用 printf呼叫出口str: .byte 0x7F, "ELF", 1,1,1,0
我认为 .byte
指令可以像 nasm 一样连接
db 0x7F, "ELF", 1, 1, 1, 0 ;电子身份
来源:http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html
在 GAS 语法中,"ELF"
是对符号名称 ELF
的符号引用,而不是一个多字符字符串.在 .byte
指令的上下文中,它只查找数字,而不是可能的字符串.
并且由于您将它用作 .byte
值列表的一个元素,它要求绝对地址的低字节,因此 .._8
重定位.含义和NASM的db
完全不同.
在 GAS 中,当它需要一个数字时,'E'
被允许作为 ASCII 常量,但 "E"
不是.例如mov $"E", %eax
会给你一个 R_X86_64_32 E
重定位.
单引号也不起作用.单字符文字确实可以用作数字,例如就像 mov $'a', %eax
一样.但与 NASM 不同的是,GAS 不支持多字符字符文字.所以 mov eax, 'Hey!'
在 NASM 中有效,但 mov $'Hey!', %eax
在 GAS 中不起作用.
AFAIK,GAS 只允许您使用多个 ASCII 字符序列作为 .ascii
/.asciz
指令或相关 .string 的文字数据
/.string16
/.string32
窄或宽字符指令.(GAS 手册)
您有几个选择:
str: .byte 0x7F.ascii "ELF" # 单独的指令.byte 1,1,1,0
str: .byte 0x7F, 'E', 'L', 'F', 1,1,1,0 # 分隔字符文字
str: .asciz "\x7F\ELF\x1\x1\x1" # 字符串中的十六进制转义
\E
阻止整个 7FE
被视为一个十六进制数.如果没有额外的反斜杠,它会组合成 fe 4c 46 01...
(坏)而不是所需的 7f 45 4c 46 01...
(好).>
IDK 如果有更好/更干净的方法来做到这一点;也许是 3 位八进制转义序列?
<小时>该教程使用 NASM 的平面二进制输出模式手动创建 ELF 程序头(用于 32 位可执行文件).我猜您出于某种原因正在尝试创建一个打印该输出的 64 位程序?它碰巧不包含任何 0
或 %
字节,所以是的,你可以用 printf
输出它.
将教程移植到 GAS 语法的更直接方法是使用 ld
将 as
输出链接到平面二进制文件中.如何使用 GNU GAS 汇编器生成像 nasm -f bin 这样的普通二进制文件?
或使用 objcopy
将 .o
或可执行文件的 .text
部分复制到平面二进制文件中.如果您使用 objcopy
,请确保所有内容都在 .text
部分.
Having this in gas:
.text
.globl main
main:
xor %eax, %eax
lea str(%rip), %rdi
call printf
call exit
str: .byte 0x7F, "ELF", 1,1,1,0
I thought the .byte
directive could be concatenate as in nasm
db 0x7F, "ELF", 1, 1, 1, 0 ; e_ident
source : http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html
In GAS syntax, "ELF"
is a symbol reference to the symbol name ELF
, not a multi-char string. In the context of .byte
directive, it's only looking for a number, not a possible string.
And since you used it as one element of a list of .byte
values, it's asking for the low byte of the absolute address, hence the .._8
relocation. The meaning is totally different from NASM's db
.
In GAS when it's expecting a number, 'E'
is allowed as an ASCII constant, but "E"
isn't. e.g. mov $"E", %eax
will give you a R_X86_64_32 E
relocation.
Single quotes don't work either. A single-character literal does work as a number, e.g. as an immediate like mov $'a', %eax
. But unlike NASM, GAS doesn't support multi-character character literals. So mov eax, 'Hey!'
works in NASM, but mov $'Hey!', %eax
doesn't work in GAS.
AFAIK, GAS only lets you use a sequence of multiple ASCII characters as literal data for a .ascii
/ .asciz
directive, or the related .string
/ .string16
/ .string32
narrow or wide character directives. (GAS manual)
You have a few options:
str: .byte 0x7F
.ascii "ELF" # separate directives
.byte 1,1,1,0
str: .byte 0x7F, 'E', 'L', 'F', 1,1,1,0 # separate character literals
str: .asciz "\x7F\ELF\x1\x1\x1" # hex escapes in a string
\E
stops the whole 7FE
from being seen as one hex number. Without the extra backslash, it assembles to fe 4c 46 01...
(bad) instead of the desired 7f 45 4c 46 01...
(good).
IDK if there's a better / cleaner way to do that; maybe 3-digit octal escape sequences?
That tutorial uses NASM's flat binary output mode to manually create ELF program headers (for a 32-bit executable). I guess you're trying to create a 64-bit program that prints that output, for some reason? It happens not to contain any 0
or %
bytes, so yes you can output it with printf
.
A more direct way to port the tutorial to GAS syntax would be to use ld
to link into as
output into a flat binary. How to generate plain binaries like nasm -f bin with the GNU GAS assembler?
Or use objcopy
to copy the .text
section of a .o
or executable into a flat binary. Make sure everything is in the .text
section if you use objcopy
.
这篇关于针对未定义符号 `ELF&#39; 重新定位 R_X86_64_8;制作PIE对象时不能使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!