制作PIE对象时,无法使用针对未定义符号"ELF"的重定位R_X86_64_8 [英] relocation R_X86_64_8 against undefined symbol `ELF' can not be used when making a PIE object

查看:191
本文介绍了制作PIE对象时,无法使用针对未定义符号"ELF"的重定位R_X86_64_8的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

充满生气:

    .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一样串联

I thought the .byte directive could be concatenate as in nasm

db      0x7F, "ELF", 1, 1, 1, 0         ;   e_ident

源: http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html

推荐答案

在GAS语法中,"ELF"是对符号名称ELF的符号引用,而不是多字符字符串.在.byte指令的上下文中,它只是在寻找数字,而不是可能的字符串.

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.

并且由于您将其用作.byte值列表的一个元素,因此它要求绝对地址的低字节,因此需要.._8重定位.含义与NASM的db完全不同.

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.

在GAS中,当需要一个数字时,允许'E'作为ASCII常数,但不允许"E".例如mov $"E", %eax将为您提供R_X86_64_32 E重定位.

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.

单引号也不起作用.单字符文字确实可以用作数字,例如如mov $'a', %eax这样的立即数.但是与NASM不同,GAS不支持多字符字符文字.因此mov eax, 'Hey!'在NASM中有效,但mov $'Hey!', %eax在GAS中不适用.

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仅允许您将多个ASCII字符序列用作.ascii/.asciz指令或相关的.string/.string16/.string32窄或宽字符指令的文字数据. ( 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)

您有几种选择:

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...(良好).

\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,如果有更好/更清洁的方式可以做到这一点;也许是3位数的八进制转义序列?

IDK if there's a better / cleaner way to do that; maybe 3-digit octal escape sequences?

该教程使用NASM的平面二进制输出模式来手动创建ELF程序标头(用于32位可执行文件).我猜您出于某种原因试图创建一个输出该输出的64位程序?它恰巧不包含任何0%字节,因此可以使用printf输出它.

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.

将本教程移植到GAS语法的更直接方法是使用ld链接到as输出并转换为平面二进制文件. 如何使用GNU GAS汇编器生成普通的二进制文件(如nasm -f bin)?

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?

或使用objcopy.o或可执行文件的.text部分复制到平面二进制文件中.如果使用objcopy,请确保所有内容都在.text部分中.

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.

这篇关于制作PIE对象时,无法使用针对未定义符号"ELF"的重定位R_X86_64_8的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