[llvm] [llvm-readobj][COFF] Implement --coff-pseudoreloc in llvm-readobj to dump runtime pseudo-relocation records (PR #151816)
James Henderson via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 22 02:21:51 PDT 2025
================
@@ -2002,52 +2002,125 @@ void COFFDumper::printCOFFBaseReloc() {
}
void COFFDumper::printCOFFPseudoReloc() {
+ ListScope D(W, "PseudoReloc");
+
+ // Pseudo-relocations are only meaningful with PE image files.
+ if (!Obj->getDOSHeader())
+ return;
+
const StringRef RelocBeginName = Obj->getArch() == Triple::x86
? "___RUNTIME_PSEUDO_RELOC_LIST__"
: "__RUNTIME_PSEUDO_RELOC_LIST__";
const StringRef RelocEndName = Obj->getArch() == Triple::x86
? "___RUNTIME_PSEUDO_RELOC_LIST_END__"
: "__RUNTIME_PSEUDO_RELOC_LIST_END__";
- COFFSymbolRef RelocBegin, RelocEnd;
- auto Count = Obj->getNumberOfSymbols();
- if (Count == 0) {
- W.startLine() << "The symbol table has been stripped\n";
+ const uint32_t Count = Obj->getNumberOfSymbols();
+ // Skip if no symbol was found (maybe stripped).
+ if (Count == 0)
return;
- }
- for (auto i = 0u;
- i < Count && (!RelocBegin.getRawPtr() || !RelocEnd.getRawPtr()); ++i) {
- auto Sym = Obj->getSymbol(i);
- if (Sym.takeError())
+
+ struct SymbolEntry {
+ uint32_t RVA;
+ COFFSymbolRef Symbol;
+ const coff_section *Section;
+ StringRef SymbolName;
+ };
+ SmallVector<SymbolEntry> RVASymbolMap;
+ COFFSymbolRef RelocBegin, RelocEnd;
+ for (uint32_t i = 0; i < Count; ++i) {
+ COFFSymbolRef Sym;
+ if (Expected<COFFSymbolRef> SymOrErr = Obj->getSymbol(i)) {
+ Sym = *SymOrErr;
+ } else {
+ reportUniqueWarning(SymOrErr.takeError());
+ continue;
+ }
+
+ i += Sym.getNumberOfAuxSymbols();
+
+ if (Sym.getSectionNumber() <= 0)
+ continue;
+
+ StringRef Name;
+ if (Expected<StringRef> NameOrErr = Obj->getSymbolName(Sym)) {
+ Name = *NameOrErr;
+ } else {
+ reportUniqueWarning(NameOrErr.takeError());
continue;
- auto Name = Obj->getSymbolName(*Sym);
- if (Name.takeError())
+ }
+
+ if (Name == RelocBeginName)
+ RelocBegin = Sym;
+ else if (Name == RelocEndName)
+ RelocEnd = Sym;
+
+ const coff_section *Sec = nullptr;
+ if (Expected<const coff_section *> SecOrErr =
+ Obj->getSection(Sym.getSectionNumber())) {
+ Sec = *SecOrErr;
+ } else {
+ reportUniqueWarning(SecOrErr.takeError());
continue;
- if (*Name == RelocBeginName) {
- if (Sym->getSectionNumber() > 0)
- RelocBegin = *Sym;
- } else if (*Name == RelocEndName) {
- if (Sym->getSectionNumber() > 0)
- RelocEnd = *Sym;
}
+
+ RVASymbolMap.push_back(
+ {Sec->VirtualAddress + Sym.getValue(), Sym, Sec, Name});
}
+
if (!RelocBegin.getRawPtr() || !RelocEnd.getRawPtr()) {
- W.startLine()
- << "The symbols for runtime pseudo-relocation are not found\n";
+ reportUniqueWarning(createStringError(
+ "the marker symbols for runtime pseudo-relocation were not found"));
+ return;
+ }
+
+ const coff_section *Section = nullptr;
+ if (Expected<const coff_section *> SecOrErr =
+ Obj->getSection(RelocBegin.getSectionNumber())) {
+ Section = *SecOrErr;
+ } else {
+ reportUniqueWarning(SecOrErr.takeError());
+ return;
+ }
+
+ if (RelocBegin.getSectionNumber() != RelocEnd.getSectionNumber()) {
+ reportUniqueWarning(createStringError(
+ "the end marker symbol for runtime pseudo-relocation must "
+ "point to the same section where the begin marker points to: "
+ "expected %d, but got %d",
+ RelocBegin.getSectionNumber(), RelocEnd.getSectionNumber()));
+ return;
+ }
+
+ // Skip if the relocation list is empty.
+ if (RelocBegin.getValue() == RelocEnd.getValue())
+ return;
+
+ if (RelocEnd.getValue() < RelocBegin.getValue()) {
+ reportUniqueWarning(createStringError(
+ "the end marker symbol for runtime pseudo-relocation must point "
+ "to a higher address than where the begin marker points to: "
+ "expected >=0x%x, but got 0x%x",
+ RelocBegin.getValue(), RelocEnd.getValue()));
return;
}
ArrayRef<uint8_t> Data;
- auto Section = Obj->getSection(RelocBegin.getSectionNumber());
- if (auto E = Section.takeError()) {
- reportError(std::move(E), Obj->getFileName());
+ if (auto E = Obj->getSectionContents(Section, Data)) {
+ reportUniqueWarning(std::move(E));
return;
}
- if (auto E = Obj->getSectionContents(*Section, Data)) {
- reportError(std::move(E), Obj->getFileName());
+
+ if (const uint32_t Begin = RelocBegin.getValue(), End = RelocEnd.getValue();
+ Begin >= Data.size() || End > Data.size()) {
+ reportUniqueWarning(
+ createStringError("the marker symbol of runtime pseudo-relocation "
+ "points past the end of the section: 0x%x",
----------------
jh7370 wrote:
I don't think it's 100% obvious that this value is the actual offset or the section end offset. Perhaps both should be present?
https://github.com/llvm/llvm-project/pull/151816
More information about the llvm-commits
mailing list