问题
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
回答1:
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
.
来源:https://stackoverflow.com/questions/62258430/relocation-r-x86-64-8-against-undefined-symbol-elf-can-not-be-used-when-making