[llvm-commits] LLD patch - symbol table and reorganization of sections

Hemant Kulkarni khemant at codeaurora.org
Mon Oct 1 12:33:04 PDT 2012


The patch does only two things. 
1. It emits symbol table.
2. To emit them and to code it without making other functions enormous, I
made all sections to be derived from one single chunk. 

You want to split them that way? This is reorganization for easy
maintainability and hence it touches lot of code.

--
Hemant Kulkarni
khemant at codeaurora.org
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by
the Linux Foundation


-----Original Message-----
From: Sean Silva [mailto:silvas at purdue.edu] 
Sent: Monday, October 01, 2012 1:35 PM
To: Hemant Kulkarni
Cc: Michael Spencer; llvm-commits at cs.uiuc.edu
Subject: Re: [llvm-commits] LLD patch - symbol table and reorganization of
sections

This patch does a lot of things. Could you split it up into logically
separate changes?

--Sean Silva

On Mon, Oct 1, 2012 at 1:28 PM, Hemant Kulkarni <khemant at codeaurora.org>
wrote:
> Please ignore my previous mail, I posted old patch again. Here is the new
patch. Sorry.
>
> --
> Hemant Kulkarni
> khemant at codeaurora.org
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
> hosted by the Linux Foundation
>
>
> -----Original Message-----
> From: Hemant Kulkarni [mailto:khemant at codeaurora.org]
> Sent: Monday, October 01, 2012 12:26 PM
> To: 'Michael Spencer'
> Cc: 'llvm-commits at cs.uiuc.edu'; 'kledzik at apple.com';
'sidneym at codeaurora.org'
> Subject: RE: LLD patch - symbol table and reorganization of sections
>
> Here is a revised patch as per comments.
>
>
> --
> Hemant Kulkarni
> khemant at codeaurora.org
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
> hosted by the Linux Foundation
>
> -----Original Message-----
> From: Michael Spencer [mailto:bigcheesegs at gmail.com]
> Sent: Friday, September 28, 2012 4:41 PM
> To: Hemant Kulkarni
> Cc: llvm-commits at cs.uiuc.edu; kledzik at apple.com; 
> sidneym at codeaurora.org
> Subject: Re: LLD patch - symbol table and reorganization of sections
>
> On Fri, Sep 28, 2012 at 12:00 PM, Hemant Kulkarni <khemant at codeaurora.org>
wrote:
>> Purpose of patch:
>>
>> Add symbol table to writer to emit symbols.
>>
>> Make all sections - ones made due to atoms and ones made by linker at 
>> output time to be derived from one class. Have this class all the 
>> attributes needed to make a section header. Use this class to build 
>> section table header and set all offsets/addresses.
>>
>>
>>
>> Added test for the same. The test needed to be changed to reflect 
>> correct order sections are now emitted; hence you might see change in 
>> existing test too.
>>
>> Please review the patch and send in comments.
>>
>>
>>
>> --
>>
>> Hemant Kulkarni
>>
>> khemant at codeaurora.org
>>
>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, 
>> hosted by the Linux Foundation
>>
>>
>
>> Index: lib/ReaderWriter/ELF/WriterELF.cpp
>> ===================================================================
>> --- lib/ReaderWriter/ELF/WriterELF.cpp        (revision 164787)
>> +++ lib/ReaderWriter/ELF/WriterELF.cpp        (working copy)
>> @@ -35,6 +35,7 @@
>>  #include "llvm/Support/raw_ostream.h"
>>  #include "llvm/Support/system_error.h"
>>
>> +
>>  #include <map>
>>  #include <tuple>
>>  #include <vector>
>> @@ -42,11 +43,14 @@
>>  using namespace llvm;
>>  using namespace llvm::object;
>>  namespace lld {
>> +
>>  namespace elf {
>>
>>  template<support::endianness target_endianness, bool is64Bits>  
>> class ELFWriter;
>>
>> +
>> +
>>  /// \brief A Chunk is a contiguous range of space.
>>  template<support::endianness target_endianness, bool is64Bits>  
>> class Chunk { @@ -63,6 +67,8 @@
>>    uint64_t            fileOffset() const;
>>    uint64_t            align2() const;
>>    static uint64_t     alignTo(uint64_t value, uint8_t align2);
>> +  uint64_t            ordinal() const { return _ordinal;}
>> +  void                setOrdinal(uint64_t newVal) { _ordinal = newVal;}
>>
>>  protected:
>>    Chunk();
>> @@ -71,43 +77,80 @@
>>    uint64_t _address;
>>    uint64_t _fileOffset;
>>    uint64_t _align2;
>> +  uint64_t _ordinal;
>>  };
>>
>> +
>> +template<support::endianness target_endianness, bool is64Bits> 
>> +static void swapChunks(uint64_t one, uint64_t two,
>> +                      std::vector<Chunk<target_endianness, is64Bits>*>
&vec){
>> +   uint64_t tempOrdinal;
>> +   if (one == two) return;
>> +   tempOrdinal = vec[one]->ordinal();
>> +   vec[one]->setOrdinal(vec[two]->ordinal());
>> +   vec[two]->setOrdinal(tempOrdinal);
>> +}
>
> This doesn't need the vector. It should just take Chunk<target_endianness,
is64Bits> &a, Chunk<target_endianness, is64Bits> &b.
> Also, this doesn't exactly swap the chunks. A more accurate name would be
swapChunkPosition.
>
>> +
>>  /// Pair of atom and offset in section.
>>  typedef std::tuple<const DefinedAtom*, uint64_t> AtomInfo;
>>
>> -/// \brief A Section represents a set of Atoms assigned to a specific
ELF
>> -///        Section.
>> +/// \brief A SectionChunk represents ELF sections
>>  template<support::endianness target_endianness, bool is64Bits>  
>> class SectionChunk : public Chunk<target_endianness, is64Bits> {
>>  public:
>> -  SectionChunk(DefinedAtom::ContentType,
>> -               StringRef sectionName,
>> -               const WriterOptionsELF &options,
>> -               ELFWriter<target_endianness, is64Bits> &writer);
>>
>> -  virtual StringRef        segmentName() const;
>> -  virtual bool             occupiesNoDiskSpace();
>> -  virtual void             write(uint8_t *fileBuffer);
>> -  virtual const char      *info();
>> -  StringRef                sectionName();
>> -  uint32_t                 flags() const;
>> -  uint32_t                 type() const;
>> -  uint32_t                 permissions();
>> -  void                     appendAtom(const DefinedAtom*);
>> -  const ArrayRef<AtomInfo> atoms() const;
>> +  virtual StringRef   segmentName() const { return _segmentName; }
>> +  virtual bool        occupiesNoDiskSpace();
>> +  virtual const char  *info();
>> +  StringRef           sectionName() { return _sectionName; }
>> +  uint64_t            shStrtableOffset(){ return _offsetInStringTable; }
>> +  void                setShStrtableOffset (uint64_t val)
>> +                      { _offsetInStringTable = val; }
>> +  uint32_t            flags()  { return _flags; }
>> +  uint32_t            type()   { return _type; }
>> +  uint64_t            link()   { return _link; }
>> +  void                link(uint64_t val)   { _link = val; }
>> +  uint16_t            shinfo() { return _shinfo; }
>> +  bool                isLoadable() { return _isLoadable; }
>> +  void                isLoadable(uint64_t val) {  _isLoadable = val; }
>> +  uint64_t            entsize() { return _entsize; }
>> +  SectionChunk(StringRef secName, StringRef segName, bool loadable,
>> +               uint64_t flags , uint64_t link,  uint64_t info ,
>> +               uint64_t type, uint64_t entsz, const WriterOptionsELF
&op,
>> +              ELFWriter<target_endianness, is64Bits> &writer);
>>
>> -private:
>> +protected:
>> +  bool                                    _isLoadable;
>> +  uint64_t                                _link;
>> +  uint64_t                                _shinfo;
>> +  uint16_t                                _entsize;
>>    StringRef                               _segmentName;
>>    StringRef                               _sectionName;
>>    const WriterOptionsELF                 &_options;
>>    ELFWriter<target_endianness, is64Bits> &_writer;
>> -  uint32_t                                _flags;
>> -  uint32_t                                _type;
>> -  uint32_t                                _permissions;
>> +  uint64_t                                _flags;
>> +  uint64_t                                _type;
>> +  uint64_t                                _offsetInStringTable;
>> +};
>> +
>> +
>> +/// \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> class 
>> +StockSectionChunk : public SectionChunk<target_endianness, is64Bits> 
>> +{
>> +public:
>> +  virtual StringRef   segmentName() { return this->_segmentName; }
>> +  void                appendAtom(const DefinedAtom*);
>> +  virtual void        write(uint8_t *filebuffer);
>> +  const               ArrayRef<AtomInfo> atoms() const;
>> +  StockSectionChunk(StringRef sectionName, bool loadable,
>> +                    DefinedAtom::ContentType type,
>> +                    const WriterOptionsELF &options,
>> +                    ELFWriter<target_endianness, is64Bits> &writer);
>> +private:
>>    std::vector<AtomInfo>                   _atoms;
>>  };
>> -
>> +
>>  /// \brief An ELFHeaderChunk represents the Elf[32/64]_Ehdr structure at
the
>>  ///        start of an ELF executable file.
>>  template<support::endianness target_endianness, bool is64Bits> @@
>> -134,7 +177,7 @@
>>    void e_shnum(uint16_t shnum)         { _eh.e_shnum = shnum; }
>>    void e_shstrndx(uint16_t shstrndx)   { _eh.e_shstrndx = shstrndx; }
>>
>> -  uint64_t  size() { return sizeof (Elf_Ehdr); }
>> +  uint64_t  size()                     { return sizeof (Elf_Ehdr); }
>>
>>    virtual StringRef   segmentName() const;
>>    virtual void        write(uint8_t *fileBuffer);
>> @@ -158,6 +201,8 @@
>>    ELFSectionHeaderChunk(const WriterOptionsELF &Options,
>>                          ELFWriter<target_endianness, is64Bits>&);
>>
>> +  void createHeaders();
>> +
>>    virtual StringRef   segmentName() const;
>>    virtual void        write(uint8_t *filebuffer);
>>    virtual const char *info();
>> @@ -169,7 +214,6 @@
>>      return _sectionInfo;
>>    }
>>
>> -  bool is64Bit() { return _options.is64Bit(); }
>>
>>  private:
>>    const WriterOptionsELF                 &_options;
>> @@ -184,32 +228,50 @@
>>  /// null character. We might need more than one such chunks shstrtab 
>> for setting  /// e_shstrndx in ELHHeaderChunk and strtab for use with 
>> symtab  template<support::endianness target_endianness, bool 
>> is64Bits> -class ELFStringSectionChunk : public 
>> Chunk<target_endianness,
>> is64Bits> {
>> +class ELFStringSectionChunk : public SectionChunk<target_endianness,
>> +is64Bits> {
>>  public:
>> -  LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
>>    ELFStringSectionChunk(const WriterOptionsELF &Options,
>>                          ELFWriter<target_endianness, is64Bits> &writer,
>>                          StringRef secName);
>> +  virtual StringRef   segmentName() const { return this->_segmentName; }
>> +  uint64_t            addString(StringRef symName);
>> +  const char          *info();
>> +  virtual void        write(uint8_t *filebuffer);
>>
>> -  uint64_t addString(StringRef symName);
>> +private:
>> +  std::vector<StringRef> _stringSection; };
>>
>> -  virtual StringRef   segmentName() const;
>> -  virtual void        write(uint8_t *filebuffer);
>> -  virtual const char *info();
>> -  StringRef           sectionName();
>> +//
>> +/// \brief Represents the symtab section /// /// ELFSymbolTableChunk 
>> +represents the Symbol table as per ELF ABI //  This is a table with 
>> +Elf[32/64]_Sym entries in it.
>> +//
>
> Get rid of the extra // and "This is a table..." is missing a /.
>
>> +template<support::endianness target_endianness, bool is64Bits> class 
>> +ELFSymbolTableChunk : public SectionChunk<target_endianness,
>> +is64Bits> {
>> +public:
>> +  typedef object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
>> +  ELFSymbolTableChunk(const WriterOptionsELF &options,
>> +                      ELFWriter<target_endianness, is64Bits> &writer,
>> +                      StringRef secName);
>> +  virtual StringRef   segmentName() const { return this->_segmentName; }
>> +  void                addSymbol(const Atom *a, uint16_t shndx);
>> +  void                addSymbol(Elf_Sym* x)
>> +                      { _symbolTable.push_back(x);
>> +                      this->_size+= sizeof(Elf_Sym) ;}
>
> Fix the indentation here.
>
>> +  const char          *info();
>> +  void                setAttributes();
>>
>> +  virtual void               write(uint8_t *fileBuffer);
>>
>>
>>  private:
>> -  StringRef _segName;
>> -  std::vector<StringRef> _StringSection;
>> -  StringRef _sectionName;
>> -  ELFWriter<target_endianness, is64Bits> &_writer;
>> -  const WriterOptionsELF &_options;
>> -
>> +  std::vector<Elf_Sym*> _symbolTable;  class 
>> + ELFStringSectionChunk<target_endianness, is64Bits> *_stringSection;
>
> Drop class.
>
>> +  llvm::BumpPtrAllocator _symbolAllocate;
>>  };
>>
>> -
>>  /// An ELFProgramHeaderChunk represents the Elf[32/64]_Phdr 
>> structure near  /// the start of an ELF executable file. Will need to 
>> update ELFHeader's  /// e_phentsize/e_phnum when done.
>> @@ -239,6 +301,9 @@
>>  template<support::endianness target_endianness, bool is64Bits> 
>> Chunk<target_endianness, is64Bits>::Chunk()
>>   : _size(0), _address(0), _fileOffset(0), _align2(0) {
>> +// 0 and 1 are reserved. 0 for ELF header and 1 for Sectiontable header.
>
> Comments should be indented to the same level as the code it describes.
>
>> +   static uint64_t orderNumber = 0;
>> +   _ordinal = orderNumber++;
>>  }
>>
>>  template<support::endianness target_endianness, bool is64Bits> @@
>> -308,86 +373,79 @@
>>
>>  template<support::endianness target_endianness, bool is64Bits> 
>> SectionChunk<target_endianness, is64Bits>::
>> -  SectionChunk(DefinedAtom::ContentType type,
>> -               StringRef sectionName,
>> -               const WriterOptionsELF &options,
>> -               ELFWriter<target_endianness, is64Bits> &writer)
>> -  :  _options(options)
>> -  , _writer(writer) {
>> -  switch(type) {
>> -  case DefinedAtom::typeCode:
>> -    _segmentName = "PT_LOAD";
>> -    _sectionName = sectionName;
>> -    _flags       = ELF::SHF_ALLOC | ELF::SHF_EXECINSTR;
>> -    _type        = ELF::SHT_PROGBITS;
>> -    break;
>> -  case DefinedAtom::typeData:
>> -    _segmentName = "PT_LOAD";
>> -    _sectionName = sectionName;
>> -    _flags       = ELF::SHF_ALLOC | ELF::SHF_WRITE;
>> -    _type        = ELF::SHT_PROGBITS;
>> -    break;
>> -  case DefinedAtom::typeZeroFill:
>> -    _segmentName = "PT_LOAD";
>> -    _sectionName = sectionName;
>> -    _flags       = ELF::SHF_ALLOC | ELF::SHF_WRITE;
>> -    _type        = ELF::SHT_NOBITS;
>> -    break;
>> -  case DefinedAtom::typeConstant:
>> -    _segmentName = "PT_LOAD";
>> -    _sectionName = sectionName;
>> -    _flags       = ELF::SHF_ALLOC;
>> -    _type        = ELF::SHT_PROGBITS;
>> -    break;
>> -  default:
>> -    llvm_unreachable("Unhandled content type for section!");
>> -  }
>> -}
>> + SectionChunk(StringRef secName, StringRef segName, bool loadable,
>> +              uint64_t flags , uint64_t link,  uint64_t info , uint64_t
type,
>> +              uint64_t entsz, const WriterOptionsELF &op,
>> +              ELFWriter<target_endianness, is64Bits> &writer)
>> +  : _isLoadable(loadable)
>> +  , _link(link)
>> +  , _shinfo(info)
>> +  , _entsize(entsz)
>> +  , _segmentName(segName)
>> +  , _sectionName(secName)
>> +  , _options(op)
>> +  , _writer(writer)
>> +  , _flags(flags)
>> +  , _type(type)
>> +  , _offsetInStringTable(0) {}
>>
>>  template<support::endianness target_endianness, bool is64Bits>  bool 
>> SectionChunk<target_endianness, is64Bits>::occupiesNoDiskSpace() {
>>    return false;
>>  }
>>
>> -template<support::endianness target_endianness, bool is64Bits> 
>> -StringRef SectionChunk<target_endianness, is64Bits>::segmentName() 
>> const {
>> -  return _segmentName;
>> -}
>>
>>  template<support::endianness target_endianness, bool is64Bits> 
>> -StringRef SectionChunk<target_endianness, is64Bits>::sectionName() {
>> -  return _sectionName;
>> +const char *SectionChunk<target_endianness, is64Bits>::info() {
>> +  return _sectionName.data();
>>  }
>>
>> -template<support::endianness target_endianness, bool is64Bits> 
>> -uint32_t SectionChunk<target_endianness, is64Bits>::flags() const {
>> -  return _flags;
>> -}
>>
>> -template<support::endianness target_endianness, bool is64Bits> 
>> -uint32_t SectionChunk<target_endianness, is64Bits>::type() const {
>> -  return _type;
>> -}
>> +//
>> +//===---------------------------------------------------------------
>> +-
>> +------===//
>> +//  StockSectionChunk
>> +//===---------------------------------------------------------------
>> +-
>> +------===//
>> +//
>>
>>  template<support::endianness target_endianness, bool is64Bits> 
>> -uint32_t SectionChunk<target_endianness, is64Bits>::permissions() {
>> -  return _permissions;
>> +StockSectionChunk<target_endianness, is64Bits>::
>> +  StockSectionChunk(StringRef secName, bool loadable,
>> +                    DefinedAtom::ContentType type,
>> +                    const WriterOptionsELF &options,
>> +                    ELFWriter<target_endianness, is64Bits> &writer)
>> + : SectionChunk<target_endianness, is64Bits>(secName,
StringRef("PT_NULL"),
>> +                                             loadable, 0lu, 0lu, 0u,
0lu, 0lu,
>> +                                             options, writer)
>> +  {
>> +
>> +  this->_segmentName = this->_isLoadable ? "PT_LOAD" : "PT_NULL" ;
>> +  switch(type) {
>> +  case DefinedAtom::typeCode:
>> +    this->_type        = ELF::SHT_PROGBITS;
>> +    break;
>> +  case DefinedAtom::typeData:
>> +    this->_type        = ELF::SHT_PROGBITS;
>> +    break;
>> +  case DefinedAtom::typeZeroFill:
>> +    this->_type        = ELF::SHT_NOBITS;
>> +  case DefinedAtom::typeConstant:
>> +    this->_type         = ELF::SHT_PROGBITS;
>
> One space after this->_type.
>
>> +    break;
>> +  default:
>> +    llvm_unreachable("Unhandled content type for section!");  }
>>  }
>> +
>>
>>  template<support::endianness target_endianness, bool is64Bits> 
>> -const char *SectionChunk<target_endianness, is64Bits>::info() {
>> -  return _sectionName.data();
>> -}
>> -
>> -template<support::endianness target_endianness, bool is64Bits> 
>> -const ArrayRef<AtomInfo> SectionChunk<target_endianness, is64Bits>::
>> +const ArrayRef<AtomInfo> StockSectionChunk<target_endianness,
is64Bits>::
>>      atoms() const {
>>    return _atoms;
>>  }
>>
>>
>>  template<support::endianness target_endianness, bool is64Bits> -void 
>> SectionChunk<target_endianness, is64Bits>::
>> +void StockSectionChunk<target_endianness, is64Bits>::
>>      appendAtom(const DefinedAtom *atom) {
>>    // Figure out offset for atom in this section given alignment
constraints.
>>    uint64_t offset = this->_size;
>> @@ -413,16 +471,16 @@
>>
>>    // TODO: Check content permissions and figure out what to do with .bss
>>    if ((perms & DefinedAtom::permR__) == DefinedAtom::permR__)
>> -    this->_permissions |= ELF::SHF_ALLOC;
>> +    this->_flags |= ELF::SHF_ALLOC;
>>    if ((perms & DefinedAtom::permRW_) == DefinedAtom::permRW_)
>> -    this->_permissions |= (ELF::SHF_ALLOC | ELF::SHF_WRITE);
>> +    this->_flags |= (ELF::SHF_ALLOC | ELF::SHF_WRITE);
>>    if ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X)
>> -    this->_permissions |= (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR);
>> +    this->_flags |= (ELF::SHF_ALLOC | ELF::SHF_EXECINSTR);
>>  }
>>
>>  template<support::endianness target_endianness, bool is64Bits> -void 
>> SectionChunk<target_endianness, is64Bits>::write(uint8_t 
>> *chunkBuffer) {
>> -  // Each section's content is just its atoms' content.
>> +void StockSectionChunk<target_endianness, is64Bits>::write(uint8_t 
>> +*chunkBuffer) { // Each section's content is just its atoms' content.
>>    for (const auto &ai : _atoms ) {
>>      // Copy raw content of atom to file buffer.
>>      ArrayRef<uint8_t> content = std::get<0>(ai)->rawContent(); @@ 
>> -437,17 +495,18 @@
>>        uint64_t targetAddress = 0;
>>
>>        if ( ref->target() != nullptr )
>> -         targetAddress = _writer.addressOfAtom(ref->target());
>> +         targetAddress = this->_writer.addressOfAtom(ref->target());
>>
>> -      uint64_t fixupAddress = _writer.addressOfAtom(std::get<0>(ai)) +
offset;
>> -      _writer.kindHandler()->applyFixup(ref->kind(), ref->addend(),
>> +      uint64_t fixupAddress =
this->_writer.addressOfAtom(std::get<0>(ai)) +
>> +                              offset;
>> +      this->_writer.kindHandler()->applyFixup(ref->kind(), 
>> + ref->addend(),
>>                                          &atomContent[offset],
>>                                          fixupAddress,
>>                                          targetAddress);
>
> Arguments should be lined up with the new call.
>
>>      }
>>    }
>>  }
>> -//
>> +
>>  
>> //===----------------------------------------------------------------
>> ------===//
>>  //  ELFStringSectionChunk
>>  
>> //===----------------------------------------------------------------
>> ------===//
>> @@ -456,54 +515,179 @@
>>      ELFStringSectionChunk(const WriterOptionsELF &options,
>>                            ELFWriter<target_endianness, is64Bits>
&writer,
>>                            StringRef secName)
>> -  : _segName("PT_NULL")
>> -  , _sectionName(secName)
>> -  , _writer(writer)
>> -  , _options(options) {
>> +  : SectionChunk<target_endianness, is64Bits>(secName, 
>> + StringRef("PT_NULL"),
>
> const char * implicitly converts to StringRef.
>
>> +                                              false, 0lu, 0lu, 0lu,
>> +                                              ELF::SHT_STRTAB, 0lu,
options,
>> +                                              writer) {
>>    // First Add a null character. It also occupies 1 byte
>> -  _StringSection.emplace_back("");
>> +  _stringSection.emplace_back("");
>>    this->_size = 1;
>>  }
>>
>>  template<support::endianness target_endianness, bool is64Bits>  
>> uint64_t ELFStringSectionChunk<target_endianness, is64Bits>::
>>           addString(StringRef symName) {
>> -  _StringSection.emplace_back(symName);
>> -
>> +
>
> No empty lines at the beginning of a function.
>
>> +  _stringSection.emplace_back(symName);
>>    uint64_t offset = this->_size;
>>    this->_size += symName.size() + 1;
>>
>>    return offset;
>>  }
>>
>> +
>> +// We need to unwrap the _stringSection and then make one large 
>> +memory // chunk of null terminated strings
>>  template<support::endianness target_endianness, bool is64Bits>
>> +void ELFStringSectionChunk<target_endianness, is64Bits>::
>> +     write(uint8_t *chunkBuffer) {
>> +  uint64_t chunkOffset = 0;
>> +
>> +  for (auto it : _stringSection) {
>> +    ::memcpy(chunkBuffer + chunkOffset, it.data(), it.size());
>> +    chunkOffset += it.size();
>> +    ::memcpy(chunkBuffer + chunkOffset, "", 1);
>> +    chunkOffset += 1;
>> +  }
>> +}
>> +
>> +template<support::endianness target_endianness, bool is64Bits>
>>  const char *ELFStringSectionChunk<target_endianness, 
>> is64Bits>::info() {
>> -  return _sectionName.data();
>> +  return "String Table";
>>  }
>>
>> +//===---------------------------------------------------------------
>> +-------===//
>> +//  ELFSymbolTableChunk
>> +//===---------------------------------------------------------------
>> +-------===// template< support::endianness target_endianness, bool 
>> +is64Bits> ELFSymbolTableChunk<target_endianness, 
>> +is64Bits>::ELFSymbolTableChunk
>> +                    (const WriterOptionsELF &options,
>> +                     ELFWriter<target_endianness, is64Bits> &writer,
>> +                     StringRef secName)
>> +  : SectionChunk<target_endianness, is64Bits>(secName,
StringRef("PT_NULL"),
>> +                                               false, 0, 0, 0,
ELF::SHT_SYMTAB,
>> +                                               sizeof(Elf_Sym), 
>> +options, writer)
>> +  {
>> +  _stringSection = this->_writer.strtab();
>> +  Elf_Sym *symbol = new Elf_Sym;
>
> Who owns this memory?
>
>> +  memset ((void *)symbol,0, sizeof(Elf_Sym));
>
> Space after ,. No space after memset.
>
>> +  _symbolTable.push_back(symbol);
>> +  this->_link = 0;
>> +  this->_entsize = sizeof(Elf_Sym);
>> +  this->_size = (sizeof(Elf_Sym));
>
> Extra ().
>
>> +}
>
> Indentation.
>
>> +
>> +/// \brief Add symbols to symbol table // We examine each property 
>> +of atom to infer the various st_* fields in Elf*_Sym
>
> Missing /.
>
>> +
>
> No newline between comment and function.
>
>> +template< support::endianness target_endianness, bool is64Bits> void 
>> +ELFSymbolTableChunk<target_endianness, is64Bits>::addSymbol(const Atom
*a,
>> +                                                        uint16_t 
>> +shndx) {
>
> A good way to reflow this would be:
>
> void ELFSymbolTableChunk<target_endianness, is64Bits>
>                         ::addSymbol(const Atom *a, uint16_t shndx) {
>
>> + Elf_Sym *symbol = new(_symbolAllocate.Allocate<Elf_Sym>()) Elf_Sym; 
>> + unsigned char b = 0 , t = 0;
>
> No space before ,.
>
>> + const DefinedAtom *da;
>> + const AbsoluteAtom *aa;
>> +
>> + symbol->st_name = _stringSection->addString(a->name());
>> +// In relocatable files, st_value holds a section offset for a defined
symbol.
>> +// st_value is an offset from the beginning of the section that 
>> +st_shndx // identifies. After we assign file offsets we can set this
value correctly.
>> + symbol->st_size = 0;
>> + symbol->st_shndx = shndx;
>> + symbol->st_value = 0;
>> +// FIXME: Need to change and account all STV* when visibilities are 
>> +supported
>> + symbol->st_other = ELF::STV_DEFAULT;
>> + if (a->definition() == lld::Atom::definitionRegular){
>
> This should be replaced with:
> if (const DefinedAtom *da = llvm::dyn_cast<const DefinedAtom>(a))
>
>> +      //da = static_cast<const DefinedAtom *>(a);
>
> Don't leave in commented out code.
>
>> +      da = llvm::dyn_cast<const DefinedAtom>(a);
>> +      symbol->st_size = da->size();
>> +      lld::DefinedAtom::ContentType ct;
>> +      switch (ct = da->contentType()){
>> +         case  DefinedAtom::typeCode:
>> +           t = ELF::STT_FUNC;
>> +           break;
>> +          case  DefinedAtom::typeData:
>
> Indentation.
>
>> +           t = ELF::STT_OBJECT;
>> +           break;
>> +          case  DefinedAtom::typeZeroFill:
>> +// In relocatable files, st_value holds alignment constraints for a 
>> +symbol whose // section index is SHN_COMMON
>> +           if (this->_options.type() == ELF::ET_REL){
>> +           t = ELF::STT_COMMON;
>> +           symbol->st_value = 0x1 << (da->alignment()).powerOf2;
>
> Why 0x? Also uneeded ().
>
>> +           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;
>> +     }
>> +// TODO: Find out how to incorporate STB_HIOS STB_LOOS // STB_HIPROC 
>> +and STB_LOPROC
>> +
>> +     if (da->scope() == DefinedAtom::scopeTranslationUnit)
>> +             b = ELF::STB_LOCAL;
>> +     else if (da->merge() == DefinedAtom::mergeAsWeak)
>> +             b= ELF::STB_WEAK;
>> +     else
>> +             b = ELF::STB_GLOBAL;
>> +    }
>> +//FIXME: Absolute atoms need more properties to differentiate each 
>> +other // based on binding and type of symbol  else if 
>> +(a->definition() == lld::Atom::definitionAbsolute){
>> +          aa = llvm::dyn_cast<const AbsoluteAtom>(a);
>
> Same alternate if as above.
>
>> +          symbol->st_value = aa->value();  } // We have an undefined 
>> +atom  else {
>
> No new lines between } and else.
>
>> +      symbol->st_value = 0;
>> +      t = ELF::STT_NOTYPE;
>> +      b = ELF::STB_LOCAL;
>> + }
>> +
>> +// This will set the st_info field in Elf_Sym
>> + symbol->setBindingAndType(b, t);
>> + _symbolTable.push_back(symbol);
>> + this->_size += sizeof(Elf_Sym);
>> +
>> +}
>
> The indentation for the above function is very messed up.
>
>> +
>> +
>>  template<support::endianness target_endianness, bool is64Bits> 
>> -StringRef ELFStringSectionChunk<target_endianness, 
>> is64Bits>::sectionName() {
>> -  return _sectionName ;
>> +void ELFSymbolTableChunk<target_endianness, 
>> +is64Bits>::setAttributes() { // sh_info should be one greater than 
>> +last symbol with STB_LOCAL binding // we sort the symbol table to 
>> +keep all local symbols at the beginning
>> +  std::stable_sort(_symbolTable.begin(), _symbolTable.end(),
>> +  static_cast<bool(*)(const Elf_Sym*, const Elf_Sym*)>([]
>
> Undeeded static_cast. This was used elsewhere due to a bug with 
> VS2010, which we no longer support.
>
>> +  (const Elf_Sym *A, const Elf_Sym *B) -> bool {
>> +          return (A->getBinding() < B->getBinding());}));  uint16_t 
>> + shInfo = 0;  for (auto i : _symbolTable) {
>> +   if (i->getBinding() != ELF::STB_LOCAL)
>
> Indentation.
>
>> +     break;
>> +   shInfo++;
>> +  }
>> +  this->_shinfo = shInfo;
>> +// we set the associated string table index in th sh_link member
>> +  this->_link = (this->_writer.strtab())->ordinal() - 1;
>
> Undeeded ().
>
>> +  this->_align2 = sizeof(void*);
>
> This seems wrong to me. The output of the linker should not depend on 
> the platform it is running on.
>
>>  }
>>
>>  template<support::endianness target_endianness, bool is64Bits> 
>> -StringRef ELFStringSectionChunk<target_endianness, is64Bits>::
>> -          segmentName() const {
>> -  return _segName;
>> +const char *ELFSymbolTableChunk<target_endianness, is64Bits>::info() 
>> +{
>> +  return "Symbol Table";
>>  }
>>
>> -// We need to unwrap the _StringSection and then make one large 
>> memory -// chunk of null terminated strings  
>> template<support::endianness target_endianness, bool is64Bits> -void 
>> ELFStringSectionChunk<target_endianness, is64Bits>::
>> +void ELFSymbolTableChunk<target_endianness, is64Bits>::
>>       write(uint8_t *chunkBuffer) {
>>    uint64_t chunkOffset = 0;
>> -
>> -  for (auto it : _StringSection) {
>> -    ::memcpy(chunkBuffer + chunkOffset, it.data(), it.size());
>> -    chunkOffset += it.size();
>> -    ::memcpy(chunkBuffer + chunkOffset, "", 1);
>> -    chunkOffset += 1;
>> +  for (auto it : _symbolTable) {
>> +    ::memcpy(chunkBuffer + chunkOffset, it, this->_entsize);
>> +    chunkOffset += this->_entsize;
>>    }
>>  }
>>
>> @@ -573,7 +757,6 @@
>>                                                         is64Bits>
&writer)
>>    : _options(options)
>>    , _writer(writer) {
>> -
>>    this->_size = 0;
>>    this->_align2 = 0;
>>    // The first element in the list is always NULL @@ -582,14 +765,20 
>> @@
>>    _sectionInfo.push_back(nullshdr);
>>
>>    this->_size += sizeof (Elf_Shdr);
>> +  }
>>
>> +template<support::endianness target_endianness, bool is64Bits> void 
>> +ELFSectionHeaderChunk<target_endianness, is64Bits>::createHeaders(){
>>    ELFStringSectionChunk<target_endianness, is64Bits> *str = 
>> _writer.shstrtab();
>>
>> -  for (const auto &chunk : _writer.sectionChunks()) {
>> +  for (const  auto &chunk : _writer.sectionChunks()) {
>
> This shouldn't have been changed.
>
>>      Elf_Shdr *shdr  = new (_sectionAllocate.Allocate<Elf_Shdr>())
Elf_Shdr;
>>      StringRef Name  = chunk->sectionName();
>> -    uint64_t offset = str->addString(Name);
>> -    shdr->sh_name   = offset;
>> +    if (chunk->shStrtableOffset() == 0){
>> +    chunk->setShStrtableOffset(str->addString(Name));
>
> Indentation.
>
>> +    }
>> +    shdr->sh_name   = chunk->shStrtableOffset();
>> +
>>      shdr->sh_type   = chunk->type();
>>      shdr->sh_flags  = chunk->flags();
>>      // TODO: At the time of creation of this section header, we will 
>> not have @@ -627,43 +816,24 @@
>>  //                                                        section group.
>>  // SHT_SYMTAB_SHNDX The section header index of
>>  //                  the associated symbol table section.  0
>> -// None of these chunks are of the above mentioned type, so we short
them.
>> -    shdr->sh_link = 0;
>> -    shdr->sh_info = 0;
>> +    shdr->sh_link = chunk->link() ;
>> +    shdr->sh_info = chunk->shinfo();
>>      shdr->sh_addralign = chunk->align2();
>> -    // Not a special section with fixed entries
>> -    shdr->sh_entsize = 0;
>> +    shdr->sh_entsize = chunk->entsize();
>>
>>      _sectionInfo.push_back(shdr);
>>      this->_size += sizeof (Elf_Shdr);
>> +// We set the attributes of symbol table as mentioned in above comment
>> +    (_writer.symtab())->setAttributes();
>
> Undeeded ().
>
>>    }
>> -
>> -  // Now I add in the section string table. For some reason This 
>> seems to be
>> -  // preferred location of string sections in contemporary
>> -  // (ones that must not be named) linker(s).
>> -  Elf_Shdr *shdr = new (_sectionAllocate.Allocate<Elf_Shdr>()) 
>> Elf_Shdr;
>> -  // I push the name of the string table into the string table as 
>> soon as
>> -  // it is created.
>> -  shdr->sh_name   = 1;
>> -  shdr->sh_type   = ELF::SHT_STRTAB;
>> -  shdr->sh_flags  = 0;
>> -  // NOTE: Refer to above note when assigning st_addr for other
sections.
>> -  shdr->sh_addr   = str->address();
>> -  shdr->sh_offset = str->fileOffset();
>> -  shdr->sh_size   = str->size();
>> -  shdr->sh_link   = 0;
>> -  shdr->sh_info   = 0;
>> -  // This section is not a loadable section, hence we do not care 
>> about
>> -  // alignment.
>> -  shdr->sh_addralign = 1;
>> -  _sectionInfo.push_back(shdr);
>> -  this->_size += sizeof (Elf_Shdr);
>>  }
>>
>> +
>> +
>>  template<support::endianness target_endianness, bool is64Bits>  
>> StringRef ELFSectionHeaderChunk<target_endianness, is64Bits>
>>                                 ::segmentName() const {
>> -  return "SHDR";
>> +  return StringRef("PT_NULL");
>
> Uneeded StringRef.
>
>>  }
>>
>>  template<support::endianness target_endianness, bool is64Bits> @@ 
>> -702,6 +872,7 @@
>>  public:
>>    LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
>>    typedef object::Elf_Shdr_Impl<target_endianness, is64Bits> 
>> Elf_Shdr;
>> +  typedef object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;
>>    ELFWriter(const WriterOptionsELF &options);
>>    virtual error_code writeFile(const lld::File &File, StringRef path);
>>    uint64_t addressOfAtom(const Atom *atom); @@ -715,7 +886,15 @@
>>    ELFStringSectionChunk<target_endianness, is64Bits> *shstrtab() {
>>      return _shstrtable;
>>    }
>> +
>> +  ELFStringSectionChunk<target_endianness, is64Bits> *strtab() {
>> +    return _strtable;
>> +  }
>> +  ELFSymbolTableChunk<target_endianness, is64Bits> *symtab() {
>> +    return _symtable;
>> +  }
>>
>> +
>>  private:
>>    void build(const lld::File &file);
>>    void createChunks(const lld::File &file); @@ -728,12 +907,16 @@
>>    typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
>>
>>    ELFStringSectionChunk<target_endianness, is64Bits> *_shstrtable ;
>> +  ELFStringSectionChunk<target_endianness, is64Bits> *_strtable ;  
>> + ELFSymbolTableChunk<target_endianness, is64Bits> *_symtable;
>>    std::unique_ptr<KindHandler> _referenceKindHandler;
>>    ELFSectionHeaderChunk<target_endianness, is64Bits>
*_sectionHeaderChunk;
>>    AtomToAddress _atomToAddress;
>>    std::vector<Chunk<target_endianness, is64Bits>*> _chunks;
>>    const DefinedAtom *_entryAtom;
>>    std::vector<SectionChunk<target_endianness, is64Bits>*> 
>> _sectionChunks;
>> +  std::vector<StockSectionChunk<target_endianness, is64Bits>*>
>> +                                                      
>> + _stockSectionChunks;
>>    llvm::BumpPtrAllocator _chunkAllocate;  };
>>
>> @@ -758,8 +941,21 @@
>>  template<support::endianness target_endianness, bool is64Bits>  void 
>> ELFWriter<target_endianness, is64Bits>
>>                ::createChunks (const lld::File &file) {
>> -  std::map<StringRef, SectionChunk<target_endianness, is64Bits>*> 
>> sectionMap;
>> +  std::map<StringRef, StockSectionChunk<target_endianness, is64Bits>*>
>> +             sectionMap;
>>
>> +  // Make header chunk
>> +  ELFHeaderChunk<target_endianness, is64Bits> *ehc =
>> +    new (_chunkAllocate.Allocate
>> +        <ELFHeaderChunk<target_endianness, is64Bits>>())
>> +        ELFHeaderChunk<target_endianness, is64Bits>(_options, file);  
>> + _chunks.push_back(ehc);
>> +
>> +  _sectionHeaderChunk = new
(_chunkAllocate.Allocate<ELFSectionHeaderChunk
>> +                               <target_endianness, is64Bits>>())
>> +                              ELFSectionHeaderChunk
>> +                               <target_endianness, 
>> + is64Bits>(_options, *this);  
>> + _chunks.push_back(_sectionHeaderChunk);
>>    // We need to create hand crafted sections such as shstrtab strtab
hash and
>>    // symtab to put relevant information in ELF structures and then
process the
>>    // atoms.
>> @@ -768,58 +964,128 @@
>>                       <ELFStringSectionChunk<target_endianness,
is64Bits>>())
>>                      ELFStringSectionChunk<target_endianness, is64Bits>
>>                               (_options, *this, ".shstrtab");
>> -  _shstrtable->addString(".shstrtab");
>> +  
>> + _shstrtable->setShStrtableOffset(_shstrtable->addString(".shstrtab"
>> + ));  _sectionChunks.push_back(_shstrtable);
>> +
>> +  _strtable = new (_chunkAllocate.Allocate
>> +                     <ELFStringSectionChunk<target_endianness,
is64Bits>>())
>> +                    ELFStringSectionChunk<target_endianness, is64Bits>
>> +                             (_options, *this, ".strtab");  
>> + _strtable->setShStrtableOffset( _shstrtable->addString(".strtab"));
>> +  _sectionChunks.push_back(_strtable);
>> +
>> +  _symtable = new (_chunkAllocate.Allocate
>> +                     <ELFSymbolTableChunk<target_endianness,
is64Bits>>())
>> +                    ELFSymbolTableChunk<target_endianness, is64Bits>
>> +                             (_options, *this, ".symtab");  
>> + _symtable->setShStrtableOffset( _shstrtable->addString(".symtab"));
>> +  _sectionChunks.push_back(_symtable);
>>
>> -  //we also need to process undefined atoms
>> +//TODO: implement .hash section
>> +
>>    for (const DefinedAtom *a : file.defined() ) {
>>      // TODO: Add sectionChoice.
>>      // assert( atom->sectionChoice() ==
DefinedAtom::sectionBasedOnContent );
>>      StringRef sectionName = a->customSectionName();
>> +    if (a->sectionChoice() ==
>> +        DefinedAtom::SectionChoice::sectionBasedOnContent) {
>> +      if (a->size() <8)
>> +         sectionName = ".sbss";
>> +      else
>> +         sectionName = ".bss";
>> +    }
>>      auto pos = sectionMap.find(sectionName);
>>      DefinedAtom::ContentType type = a->contentType();
>> -    if (pos == sectionMap.end()) {
>> -      if (type != DefinedAtom::typeUnknown){
>> -       SectionChunk<target_endianness, is64Bits>
>> -                  *chunk = new (_chunkAllocate.Allocate
>> -                                <SectionChunk<target_endianness,
is64Bits>>())
>> -                                SectionChunk<target_endianness,
is64Bits>
>> -                                   (type, sectionName, _options, *this);
>> +    if (type != DefinedAtom::typeUnknown){
>> +      if (pos == sectionMap.end()) {
>> +       StockSectionChunk<target_endianness, is64Bits>
>> +                  *chunk = new(_chunkAllocate.Allocate
>> +                               <StockSectionChunk<target_endianness,
is64Bits>>
>> +                               ())StockSectionChunk<target_endianness,
is64Bits>
>> +                                   (sectionName, true, type, 
>> + _options, *this);
>>
>>           sectionMap[sectionName] = chunk;
>>           chunk->appendAtom(a);
>>           _sectionChunks.push_back(chunk);
>> +         _stockSectionChunks.push_back(chunk);
>> +
>> +      } else {
>> +        pos->second->appendAtom(a);
>>        }
>> -    } else {
>> -      pos->second->appendAtom(a);
>>      }
>>    }
>>
>> -  //put in the Undefined atoms as well
>> -  // Make header chunk
>> -  ELFHeaderChunk<target_endianness, is64Bits> *ehc =
>> -    new (_chunkAllocate.Allocate
>> -        <ELFHeaderChunk<target_endianness, is64Bits>>())
>> -        ELFHeaderChunk<target_endianness, is64Bits>(_options, file);
>>
>> -  _sectionHeaderChunk = new
(_chunkAllocate.Allocate<ELFSectionHeaderChunk
>> -                               <target_endianness, is64Bits>>())
>> -                              ELFSectionHeaderChunk
>> -                               <target_endianness, is64Bits>(_options,
*this);
>> +  for (auto chnk : _sectionChunks)
>> +    _chunks.push_back(chnk);
>>
>> +
>> +// After creating chunks, we might lay them out diffrently.
>> +// Lets make sure symbol table, string table and section string 
>> +table // are at the end. In future we might provide knob // to the 
>> +driver to decide layout.
>> +
>> +  swapChunks(reinterpret_cast<uint64_t>(_chunks.size()) - 1,
>> +                                        _shstrtable->ordinal(), 
>> + _chunks);
>> +  swapChunks(reinterpret_cast<uint64_t>(_chunks.size()) - 2,
>> +                                        _strtable->ordinal(), 
>> + _chunks);
>> +  swapChunks(reinterpret_cast<uint64_t>(_chunks.size()) - 3,
>> +                                        _symtable->ordinal(), 
>> + _chunks);
>> +
>> +// We sort the _chunks vector to have all chunks as per ordianl 
>> +number // this will help to write out the chunks in the order we 
>> +decided
>> +
>> +  std::stable_sort(_chunks.begin(), _chunks.end(),  
>> + static_cast<bool(*)(const Chunk<target_endianness, is64Bits>*,
>> +                      const Chunk<target_endianness, is64Bits>*)>([]  
>> + (const Chunk<target_endianness, is64Bits> *A,
>> +   const Chunk<target_endianness, is64Bits> *B) -> bool {
>> +          return (A->ordinal() < B->ordinal());}));
>> +
>> +  std::stable_sort(_sectionChunks.begin(), _sectionChunks.end(),  
>> + static_cast<bool(*)(const SectionChunk<target_endianness, is64Bits>*,
>> +                      const SectionChunk<target_endianness, 
>> + is64Bits>*)>([]  (const SectionChunk<target_endianness, is64Bits> *A,
>> +   const SectionChunk<target_endianness, is64Bits> *B) -> bool {
>> +          return (A->ordinal() < B->ordinal());}));
>> +
>> +// Once the layout is fixed, we can now go and populate symbol table 
>> +// with correct st_shndx member.
>> +
>> + 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()) {
>
> Indentation.
>
>> +  _symtable->addSymbol(std::get<0>(da),ssc->ordinal() -1);
>
> Space after ,.
>
>> + }
>> +}
>> + for (const UndefinedAtom *a : file.undefined()) {
>> +    _symtable->addSymbol(a, ELF::SHN_UNDEF);  }
>> +
>> + for (const AbsoluteAtom *a : file.absolute()) {
>> +    _symtable->addSymbol(a, ELF::SHN_ABS); }
>> +
>> +  _sectionHeaderChunk->createHeaders();
>>    ehc->e_shoff(ehc->size());
>>    ehc->e_shentsize(_sectionHeaderChunk->size());
>>    ehc->e_shnum(_sectionHeaderChunk->count());
>> -
>> -   // I am pushing string section after all sections are in.
>> -   // Hence the index will be total number of non-custom sections we
have
>> -
>> -  ehc->e_shstrndx(_sectionChunks.size() + 1);
>> -  _chunks.push_back(ehc);
>> -  _chunks.push_back(_sectionHeaderChunk);
>> -  // We have ELF header, section header. Now push rest of sections
>> -  for (auto chnk : _sectionChunks)
>> -    _chunks.push_back(chnk);
>> -  _chunks.push_back(_shstrtable);
>> +// We need to put the index of section string table in ELF header // 
>> +first two chunks are not sections so we subtract 2 to start sections 
>> +// and add 1 since we have a NULL header
>> +  ehc->e_shstrndx(_shstrtable->ordinal() - 1);
>>  }
>>
>>  template<support::endianness target_endianness, bool is64Bits> @@ 
>> -828,13 +1094,11 @@
>>
>>  // _atomToAddress is a DenseMap that maps an atom its file address.
>>  // std::get<1>(ai) is the offset from the start of the section to the
atom.
>> -  for (auto &chunk : _sectionChunks){
>> +  for (auto chunk : _stockSectionChunks){
>>      for (auto &ai : chunk->atoms() ) {
>>        _atomToAddress[std::get<0>(ai)] = chunk->address() +
std::get<1>(ai);
>>      }
>>    }
>> -
>> -
>>  }
>>
>>  template<support::endianness target_endianness, bool is64Bits> @@ 
>> -859,11 +1123,6 @@
>>      (*it)->sh_addr = chunk->address();
>>      ++it;
>>    }
>> -  // We  have taken care of  all the stock sections. We need to deal 
>> with
>> -  // custom sections
>> -  // They are section string table, string table and symbol table
>> -  (*it)->sh_offset = _shstrtable->fileOffset();
>> -  (*it)->sh_addr = _shstrtable->address();  }
>>
>>  template<support::endianness target_endianness, bool is64Bits> @@ 
>> -895,7 +1154,7 @@
>>
>>  Writer *createWriterELF(const WriterOptionsELF &options) {
>>    if (!options.is64Bit() && options.endianness() ==
llvm::support::little)
>> -       return new lld::elf::ELFWriter<support::little, false>(options);
>> +    return new lld::elf::ELFWriter<support::little, false>(options);
>>    else if (options.is64Bit() && options.endianness() ==
llvm::support::little)
>>      return new lld::elf::ELFWriter<support::little, true>(options);
>>    else if (!options.is64Bit() && options.endianness() == 
>> llvm::support::big)
>> Index: test/elf/sections.objtxt
>> ===================================================================
>> --- test/elf/sections.objtxt  (revision 164035)
>> +++ test/elf/sections.objtxt  (working copy)
>> @@ -3,20 +3,27 @@
>>  RUN: elf-dump  --dump-section %t1 |  FileCheck -check-prefix=ED %s
>>
>>  OBJDUMP:  0 000000000 00000000000000000
>> -OBJDUMP:  1 .text 00000000a 0000000000000014c TEXT DATA
>> -OBJDUMP:  2 .data 000000004 00000000000000158 DATA
>> -OBJDUMP:  3 .special 000000004 0000000000000015c DATA
>> -OBJDUMP:  4 .anotherspecial 000000004 00000000000000160 DATA
>> -OBJDUMP:  5 .bss 000000000 00000000000000164 BSS
>> -OBJDUMP:  6 .shstrtab 000000035 00000000000000164
>> +OBJDUMP:  1 .sbss         000000000 0000000000000019c
>> +OBJDUMP:  2 .anotherspecial 000000004 000000000000001a0 DATA
>> +OBJDUMP:  3 .special      000000004 000000000000001a4 DATA
>> +OBJDUMP:  4 .text         00000000a 000000000000001a8 TEXT DATA
>> +OBJDUMP:  5 .data         000000004 000000000000001b4 DATA
>> +OBJDUMP:  6 .symtab       0000000f0 000000000000001b8
>> +OBJDUMP:  7 .strtab       000000011 000000000000002a8
>> +OBJDUMP:  8 .shstrtab     000000046 000000000000002b9
>>
>>  READOBJ: File Format : ELF32-i386
>>  READOBJ: Arch        : i386
>>  READOBJ: Address Size: 32 bits
>> +READOBJ: Symbols
>> +READOBJ: .anotherspecial                   DBG                1a0
0               1a0  formatspecific
>> +READOBJ: .symtab                           DBG                1b8
0               1b8  formatspecific
>> +READOBJ: baz                               FUNC               1a8
a               1a8  global
>> +READOBJ:  z                                 DATA               1a0
4               1a0  global
>>
>>  ED: 'e_indent[EI_DATA]', 0x01
>>  ED: 'e_machine', 0x0003
>>  ED: Section 1
>> -ED: 'sh_addralign', 0x00000004
>> +ED: 'sh_addralign', 0x00000002
>>  ED: Section 2
>> -ED: 'sh_addralign', 0x00000004
>> +ED: 'sh_addralign', 0x00000008
>>
>
> - Michael Spencer
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>




More information about the llvm-commits mailing list