summaryrefslogtreecommitdiffstats
path: root/lld/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib')
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h9
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h15
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h8
-rw-r--r--lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h61
-rw-r--r--lld/lib/ReaderWriter/ELF/OutputELFWriter.h13
-rw-r--r--lld/lib/ReaderWriter/Native/NativeFileFormat.h1
-rw-r--r--lld/lib/ReaderWriter/Native/ReaderNative.cpp4
-rw-r--r--lld/lib/ReaderWriter/Native/WriterNative.cpp1
-rw-r--r--lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp14
9 files changed, 118 insertions, 8 deletions
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h b/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h
index 3a6df13b09d..a23f707f2e9 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h
@@ -17,6 +17,7 @@
namespace lld {
namespace elf {
+template <typename ELFT> class MipsSymbolTable;
template <typename ELFT> class MipsDynamicSymbolTable;
template <typename ELFT> class MipsTargetLayout;
@@ -39,6 +40,7 @@ protected:
return std::error_code();
}
+ LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) createSymbolTable() override;
LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable() override;
LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)
@@ -73,6 +75,13 @@ void MipsDynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
_writeHelper.finalizeMipsRuntimeAtomValues();
}
+template <class ELFT>
+LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>)
+ MipsDynamicLibraryWriter<ELFT>::createSymbolTable() {
+ return LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>)(new (
+ this->_alloc) MipsSymbolTable<ELFT>(_mipsContext));
+}
+
/// \brief create dynamic table
template <class ELFT>
LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>)
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
index 9120f9149ea..4cc2c9745b0 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
@@ -60,6 +60,21 @@ public:
const MipsELFFile<ELFT>& file() const override {
return static_cast<const MipsELFFile<ELFT> &>(this->_owningFile);
}
+
+ DefinedAtom::CodeModel codeModel() const override {
+ switch (this->_symbol->st_other & llvm::ELF::STO_MIPS_MIPS16) {
+ case llvm::ELF::STO_MIPS_MIPS16:
+ return DefinedAtom::codeMips16;
+ case llvm::ELF::STO_MIPS_PIC:
+ return DefinedAtom::codeMipsPIC;
+ case llvm::ELF::STO_MIPS_MICROMIPS:
+ return DefinedAtom::codeMipsMicro;
+ case llvm::ELF::STO_MIPS_MICROMIPS | llvm::ELF::STO_MIPS_PIC:
+ return DefinedAtom::codeMipsMicroPIC;
+ default:
+ return DefinedAtom::codeNA;
+ }
+ }
};
template <class ELFT> class MipsELFFile : public ELFFile<ELFT> {
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h b/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
index 0e351b46b2a..eebb56e039d 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
@@ -39,6 +39,7 @@ protected:
return std::error_code();
}
+ LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) createSymbolTable() override;
LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable() override;
LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)
@@ -113,6 +114,13 @@ void MipsExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
_writeHelper.finalizeMipsRuntimeAtomValues();
}
+template <class ELFT>
+LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>)
+ MipsExecutableWriter<ELFT>::createSymbolTable() {
+ return LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>)(new (
+ this->_alloc) MipsSymbolTable<ELFT>(_mipsContext));
+}
+
/// \brief create dynamic table
template <class ELFT>
LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>)
diff --git a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
index 50fa8e966ae..c32ce8590ca 100644
--- a/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
+++ b/lld/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
@@ -135,6 +135,48 @@ private:
std::unique_ptr<MipsTargetRelocationHandler> _relocationHandler;
};
+template <class ELFT> class MipsSymbolTable : public SymbolTable<ELFT> {
+public:
+ typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
+
+ MipsSymbolTable(const MipsLinkingContext &ctx)
+ : SymbolTable<ELFT>(ctx, ".symtab",
+ DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE) {}
+
+ void addDefinedAtom(Elf_Sym &sym, const DefinedAtom *da,
+ int64_t addr) override {
+ SymbolTable<ELFT>::addDefinedAtom(sym, da, addr);
+
+ switch (da->codeModel()) {
+ case DefinedAtom::codeMipsMicro:
+ sym.st_other |= llvm::ELF::STO_MIPS_MICROMIPS;
+ break;
+ case DefinedAtom::codeMipsMicroPIC:
+ sym.st_other |= llvm::ELF::STO_MIPS_MICROMIPS | llvm::ELF::STO_MIPS_PIC;
+ break;
+ default:
+ break;
+ }
+ }
+
+ void finalize(bool sort = true) override {
+ SymbolTable<ELFT>::finalize(sort);
+
+ for (auto &ste : this->_symbolTable) {
+ if (!ste._atom)
+ continue;
+ if (const auto *da = dyn_cast<DefinedAtom>(ste._atom)) {
+ if (da->codeModel() == DefinedAtom::codeMipsMicro ||
+ da->codeModel() == DefinedAtom::codeMipsMicroPIC) {
+ // Adjust dynamic microMIPS symbol value. That allows a dynamic
+ // linker to recognize and handle this symbol correctly.
+ ste._symbol.st_value = ste._symbol.st_value | 1;
+ }
+ }
+ }
+ }
+};
+
template <class ELFT>
class MipsDynamicSymbolTable : public DynamicSymbolTable<ELFT> {
public:
@@ -157,23 +199,30 @@ public:
}
void finalize() override {
+ DynamicSymbolTable<ELFT>::finalize();
+
const auto &pltSection = _targetLayout.getPLTSection();
- // Under some conditions a dynamic symbol table record should hold a symbol
- // value of the corresponding PLT entry. For details look at the PLT entry
- // creation code in the class MipsRelocationPass. Let's update atomLayout
- // fields for such symbols.
for (auto &ste : this->_symbolTable) {
if (!ste._atom)
continue;
if (auto *layout = pltSection.findPLTLayout(ste._atom)) {
+ // Under some conditions a dynamic symbol table record should hold
+ // a symbol value of the corresponding PLT entry. For details look
+ // at the PLT entry creation code in the class MipsRelocationPass.
+ // Let's update atomLayout fields for such symbols.
assert(!ste._atomLayout);
ste._symbol.st_value = layout->_virtualAddr;
ste._symbol.st_other |= ELF::STO_MIPS_PLT;
+ } else if (const auto *da = dyn_cast<DefinedAtom>(ste._atom)) {
+ if (da->codeModel() == DefinedAtom::codeMipsMicro ||
+ da->codeModel() == DefinedAtom::codeMipsMicroPIC) {
+ // Adjust dynamic microMIPS symbol value. That allows a dynamic
+ // linker to recognize and handle this symbol correctly.
+ ste._symbol.st_value = ste._symbol.st_value | 1;
+ }
}
}
-
- DynamicSymbolTable<Mips32ElELFType>::finalize();
}
private:
diff --git a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
index 8231136ebe9..2cb8ded4f1f 100644
--- a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
+++ b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h
@@ -100,6 +100,9 @@ protected:
// This is a hook for creating default dynamic entries
virtual void createDefaultDynamicEntries() {}
+ /// \brief Create symbol table.
+ virtual LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>) createSymbolTable();
+
/// \brief create dynamic table.
virtual LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) createDynamicTable();
@@ -284,8 +287,7 @@ template <class ELFT> void OutputELFWriter<ELFT>::createDefaultSections() {
_layout.setHeader(_elfHeader.get());
_layout.setProgramHeader(_programHeader.get());
- _symtab.reset(new (_alloc) SymbolTable<ELFT>(
- _context, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE));
+ _symtab = std::move(this->createSymbolTable());
_strtab.reset(new (_alloc) StringTable<ELFT>(
_context, ".strtab", DefaultLayout<ELFT>::ORDER_STRING_TABLE));
_shstrtab.reset(new (_alloc) StringTable<ELFT>(
@@ -336,6 +338,13 @@ template <class ELFT> void OutputELFWriter<ELFT>::createDefaultSections() {
}
}
+template <class ELFT>
+LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>)
+ OutputELFWriter<ELFT>::createSymbolTable() {
+ return LLD_UNIQUE_BUMP_PTR(SymbolTable<ELFT>)(new (_alloc) SymbolTable<ELFT>(
+ this->_context, ".symtab", DefaultLayout<ELFT>::ORDER_SYMBOL_TABLE));
+}
+
/// \brief create dynamic table
template <class ELFT>
LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>)
diff --git a/lld/lib/ReaderWriter/Native/NativeFileFormat.h b/lld/lib/ReaderWriter/Native/NativeFileFormat.h
index e595bcd6489..5dfb87fcf7e 100644
--- a/lld/lib/ReaderWriter/Native/NativeFileFormat.h
+++ b/lld/lib/ReaderWriter/Native/NativeFileFormat.h
@@ -155,6 +155,7 @@ struct NativeAtomAttributesV1 {
uint8_t dynamicExport;
uint8_t permissions;
uint8_t alias;
+ uint8_t codeModel;
};
diff --git a/lld/lib/ReaderWriter/Native/ReaderNative.cpp b/lld/lib/ReaderWriter/Native/ReaderNative.cpp
index 62bb9a14e67..edecbcd64e3 100644
--- a/lld/lib/ReaderWriter/Native/ReaderNative.cpp
+++ b/lld/lib/ReaderWriter/Native/ReaderNative.cpp
@@ -90,6 +90,10 @@ public:
return (DynamicExport)attributes().dynamicExport;
}
+ DefinedAtom::CodeModel codeModel() const override {
+ return DefinedAtom::CodeModel(attributes().codeModel);
+ }
+
DefinedAtom::ContentPermissions permissions() const override {
return (DefinedAtom::ContentPermissions)(attributes().permissions);
}
diff --git a/lld/lib/ReaderWriter/Native/WriterNative.cpp b/lld/lib/ReaderWriter/Native/WriterNative.cpp
index 76b73562afc..ab8dad1493a 100644
--- a/lld/lib/ReaderWriter/Native/WriterNative.cpp
+++ b/lld/lib/ReaderWriter/Native/WriterNative.cpp
@@ -426,6 +426,7 @@ private:
= atom.sectionChoice() << 4 | atom.sectionPosition();
attrs.deadStrip = atom.deadStrip();
attrs.dynamicExport = atom.dynamicExport();
+ attrs.codeModel = atom.codeModel();
attrs.permissions = atom.permissions();
return attrs;
}
diff --git a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
index 6993ee4a099..5b83f5868be 100644
--- a/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
+++ b/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
@@ -386,6 +386,16 @@ template <> struct ScalarEnumerationTraits<lld::DefinedAtom::DynamicExport> {
}
};
+template <> struct ScalarEnumerationTraits<lld::DefinedAtom::CodeModel> {
+ static void enumeration(IO &io, lld::DefinedAtom::CodeModel &value) {
+ io.enumCase(value, "none", lld::DefinedAtom::codeNA);
+ io.enumCase(value, "mips-pic", lld::DefinedAtom::codeMipsPIC);
+ io.enumCase(value, "mips-micro", lld::DefinedAtom::codeMipsMicro);
+ io.enumCase(value, "mips-micro-pic", lld::DefinedAtom::codeMipsMicroPIC);
+ io.enumCase(value, "mips-16", lld::DefinedAtom::codeMips16);
+ }
+};
+
template <>
struct ScalarEnumerationTraits<lld::DefinedAtom::ContentPermissions> {
static void enumeration(IO &io, lld::DefinedAtom::ContentPermissions &value) {
@@ -809,6 +819,7 @@ template <> struct MappingTraits<const lld::DefinedAtom *> {
_alignment(atom->alignment()), _sectionChoice(atom->sectionChoice()),
_sectionPosition(atom->sectionPosition()),
_deadStrip(atom->deadStrip()), _dynamicExport(atom->dynamicExport()),
+ _codeModel(atom->codeModel()),
_permissions(atom->permissions()), _size(atom->size()),
_sectionName(atom->customSectionName()) {
for (const lld::Reference *r : *atom)
@@ -859,6 +870,7 @@ template <> struct MappingTraits<const lld::DefinedAtom *> {
SectionPosition sectionPosition() const override { return _sectionPosition; }
DeadStripKind deadStrip() const override { return _deadStrip; }
DynamicExport dynamicExport() const override { return _dynamicExport; }
+ CodeModel codeModel() const override { return _codeModel; }
ContentPermissions permissions() const override { return _permissions; }
void setGroupChild(bool val) { _isGroupChild = val; }
bool isGroupChild() const { return _isGroupChild; }
@@ -904,6 +916,7 @@ template <> struct MappingTraits<const lld::DefinedAtom *> {
SectionPosition _sectionPosition;
DeadStripKind _deadStrip;
DynamicExport _dynamicExport;
+ CodeModel _codeModel;
ContentPermissions _permissions;
uint32_t _ordinal;
std::vector<ImplicitHex8> _content;
@@ -951,6 +964,7 @@ template <> struct MappingTraits<const lld::DefinedAtom *> {
DefinedAtom::deadStripNormal);
io.mapOptional("dynamic-export", keys->_dynamicExport,
DefinedAtom::dynamicExportNormal);
+ io.mapOptional("code-model", keys->_codeModel, DefinedAtom::codeNA);
// default permissions based on content type
io.mapOptional("permissions", keys->_permissions,
DefinedAtom::permissions(
OpenPOWER on IntegriCloud