relocation R_X86_64_32S against undefined symbol `_symbol` can not be used when making a PIE object

Viewed 2804

Since a few days, I've started to learn Assembly, using a book I've gotten as a present, and I got an issue.

I'm trying to access a C++ global variable from within Assembly, but I keep getting a Linking Error, saying relocation R_X86_64_32S against undefined symbol '_symbol' can not be used when making a PIE object; recompile with -fPIE.

I've tried several things already, like changing the extern to global in my asm file, and vice versa. I've also tried removing the underscore, adding an underscore in both Assembly and C++, but I can't manage to work it out...

Here's my Assembly code:

;---------------------
;      Functions
;---------------------
global IntegerLogical_

;----------------------------
;      Global Variables
;----------------------------
extern _symbol  ; Defines the symbol C/C++ Global Variable as a dword (unsigned int)

IntegerLogical_:
    and ecx, edx                ; a & b
    or  ecx, r8d                ; (a & b) | c
    xor ecx, r9d                ; ((a & b) | c) ^ d
    add ecx, [_symbol]            ; (((a & b) | c) ^ d) + g_Val1

    mov eax, ecx                ; Move the return value into the EAX Register
    ret                         ; Return to caller

And here's my C++ code:

#include <iostream>
#include <iomanip>

extern "C" unsigned int IntegerLogical_(unsigned int a, unsigned int b, unsigned int c, unsigned int d);
extern "C" unsigned int symbol = 0;

unsigned int integerLogicalCpp(unsigned int a, unsigned int b, unsigned int c, unsigned int d) {
    // Calculate (((a & b) | c) ^ d) + symbol
    unsigned int t1 = a & b;
    unsigned int t2 = t1 | c;
    unsigned int t3 = t2 ^ d;
    
    return t3 + symbol;
}

void printResult(const char* message, unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned int val1, unsigned int r1, unsigned int r2) {
    const int w = 8;

    std::cout << message << std::endl;
    std::cout << std::setfill('0');
    std::cout << "a =    0x" << std::hex << std::setw(w) << a << " (" << std::dec << a << ")" << std::endl;
    std::cout << "b =    0x" << std::hex << std::setw(w) << b << " (" << std::dec << b << ")" << std::endl;
    std::cout << "c =    0x" << std::hex << std::setw(w) << c << " (" << std::dec << c << ")" << std::endl;
    std::cout << "d =    0x" << std::hex << std::setw(w) << d << " (" << std::dec << d << ")" << std::endl;
    std::cout << "val1 = 0x" << std::hex << std::setw(w) << val1 << " (" << std::dec << val1 << ")" << std::endl;
    std::cout << "r1 =   0x" << std::hex << std::setw(w) << r1 << " (" << std::dec << r1 << ")" << std::endl;
    std::cout << "r2 =   0x" << std::hex << std::setw(w) << r2 << " (" << std::dec << r2 << ")" << std::endl;
    std::cout << std::endl;

    if (r1 != r2) std::cout << "Comparison failed! Values do not match! (" << r1 << " <-> " << r2 << ")" << std::endl;
}

int main() {
    unsigned int a = 0x00223344;
    unsigned int b = 0x00775544;
    unsigned int c = 0x00555555;
    unsigned int d = 0x00998877;
    symbol = 7;
    unsigned int r1 = integerLogicalCpp(a, b, c, d);
    unsigned int r2 = IntegerLogical_(a, b, c, d);
    printResult("Test 1", a, b, c, d, symbol, r1, r2);

    a = 0x70987655;
    b = 0x55555555;
    c = 0xAAAAAAAA;
    d = 0x12345678;
    symbol = 23;
    r1 = integerLogicalCpp(a, b, c, d);
    r2 = IntegerLogical_(a, b, c, d);
    printResult("Test 2", a, b, c, d, symbol, r1, r2);
}

I'm new to this, so I might just have made a stupid mistake, if so, please tell me. I'll also supply some extra information that might be of use.

NASM Build Instruction: nasm -f elf64 -o [Assembled file].o [Assembly file].asm G++ Build Instruction: g++ [Assembled file].o [C++ Source File].cpp -o [Output]

G++ Output:

[C++ Source File].cpp:5:25: warning: ‘symbol’ initialized and declared ‘extern’
    5 | extern "C" unsigned int symbol = 0;
      |                         ^~~~~~
/usr/bin/ld: [Assembled file].o: relocation R_X86_64_32S against undefined symbol `_symbol' can not be used when making a PIE object; recompile with -fPIE
collect2: error: ld returned 1 exit status

I'm using NASM 2.15.05 and G++ 11.1.0. Edit: I'm programming in an x64 Linux Environment

Thanks in advance, and enjoy the rest of your day.

0 Answers
Related