[lld] More logging info for lld (PR #135004)
Serge S. Gulin via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 9 06:34:29 PDT 2025
https://github.com/GulinSS created https://github.com/llvm/llvm-project/pull/135004
It adds details to lld error message for aarch64 misalign mistakes.
The origin message:
```
ld.lld: error: misaligned ldr/str offset
ld.lld: error: misaligned ldr/str offset
ld.lld: error: misaligned ldr/str offset
ld.lld: error: misaligned ldr/str offset
ld.lld: error: misaligned ldr/str offset
ld.lld: error: misaligned ldr/str offset
```
Very non-informative. What is the cause? Who knows. How to debug it? No easy ways. 🩸 😔
The new message is:
```
ld.lld: error: misaligned ldr/str offset: 0x76c at f9400318 with align 2^3 from free at Signal.o
ld.lld: error: misaligned ldr/str offset: 0x574 at f9400318 with align 2^3 from backtraceFree at Internal.o
ld.lld: error: misaligned ldr/str offset: 0x904 at f9400252 with align 2^3 from enabled_capabilities at Sync.o
ld.lld: error: misaligned ldr/str offset: 0x904 at f9400252 with align 2^3 from enabled_capabilities at Sync.o
ld.lld: error: misaligned ldr/str offset: 0x804 at f9400252 with align 2^3 from rts_stop_on_exception at Exception.o
ld.lld: error: misaligned ldr/str offset: 0x804 at f9400231 with align 2^3 from rts_stop_on_exception at Exception.o
```
Well, notable better. Now we know the instruction code, the actual offset and the reason of the relocation: object file + symbol name. Enough information to resolve any similar issues! :godmode: 💪
Without these changes it would be notable more painful to deal with [this](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/13856).
>From a6b7acc3b8645209767c03ece233b8d0e8f2513e Mon Sep 17 00:00:00 2001
From: "Serge S. Gulin" <gulin.serge at gmail.com>
Date: Wed, 9 Apr 2025 16:28:40 +0300
Subject: [PATCH] More logging info for lld
Co-authored-by: Kirill Andreev <hindmost.one at gmail.com>
Co-authored-by: Andrei Borzenkov <root at sandwitch.dev>
Co-authored-by: Dmitrii Egorov <egorov.d.i at icloud.com>
Co-authored-by: Danil Berestov <goosedb at yandex.ru>
Co-authored-by: Ilya Baryshnikov <zlonast3 at gmail.com>
---
lld/COFF/Chunks.cpp | 43 +++++++++++++++++++++++++++++++------------
lld/COFF/Chunks.h | 2 +-
2 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index 3494d1ba0ac02..90c33b52c4cbe 100644
--- a/lld/COFF/Chunks.cpp
+++ b/lld/COFF/Chunks.cpp
@@ -268,7 +268,7 @@ void applyArm64Imm(uint8_t *off, uint64_t imm, uint32_t rangeLimit) {
// Even if larger loads/stores have a larger range, limit the
// effective offset to 12 bit, since it is intended to be a
// page offset.
-static void applyArm64Ldr(uint8_t *off, uint64_t imm) {
+static void applyArm64Ldr(const Twine &msg_location, uint8_t *off, uint64_t imm) {
uint32_t orig = read32le(off);
uint32_t size = orig >> 30;
// 0x04000000 indicates SIMD/FP registers
@@ -276,7 +276,9 @@ static void applyArm64Ldr(uint8_t *off, uint64_t imm) {
if ((orig & 0x4800000) == 0x4800000)
size += 4;
if ((imm & ((1 << size) - 1)) != 0)
- error("misaligned ldr/str offset");
+ error(llvm::Twine {"misaligned ldr/str offset: 0x"} + llvm::Twine::utohexstr(imm)
+ + "@" + llvm::Twine::utohexstr(static_cast<uint64_t>(orig))
+ + " with align 2^" + llvm::Twine(size) + " from " + msg_location);
applyArm64Imm(off, imm >> size, size);
}
@@ -299,10 +301,10 @@ static void applySecRelHigh12A(const SectionChunk *sec, uint8_t *off,
applyArm64Imm(off, secRel & 0xfff, 0);
}
-static void applySecRelLdr(const SectionChunk *sec, uint8_t *off,
+static void applySecRelLdr(const SectionChunk *sec, const Twine &msg_location, uint8_t *off,
OutputSection *os, uint64_t s) {
if (checkSecRel(sec, os))
- applyArm64Ldr(off, (s - os->getRVA()) & 0xfff);
+ applyArm64Ldr(msg_location, off, (s - os->getRVA()) & 0xfff);
}
void applyArm64Branch26(uint8_t *off, int64_t v) {
@@ -323,14 +325,23 @@ static void applyArm64Branch14(uint8_t *off, int64_t v) {
or32(off, (v & 0x0000FFFC) << 3);
}
-void SectionChunk::applyRelARM64(uint8_t *off, uint16_t type, OutputSection *os,
+void SectionChunk::applyRelARM64(uint8_t *off, const coff_relocation &rel, OutputSection *os,
uint64_t s, uint64_t p,
uint64_t imageBase) const {
- switch (type) {
+ // COPY FROM: maybeReportRelocationToDiscarded
+ StringRef sym_name;
+ if (this->sym) {
+ sym_name = this->sym->getName();
+ } else {
+ COFFSymbolRef coffSym = check(this->file->getCOFFObj()->getSymbol(rel.SymbolTableIndex));
+ sym_name = check(this->file->getCOFFObj()->getSymbolName(coffSym));
+ }
+
+ switch (rel.Type) {
case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(off, s, p, 12); break;
case IMAGE_REL_ARM64_REL21: applyArm64Addr(off, s, p, 0); break;
case IMAGE_REL_ARM64_PAGEOFFSET_12A: applyArm64Imm(off, s & 0xfff, 0); break;
- case IMAGE_REL_ARM64_PAGEOFFSET_12L: applyArm64Ldr(off, s & 0xfff); break;
+ case IMAGE_REL_ARM64_PAGEOFFSET_12L: applyArm64Ldr(sym_name + "@" + this->file->getName(), off, s & 0xfff); break;
case IMAGE_REL_ARM64_BRANCH26: applyArm64Branch26(off, s - p); break;
case IMAGE_REL_ARM64_BRANCH19: applyArm64Branch19(off, s - p); break;
case IMAGE_REL_ARM64_BRANCH14: applyArm64Branch14(off, s - p); break;
@@ -344,13 +355,13 @@ void SectionChunk::applyRelARM64(uint8_t *off, uint16_t type, OutputSection *os,
case IMAGE_REL_ARM64_SECREL: applySecRel(this, off, os, s); break;
case IMAGE_REL_ARM64_SECREL_LOW12A: applySecRelLow12A(this, off, os, s); break;
case IMAGE_REL_ARM64_SECREL_HIGH12A: applySecRelHigh12A(this, off, os, s); break;
- case IMAGE_REL_ARM64_SECREL_LOW12L: applySecRelLdr(this, off, os, s); break;
+ case IMAGE_REL_ARM64_SECREL_LOW12L: applySecRelLdr(this, sym_name + "@" + this->file->getName(), off, os, s); break;
case IMAGE_REL_ARM64_SECTION:
applySecIdx(off, os, file->symtab.ctx.outputSections.size());
break;
case IMAGE_REL_ARM64_REL32: add32(off, s - p - 4); break;
default:
- error("unsupported relocation type 0x" + Twine::utohexstr(type) + " in " +
+ error("unsupported relocation type 0x" + Twine::utohexstr(rel.Type) + " in " +
toString(file));
}
}
@@ -368,6 +379,7 @@ static void maybeReportRelocationToDiscarded(const SectionChunk *fromChunk,
// Get the name of the symbol. If it's null, it was discarded early, so we
// have to go back to the object file.
+ // COPY TO: SectionChunk::applyRelARM64.
ObjFile *file = fromChunk->file;
std::string name;
if (sym) {
@@ -457,7 +469,7 @@ void SectionChunk::applyRelocation(uint8_t *off,
applyRelARM(off, rel.Type, os, s, p, imageBase);
break;
case Triple::aarch64:
- applyRelARM64(off, rel.Type, os, s, p, imageBase);
+ applyRelARM64(off, rel, os, s, p, imageBase);
break;
default:
llvm_unreachable("unknown machine type");
@@ -829,10 +841,17 @@ void ImportThunkChunkARM::writeTo(uint8_t *buf) const {
}
void ImportThunkChunkARM64::writeTo(uint8_t *buf) const {
- int64_t off = impSymbol->getRVA() & 0xfff;
memcpy(buf, importThunkARM64, sizeof(importThunkARM64));
applyArm64Addr(buf, impSymbol->getRVA(), rva, 12);
- applyArm64Ldr(buf + 4, off);
+
+ StringRef fileName;
+ if (isa<DefinedImportData>(impSymbol))
+ fileName = static_cast<DefinedImportData *>(impSymbol)->getDLLName();
+ else
+ fileName = "<not_defined_import_data>";
+
+ int64_t off = impSymbol->getRVA() & 0xfff;
+ applyArm64Ldr(impSymbol->getName() + "@" + fileName, buf + 4, off);
}
// A Thumb2, PIC, non-interworking range extension thunk.
diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
index 9f68d5a325cc5..0e04f7b82cc20 100644
--- a/lld/COFF/Chunks.h
+++ b/lld/COFF/Chunks.h
@@ -280,7 +280,7 @@ class SectionChunk : public Chunk {
uint64_t p, uint64_t imageBase) const;
void applyRelARM(uint8_t *off, uint16_t type, OutputSection *os, uint64_t s,
uint64_t p, uint64_t imageBase) const;
- void applyRelARM64(uint8_t *off, uint16_t type, OutputSection *os, uint64_t s,
+ void applyRelARM64(uint8_t *off, const coff_relocation &rel, OutputSection *os, uint64_t s,
uint64_t p, uint64_t imageBase) const;
void getRuntimePseudoRelocs(std::vector<RuntimePseudoReloc> &res);
More information about the llvm-commits
mailing list