2
From seyfarth's book:

        segment .data
a       dw      175

b       dw      4097

        segment .text
        global  main
main:

        mov     rax, [a]    ; mov a (175)into rax

        add     rax, [b]    ; add b to rax
        xor     rax, rax
        ret

It fails to link using the commands given in seyfarth's book:

yasm -P ebe.inc -Worphan-labels -f elf64 -g dwarf2 -l add1.lst add1.asm
gcc -g -o add1 add1.o
/usr/bin/ld: add1.o: relocation R_X86_64_32 against `.data' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
Makefile:20: recipe for target 'add1' failed
make: *** [add1] Error 1

If I replace main with _start and then assemble using yasm and then link using ld it works.

fuz
  • 88,405
  • 25
  • 200
  • 352
SRK
  • 53
  • 4

1 Answers1

3

Link with -no-pie.

PIE is a rather recent security feature which requires you to write position-independent code. Your code is not position-independent, so your code can't link. Turning the feature off is the best solution for a beginner. Alternatively, you can also make your code position-independent by using appropriate addressing modes:

mov rax, [rel a]
add rax, [rel b]
fuz
  • 88,405
  • 25
  • 200
  • 352
  • I've marked it as "accepted". Thank you for your "to the point" answer. Please provide any references you might have for your answer. – SRK Dec 25 '18 at 13:44
  • @SRK Sorry, I don't have any reference about that. Perhaps [this article](https://en.wikipedia.org/wiki/Position-independent_code) might be helpful as an introduction. – fuz Dec 25 '18 at 14:55
  • 1
    @SRK: Or better, use `default rel` at the top of your file. You pretty much never want an absolute addressing mode when RIP-relative is an option. (But it's not when you have something like `[a + rax]`, so no-pie allows slightly more efficient code if you're indexing a static array.) Almost a duplicate of [32-bit absolute addresses no longer allowed in x86-64 Linux?](https://stackoverflow.com/q/43367427), but that Q&A mostly assumes you know about RIP-relative addressing vs. absolute already. – Peter Cordes Dec 25 '18 at 18:30
  • @PeterCordes: This sounds good. But where's the documentation for the same? I mean how to use rel etc in x86-64 assembly? – SRK Dec 25 '18 at 18:41
  • @SRK: The documentation is in the NASM manual: https://www.nasm.us/doc/nasmdoc6.html#section-6.2. For how RIP-relative addressing works in general, see Intel's or AMD's manual, or various other docs/guides about x86-64. If you want to understand the machine encoding, see https://wiki.osdev.org/X86-64_Instruction_Encoding#32.2F64-bit_addressing (32-bit had 2 redundant ways to encode a 32-bit absolute address. x86-64 RIP-relative uses the shorter one (no SIB byte), leaving the longer encoding as still `[disp32]`.) – Peter Cordes Dec 25 '18 at 18:50
  • @PeterCordes: As I understand, in PI code, the segments will be assigned random addresses. As far as the data offsets are concerned, they'll still be same, right? Or will the data be shuffled as well in data segment? – SRK Dec 25 '18 at 18:52
  • @SRK: ASLR doesn't move segments relative to each other; the same random page offset is added to all mappings. `rel32` addressing in machine code in the text segment doesn't need any fixups to address the data or bss segments. So the executable (or shared library) as a whole is position-independent if it doesn't have any absolute addresses embedded anywhere (not even for a jump table or a statically-initialized pointer / reference). Linux/ELF does allow runtime fixups, though, so full 64-bit absolute addresses are actually allowed. – Peter Cordes Dec 25 '18 at 19:08