summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHemant Kulkarni <khemant@codeaurora.org>2012-11-21 21:07:36 +0000
committerHemant Kulkarni <khemant@codeaurora.org>2012-11-21 21:07:36 +0000
commit736f7fbee236c3c0aa4722ebdde5ff5dc5868bf2 (patch)
tree0dd718a477b9c61deab2d2138e5d12ca0293dd05
parentbb6e74a2f17c0b5ab66749343f48103ea03da968 (diff)
downloadbcm5719-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.h7
-rw-r--r--lld/lib/ReaderWriter/ELF/ReaderELF.cpp5
-rw-r--r--lld/lib/ReaderWriter/ELF/WriterELF.cpp63
-rw-r--r--lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp2
-rw-r--r--lld/test/elf/Inputs/phdr.i386bin0 -> 17536 bytes
-rw-r--r--lld/test/elf/phdr.objtxt17
-rw-r--r--lld/test/elf/sections.objtxt2
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
new file mode 100644
index 00000000000..7c83dd31489
--- /dev/null
+++ b/lld/test/elf/Inputs/phdr.i386
Binary files differ
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
OpenPOWER on IntegriCloud