[LLVMdev] R_ARM_ABS32 disassembly with integrated-as
Greg Fitzgerald
garious at gmail.com
Wed Oct 17 07:05:24 PDT 2012
Hi Jim,
The diff below is not intended to be a patch, but a starting point.
It is the shortest path (I hope) to getting LLVM to emit ARM mapping
symbols to the ELF without changing any shared interfaces. Could you
have a look at the FIXME comments and offer some pointers on how to
get this code out of MCELFStreamer?
Thanks,
Greg
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index 8107005..153ca78 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -40,12 +40,14 @@ class MCELFStreamer : public MCObjectStreamer {
public:
MCELFStreamer(MCContext &Context, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, TAB, OS, Emitter) {}
+ : MCObjectStreamer(Context, TAB, OS, Emitter),
+ IsThumb(false), MappingSymbolCounter(0) {}
MCELFStreamer(MCContext &Context, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *Emitter,
MCAssembler *Assembler)
- : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler) {}
+ : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler),
+ IsThumb(false), MappingSymbolCounter(0) {}
~MCELFStreamer() {}
@@ -58,6 +60,7 @@ public:
virtual void EmitLabel(MCSymbol *Symbol);
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
virtual void EmitThumbFunc(MCSymbol *Func);
+ virtual void EmitDataRegion(MCDataRegionType Kind);
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
@@ -108,6 +111,7 @@ public:
private:
virtual void EmitInstToFragment(const MCInst &Inst);
virtual void EmitInstToData(const MCInst &Inst);
+ virtual void EmitMappingSymbol(bool IsData);
void fixSymbolsInTLSFixups(const MCExpr *expr);
@@ -119,6 +123,11 @@ private:
std::vector<LocalCommon> LocalCommons;
SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
+
+ // FIXME: This information is in ARMAsmBackend, but we currently
+ // have no way to reach it.
+ bool IsThumb;
+ int64_t MappingSymbolCounter;
/// @}
void SetSection(StringRef Section, unsigned Type, unsigned Flags,
SectionKind Kind) {
@@ -130,18 +139,21 @@ private:
ELF::SHF_WRITE |ELF::SHF_ALLOC,
SectionKind::getDataRel());
EmitCodeAlignment(4, 0);
+ EmitMappingSymbol(/*IsData*/true);
}
void SetSectionText() {
SetSection(".text", ELF::SHT_PROGBITS,
ELF::SHF_EXECINSTR |
ELF::SHF_ALLOC, SectionKind::getText());
EmitCodeAlignment(4, 0);
+ EmitMappingSymbol(/*IsData*/false);
}
void SetSectionBss() {
SetSection(".bss", ELF::SHT_NOBITS,
ELF::SHF_WRITE |
ELF::SHF_ALLOC, SectionKind::getBSS());
EmitCodeAlignment(4, 0);
+ EmitMappingSymbol(/*IsData*/true);
}
};
}
@@ -188,6 +200,55 @@ void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) {
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func);
SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc);
+
+ // Use this flag to output Thumb symbols after data sections.
+ IsThumb = true;
+
+ // FIXME: Instead, emit the correct mapping symbol at .text
+ EmitMappingSymbol(/*IsData*/false);
+}
+
+void MCELFStreamer::EmitMappingSymbol(bool IsData) {
+ // FIXME: The following is specific to the ARM. This should be moved
+ // to ARMAsmBackend.
+
+ if (!getAssembler().getBackend().hasDataInCodeSupport())
+ return;
+
+ // Create a temporary label to mark the start of the data region.
+ MCSymbol *Start = getContext().CreateTempSymbol();
+ EmitLabel(Start);
+
+ // FIXME: We want to generate symbols with the same name, but
+ // CreateSymbol() is not a public function. So instead
+ // we generate a unique name as we go. Luckily, the ARM
+ // ELF spec says that everything after the '.' is ignored.
+ StringRef Name = IsData ? "$d" : IsThumb ? "$t" : "$a";
+ StringRef UniqueName = Name.str() + "." + itostr(MappingSymbolCounter++);
+ MCSymbol *Symbol = getContext().GetOrCreateSymbol(UniqueName);
+
+ MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
+ MCELF::SetType(SD, ELF::STT_NOTYPE);
+ MCELF::SetBinding(SD, ELF::STB_LOCAL);
+ SD.setExternal(false);
+ Symbol->setSection(*getCurrentSection());
+
+ const MCExpr *Value = MCSymbolRefExpr::Create(Start, getContext());
+ Symbol->setVariableValue(Value);
+}
+
+void MCELFStreamer::EmitDataRegion(MCDataRegionType Kind) {
+ switch (Kind) {
+ case MCDR_DataRegion:
+ case MCDR_DataRegionJT8:
+ case MCDR_DataRegionJT16:
+ case MCDR_DataRegionJT32:
+ EmitMappingSymbol(/*IsData*/true);
+ break;
+ case MCDR_DataRegionEnd:
+ EmitMappingSymbol(/*IsData*/false);
+ break;
+ }
}
void MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
diff --git a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 1ba6ab0..a2c6f7d 100644
--- a/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -561,7 +561,10 @@ public:
uint8_t OSABI;
ELFARMAsmBackend(const Target &T, const StringRef TT,
uint8_t _OSABI)
- : ARMAsmBackend(T, TT), OSABI(_OSABI) { }
+ : ARMAsmBackend(T, TT), OSABI(_OSABI) {
+ // FIXME: Are there versions of ELF-ARM that do not support
data-in-code?
+ HasDataInCodeSupport = true;
+ }
void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
uint64_t Value) const;
More information about the llvm-dev
mailing list