| 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
|
|
|