Index: src/IceELFSection.h |
diff --git a/src/IceELFSection.h b/src/IceELFSection.h |
index 227affe9bf6cc4dd77b7d82762e71981a766b0c8..5821a8382d6caefa7855f5f8d5ef053fe43421fc 100644 |
--- a/src/IceELFSection.h |
+++ b/src/IceELFSection.h |
@@ -16,6 +16,8 @@ |
#include "IceDefs.h" |
#include "IceELFStreamer.h" |
+#include "IceFixups.h" |
+#include "IceOperand.h" |
using namespace llvm::ELF; |
@@ -122,6 +124,7 @@ public: |
// represents the symbol's final index in the symbol table. |
struct ELFSym { |
Elf64_Sym Sym; |
+ ELFSection *Section; |
SizeT Number; |
// Sentinel value for symbols that haven't been assigned a number yet. |
@@ -157,6 +160,8 @@ public: |
// symbol because it is undefined. |
void noteUndefinedSym(const IceString &Name, ELFSection *NullSection); |
+ const ELFSym *findSymbol(const IceString &Name) const; |
+ |
size_t getSectionDataSize() const { |
return (LocalSymbols.size() + GlobalSymbols.size()) * Header.sh_entsize; |
} |
@@ -168,8 +173,9 @@ public: |
void writeData(ELFStreamer &Str, bool IsELF64); |
private: |
- // Map from symbol name + section to its symbol information. |
- typedef std::pair<IceString, ELFSection *> SymtabKey; |
+ // Map from symbol name to its symbol information. |
+ // This assumes symbols are unique across all sections. |
+ typedef IceString SymtabKey; |
typedef std::map<SymtabKey, ELFSym> SymMap; |
template <bool IsELF64> |
@@ -181,45 +187,31 @@ private: |
SymMap GlobalSymbols; |
}; |
-// Base model of a relocation section. |
-class ELFRelocationSectionBase : public ELFSection { |
- ELFRelocationSectionBase(const ELFRelocationSectionBase &) = delete; |
- ELFRelocationSectionBase & |
- operator=(const ELFRelocationSectionBase &) = delete; |
+// Models a relocation section. |
+class ELFRelocationSection : public ELFSection { |
+ ELFRelocationSection(const ELFRelocationSection &) = delete; |
+ ELFRelocationSection &operator=(const ELFRelocationSection &) = delete; |
public: |
- ELFRelocationSectionBase(const IceString &Name, Elf64_Word ShType, |
- Elf64_Xword ShFlags, Elf64_Xword ShAddralign, |
- Elf64_Xword ShEntsize, ELFSection *RelatedSection) |
- : ELFSection(Name, ShType, ShFlags, ShAddralign, ShEntsize), |
- RelatedSection(RelatedSection) {} |
+ using ELFSection::ELFSection; |
ELFSection *getRelatedSection() const { return RelatedSection; } |
+ void setRelatedSection(ELFSection *Section) { RelatedSection = Section; } |
-private: |
- ELFSection *RelatedSection; |
-}; |
- |
-// ELFRelocationSection which depends on the actual relocation type. |
-// Specializations are needed depending on the ELFCLASS and whether |
-// or not addends are explicit or implicitly embedded in the related |
-// section (ELFCLASS64 pack their r_info field differently from ELFCLASS32). |
-template <typename RelType> |
-class ELFRelocationSection : ELFRelocationSectionBase { |
- ELFRelocationSection(const ELFRelocationSectionBase &) = delete; |
- ELFRelocationSection &operator=(const ELFRelocationSectionBase &) = delete; |
+ // Track additional relocations which start out relative to offset 0, |
+ // but should be adjusted to be relative to BaseOff. |
+ void addRelocations(RelocOffsetT BaseOff, const FixupRefList &FixupRefs); |
-public: |
- using ELFRelocationSectionBase::ELFRelocationSectionBase; |
+ size_t getSectionDataSize(const GlobalContext &Ctx, |
+ const ELFSymbolTableSection *SymTab) const; |
- void addRelocations() { |
- // TODO: fill me in |
- } |
+ template <bool IsELF64> |
+ void writeData(const GlobalContext &Ctx, ELFStreamer &Str, |
+ const ELFSymbolTableSection *SymTab); |
private: |
- typedef std::pair<RelType, ELFSym *> ELFRelSym; |
- typedef std::vector<ELFRelSym> RelocationList; |
- RelocationList Relocations; |
+ ELFSection *RelatedSection; |
+ FixupList Fixups; |
}; |
// Models a string table. The user will build the string table by |
@@ -319,6 +311,34 @@ void ELFSymbolTableSection::writeSymbolMap(ELFStreamer &Str, |
} |
} |
+template <bool IsELF64> |
+void ELFRelocationSection::writeData(const GlobalContext &Ctx, ELFStreamer &Str, |
+ const ELFSymbolTableSection *SymTab) { |
+ for (const AssemblerFixup &Fixup : Fixups) { |
+ const ELFSym *Symbol = SymTab->findSymbol(Fixup.symbol(&Ctx)); |
+ // TODO(jvoung): Make sure this always succeeds. |
+ // We currently don't track data symbols, so they aren't even marked |
+ // as undefined symbols. |
+ if (Symbol) { |
+ if (IsELF64) { |
+ Elf64_Rela Rela; |
+ Rela.r_offset = Fixup.position(); |
+ Rela.setSymbolAndType(Symbol->getNumber(), Fixup.kind()); |
+ Rela.r_addend = Fixup.offset(); |
+ Str.writeAddrOrOffset<IsELF64>(Rela.r_offset); |
+ Str.writeELFXword<IsELF64>(Rela.r_info); |
+ Str.writeELFXword<IsELF64>(Rela.r_addend); |
+ } else { |
+ Elf32_Rel Rel; |
+ Rel.r_offset = Fixup.position(); |
+ Rel.setSymbolAndType(Symbol->getNumber(), Fixup.kind()); |
+ Str.writeAddrOrOffset<IsELF64>(Rel.r_offset); |
+ Str.writeELFWord<IsELF64>(Rel.r_info); |
+ } |
+ } |
+ } |
+} |
+ |
} // end of namespace Ice |
#endif // SUBZERO_SRC_ICEELFSECTION_H |