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.