summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Atanasyan <simon@atanasyan.com>2014-11-13 07:03:41 +0000
committerSimon Atanasyan <simon@atanasyan.com>2014-11-13 07:03:41 +0000
commitc77f5fa4f4fa6199915c8922d7679d824c9d2252 (patch)
tree4815544c0e93aea798a2da69d62bb1c917b80eef
parent2a18f352127118ab2547ba9f03bb059945f99acb (diff)
downloadbcm5719-llvm-c77f5fa4f4fa6199915c8922d7679d824c9d2252.tar.gz
bcm5719-llvm-c77f5fa4f4fa6199915c8922d7679d824c9d2252.zip
[ELF] Add CodeModel attribute to the DefinedAtom class
MIPS ELF symbols might contain some additional MIPS-specific flags in the st_other field besides visibility ones. These flags indicate code properties like microMIPS / MIPS16 encoding, position independent code etc. We need to transfer the flags from input objects to the output linked file to write them into the symbol table, adjust symbols addresses etc. I add new attribute CodeModel to the DefinedAtom class to hold target specific flag and to get over YAML/Native format conversion barrier. Other architectures/targets can extend CodeModel enumeration by their own flags. MIPS specific part of this patch adds support for STO_MIPS_MICROMIPS flag. This flag marks microMIPS symbols. Such symbol should: a) Has STO_MIPS_MICROMIPS in the corresponding .symtab record. b) Has adjusted (odd) address in the corresponding .symtab and .dynsym records. llvm-svn: 221864
-rw-r--r--lld/include/lld/Core/DefinedAtom.h12
-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
-rw-r--r--lld/test/core/code-model-attributes.objtxt50
-rw-r--r--lld/test/elf/Mips/st-other.test90
12 files changed, 270 insertions, 8 deletions
diff --git a/lld/include/lld/Core/DefinedAtom.h b/lld/include/lld/Core/DefinedAtom.h
index cc3b9e674f0..5414653c747 100644
--- a/lld/include/lld/Core/DefinedAtom.h
+++ b/lld/include/lld/Core/DefinedAtom.h
@@ -194,6 +194,15 @@ public:
dynamicExportAlways,
};
+ // Attributes describe a code model used by the atom.
+ enum CodeModel {
+ codeNA, // no specific code model
+ codeMipsPIC, // PIC function in a PIC / non-PIC mixed file
+ codeMipsMicro, // microMIPS instruction encoding
+ codeMipsMicroPIC, // microMIPS instruction encoding + PIC
+ codeMips16, // MIPS-16 instruction encoding
+ };
+
struct Alignment {
Alignment(int p2, int m = 0)
: powerOf2(p2)
@@ -266,6 +275,9 @@ public:
return dynamicExportNormal;
}
+ /// \brief Code model used by the atom.
+ virtual CodeModel codeModel() const { return codeNA; }
+
/// \brief Returns the OS memory protections required for this atom's content
/// at runtime.
///
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(
diff --git a/lld/test/core/code-model-attributes.objtxt b/lld/test/core/code-model-attributes.objtxt
new file mode 100644
index 00000000000..8c30e868567
--- /dev/null
+++ b/lld/test/core/code-model-attributes.objtxt
@@ -0,0 +1,50 @@
+# RUN: lld -core %s | FileCheck %s
+
+#
+# Test that code model attributes are preserved
+#
+
+---
+defined-atoms:
+ - name: _def
+---
+defined-atoms:
+ - name: _none
+ code-model: none
+---
+defined-atoms:
+ - name: _mips_pic
+ code-model: mips-pic
+---
+defined-atoms:
+ - name: _mips_micro
+ code-model: mips-micro
+---
+defined-atoms:
+ - name: _mips_micro_pic
+ code-model: mips-micro-pic
+---
+defined-atoms:
+ - name: _mips_16
+ code-model: mips-16
+...
+
+# CHECK: name: _def
+# CHECK-NOT: code-model: mips-pic
+# CHECK-NOT: code-model: mips-micro
+# CHECK-NOT: code-model: mips-micro-pic
+# CHECK-NOT: code-model: mips-16
+# CHECK: name: _none
+# CHECK-NOT: code-model: mips-pic
+# CHECK-NOT: code-model: mips-micro
+# CHECK-NOT: code-model: mips-micro-pic
+# CHECK-NOT: code-model: mips-16
+# CHECK: name: _mips_pic
+# CHECK: code-model: mips-pic
+# CHECK: name: _mips_micro
+# CHECK: code-model: mips-micro
+# CHECK: name: _mips_micro_pic
+# CHECK: code-model: mips-micro-pic
+# CHECK: name: _mips_16
+# CHECK: code-model: mips-16
+# CHECK: ...
diff --git a/lld/test/elf/Mips/st-other.test b/lld/test/elf/Mips/st-other.test
new file mode 100644
index 00000000000..8d15e75676b
--- /dev/null
+++ b/lld/test/elf/Mips/st-other.test
@@ -0,0 +1,90 @@
+# Check STO_MICROMIPS flag handling. microMIPS symbol records in a dynamic
+# symbol table should not have STO_MICROMIPS flag but their value field
+# must be odd. microMIPS symbol records in a regular symbol table should
+# have the STO_MICROMIPS flag.
+
+# RUN: yaml2obj -format=elf %s > %t-micro.o
+
+# RUN: lld -flavor gnu -target mipsel -shared -o %t.so %t-micro.o
+# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck -check-prefix=SO %s
+
+# RUN: lld -flavor gnu -target mipsel -e S0 -o %t.exe %t-micro.o
+# RUN: llvm-readobj -symbols %t.exe | FileCheck -check-prefix=EXE-SYM %s
+# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=EXE-DSYM %s
+
+# SO: Symbol {
+# SO: Name: S0@ (1)
+# SO-NEXT: Value: 0xEC
+# SO-NEXT: Size: 4
+# SO-NEXT: Binding: Global (0x1)
+# SO-NEXT: Type: Function (0x2)
+# SO-NEXT: Other: 0
+# SO-NEXT: Section: .text (0x4)
+# SO-NEXT: }
+
+# SO: Symbol {
+# SO: Name: S1@ (4)
+# SO-NEXT: Value: 0xF1
+# SO-NEXT: Size: 4
+# SO-NEXT: Binding: Global (0x1)
+# SO-NEXT: Type: Function (0x2)
+# SO-NEXT: Other: 0
+# SO-NEXT: Section: .text (0x4)
+# SO-NEXT: }
+
+# EXE-SYM: Symbol {
+# EXE-SYM: Name: S0 (1)
+# EXE-SYM-NEXT: Value: 0x400108
+# EXE-SYM-NEXT: Size: 4
+# EXE-SYM-NEXT: Binding: Global (0x1)
+# EXE-SYM-NEXT: Type: Function (0x2)
+# EXE-SYM-NEXT: Other: 0
+# EXE-SYM-NEXT: Section: .text (0x5)
+# EXE-SYM-NEXT: }
+
+# EXE-SYM: Symbol {
+# EXE-SYM: Name: S1 (4)
+# EXE-SYM-NEXT: Value: 0x40010D
+# EXE-SYM-NEXT: Size: 4
+# EXE-SYM-NEXT: Binding: Global (0x1)
+# EXE-SYM-NEXT: Type: Function (0x2)
+# EXE-SYM-NEXT: Other: 128
+# EXE-SYM-NEXT: Section: .text (0x5)
+# EXE-SYM-NEXT: }
+
+# EXE-DSYM-NOT: Name: S1 (4)
+
+# micro.o
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_MIPS
+ Flags: [EF_MIPS_ABI_O32, EF_MIPS_ARCH_32R2, EF_MIPS_MICROMIPS]
+
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x04
+ Size: 0x08
+
+Symbols:
+ Global:
+ - Name: S0
+ Type: STT_FUNC
+ Section: .text
+ Size: 0x04
+ Value: 0x00
+ Visibility: STV_DEFAULT
+ Other: [ ]
+
+ - Name: S1
+ Type: STT_FUNC
+ Section: .text
+ Size: 0x04
+ Value: 0x04
+ Visibility: STV_DEFAULT
+ Other: [ STO_MIPS_MICROMIPS ]
+...
OpenPOWER on IntegriCloud