From b034d006dad2196237041590a84fc2aa7a74bfed Mon Sep 17 00:00:00 2001 From: Popax21 Date: Fri, 3 Mar 2023 13:45:21 +0000 Subject: [PATCH] Fix PC-relative expression relocations This change fixes relocations which are emitted as a result of PC-relative assembler expressions (of the form `XYZ - $`). Previously, these expressions were evaluated down to offsets, and the offset itself (which could be negative!) was passed onto the output backend, instead of the actual absolute address. In particular, this could cause e.g. the Mach-O backend to emit a relocation against garbage symbols, as attempts to resolve the symbol based on the invalid address would not find the actual symbol being referenced in the original code. This was fixed in this patch by making the address absolute again before passing it onto the backend, as well as setting `data->relbase` so that the backend can properly compute the relative offset. --- asm/assemble.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/asm/assemble.c b/asm/assemble.c index 7eab5ce12..b451b0421 100644 --- a/asm/assemble.c +++ b/asm/assemble.c @@ -657,7 +657,7 @@ static void out_eops(struct out_data *data, const extop *e) data->tsegment = e->val.num.segment; data->toffset = e->val.num.offset; data->twrt = e->val.num.wrt; - data->relbase = 0; + data->relbase = data->offset; if (e->val.num.segment != NO_SEG && (e->val.num.segment & 1)) { data->type = OUT_SEGMENT; @@ -666,6 +666,11 @@ static void out_eops(struct out_data *data, const extop *e) data->type = e->val.num.relative ? OUT_RELADDR : OUT_ADDRESS; data->flags = OUT_WRAP; + + if (e->val.num.relative) { + /* Make the address absolute again */ + data->toffset += data->offset; + } } out(data); }