[llvm-commits] PATCH: lld ReaderELF.cpp update

Sid Manning sidneym at codeaurora.org
Fri Jul 13 22:28:36 PDT 2012


On 07/13/12 18:16, Michael Spencer wrote:
> On Fri, Jul 13, 2012 at 11:44 AM, Sid Manning<sidneym at codeaurora.org>  wrote:

>> +  const Elf_Shdr *getSection(DataRefImpl index) const;
>> +  const Elf_Sym  *getSymbol(DataRefImpl Symb) const;
>>     const Elf_Dyn  *getDyn(DataRefImpl DynData) const;
>>     error_code getSymbolVersion(SymbolRef Symb, StringRef&Version,
>>                                 bool&IsDefault) const;
>>
>
> I realize you were following the example of getDyn here. However, all
> of these should take a {section,symbol,dynasymbol,relocation}_iterator
> instead as COFF does. DataRefImpl should never be used by clients of
> LLVMObject. There's no need for you to change getDyn over if it's not
> trivial.
So I would add new methods to ELF.h similar to getCOFFSection/Symbol.  I 
will give this a try.


>> +:# RUN: lld-core -reader ELF %p/Inputs/object-test.elf-i386 | FileCheck %s -check-prefix ELF-i386
>> +:# RUN: lld-core -reader ELF %p/Inputs/object-test.elf-hexagon | FileCheck %s -check-prefix ELF-hexagon
>> +
>
> What's with the : at the front of the run lines?
>
Removed.  These are leftovers from when I prefixed the ELF-XX: results.


> Index: lib/ReaderWriter/ELF/ReaderELF.cpp
>> +//===---------------------------------------------------------------------===//
>
> These lines are the wrong length.

Easy to fix, didn't notice.

>
>>
>>   #include "lld/ReaderWriter/ReaderELF.h"
>>   #include "lld/Core/File.h"
>>
>> +#include "llvm/ADT/ArrayRef.h"
>> +#include "llvm/ADT/StringRef.h"
>> +#include "llvm/Support/Allocator.h"
>>   #include "llvm/Support/Casting.h"
>>   #include "llvm/Support/ErrorHandling.h"
>>   #include "llvm/Support/Memory.h"
>>   #include "llvm/Support/MemoryBuffer.h"
>>   #include "llvm/Support/raw_ostream.h"
>>   #include "llvm/Support/system_error.h"
>> +#include "llvm/Support/Endian.h"
>> +#include "llvm/Support/MathExtras.h"
>> +#include "llvm/Support/ELF.h"
>> +#include "llvm/Object/ObjectFile.h"
>> +#include "llvm/Object/ELF.h"
>
> These need to be sorted in alphabetical order.
>
No problem.

