重定位 R_X86_64_8 针对未定义的符号 `ELF' 在制作 PIE 对象时不能使用
relocation R_X86_64_8 against undefined symbol `ELF' can not be used when making a PIE object
加油:
.text
.globl main
main:
xor %eax, %eax
lea str(%rip), %rdi
call printf
call exit
str: .byte 0x7F, "ELF", 1,1,1,0
我认为 .byte
指令可以像 nasm
中那样连接
db 0x7F, "ELF", 1, 1, 1, 0 ; e_ident
来源: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 manual)
您有几个选择:
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
阻止整个 7FE
被视为一个十六进制数。如果没有额外的反斜杠,它会组装成 fe 4c 46 01...
(坏)而不是所需的 7f 45 4c 46 01...
(好)。
IDK 如果有更好/更清洁的方法来做到这一点;也许是 3 位八进制转义序列?
该教程使用 NASM 的平面二进制输出模式手动创建 ELF 程序头(对于 32 位可执行文件)。我猜你出于某种原因正在尝试创建一个打印该输出的 64 位程序?它恰好不包含任何 0
或 %
字节,所以是的,您可以使用 printf
.
输出它
将教程移植到 GAS 语法的更直接方法是使用 ld
到 link 到 as
输出到平面二进制文件。 How to generate plain binaries like nasm -f bin with the GNU GAS assembler?
或使用 objcopy
将 .o
或可执行文件的 .text
部分复制到平面二进制文件中。如果您使用 objcopy
.
,请确保所有内容都在 .text
部分中
加油:
.text
.globl main
main:
xor %eax, %eax
lea str(%rip), %rdi
call printf
call exit
str: .byte 0x7F, "ELF", 1,1,1,0
我认为 .byte
指令可以像 nasm
db 0x7F, "ELF", 1, 1, 1, 0 ; e_ident
来源: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 manual)
您有几个选择:
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
阻止整个 7FE
被视为一个十六进制数。如果没有额外的反斜杠,它会组装成 fe 4c 46 01...
(坏)而不是所需的 7f 45 4c 46 01...
(好)。
IDK 如果有更好/更清洁的方法来做到这一点;也许是 3 位八进制转义序列?
该教程使用 NASM 的平面二进制输出模式手动创建 ELF 程序头(对于 32 位可执行文件)。我猜你出于某种原因正在尝试创建一个打印该输出的 64 位程序?它恰好不包含任何 0
或 %
字节,所以是的,您可以使用 printf
.
将教程移植到 GAS 语法的更直接方法是使用 ld
到 link 到 as
输出到平面二进制文件。 How to generate plain binaries like nasm -f bin with the GNU GAS assembler?
或使用 objcopy
将 .o
或可执行文件的 .text
部分复制到平面二进制文件中。如果您使用 objcopy
.
.text
部分中