diff options
| author | Hemant Kulkarni <khemant@codeaurora.org> | 2012-11-21 21:07:36 +0000 |
|---|---|---|
| committer | Hemant Kulkarni <khemant@codeaurora.org> | 2012-11-21 21:07:36 +0000 |
| commit | 736f7fbee236c3c0aa4722ebdde5ff5dc5868bf2 (patch) | |
| tree | 0dd718a477b9c61deab2d2138e5d12ca0293dd05 | |
| parent | bb6e74a2f17c0b5ab66749343f48103ea03da968 (diff) | |
| download | bcm5719-llvm-736f7fbee236c3c0aa4722ebdde5ff5dc5868bf2.tar.gz bcm5719-llvm-736f7fbee236c3c0aa4722ebdde5ff5dc5868bf2.zip | |
Populate entry point into ELF executable.
llvm-svn: 168461
| -rw-r--r-- | lld/include/lld/ReaderWriter/WriterELF.h | 7 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/ReaderELF.cpp | 5 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/WriterELF.cpp | 63 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp | 2 | ||||
| -rw-r--r-- | lld/test/elf/Inputs/phdr.i386 | bin | 0 -> 17536 bytes | |||
| -rw-r--r-- | lld/test/elf/phdr.objtxt | 17 | ||||
| -rw-r--r-- | lld/test/elf/sections.objtxt | 2 |
7 files changed, 72 insertions, 24 deletions
diff --git a/lld/include/lld/ReaderWriter/WriterELF.h b/lld/include/lld/ReaderWriter/WriterELF.h index ebd559147a2..87f64e43bfa 100644 --- a/lld/include/lld/ReaderWriter/WriterELF.h +++ b/lld/include/lld/ReaderWriter/WriterELF.h @@ -35,7 +35,7 @@ public: , _machine(llvm::ELF::EM_386) , _baseAddress(0x400000) , _pageSize(0x1000) - {} + , _entryPoint("start") {} /// \brief Create a specific instance of an architecture. /// @@ -56,7 +56,8 @@ public: , _pointerWidth(pointerWidth) , _machine(Machine) , _baseAddress(baseAddress) - , _pageSize(pageSize) {} + , _pageSize(pageSize) + , _entryPoint("start") {} bool is64Bit() const { return _is64Bit; } llvm::support::endianness endianness() const { return _endianness; } @@ -65,6 +66,7 @@ public: uint16_t pointerWidth() const { return _pointerWidth; } uint64_t baseAddress() const { return _baseAddress; } uint64_t pageSize() const { return _pageSize; } + void setEntryPoint(StringRef name) { _entryPoint = name; } /// \brief Get the entry point if type() is ET_EXEC. Empty otherwise. StringRef entryPoint() const; @@ -77,6 +79,7 @@ protected: uint16_t _machine; uint64_t _baseAddress; uint64_t _pageSize; + StringRef _entryPoint; }; /// \brief Create a WriterELF using the given options. diff --git a/lld/lib/ReaderWriter/ELF/ReaderELF.cpp b/lld/lib/ReaderWriter/ELF/ReaderELF.cpp index ad0227fa6cd..35a4d81a07c 100644 --- a/lld/lib/ReaderWriter/ELF/ReaderELF.cpp +++ b/lld/lib/ReaderWriter/ELF/ReaderELF.cpp @@ -294,11 +294,14 @@ public: ContentType ret = typeUnknown; - switch (_section->sh_type) { case llvm::ELF::SHT_PROGBITS: case llvm::ELF::SHT_DYNAMIC: switch (_section->sh_flags) { + case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR + | llvm::ELF::SHF_WRITE): + ret = typeCode; + break; case (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR): ret = typeCode; break; diff --git a/lld/lib/ReaderWriter/ELF/WriterELF.cpp b/lld/lib/ReaderWriter/ELF/WriterELF.cpp index 2c4d384cd5d..4282732e0f4 100644 --- a/lld/lib/ReaderWriter/ELF/WriterELF.cpp +++ b/lld/lib/ReaderWriter/ELF/WriterELF.cpp @@ -88,6 +88,9 @@ enum { template<support::endianness target_endianness, bool is64Bits> class ELFWriter; +template<support::endianness target_endianness, bool is64Bits> +class StockSectionChunk; + /// \brief A Chunk is a contiguous range of space. template<support::endianness target_endianness, bool is64Bits> class Chunk { @@ -188,7 +191,7 @@ public: uint64_t flags , uint64_t link, uint64_t info , uint64_t type, uint64_t entsz, const WriterOptionsELF &op, ELFWriter<target_endianness, is64Bits> &writer); - + static inline bool classof(const Chunk<target_endianness, is64Bits> *c) { return c->getChunkKind() == Chunk<target_endianness, is64Bits>::Kind ::Section; @@ -215,6 +218,24 @@ bool IsBss(const Chunk<target_endianness, is64Bits> *A) { return false; } +/// \brief Return pointer to a defined atom whose name is specified as parameter +/// if present in the specified section. +/// When all the atoms are resolved, get addresses and offsets, we +/// have atoms with unique names. Only then this routine is guaranteed +/// to return the atom of interest. This routine is useful in finding atoms +/// which are special such as entry point to a file +template<support::endianness target_endianness, bool is64Bits> +static const DefinedAtom* findDefinedAtomByName(StringRef name, + StockSectionChunk<target_endianness, + is64Bits> *sec) { + ArrayRef<AtomInfo> atoms = sec->atoms(); + for (auto ai = atoms.begin(); ai != atoms.end(); ai++) { + if ((std::get<0>(*ai))->name() == name ) + return std::get<0>(*ai); + } + return nullptr; +} + /// \brief A StockSectionChunk is a section created by linker with all /// attributes concluded from the defined atom contained within. template<support::endianness target_endianness, bool is64Bits> @@ -266,7 +287,6 @@ public: return c->getChunkKind() == Chunk<target_endianness, is64Bits>::Kind ::Header; } - private: Elf_Ehdr _eh; }; @@ -740,9 +760,6 @@ void ELFSymbolTableChunk<target_endianness, is64Bits> symbol->st_shndx = ELF::SHN_COMMON; } break; - case DefinedAtom::typeFirstInSection: - t = ELF::STT_SECTION; - break; // TODO:: How to find STT_FILE symbols? default: t = ELF::STT_NOTYPE; @@ -847,7 +864,7 @@ ELFHeaderChunk<target_endianness, is64Bits> e_phoff(0); e_shoff(0ULL); - e_flags(0); + e_flags(2); e_ehsize(this->_size); e_phentsize(0); e_phnum(0); @@ -1190,6 +1207,12 @@ void ELFWriter<target_endianness, is64Bits>::build(const lld::File &file){ ehc->e_phnum(_phdr->computeNumber()); ehc->e_phoff(_phdr->fileOffset()); ehc->e_phentsize(sizeof(Elf_Phdr)); + for (auto i : _stockSectionChunks) { + if(const DefinedAtom* da = findDefinedAtomByName(_options.entryPoint(), i)) { + ehc->e_entry(this->addressOfAtom(da)); + return; + } + } } template<support::endianness target_endianness, bool is64Bits> @@ -1237,7 +1260,11 @@ void ELFWriter<target_endianness, is64Bits> //TODO: implement .hash section + DEBUG_WITH_TYPE("WriterELF-layout", dbgs() + << "Atoms in file" << file.path()<<":\n"); for (const DefinedAtom *a : file.defined() ) { + DEBUG_WITH_TYPE("WriterELF-layout", dbgs() + << a->name() << " type: " << a->contentType() <<"\n"); StringRef sectionName = a->customSectionName(); if (a->sectionChoice() == DefinedAtom::SectionChoice::sectionBasedOnContent) { @@ -1302,19 +1329,17 @@ void ELFWriter<target_endianness, is64Bits> return A->ordinal() < B->ordinal();})); // Populate symbol table with correct st_shndx member. - if (_options.type() == ELF::ET_REL) { - for (auto chnk : _sectionChunks ) { - Elf_Sym *sym = new (_chunkAllocate.Allocate<Elf_Sym>()) Elf_Sym; - sym->st_name = 0; - sym->st_value = 0; - sym->st_size = 0; - sym->st_other = ELF::STV_DEFAULT; - // first two chunks are not sections hence we subtract 2 but there is a - // NULL section in section table so add 1 - sym->st_shndx = chnk->ordinal() - 1 ; - sym->setBindingAndType(ELF::STB_LOCAL, ELF::STT_SECTION); - _symtable->addSymbol(sym); - } + for (auto chnk : _sectionChunks ) { + Elf_Sym *sym = new (_chunkAllocate.Allocate<Elf_Sym>()) Elf_Sym; + sym->st_name = 0; + sym->st_value = 0; + sym->st_size = 0; + sym->st_other = ELF::STV_DEFAULT; + // first two chunks are not sections hence we subtract 2 but there is a + // NULL section in section table so add 1 + sym->st_shndx = chnk->ordinal() - 1 ; + sym->setBindingAndType(ELF::STB_LOCAL, ELF::STT_SECTION); + _symtable->addSymbol(sym); } for (const auto ssc : _stockSectionChunks){ for (const auto da : ssc->atoms()) { diff --git a/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp b/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp index 1a7d84484e0..4d832aed05e 100644 --- a/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp +++ b/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp @@ -21,7 +21,7 @@ namespace lld { StringRef WriterOptionsELF::entryPoint() const { if (_type == llvm::ELF::ET_EXEC) - return "start"; + return _entryPoint; return StringRef(); } diff --git a/lld/test/elf/Inputs/phdr.i386 b/lld/test/elf/Inputs/phdr.i386 Binary files differnew file mode 100644 index 00000000000..7c83dd31489 --- /dev/null +++ b/lld/test/elf/Inputs/phdr.i386 diff --git a/lld/test/elf/phdr.objtxt b/lld/test/elf/phdr.objtxt new file mode 100644 index 00000000000..d1633017f99 --- /dev/null +++ b/lld/test/elf/phdr.objtxt @@ -0,0 +1,17 @@ +RUN: lld-core -reader ELF -writer ELF -o %t1 %p/Inputs/phdr.i386 | elf-dump %t1 | FileCheck -check-prefix=ED %s + +ED: # Program Header 0 +ED: 'p_flags', 0x00000005 +ED: 'p_filesz', 0x0000002a +ED: # Program Header 1 +ED: 'p_flags', 0x00000004 +ED: 'p_vaddr', 0x004010e0 +ED: 'p_memsz', 0x00000078 +ED: # Program Header 2 +ED: 'p_flags', 0x00000006 +ED: 'p_vaddr', 0x00402158 +ED: 'p_memsz', 0x000000ac +ED: # Program Header 3 +ED: 'p_flags', 0x00000006 +ED: 'p_vaddr', 0x00404000 +ED: 'p_memsz', 0x00000005 diff --git a/lld/test/elf/sections.objtxt b/lld/test/elf/sections.objtxt index 6b499e1be4b..3909cf9a2c0 100644 --- a/lld/test/elf/sections.objtxt +++ b/lld/test/elf/sections.objtxt @@ -10,7 +10,7 @@ OBJDUMP: 4 .anotherspecial 000000004 00000000000401088 DATA OBJDUMP: 5 .bss 000000001 0000000000040108c BSS OBJDUMP: 6 .shstrtab 000000045 0000000000040108d OBJDUMP: 7 .strtab 00000003b 000000000004010d2 -OBJDUMP: 8 .symtab 0000000c0 00000000000401110 +OBJDUMP: 8 .symtab 000000140 00000000000401110 READOBJ: File Format : ELF32-i386 READOBJ: Arch : i386 |

