diff options
author | Fangrui Song <i@maskray.me> | 2025-05-26 21:58:17 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2025-05-26 21:58:18 -0700 |
commit | e015626f189dc76f8df9fdc25a47638c6a2f3feb (patch) | |
tree | ea77e8d4093c6bd7f83701d17ec1add55aeddd3e /llvm/lib/MC/ELFObjectWriter.cpp | |
parent | de93f7ed0d615060735ad15e720f2497ed1d2468 (diff) | |
download | llvm-e015626f189dc76f8df9fdc25a47638c6a2f3feb.zip llvm-e015626f189dc76f8df9fdc25a47638c6a2f3feb.tar.gz llvm-e015626f189dc76f8df9fdc25a47638c6a2f3feb.tar.bz2 |
MC: Allow .set to reassign non-MCConstantExpr expressions
GNU Assembler supports symbol reassignment via .set, .equ, or =.
However, LLVM's integrated assembler only allows reassignment for
MCConstantExpr cases, as it struggles with scenarios like:
```
.data
.set x, 0
.long x // reference the first instance
x = .-.data
.long x // reference the second instance
.set x,.-.data
.long x // reference the third instance
```
Between two assignments binds, we cannot ensure that a reference binds
to the earlier assignment. We use MCSymbol::IsUsed and other conditions
to reject potentially unsafe reassignments, but certain MCConstantExpr
uses could be unsafe as well.
This patch enables reassignment by cloning the symbol upon reassignment
and updating the symbol table. Existing references to the original
symbol remain unchanged, and the original symbol is excluded from the
emitted symbol table.
Diffstat (limited to 'llvm/lib/MC/ELFObjectWriter.cpp')
-rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 3 |
1 files changed, 1 insertions, 2 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 592081d..933a64d 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -446,8 +446,7 @@ void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex, // needs. MCBinaryExpr is not handled. const MCSymbolELF *Sym = &Symbol; while (Sym->isVariable()) { - if (auto *Expr = - dyn_cast<MCSymbolRefExpr>(Sym->getVariableValue(false))) { + if (auto *Expr = dyn_cast<MCSymbolRefExpr>(Sym->getVariableValue())) { Sym = cast<MCSymbolELF>(&Expr->getSymbol()); if (!Sym->getSize()) continue; |