Example #1
0
  bool operator()(const SymbolRef &A, const SymbolRef &B) {
    SymbolRef::Type AType, BType;
    A.getType(AType);
    B.getType(BType);

    uint64_t AAddr, BAddr;
    if (AType != SymbolRef::ST_Function)
      AAddr = 0;
    else
      A.getAddress(AAddr);
    if (BType != SymbolRef::ST_Function)
      BAddr = 0;
    else
      B.getAddress(BAddr);
    return AAddr < BAddr;
  }
Example #2
0
void ModuleInfo::addSymbol(const SymbolRef &Symbol) {
  SymbolRef::Type SymbolType;
  if (error(Symbol.getType(SymbolType)))
    return;
  if (SymbolType != SymbolRef::ST_Function && SymbolType != SymbolRef::ST_Data)
    return;
  uint64_t SymbolAddress;
  if (error(Symbol.getAddress(SymbolAddress)) ||
      SymbolAddress == UnknownAddressOrSize)
    return;
  uint64_t SymbolSize;
  // Getting symbol size is linear for Mach-O files, so assume that symbol
  // occupies the memory range up to the following symbol.
  if (isa<MachOObjectFile>(Module))
    SymbolSize = 0;
  else if (error(Symbol.getSize(SymbolSize)) ||
           SymbolSize == UnknownAddressOrSize)
    return;
  StringRef SymbolName;
  if (error(Symbol.getName(SymbolName)))
    return;
  // Mach-O symbol table names have leading underscore, skip it.
  if (Module->isMachO() && SymbolName.size() > 0 && SymbolName[0] == '_')
    SymbolName = SymbolName.drop_front();
  // FIXME: If a function has alias, there are two entries in symbol table
  // with same address size. Make sure we choose the correct one.
  SymbolMapTy &M = SymbolType == SymbolRef::ST_Function ? Functions : Objects;
  SymbolDesc SD = { SymbolAddress, SymbolSize };
  M.insert(std::make_pair(SD, SymbolName));
}
Example #3
0
    explicit symbol(const SymbolRef& sym) {
        StringRef name;
        if(error_code err = sym.getName(name))
            llvm_binary_fail(err);
        this->name_ = name.str();

        if (error_code err = sym.getType(this->kind_))
            llvm_binary_fail(err);

        if (error_code err = sym.getAddress(this->addr_))
            llvm_binary_fail(err);

        if (error_code err = sym.getSize(this->size_))
            llvm_binary_fail(err);

        uint32_t flags;
        if (error_code err = sym.getFlags(flags))
            llvm_binary_fail(err);

        if (flags & SymbolRef::SF_Undefined) {
            uint64_t addr;
            if (error_code err = sym.getValue(addr))
                llvm_binary_fail(err);
            // This will not work for x86-64, since they usually zero
            // the value. BFD library uses index correspondence
            // between plt entry and relocation, to name the plt
            // entry. We can't afford this.
            if (addr) {
                addr_ = addr;
                size_ = 8;
            }
        }
    }
Example #4
0
// Given a symbol sym this functions returns the address and section of it.
static error_code resolveSectionAndAddress(const COFFObjectFile *Obj,
                                           const SymbolRef &Sym,
                                           const coff_section *&ResolvedSection,
                                           uint64_t &ResolvedAddr) {
  if (error_code ec = Sym.getAddress(ResolvedAddr)) return ec;
  section_iterator iter(Obj->begin_sections());
  if (error_code ec = Sym.getSection(iter)) return ec;
  ResolvedSection = Obj->getCOFFSection(iter);
  return object_error::success;
}
Example #5
0
// Given a symbol sym this functions returns the address and section of it.
static std::error_code
resolveSectionAndAddress(const COFFObjectFile *Obj, const SymbolRef &Sym,
                         const coff_section *&ResolvedSection,
                         uint64_t &ResolvedAddr) {
  if (std::error_code EC = Sym.getAddress(ResolvedAddr))
    return EC;
  section_iterator iter(Obj->section_begin());
  if (std::error_code EC = Sym.getSection(iter))
    return EC;
  ResolvedSection = Obj->getCOFFSection(*iter);
  return std::error_code();
}
Example #6
0
// Given a symbol sym this functions returns the address and section of it.
static std::error_code
resolveSectionAndAddress(const COFFObjectFile *Obj, const SymbolRef &Sym,
                         const coff_section *&ResolvedSection,
                         uint64_t &ResolvedAddr) {
  ErrorOr<uint64_t> ResolvedAddrOrErr = Sym.getAddress();
  if (std::error_code EC = ResolvedAddrOrErr.getError())
    return EC;
  ResolvedAddr = *ResolvedAddrOrErr;
  Expected<section_iterator> Iter = Sym.getSection();
  if (!Iter)
    return errorToErrorCode(Iter.takeError());
  ResolvedSection = Obj->getCOFFSection(**Iter);
  return std::error_code();
}
Example #7
0
 explicit symbol(const SymbolRef& sym) {
     StringRef name;
     if(error_code err = sym.getName(name))
         llvm_binary_fail(err);
     this->name_ = name.str();
     
     if (error_code err = sym.getType(this->kind_))
         llvm_binary_fail(err);
     
     if (error_code err = sym.getAddress(this->addr_))
         llvm_binary_fail(err);
     
     if (error_code err = sym.getSize(this->size_))
         llvm_binary_fail(err);
 }
