llvm.org GIT mirror llvm / 24973c1
Basic runtime dynamic loading capabilities added to ELFObjectFile, implemented in a subclass named DyldELFObject. This class supports rebasing the object file it represents by re-mapping section addresses to the actual memory addresses the object was placed in. This is required for MC-JIT implementation on ELF with debugging support. Patch reviewed on llvm-commits. Developed together with Ashok Thirumurthi and Andrew Kaylor. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148653 91177308-0d34-0410-b5e6-96231b3b80d8 Eli Bendersky 8 years ago
3 changed file(s) with 255 addition(s) and 21 deletion(s). Raw diff Collapse all Expand all
1919 #include "llvm/Support/ErrorHandling.h"
2020 #include "llvm/Support/MemoryBuffer.h"
2121 #include
22 #include
2223
2324 namespace llvm {
2425 namespace object {
336337
337338 public:
338339 static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object);
339 static ObjectFile *createELFObjectFile(MemoryBuffer *Object);
340 static ObjectFile *createELFObjectFile(MemoryBuffer *Object,
341 bool doDyld = false, std::vector *MemoryMap = 0);
340342 static ObjectFile *createMachOObjectFile(MemoryBuffer *Object);
341343 };
342344
9797 operator value_type() const {
9898 return endian::read_le(Value);
9999 }
100 void operator=(value_type newValue) {
101 endian::write_le((void *)&Value, newValue);
102 }
100103 private:
101104 uint8_t Value[sizeof(value_type)];
102105 };
107110 operator value_type() const {
108111 return endian::read_be(Value);
109112 }
113 void operator=(value_type newValue) {
114 endian::write_be((void *)&Value, newValue);
115 }
110116 private:
111117 uint8_t Value[sizeof(value_type)];
112118 };
117123 operator value_type() const {
118124 return endian::read_le(&Value);
119125 }
126 void operator=(value_type newValue) {
127 endian::write_le((void *)&Value, newValue);
128 }
120129 private:
121130 value_type Value;
122131 };
126135 public:
127136 operator value_type() const {
128137 return endian::read_be(&Value);
138 }
139 void operator=(value_type newValue) {
140 endian::write_be((void *)&Value, newValue);
129141 }
130142 private:
131143 value_type Value;
66 //
77 //===----------------------------------------------------------------------===//
88 //
9 // This file defines the ELFObjectFile class.
9 // This file defines the ELFObjectFile and DyldELFObject classes.
1010 //
1111 //===----------------------------------------------------------------------===//
1212
1515 #include "llvm/ADT/Triple.h"
1616 #include "llvm/ADT/DenseMap.h"
1717 #include "llvm/Object/ObjectFile.h"
18 #include "llvm/Support/Casting.h"
1819 #include "llvm/Support/ELF.h"
1920 #include "llvm/Support/Endian.h"
2021 #include "llvm/Support/ErrorHandling.h"
5253 template
5354 struct ELFDataTypeTypedefHelper
5455 : ELFDataTypeTypedefHelperCommon {
56 typedef uint32_t value_type;
5557 typedef support::detail::packed_endian_specific_integral
56 <uint32_t, target_endianness, support::aligned> Elf_Addr;
58 <value_type, target_endianness, support::aligned> Elf_Addr;
5759 typedef support::detail::packed_endian_specific_integral
58 <uint32_t, target_endianness, support::aligned> Elf_Off;
60 <value_type, target_endianness, support::aligned> Elf_Off;
5961 };
6062
6163 /// ELF 64bit types.
6264 template
6365 struct ELFDataTypeTypedefHelper
6466 : ELFDataTypeTypedefHelperCommon{
67 typedef uint64_t value_type;
6568 typedef support::detail::packed_endian_specific_integral
66 <uint64_t, target_endianness, support::aligned> Elf_Addr;
69 <value_type, target_endianness, support::aligned> Elf_Addr;
6770 typedef support::detail::packed_endian_specific_integral
68 <uint64_t, target_endianness, support::aligned> Elf_Off;
71 <value_type, target_endianness, support::aligned> Elf_Off;
6972 };
7073 }
7174
262265 typedef Elf_Rel_Impl Elf_Rel;
263266 typedef Elf_Rel_Impl Elf_Rela;
264267
268 protected:
265269 struct Elf_Ehdr {
266270 unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
267271 Elf_Half e_type; // Type of file (see ET_*)
284288 unsigned char getFileClass() const { return e_ident[ELF::EI_CLASS]; }
285289 unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
286290 };
287
291 // This flag is used for classof, to distinguish ELFObjectFile from
292 // its subclass. If more subclasses will be created, this flag will
293 // have to become an enum.
294 bool isDyldELFObject;
295
296 private:
288297 typedef SmallVector Sections_t;
289298 typedef DenseMap IndexMap_t;
290299 typedef DenseMap > RelocMap_t;
306315 return getSection(Rel.w.b);
307316 }
308317
309 void validateSymbol(DataRefImpl Symb) const;
310318 bool isRelocationHasAddend(DataRefImpl Rel) const;
311319 template
312320 const T *getEntry(uint16_t Section, uint32_t Entry) const;
313321 template
314322 const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const;
315 const Elf_Sym *getSymbol(DataRefImpl Symb) const;
316323 const Elf_Shdr *getSection(DataRefImpl index) const;
317324 const Elf_Shdr *getSection(uint32_t index) const;
318325 const Elf_Rel *getRel(DataRefImpl Rel) const;
320327 const char *getString(uint32_t section, uint32_t offset) const;
321328 const char *getString(const Elf_Shdr *section, uint32_t offset) const;
322329 error_code getSymbolName(const Elf_Sym *Symb, StringRef &Res) const;
330
331 protected:
332 const Elf_Sym *getSymbol(DataRefImpl Symb) const; // FIXME: Should be private?
333 void validateSymbol(DataRefImpl Symb) const;
323334
324335 protected:
325336 virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
383394 ELF::Elf64_Word getSymbolTableIndex(const Elf_Sym *symb) const;
384395 const Elf_Shdr *getSection(const Elf_Sym *symb) const;
385396
397 // Methods for type inquiry through isa, cast, and dyn_cast
398 bool isDyldType() const { return isDyldELFObject; }
386399 static inline bool classof(const Binary *v) {
387 return v->getType() == isELF;
400 return v->getType() == Binary::isELF;
388401 }
389402 static inline bool classof(const ELFObjectFile *v) { return true; }
390403 };
470483 const Elf_Shdr *Section;
471484 switch (getSymbolTableIndex(symb)) {
472485 case ELF::SHN_COMMON:
473 // Undefined symbols have no address yet.
486 // Unintialized symbols have no offset in the object file
474487 case ELF::SHN_UNDEF:
475488 Result = UnknownAddressOrSize;
476489 return object_error::success;
488501 case ELF::STT_OBJECT:
489502 case ELF::STT_NOTYPE:
490503 Result = symb->st_value +
491 (Section ? Section->sh_offset - Section->sh_addr : 0);
504 (Section ? Section->sh_offset : 0);
492505 return object_error::success;
493506 default:
494507 Result = UnknownAddressOrSize;
505518 const Elf_Shdr *Section;
506519 switch (getSymbolTableIndex(symb)) {
507520 case ELF::SHN_COMMON:
508 // Undefined symbols have no address yet.
509521 case ELF::SHN_UNDEF:
510522 Result = UnknownAddressOrSize;
511523 return object_error::success;
522534 case ELF::STT_FUNC:
523535 case ELF::STT_OBJECT:
524536 case ELF::STT_NOTYPE:
525 Result = symb->st_value;
537 Result = symb->st_value + (Section ? Section->sh_addr : 0);
526538 return object_error::success;
527539 default:
528540 Result = UnknownAddressOrSize;
11561168 ELFObjectFile::ELFObjectFile(MemoryBuffer *Object
11571169 , error_code &ec)
11581170 : ObjectFile(Binary::isELF, Object, ec)
1171 , isDyldELFObject(false)
11591172 , SectionHeaderTable(0)
11601173 , dot_shstrtab_sec(0)
11611174 , dot_strtab_sec(0) {
11671180 SectionHeaderTable =
11681181 reinterpret_cast(base() + Header->e_shoff);
11691182 uint64_t SectionTableSize = getNumSections() * Header->e_shentsize;
1170 if (!( (const uint8_t *)SectionHeaderTable + SectionTableSize
1171 <= base() + Data->getBufferSize()))
1183
1184 if ((const uint8_t *)SectionHeaderTable + SectionTableSize
1185 > base() + Data->getBufferSize()) {
11721186 // FIXME: Proper error handling.
11731187 report_fatal_error("Section table goes past end of file!");
1188 }
11741189
11751190
11761191 // To find the symbol tables we walk the section table to find SHT_SYMTAB.
14651480 , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]);
14661481 }
14671482
1483
1484 namespace {
1485 template
1486 class DyldELFObject : public ELFObjectFile {
1487 LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
1488
1489 typedef Elf_Shdr_Impl Elf_Shdr;
1490 typedef Elf_Sym_Impl Elf_Sym;
1491 typedef Elf_Rel_Impl Elf_Rel;
1492 typedef Elf_Rel_Impl Elf_Rela;
1493
1494 typedef typename ELFObjectFile::
1495 Elf_Ehdr Elf_Ehdr;
1496 Elf_Ehdr *Header;
1497
1498 // Update section headers according to the current location in memory
1499 virtual void rebaseObject(std::vector *MemoryMap);
1500 // Record memory addresses for cleanup
1501 virtual void saveAddress(std::vector *MemoryMap, uint8_t *addr);
1502
1503 protected:
1504 virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
1505
1506 public:
1507 DyldELFObject(MemoryBuffer *Object, std::vector *MemoryMap,
1508 error_code &ec);
1509
1510 // Methods for type inquiry through isa, cast, and dyn_cast
1511 static inline bool classof(const Binary *v) {
1512 return (isa >(v)
1513 && classof(cast >(v)));
1514 }
1515 static inline bool classof(
1516 const ELFObjectFile *v) {
1517 return v->isDyldType();
1518 }
1519 static inline bool classof(const DyldELFObject *v) {
1520 return true;
1521 }
1522 };
1523 } // end anonymous namespace
1524
1525 template
1526 DyldELFObject::DyldELFObject(MemoryBuffer *Object,
1527 std::vector *MemoryMap, error_code &ec)
1528 : ELFObjectFile(Object, ec)
1529 , Header(0) {
1530 this->isDyldELFObject = true;
1531 Header = const_cast(
1532 reinterpret_cast(this->base()));
1533 if (Header->e_shoff == 0)
1534 return;
1535
1536 // Mark the image as a dynamic shared library
1537 Header->e_type = ELF::ET_DYN;
1538
1539 rebaseObject(MemoryMap);
1540 }
1541
1542 // Walk through the ELF headers, updating virtual addresses to reflect where
1543 // the object is currently loaded in memory
1544 template
1545 void DyldELFObject::rebaseObject(
1546 std::vector *MemoryMap) {
1547 typedef typename ELFDataTypeTypedefHelper<
1548 target_endianness, is64Bits>::value_type addr_type;
1549
1550 uint8_t *base_p = const_cast(this->base());
1551 Elf_Shdr *sectionTable =
1552 reinterpret_cast(base_p + Header->e_shoff);
1553 uint64_t numSections = this->getNumSections();
1554
1555 // Allocate memory space for NOBITS sections (such as .bss), which only exist
1556 // in memory, but don't occupy space in the object file.
1557 // Update the address in the section headers to reflect this allocation.
1558 for (uint64_t index = 0; index < numSections; index++) {
1559 Elf_Shdr *sec = reinterpret_cast(
1560 reinterpret_cast(sectionTable) + index * Header->e_shentsize);
1561
1562 // Only update sections that are meant to be present in program memory
1563 if (sec->sh_flags & ELF::SHF_ALLOC) {
1564 uint8_t *addr = base_p + sec->sh_offset;
1565 if (sec->sh_type == ELF::SHT_NOBITS) {
1566 addr = static_cast(calloc(sec->sh_size, 1));
1567 saveAddress(MemoryMap, addr);
1568 }
1569 else {
1570 // FIXME: Currently memory with RWX permissions is allocated. In the
1571 // future, make sure that permissions are as necessary
1572 if (sec->sh_flags & ELF::SHF_WRITE) {
1573 // see FIXME above
1574 }
1575 if (sec->sh_flags & ELF::SHF_EXECINSTR) {
1576 // see FIXME above
1577 }
1578 }
1579 assert(sizeof(addr_type) == sizeof(intptr_t) &&
1580 "Cross-architecture ELF dy-load is not supported!");
1581 sec->sh_addr = static_cast(intptr_t(addr));
1582 }
1583 }
1584
1585 // Now allocate actual space for COMMON symbols, which also don't occupy
1586 // space in the object file.
1587 // We want to allocate space for all COMMON symbols at once, so the flow is:
1588 // 1. Go over all symbols, find those that are in COMMON. For each such
1589 // symbol, record its size and the value field in its symbol header in a
1590 // special vector.
1591 // 2. Allocate memory for all COMMON symbols in one fell swoop.
1592 // 3. Using the recorded information from (1), update the address fields in
1593 // the symbol headers of the COMMON symbols to reflect their allocated
1594 // address.
1595 uint64_t TotalSize = 0;
1596 std::vector > SymbAddrInfo;
1597 error_code ec = object_error::success;
1598 for (symbol_iterator si = this->begin_symbols(),
1599 se = this->end_symbols(); si != se; si.increment(ec)) {
1600 uint64_t Size = 0;
1601 ec = si->getSize(Size);
1602 Elf_Sym* symb = const_cast(
1603 this->getSymbol(si->getRawDataRefImpl()));
1604 if (ec == object_error::success &&
1605 this->getSymbolTableIndex(symb) == ELF::SHN_COMMON && Size > 0) {
1606 SymbAddrInfo.push_back(std::make_pair(&(symb->st_value), Size));
1607 TotalSize += Size;
1608 }
1609 }
1610
1611 uint8_t* SectionPtr = (uint8_t *)calloc(TotalSize, 1);
1612 saveAddress(MemoryMap, SectionPtr);
1613
1614 typedef typename std::vector >::iterator
1615 AddrInfoIterator;
1616 AddrInfoIterator EndIter = SymbAddrInfo.end();
1617 for (AddrInfoIterator AddrIter = SymbAddrInfo.begin();
1618 AddrIter != EndIter; ++AddrIter) {
1619 assert(sizeof(addr_type) == sizeof(intptr_t) &&
1620 "Cross-architecture ELF dy-load is not supported!");
1621 *(AddrIter->first) = static_cast(intptr_t(SectionPtr));
1622 SectionPtr += AddrIter->second;
1623 }
1624 }
1625
1626 // Record memory addresses for callers
1627 template
1628 void DyldELFObject::saveAddress(
1629 std::vector *MemoryMap, uint8_t* addr) {
1630 if (MemoryMap)
1631 MemoryMap->push_back(addr);
1632 else
1633 errs() << "WARNING: Memory leak - cannot record memory for ELF dyld.";
1634 }
1635
1636 template
1637 error_code DyldELFObject::getSymbolAddress(
1638 DataRefImpl Symb, uint64_t &Result) const {
1639 this->validateSymbol(Symb);
1640 const Elf_Sym *symb = this->getSymbol(Symb);
1641 if (this->getSymbolTableIndex(symb) == ELF::SHN_COMMON) {
1642 Result = symb->st_value;
1643 return object_error::success;
1644 }
1645 else {
1646 return ELFObjectFile::getSymbolAddress(
1647 Symb, Result);
1648 }
1649 }
1650
14681651 namespace llvm {
14691652
1470 ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) {
1653 // Creates an in-memory object-file by default: createELFObjectFile(Buffer)
1654 // Set doDyld to true to create a live (executable/debug-worthy) image
1655 // If doDyld is true, any memory allocated for non-resident sections and
1656 // symbols is recorded in MemoryMap.
1657 ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object,
1658 bool doDyld, std::vector *MemoryMap) {
14711659 std::pair Ident = getElfArchType(Object);
14721660 error_code ec;
1661
1662 if (doDyld) {
1663 if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
1664 return new DyldELFObject(Object, MemoryMap, ec);
1665 else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
1666 return new DyldELFObject(Object, MemoryMap, ec);
1667 else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
1668 return new DyldELFObject(Object, MemoryMap, ec);
1669 else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
1670 DyldELFObject *result =
1671 new DyldELFObject(Object, MemoryMap, ec);
1672
1673 // Unit testing for type inquiry
1674 bool isBinary = isa(result);
1675 bool isDyld = isa >(result);
1676 bool isFile = isa >(result);
1677 assert(isBinary && isDyld && isFile &&
1678 "Type inquiry failed for ELF object!");
1679 return result;
1680 }
1681 }
1682
14731683 if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
14741684 return new ELFObjectFile(Object, ec);
14751685 else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
14761686 return new ELFObjectFile(Object, ec);
1477 else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB)
1478 return new ELFObjectFile(Object, ec);
14791687 else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
14801688 return new ELFObjectFile(Object, ec);
1481 // FIXME: Proper error handling.
1482 report_fatal_error("Not an ELF object file!");
1689 else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
1690 ELFObjectFile *result =
1691 new ELFObjectFile(Object, ec);
1692
1693 // Unit testing for type inquiry
1694 bool isBinary = isa(result);
1695 bool isDyld = isa >(result);
1696 bool isFile = isa >(result);
1697 assert(isBinary && isFile && !isDyld &&
1698 "Type inquiry failed for ELF object!");
1699 return result;
1700 }
1701
1702 report_fatal_error("Buffer is not an ELF object file!");
14831703 }
14841704
14851705 } // end namespace llvm