>> +class ELFAbsoluteAtom: public AbsoluteAtom {
>> +
>> +public:
>> +  ELFAbsoluteAtom(const File&F,
>> +                  llvm::StringRef N,
>> +                  uint64_t V)
>> +    : OwningFile(F)
>> +    , Name(N)
>> +    , Value(V)
>> +  {}
>> +
>> +  virtual const class File&  file() const {
>
> &  on the right side. A few other places need this too.
>
The above declaration was copied from the PECOFF reader and I'm not sure 
what to change.


>> +    for (; si != se; si.increment(EC)) {
>> +      if (EC)
>> +        llvm::report_fatal_error("Could not read all symbols");
>> +      llvm::StringRef SymbolName;
>> +      llvm::StringRef SectionName;
>> +
>> +      llvm::object::SymbolRef::Type type;
>> +      uint32_t flags = 0;
>> +
>> +      EC = si->getName(SymbolName);
>
> For this and all the below code, why are you using the generic
> interface instead of the ELF specific interface? Quite a bit of this
> would be a lot cleaner with the ELF interface.
>
The generic interface seemed to work, si->getName returns the symbol 
name.  If methods similar to getCOFFSection/Symbol taking the iterator 
are available and getSymbolName (const Elf_Shdr *,const Elf_sym *, 
StringRef) is made public then I think the generic interface calls can 
be done away with.  I will try to work this out.



>> +      if (EC)
>> +        llvm::report_fatal_error("Could not get symbol name");
>> +
>> +      EC = si->getType(type);
>> +      if (EC)
>> +        llvm::report_fatal_error("Could not get symbol type");
>> +
>> +      EC = si->getFlags(flags);
>> +      if (EC)
>> +        llvm::report_fatal_error("Could not get symbol flags");
>> +
>> +      if ((flags&  llvm::object::SymbolRef::SF_Absolute)
>> +           == llvm::object::SymbolRef::SF_Absolute) {
>> +        uint64_t AbsValue;
>> +
>> +        EC = si->getAddress(AbsValue);
>> +        if (EC)
>> +          llvm::report_fatal_error(
>> +              "Could not get absolute symbol st_value");
>> +
>> +        AbsoluteAtoms._atoms.push_back(
>> +                             new (AtomStorage.Allocate<ELFAbsoluteAtom>  ())
>> +                             ELFAbsoluteAtom(*this, SymbolName, AbsValue));
>> +
>> +      } else if ((flags&  llvm::object::SymbolRef::SF_Undefined)
>> +                       == llvm::object::SymbolRef::SF_Undefined) {
>> +
>> +        // Get a pointer to the symbol:
>> +        const Elf_Sym *Symbol = (Obj->getSymbol(si->getRawDataRefImpl()));
>> +
>> +        UndefinedAtoms._atoms.push_back(
>> +            new (AtomStorage.Allocate<ELFUndefinedAtom<
>> +                 target_endianness, is64Bits>  >  ())
>
> No space needed between the>  and>. Also there should be no space
> between the>  and (.
>
No problem.

>> +                 ELFUndefinedAtom<target_endianness, is64Bits>  (
>> +                                 *this, SymbolName, Symbol));
>> +
>> +      } else {
>> +        uint32_t SymbolFlags;
>> +        EC = si->getFlags(SymbolFlags);
>> +        if (EC)
>> +          llvm::report_fatal_error("Could not get symbol flags");
>> +
>> +        //TODO We need to think about how to put other
>> +        //symbol types into the defined atom model.
>> +
>> +        if (type == llvm::object::SymbolRef::ST_Data ||
>> +            type == llvm::object::SymbolRef::ST_Function ||
>> +            type == llvm::object::SymbolRef::ST_Unknown) {
>> +
>> +          llvm::object::SectionRef SR;
>> +          llvm::object::section_iterator section(SR);
>> +
>> +          EC = si->getSection(section);
>> +          if (EC)
>> +            llvm::report_fatal_error("Could not get section iterator");
>> +
>> +          EC = section->getName(SectionName);
>> +          if (EC)
>> +            llvm::report_fatal_error("Could not get section name");
>> +
>> +          StringRef symbolContents;
>> +          EC = section->getContents (symbolContents);
>> +          if (EC)
>> +              llvm::report_fatal_error("Could not get section contents");
>> +
>> +          uint64_t symbolSize;
>> +          EC = si->getSize (symbolSize);
>> +          if (EC)
>> +            llvm::report_fatal_error("Could not get symbol size");
>> +
>> +          uint64_t symbolOffset;
>> +          EC = si->getAddress (symbolOffset);
>> +          if (EC)
>> +            llvm::report_fatal_error("Could not get symbol address");
>> +
>> +          bool IsCommon = false;
>> +          if ((SymbolFlags&  llvm::object::SymbolRef::SF_Common)
>> +               == llvm::object::SymbolRef::SF_Common)
>> +            IsCommon = true;
>> +
>> +          // Get the symbol's content:
>> +          llvm::ArrayRef<uint8_t>  SymbolData((uint8_t *)symbolContents.data()
>> +                                             + symbolOffset,
>> +                                             (IsCommon) ? 0 : symbolSize);
>
> st_size is not guaranteed to be the size of the data associated with
> the symbol. See the MachO and COFF reader for how to properly deal
> with this. This is important because every byte in a section must be
> allocated to an atom, as sections can have internal references that we
> don't know about that must be maintained.
>
I think get this.  When functions don't use .size their size will be 
recored as zero so we have to take the difference between this address 
and the next.


>> +
>> +          // Get a pointer to the section the symbol lives in:
>> +          llvm::object::DataRefImpl ShdrRef = section->getRawDataRefImpl();
>> +          Elf_Shdr *Section = const_cast<Elf_Shdr*>
>> +                              (reinterpret_cast<const Elf_Shdr *>(ShdrRef.p));
>
> Why is there a const cast here? ELFDefinedAtom takes a const Elf_Shdr
> *. Also this should not rely on the implementation details of
> DataRefImpl to get the Elf_Shdr pointer.
>

I ripped this off from DyldELFObject in RuntimeDynldELF.cpp, If some of 
the interfaces changes mentioned above are done then this shouldn't be 
needed.

-- 
Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum



More information about the llvm-commits mailing list