Example #8
0
static std::error_code resolveRelocation(const Dumper::Context &Ctx,
                                         const coff_section *Section,
                                         uint64_t Offset,
                                         const coff_section *&ResolvedSection,
                                         uint64_t &ResolvedAddress) {
  SymbolRef Symbol;
  if (std::error_code EC =
          Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData))
    return EC;

  ErrorOr<uint64_t> ResolvedAddressOrErr = Symbol.getAddress();
  if (std::error_code EC = ResolvedAddressOrErr.getError())
    return EC;
  ResolvedAddress = *ResolvedAddressOrErr;

  ErrorOr<section_iterator> SI = Symbol.getSection();
  ResolvedSection = Ctx.COFF.getCOFFSection(**SI);
  return std::error_code();
}
std::error_code SymbolizableObjectFile::addSymbol(const SymbolRef &Symbol,
                                                  uint64_t SymbolSize,
                                                  DataExtractor *OpdExtractor,
                                                  uint64_t OpdAddress) {
  ErrorOr<SymbolRef::Type> SymbolTypeOrErr = Symbol.getType();
  if (auto EC = SymbolTypeOrErr.getError())
    return EC;
  SymbolRef::Type SymbolType = *SymbolTypeOrErr;
  if (SymbolType != SymbolRef::ST_Function && SymbolType != SymbolRef::ST_Data)
    return std::error_code();
  ErrorOr<uint64_t> SymbolAddressOrErr = Symbol.getAddress();
  if (auto EC = SymbolAddressOrErr.getError())
    return EC;
  uint64_t SymbolAddress = *SymbolAddressOrErr;
  if (OpdExtractor) {
    // For big-endian PowerPC64 ELF, symbols in the .opd section refer to
    // function descriptors. The first word of the descriptor is a pointer to
    // the function's code.
    // For the purposes of symbolization, pretend the symbol's address is that
    // of the function's code, not the descriptor.
    uint64_t OpdOffset = SymbolAddress - OpdAddress;
    uint32_t OpdOffset32 = OpdOffset;
    if (OpdOffset == OpdOffset32 && 
        OpdExtractor->isValidOffsetForAddress(OpdOffset32))
      SymbolAddress = OpdExtractor->getAddress(&OpdOffset32);
  }
  Expected<StringRef> SymbolNameOrErr = Symbol.getName();
  if (!SymbolNameOrErr)
    return errorToErrorCode(SymbolNameOrErr.takeError());
  StringRef SymbolName = *SymbolNameOrErr;
  // Mach-O symbol table names have leading underscore, skip it.
  if (Module->isMachO() && SymbolName.size() > 0 && SymbolName[0] == '_')
    SymbolName = SymbolName.drop_front();
  // FIXME: If a function has alias, there are two entries in symbol table
  // with same address size. Make sure we choose the correct one.
  auto &M = SymbolType == SymbolRef::ST_Function ? Functions : Objects;
  SymbolDesc SD = { SymbolAddress, SymbolSize };
  M.insert(std::make_pair(SD, SymbolName));
  return std::error_code();
}
Example #10
0
static std::error_code getOffset(const SymbolRef &Sym, uint64_t &Result) {
  uint64_t Address;
  if (std::error_code EC = Sym.getAddress(Address))
    return EC;

  if (Address == UnknownAddressOrSize) {
    Result = UnknownAddressOrSize;
    return object_error::success;
  }

  const ObjectFile *Obj = Sym.getObject();
  section_iterator SecI(Obj->section_begin());
  if (std::error_code EC = Sym.getSection(SecI))
    return EC;

  if (SecI == Obj->section_end()) {
    Result = UnknownAddressOrSize;
    return object_error::success;
  }

  uint64_t SectionAddress = SecI->getAddress();
  Result = Address - SectionAddress;
  return object_error::success;
}
Example #11
0
error_or<uint64_t> get_addr(const SymbolRef &sym, const COFFObjectFile &obj) {
    auto er_addr = sym.getAddress();
    return of_llvm_error_or(er_addr);
}