[llvm-commits] [PATCH 9/10] Initial support for PowerPC64 MCJIT

Hal Finkel hfinkel at anl.gov
Wed Sep 19 12:45:24 PDT 2012


On Wed, 19 Sep 2012 20:09:45 +0200
Roman Divacky <rdivacky at freebsd.org> wrote:

> Some comments below. 

I've added a few additional comments.

> 
> On Wed, Sep 19, 2012 at 10:04:20AM -0300, Adhemerval Zanella wrote:
> > On 09/18/2012 05:34 PM, Jim Grosbach wrote:
> > > Yeah, there is unfortunately some current code which already
> > > violates the host/target relationship. I'm in the process of
> > > cleaning some of that up, partly because it sets a misleading
> > > example.
> > >
> > > Anyways, thanks again for working on this for PPC. It's great to
> > > see all the progress there recently.
> > >
> > > -Jim
> > 
> > I believe this patch has a better approach now: both the stub and
> > relocation are done using byte stores. I also corrected the
> > indentation in switch/case you pointed early.
> > 
> > 
> > -- 
> > Adhemerval Zanella Netto
> >   Software Engineer
> >   Linux Technology Center Brazil
> >   Toolchain / GLIBC on Power Architecture
> >   azanella at linux.vnet.ibm.com / azanella at br.ibm.com
> >   +55 61 8642-9890
> > 
> 
> > >From a48b8044780c1764a55fbfccfb63681b7c944009 Mon Sep 17 00:00:00
> > >2001
> > From: Adhemerval Zanella <azanella at linux.vnet.ibm.com>
> > Date: Mon, 17 Sep 2012 12:32:35 -0500
> > Subject: [PATCH 10/12] Initial support for PowerPC64 MCJIT
> > 
> > ---
> >  lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp    |   18 ++
> >  lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp |  276
> > +++++++++++++++++++-
> > lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h   |   11 +
> > lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h  |   33 +++ 4
> > files changed, 336 insertions(+), 2 deletions(-)
> > 
> > diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
> > b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index
> > 880129d..5ffb68a 100644 ---
> > a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++
> > b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -362,6 +362,24
> > @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr)
> > { StubAddr++; *StubAddr = NopInstr;
> >      return Addr;
> > +  } else if (Arch == Triple::ppc64) {
> > +    // PowerPC64 stub: the address points to a function descriptor
> > +    // instead of the function itself. Load the function address
> > +    // on r11 and sets it to control register. Also loads the
> > function
> > +    // TOC in r2 and environment pointer to r11.
> > +    writeInt32BE(Addr,    0x3D800000); // lis   r12, highest(addr)
> > +    writeInt32BE(Addr+4,  0x618C0000); // ori   r12, higher(addr)
> > +    writeInt32BE(Addr+8,  0x798C07C6); // sldi  r12, r12, 32
> > +    writeInt32BE(Addr+12, 0x658C0000); // oris  r12, r12, h(addr)
> > +    writeInt32BE(Addr+16, 0x618C0000); // ori   r12, r12, l(addr)
> > +    writeInt32BE(Addr+20, 0xF8410028); // std   r2,  40(r1)
> > +    writeInt32BE(Addr+24, 0xE96C0000); // ld    r11, 0(r12)
> > +    writeInt32BE(Addr+28, 0xE84C0008); // ld    r2,  0(r12)
> > +    writeInt32BE(Addr+32, 0x7D6903A6); // mtctr r11
> > +    writeInt32BE(Addr+36, 0xE96C0010); // ld    r11, 16(r2)
> > +    writeInt32BE(Addr+40, 0x4E800420); // bctr
> > +    
> > +    return Addr;
> >    }
> >    return Addr;
> >  }
> > diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
> > b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index
> > a1c0e40..5742a1d 100644 ---
> > a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++
> > b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -27,6
> > +27,14 @@ using namespace llvm::object; 
> >  namespace {
> >  
> > +static inline
> > +error_code Check(error_code Err) {

Should be 'check' by the coding convention.

> > +  if (Err) {
> > +    report_fatal_error(Err.message());
> > +  }
> > +  return Err;
> > +}
> > +
> >  template<support::endianness target_endianness, bool is64Bits>
> >  class DyldELFObject : public ELFObjectFile<target_endianness,
> > is64Bits> { LLVM_ELF_IMPORT_TYPES(target_endianness, is64Bits)
> > @@ -343,6 +351,180 @@ void
> > RuntimeDyldELF::resolveMIPSRelocation(uint8_t *LocalAddress, }
> >  }
> >  
> > +// Return the .TOC. section address to R_PPC64_TOC relocations.
> > +uint64_t RuntimeDyldELF::findPPC64TOC() const {
> > +  // The TOC consists of sections .got, .toc, .tocbss, .plt in that
> > +  // order. The TOC starts where the first of these sections
> > starts.
> > +  SectionList::const_iterator it = Sections.begin();
> > +  for (; it != Sections.end(); ++it) {
> 
> Dont evaluate Sections.end() on every iteration. Create ie =
> Sections.end() and check against it. Thats the preferred llvm style.
> 
> > +    if (it->Name == ".got")
> > +      break;
> > +    if (it->Name == ".toc")
> > +      break;
> > +    if (it->Name == ".tocbss")
> > +      break;
> > +    if (it->Name == ".plt")
> > +      break;
> > +  }
> 
> Can you reflow this to use else if?
> 
> > +  if (it == Sections.end()) {
> > +    // This may happen for
> > +    // * references to TOC base base (sym at toc, .odp relocation)
> > without
> > +    // a .toc directive.
> > +    // In this case just use the first section (which is usually
> > +    // the .odp) since the code won't reference the .toc base
> > +    // directly.
> > +    it = Sections.begin();
> > +  }
> > +  assert (it != Sections.end());
> > +  // Per the ppc64-elf-linux ABI, The TOC base if TOC value plus

typo: if -> is

> > 0x8000
> > +  // thus permitting a full 64 Kbytes segment.
> > +  return (*it).LoadAddress + 0x8000;
> 
> Use it->LoadAddress.
> 
> > +}
> > +
> > +// Returns the sections and offset associated with the ODP entry
> > referenced +// by Symbol.
> > +void RuntimeDyldELF::findOPDEntrySection(ObjectImage &Obj,
> > +                                         ObjSectionToIDMap
> > &LocalSections,
> > +                                         RelocationValueRef &Rel) {
> > +  // Get the ELF symbol value (st_value) to compare with
> > Relocation offset in
> > +  // .opd entries
> > +
> > +  error_code err;
> > +  for (section_iterator si = Obj.begin_sections(),
> > +     se = Obj.end_sections(); si != se; si.increment(err)) {
> > +    StringRef SectionName;
> > +    Check(si->getName(SectionName));
> > +    if (SectionName != ".opd")
> > +      continue;
> > +
> > +    for (relocation_iterator i = si->begin_relocations(),
> > +         e = si->end_relocations(); i != e;) {
> > +      Check(err);
> > +
> > +      // The R_PPC64_ADDR64 relocation indicates the first field
> > +      // of a .opd entry
> > +      uint64_t TypeFunc;
> > +      Check(i->getType(TypeFunc));
> > +      if (TypeFunc != ELF::R_PPC64_ADDR64) {
> > +        i.increment(err);
> > +        continue;
> > +      }
> > +
> > +      SymbolRef TargetSymbol;
> > +      Check(i->getSymbol(TargetSymbol));
> > +      uint64_t TargetSymbolOffset;
> > +      Check(i->getOffset(TargetSymbolOffset));
> > +      int64_t TargetAdditionalInfo;
> > +      Check(i->getAdditionalInfo(TargetAdditionalInfo));
> 
> Please declare all variables first and then Check all of them at once.
> 
> > +
> > +      i = i.increment(err);
> > +      if (i == e)
> > +        break;
> > +      Check(err);
> > +
> > +      // Just check if following relocation is a R_PPC64_TOC
> > +      uint64_t TypeTOC;
> > +      Check(i->getType(TypeTOC));
> > +      if (TypeTOC != ELF::R_PPC64_TOC)
> > +        continue;
> > +
> > +      // Finally compares the Symbol value and the target symbol
> > offset
> > +      // to check if this .opd entry refers to the symbol the
> > relocation
> > +      // points to.
> > +      if (Rel.Addend != (intptr_t)TargetSymbolOffset)
> > +        continue;
> > +
> > +      section_iterator tsi(Obj.end_sections());
> > +      Check(TargetSymbol.getSection(tsi));
> > +      Rel.SectionID = findOrEmitSection(Obj, (*tsi), true,
> > LocalSections);
> > +      Rel.Addend = (intptr_t)TargetAdditionalInfo;
> > +      return;
> > +    }
> > +  }
> > +  llvm_unreachable("Attempting to get address of ODP entry!");
> > +}
> > +
> > +// Relocation masks following the #lo(value), #hi(value),
> > #higher(value), +// and #highest(value) macros defined in section
> > 4.5.1. Relocation Types +// in PPC-elf64abi document.
> > +//
> > +static inline
> > +uint16_t applyPPClo (uint64_t value)
> > +{
> > +  return value & 0xffff;
> > +}
> > +
> > +static inline
> > +uint16_t applyPPChi (uint64_t value)
> > +{
> > +  return (value >> 16) & 0xffff;
> > +}
> > +
> > +static inline
> > +uint16_t applyPPChigher (uint64_t value)
> > +{
> > +  return (value >> 32) & 0xffff;
> > +}
> > +
> > +static inline
> > +uint16_t applyPPChighest (uint64_t value)
> > +{
> > +  return (value >> 48) & 0xffff;
> > +}
> > +
> > +void RuntimeDyldELF::resolvePPC64Relocation(uint8_t *LocalAddress,
> > +					    uint64_t FinalAddress,
> > +					    uint64_t Value,
> > +					    uint32_t Type,
> > +					    int64_t Addend) {
> > +  switch (Type) {
> > +  default:
> > +    llvm_unreachable("Relocation type not implemented yet!");
> > +  break;
> > +  case ELF::R_PPC64_ADDR16_LO :
> > +    writeInt16BE(LocalAddress, applyPPClo (Value + Addend));
> > +    break;
> > +  case ELF::R_PPC64_ADDR16_HI :
> > +    writeInt16BE(LocalAddress, applyPPChi (Value + Addend));
> > +    break;
> > +  case ELF::R_PPC64_ADDR16_HIGHER :
> > +    writeInt16BE(LocalAddress, applyPPChigher (Value + Addend));
> > +    break;
> > +  case ELF::R_PPC64_ADDR16_HIGHEST :
> > +    writeInt16BE(LocalAddress, applyPPChighest (Value + Addend));
> > +    break;
> > +  case ELF::R_PPC64_ADDR14 : {
> > +    assert(((Value + Addend) & 3) == 0);
> > +    uint16_t *insn = ((uint16_t*)LocalAddress+1);
> > +    writeInt16BE(LocalAddress + 2, (*insn & 3) | ((Value + Addend)
> > & 0xfffc));
> 
> Can you please add the comment here why +1 and +2? It's not obvious.
> 
> > +  } break;
> > +  case ELF::R_PPC64_REL24 : {
> > +    int32_t delta = static_cast<int32_t>(Value - FinalAddress +
> > Addend);
> > +    if (SignExtend32<24>(delta) != delta)
> > +      llvm_unreachable("Relocation R_PPC64_REL24 overflow");
> > +    // Generates a 'bl <address>' instruction
> > +    writeInt32BE(LocalAddress, 0x48000001 | (delta & 0x03FFFFFC));
> > +  } break;
> > +  case ELF::R_PPC64_ADDR64 :
> > +    writeInt64BE(LocalAddress, Value + Addend);
> > +    break;
> > +  case ELF::R_PPC64_TOC :
> > +    writeInt64BE(LocalAddress, findPPC64TOC());
> > +    break;
> > +  case ELF::R_PPC64_TOC16 : {
> > +    uint64_t TOCStart = findPPC64TOC();
> > +    Value = applyPPClo((Value + Addend) - TOCStart);
> > +    writeInt16BE(LocalAddress, applyPPClo(Value));
> > +  } break;
> > +  case ELF::R_PPC64_TOC16_DS : { 
> > +    uint64_t TOCStart = findPPC64TOC();
> > +    Value = ((Value + Addend) - TOCStart);
> > +    writeInt16BE(LocalAddress, applyPPClo(Value));
> > +  } break;
> > +  }
> > +}
> > +
> > +
> >  void RuntimeDyldELF::resolveRelocation(uint8_t *LocalAddress,
> >                                         uint64_t FinalAddress,
> >                                         uint64_t Value,
> > @@ -369,6 +551,9 @@ void RuntimeDyldELF::resolveRelocation(uint8_t
> > *LocalAddress, (uint32_t)(Value & 0xffffffffL), Type,
> >                            (uint32_t)(Addend & 0xffffffffL));
> >      break;
> > +  case Triple::ppc64:
> > +    resolvePPC64Relocation(LocalAddress, FinalAddress, Value,
> > Type, Addend);
> > +    break;
> >    default: llvm_unreachable("Unsupported CPU type!");
> >    }
> >  }
> > @@ -393,6 +578,8 @@ void RuntimeDyldELF::processRelocationRef(const
> > ObjRelocationInfo &Rel, RelocationValueRef Value;
> >    // First search for the symbol in the local symbol table
> >    SymbolTableMap::const_iterator lsi =
> > Symbols.find(TargetName.data());
> > +  SymbolRef::Type SymType;
> > +  Symbol.getType(SymType);
> >    if (lsi != Symbols.end()) {
> >      Value.SectionID = lsi->second.first;
> >      Value.Addend = lsi->second.second;
> > @@ -404,8 +591,6 @@ void RuntimeDyldELF::processRelocationRef(const
> > ObjRelocationInfo &Rel, Value.SectionID = gsi->second.first;
> >        Value.Addend = gsi->second.second;
> >      } else {
> > -      SymbolRef::Type SymType;
> > -      Symbol.getType(SymType);
> >        switch (SymType) {
> >          case SymbolRef::ST_Debug: {
> >            // TODO: Now ELF SymbolRef::ST_Debug = STT_SECTION, it's
> > not obviously @@ -513,6 +698,93 @@ void
> > RuntimeDyldELF::processRelocationRef(const ObjRelocationInfo &Rel,
> > Section.StubOffset, RelType, 0); Section.StubOffset +=
> > getMaxStubSize(); }
> > +  } else if (Arch == Triple::ppc64) {
> > +    if (RelType == ELF::R_PPC64_REL24) {
> > +      // A PPC branch relocation will need a stub function if the
> > target is
> > +      // an external symbol (Symbol::ST_Unknown) or if the target
> > address
> > +      // is not within the signed 24-bits branch address.
> > +      SectionEntry &Section = Sections[Rel.SectionID];
> > +      uint8_t *Target = Section.Address + Rel.Offset;
> > +      bool RangeOverflow = false;
> > +      if (SymType != SymbolRef::ST_Unknown) {
> > +        // A function call may points to the .opd entry, so the
> > final symbol value
> > +        // in calculated based in the relocation values in .opd
> > section.
> > +        findOPDEntrySection(Obj, ObjSectionToID, Value);
> > +        uint8_t *RelocTarget = Sections[Value.SectionID].Address +
> > Value.Addend;
> > +        int32_t delta = static_cast<int32_t>(Target - RelocTarget);
> > +        // If it is within 24-bits branch range, just set the
> > branch target
> > +        if (SignExtend32<24>(delta) == delta) {
> > +          RelocationEntry RE(Rel.SectionID, Rel.Offset, RelType,
> > Value.Addend);
> > +          if (Value.SymbolName)
> > +            addRelocationForSymbol(RE, Value.SymbolName);
> > +          else
> > +            addRelocationForSection(RE, Value.SectionID);
> > +        } else {
> > +          RangeOverflow = true;
> > +        }
> > +      }
> > +      if (SymType == SymbolRef::ST_Unknown || RangeOverflow ==
> > true) {
> > +        // It is an external symbol (SymbolRef::ST_Unknown) or
> > within a range
> > +        // larger than 24-bits.
> > +        StubMap::const_iterator i = Stubs.find(Value);
> > +        if (i != Stubs.end()) {
> > +          // Symbol function stub already created, just relocate
> > to it
> > +          resolveRelocation(Target, (uint64_t)Target,
> > (uint64_t)Section.Address
> > +                            + i->second, RelType, 0);
> > +          DEBUG(dbgs() << " Stub function found\n");

Would it make sense to print the symbol name in this debugging
statement?

> > +        } else {
> > +          // Create a new stub function.
> > +          DEBUG(dbgs() << " Create a new stub function\n");

Same here; context would be useful.

> > +          Stubs[Value] = Section.StubOffset;
> > +          uint8_t *StubTargetAddr =
> > createStubFunction(Section.Address +
> > +
> > Section.StubOffset);
> > +          RelocationEntry RE(Rel.SectionID, StubTargetAddr -
> > Section.Address,
> > +                             ELF::R_PPC64_ADDR64, Value.Addend);
> > +
> > +          // Generates the 64-bits address loads as exemplified in
> > section
> > +          // 4.5.1 in PPC64 ELF ABI.
> > +          RelocationEntry REhst(Rel.SectionID,
> > +                                StubTargetAddr - Section.Address +
> > 2,
> > +                                ELF::R_PPC64_ADDR16_HIGHEST,
> > Value.Addend);
> > +          RelocationEntry REhr(Rel.SectionID,
> > +                               StubTargetAddr - Section.Address +
> > 6,
> > +                               ELF::R_PPC64_ADDR16_HIGHER,
> > Value.Addend);
> > +          RelocationEntry REh(Rel.SectionID,
> > +                              StubTargetAddr - Section.Address +
> > 14,
> > +                              ELF::R_PPC64_ADDR16_HI,
> > Value.Addend);
> > +          RelocationEntry REl(Rel.SectionID,
> > +                              StubTargetAddr - Section.Address +
> > 18,
> > +                              ELF::R_PPC64_ADDR16_LO,
> > Value.Addend); +
> > +          if (Value.SymbolName) {
> > +            addRelocationForSymbol(REhst, Value.SymbolName);
> > +            addRelocationForSymbol(REhr,  Value.SymbolName);
> > +            addRelocationForSymbol(REh,   Value.SymbolName);
> > +            addRelocationForSymbol(REl,   Value.SymbolName);
> > +          } else {
> > +            addRelocationForSection(REhst, Value.SectionID);
> > +            addRelocationForSection(REhr,  Value.SectionID);
> > +            addRelocationForSection(REh,   Value.SectionID);
> > +            addRelocationForSection(REl,   Value.SectionID);
> > +          }
> > +
> > +          resolveRelocation(Target, (uint64_t)Target,
> > (uint64_t)Section.Address
> > +                            + Section.StubOffset, RelType, 0);
> > +          if (SymType == SymbolRef::ST_Unknown)
> > +            // Restore the TOC for external calls
> > +            *((uint32_t*)Target+1) = 0xE8410028;  // ld r2,40(r1)
> 
> Is the alignment ok here as Jim Grosbnach mentioned?
> 
> > +          Section.StubOffset += getMaxStubSize();
> > +        }
> > +      }
> > +    } else {
> > +      RelocationEntry RE(Rel.SectionID, Rel.Offset, RelType,
> > Value.Addend);
> > +      // Extra check to avoid relocation againt empty symbols
> > (usually
> > +      // the R_PPC64_TOC).
> > +      if (Value.SymbolName && !TargetName.empty())
> > +        addRelocationForSymbol(RE, Value.SymbolName);
> > +      else
> > +        addRelocationForSection(RE, Value.SectionID);
> > +    }
> >    } else {
> >      RelocationEntry RE(Rel.SectionID, Rel.Offset, RelType,
> > Value.Addend); if (Value.SymbolName)
> > diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h
> > b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h index
> > eade49e..997351b 100644 ---
> > a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++
> > b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -48,6 +48,12
> > @@ protected: uint32_t Type,
> >                               int32_t Addend);
> >  
> > +  void resolvePPC64Relocation(uint8_t *LocalAddress,
> > +                              uint64_t FinalAddress,
> > +                              uint64_t Value,
> > +                              uint32_t Type,
> > +                              int64_t Addend);
> > +
> >    virtual void resolveRelocation(uint8_t *LocalAddress,
> >                                   uint64_t FinalAddress,
> >                                   uint64_t Value,
> > @@ -63,6 +69,11 @@ protected:
> >    virtual ObjectImage *createObjectImage(const MemoryBuffer
> > *InputBuffer); virtual void handleObjectLoaded(ObjectImage *Obj);
> >  
> > +  uint64_t findPPC64TOC() const;
> > +  void findOPDEntrySection(ObjectImage &Obj,
> > +                           ObjSectionToIDMap &LocalSections,
> > +                           RelocationValueRef &Rel);
> > +
> >  public:
> >    RuntimeDyldELF(RTDyldMemoryManager *mm)
> >        : RuntimeDyldImpl(mm), LoadedObject(0) {}
> > diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h
> > b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index
> > b29ff40..444d095 100644 ---
> > a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++
> > b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -24,6 +24,8
> > @@ #include "llvm/Support/Debug.h"
> >  #include "llvm/Support/ErrorHandling.h"
> >  #include "llvm/Support/Format.h"
> > +#include "llvm/Support/Host.h"
> > +#include "llvm/Support/SwapByteOrder.h"
> >  #include "llvm/Support/raw_ostream.h"
> >  #include "llvm/Support/system_error.h"
> >  #include <map>
> > @@ -166,6 +168,8 @@ protected:
> >        return 8; // 32-bit instruction and 32-bit address
> >      else if (Arch == Triple::mipsel)
> >        return 16;
> > +    else if (Arch == Triple::ppc64)
> > +      return 44;
> >      else
> >        return 0;
> >    }
> > @@ -188,6 +192,35 @@ protected:
> >      return (uint8_t*)Sections[SectionID].Address;
> >    }
> >  
> > +  void writeInt16BE(uint8_t *Addr, uint16_t Value) {
> > +    if (sys::isLittleEndianHost())
> > +      Value = sys::SwapByteOrder(Value);
> > +    *Addr     = (Value >> 8) & 0xFF;
> > +    *(Addr+1) = Value & 0xFF;
> > +  }
> > +
> > +  void writeInt32BE(uint8_t *Addr, uint32_t Value) {
> > +    if (sys::isLittleEndianHost())
> > +      Value = sys::SwapByteOrder(Value);
> > +    *Addr     = (Value >> 24) & 0xFF;
> > +    *(Addr+1) = (Value >> 16) & 0xFF;
> > +    *(Addr+2) = (Value >> 8) & 0xFF;
> > +    *(Addr+3) = Value & 0xFF;
> > +  }
> > +
> > +  void writeInt64BE(uint8_t *Addr, uint64_t Value) {
> > +    if (sys::isLittleEndianHost())
> > +      Value = sys::SwapByteOrder(Value);
> > +    *Addr     = (Value >> 56) & 0xFF;
> > +    *(Addr+1) = (Value >> 48) & 0xFF;
> > +    *(Addr+2) = (Value >> 40) & 0xFF;
> > +    *(Addr+3) = (Value >> 32) & 0xFF;
> > +    *(Addr+4) = (Value >> 24) & 0xFF;
> > +    *(Addr+5) = (Value >> 16) & 0xFF;
> > +    *(Addr+6) = (Value >> 8) & 0xFF;
> > +    *(Addr+7) = Value & 0xFF;
> > +  }
> > +
> >    /// \brief Given the common symbols discovered in the object
> > file, emit a /// new section for them and update the symbol
> > mappings in the object and /// symbol table.
> > -- 
> > 1.7.1

Otherwise, LGTM.

Thanks again,
Hal

> > 
> 
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



-- 
Hal Finkel
Postdoctoral Appointee
Leadership Computing Facility
Argonne National Laboratory



More information about the llvm-commits mailing list