[llvm-commits] lld update to add support for some hexagon relocations.

David Blaikie dblaikie at gmail.com
Tue Oct 2 23:46:49 PDT 2012


On Tue, Oct 2, 2012 at 12:17 PM, Michael Spencer <bigcheesegs at gmail.com> wrote:
> On Tue, Oct 2, 2012 at 11:09 AM, Sid Manning <sidneym at codeaurora.org> wrote:
>> On 09/28/12 12:22, Sid Manning wrote:
>>>
>>>
>>> Attached are files that add support for the most basic relocation fixups
>>> for hexagon.
>>>
>>> I added a new applyFixup method to take an int32_t, so instead of Kind
>>> enums applyFixup can take enums defined in ELF.h.
>>>
>>> In the case of hexagon I moved code from ReferenceKinds.cpp to a new
>>> file HexagonReference.cpp which will hold the Hexagon specific
>>> relocation code.
>>>
>> Any comments on this patch?
>>
>>
>>
>>
>> --
>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by
>> The Linux Foundation
>
>> Index: lib/ReaderWriter/ELF/ReferenceKinds.cpp
>> ===================================================================
>> --- lib/ReaderWriter/ELF/ReferenceKinds.cpp   (revision 164787)
>> +++ lib/ReaderWriter/ELF/ReferenceKinds.cpp   (working copy)
>> @@ -82,82 +82,13 @@
>>    return false;
>>  }
>>
>> -
>> -void KindHandler_x86::applyFixup(Kind kind, uint64_t addend,
>> -                                    uint8_t *location, uint64_t fixupAddress,
>> +void KindHandler_x86::applyFixup(int32_t reloc, uint64_t addend,
>> +                                    uint8_t *location, uint64_t fixupAddress,
>>                                      uint64_t targetAddress) {
>> -  switch ((Kinds)kind) {
>> -  case none:
>> -    // do nothing
>> -    break;
>> -  case invalid:
>> -    assert(0 && "invalid Reference Kind");
>> -    break;
>> -  }
>> +  return;
>> +  llvm_unreachable("Unimplemented: KindHandler_x86::applyFixup");
>>  }
>
> The llvm_unreachable is super unreachable :P. This should read:
>
>   llvm_unreachable(...);
>   return;
>
> Or:
>
>   return llvm_unreachable(...);

or, you know, just: llvm_unreachable(...); since it's a void returning
function anyway it can just fall off the end in the
non-supporting-unreachable case.

>
>>
>> -//===----------------------------------------------------------------------===//
>> -//  KindHandler_hexagon
>> -//  TODO: more to do here
>> -//===----------------------------------------------------------------------===//
>> -
>> -KindHandler_hexagon::~KindHandler_hexagon() {
>> -}
>> -
>> -Reference::Kind KindHandler_hexagon::stringToKind(StringRef str) {
>> -  return llvm::StringSwitch<Reference::Kind>(str)
>> -    .Case("none",                  none)
>> -    .Default(invalid);
>> -
>> -  llvm_unreachable("invalid hexagon Reference kind");
>> -}
>> -
>> -StringRef KindHandler_hexagon::kindToString(Reference::Kind kind) {
>> -  switch ( (Kinds)kind ) {
>> -    case invalid:
>> -      return StringRef("invalid");
>> -    case none:
>> -      return StringRef("none");
>
> No need for StringRef here. Same for a bunch of other places.
>
>> -  }
>> -  llvm_unreachable("invalid hexagon Reference kind");
>> -}
>> -
>> -bool KindHandler_hexagon::isCallSite(Kind kind) {
>> -  llvm_unreachable("Unimplemented: KindHandler_hexagon::isCallSite");
>> -  return false;
>> -}
>> -
>> -bool KindHandler_hexagon::isPointer(Kind kind) {
>> -  llvm_unreachable("Unimplemented: KindHandler_hexagon::isPointer");
>> -  return false;
>> -}
>> -
>> -bool KindHandler_hexagon::isLazyImmediate(Kind kind) {
>> -  llvm_unreachable("Unimplemented: KindHandler_hexagon::isLazyImmediate");
>> -  return false;
>> -}
>> -
>> -bool KindHandler_hexagon::isLazyTarget(Kind kind) {
>> -  llvm_unreachable("Unimplemented: KindHandler_hexagon::isLazyTarget");
>> -  return false;
>> -}
>> -
>> -
>> -void KindHandler_hexagon::applyFixup(Kind kind, uint64_t addend,
>> -                                    uint8_t *location, uint64_t fixupAddress,
>> -                                    uint64_t targetAddress) {
>> -  switch ((Kinds)kind) {
>> -  case none:
>> -    // do nothing
>> -    break;
>> -  case invalid:
>> -    llvm_unreachable("invalid Reference Kind");
>> -    break;
>> -  }
>> -}
>> -
>> -
>> -
>>  } // namespace elf
>>  } // namespace lld
>>
>> Index: lib/ReaderWriter/ELF/HexagonReference.cpp
>> ===================================================================
>> --- lib/ReaderWriter/ELF/HexagonReference.cpp (revision 0)
>> +++ lib/ReaderWriter/ELF/HexagonReference.cpp (revision 0)
>> @@ -0,0 +1,172 @@
>> +//===- lib/ReaderWriter/ELF/ReferenceKinds.cpp ----------------------------===//
>> +//
>> +//                             The LLVM Linker
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//===----------------------------------------------------------------------===//
>> +
>> +
>> +#include "ReferenceKinds.h"
>> +
>> +#include "llvm/ADT/StringRef.h"
>> +#include "llvm/ADT/StringSwitch.h"
>> +
>> +#include "llvm/Support/ErrorHandling.h"
>> +#include "llvm/Support/ELF.h"
>> +namespace lld {
>> +namespace elf {
>> +
>> +//===----------------------------------------------------------------------===//
>> +//  KindHandler_hexagon
>> +//  TODO: more to do here
>> +//===----------------------------------------------------------------------===//
>> +
>> +KindHandler_hexagon::~KindHandler_hexagon() {
>> +}
>> +
>> +/// \brief The following relocation routines are derived from the
>> +/// Hexagon ABI specification, Section 11.6: Relocation
>> +/// Symbols used:
>> +///  A: Added used to compute the value, r_addend
>> +///  P: Place address of the field being relocated, r_offset
>> +///  S: Value of the symbol whose index resides in the relocation entry.
>> +
>> +int reloc_NONE(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
>> +  return KindHandler_hexagon::NoError;
>> +}
>> +
>> +/// \brief Word32_B22: 0x01ff3ffe : (S + A - P) >> 2 : Verify
>> +int reloc_B22_PCREL(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
>> +  int32_t result = (uint32_t)(((S + A) - P)>>2);
>> +  if ((result < 0x200000) && (result > -0x200000)) {
>> +      result = ((result<<1) & 0x3ffe) | ((result<<3) & 0x01ff0000);
>> +      *(uint32_t *)location |= result;
>
> This assumes the target and host have the same endianess. Use somthing
> equivelent to:
>
>   *reinterpret_cast<u{little,big}32_t*>(location) = result |
> *reinterpret_cast<const u{little,big}32_t*>(location);
>
> This is true for all of the following. You will need to modify
> KindHandler::makeHandler to get the endianess.
>
>> +      return KindHandler_hexagon::NoError;
>> +  }
>> +  return KindHandler_hexagon::Overflow;
>> +}
>> +
>> +/// \brief Word32_B15: 0x00df20fe : (S + A - P) >> 2 : Verify
>> +int reloc_B15_PCREL(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
>> +  int32_t result = (uint32_t)(((S + A) - P)>>2);
>> +  if ((result < 0x8000) && (result > -0x8000)) {
>> +    result = ((result<<1) & 0x20fe) | ((result<<7) & 0x00df0000);
>> +    *(uint32_t *)location |= result;
>> +    return KindHandler_hexagon::NoError;
>> +  }
>> +  return KindHandler_hexagon::Overflow;
>> +}
>> +
>> +/// \brief Word32_LO: 0x00c03fff : (S + A) : Truncate
>> +int reloc_LO16(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
>> +  uint32_t result = (uint32_t)(S + A);
>> +  result = ((result & 0x3fff) | ((result << 2) & 0x00c00000));
>> +  *(uint32_t *)location |= result;
>> +  return KindHandler_hexagon::NoError;
>> +}
>> +
>> +/// \brief Word32_LO: 0x00c03fff : (S + A) >> 16 : Truncate
>> +int reloc_HI16(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
>> +  uint32_t result = (uint32_t)((S + A)>>16);
>> +  result = ((result & 0x3fff) | ((result << 2) & 0x00c00000));
>> +  *(uint32_t *)location |= result;
>> +  return KindHandler_hexagon::NoError;
>> +}
>> +
>> +/// \brief Word32: 0xffffffff : (S + A) : Truncate
>> +int reloc_32(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
>> +  uint32_t result = (uint32_t)(S + A);
>> +  *(uint32_t *)location |= result;
>> +  return KindHandler_hexagon::NoError;
>> +}
>> +
>> +
>> +void testfunc(void){}
>> +KindHandler_hexagon::KindHandler_hexagon(){
>> +
>
> Remove undeeded blank lines.
>
>> +  _fixupHandler[llvm::ELF::R_HEX_B22_PCREL] = reloc_B22_PCREL;
>> +  _fixupHandler[llvm::ELF::R_HEX_B15_PCREL] = reloc_B15_PCREL;
>> +  _fixupHandler[llvm::ELF::R_HEX_LO16]      = reloc_LO16;
>> +  _fixupHandler[llvm::ELF::R_HEX_HI16]      = reloc_HI16;
>> +  _fixupHandler[llvm::ELF::R_HEX_32]        = reloc_32;
>> +
>> +}
>> +
>> +Reference::Kind KindHandler_hexagon::stringToKind(StringRef str) {
>> +  return llvm::StringSwitch<Reference::Kind>(str)
>> +    .Case("none",                  none)
>> +    .Case("R_HEX_B22_PCREL", llvm::ELF::R_HEX_B22_PCREL)
>> +    .Case("R_HEX_B15_PCREL", llvm::ELF::R_HEX_B15_PCREL)
>> +    .Case("R_HEX_LO16",      llvm::ELF::R_HEX_LO16)
>> +    .Case("R_HEX_HI16",      llvm::ELF::R_HEX_HI16)
>> +    .Case("R_HEX_32",        llvm::ELF::R_HEX_32)
>> +    .Default(invalid);
>> +  llvm_unreachable("invalid hexagon Reference kind");
>
> StringSwitch doesn't work like this. llvm_unreachable statically cannot be
> reached. If you want to disallow the invalid case, store the result of the
> StringSwitch in a local and assert on it. Then return the value.
>
>> +}
>> +
>> +StringRef KindHandler_hexagon::kindToString(Reference::Kind kind) {
>> +  switch ( (int32_t)kind ) {
>
> static_cast and no spaces after ( and before ).
>
>> +    case llvm::ELF::R_HEX_B22_PCREL:
>> +      return StringRef("R_HEX_B22_PCREL");
>> +    case llvm::ELF::R_HEX_B15_PCREL:
>> +      return StringRef("R_HEX_B15_PCREL");
>> +    case llvm::ELF::R_HEX_LO16:
>> +      return StringRef("R_HEX_LO16");
>> +    case llvm::ELF::R_HEX_HI16:
>> +      return StringRef("R_HEX_HI16");
>> +    case llvm::ELF::R_HEX_32:
>> +      return StringRef("R_HEX_32");
>> +    default:
>> +      return StringRef("none");
>
> This block needs be deinteded two spaces.
>
>> +  }
>> +  llvm_unreachable("invalid hexagon Reference kind");
>
> llvm_unreachable shouldn't be used when it is known that the switch statically
> covers all cases.
>
>> +}
>> +
>> +bool KindHandler_hexagon::isCallSite(Kind kind) {
>> +  llvm_unreachable("Unimplemented: KindHandler_hexagon::isCallSite");
>> +  return false;
>> +}
>> +
>> +bool KindHandler_hexagon::isPointer(Kind kind) {
>> +  llvm_unreachable("Unimplemented: KindHandler_hexagon::isPointer");
>> +  return false;
>> +}
>> +
>> +bool KindHandler_hexagon::isLazyImmediate(Kind kind) {
>> +  llvm_unreachable("Unimplemented: KindHandler_hexagon::isLazyImmediate");
>> +  return false;
>> +}
>> +
>> +bool KindHandler_hexagon::isLazyTarget(Kind kind) {
>> +  llvm_unreachable("Unimplemented: KindHandler_hexagon::isLazyTarget");
>> +  return false;
>> +}
>> +
>> +void KindHandler_hexagon::applyFixup(int32_t reloc, uint64_t addend,
>> +                                    uint8_t *location, uint64_t fixupAddress,
>> +                                    uint64_t targetAddress) {
>
> Line up with other arguments.
>
>> +  int error;
>> +  if (_fixupHandler[reloc])
>> +  {
>
> { needs to be on previous line.
>
>> +    error = (*_fixupHandler[reloc])(location,
>> +                                   fixupAddress, targetAddress, addend);
>
> Line up with other arguments.
>
>> +
>> +    switch ((RelocationError)error) {
>> +    case NoError:
>> +      return;
>> +    case Overflow:
>> +      llvm_unreachable("KindHandler_hexagon::applyFixup relocation overflow");
>
> Is this actually unreachable? Or is this an error condition?
>
>> +      return;
>> +    }
>> +  }
>> +
>> +  llvm_unreachable(
>> +       "Unimplemented _fixupHandler KindHandler_hexagon::applyFixup");
>> +}
>> +
>> +
>> +
>> +} // namespace elf
>> +} // namespace lld
>> Index: lib/ReaderWriter/ELF/CMakeLists.txt
>> ===================================================================
>> --- lib/ReaderWriter/ELF/CMakeLists.txt       (revision 164787)
>> +++ lib/ReaderWriter/ELF/CMakeLists.txt       (working copy)
>> @@ -2,5 +2,6 @@
>>    ReaderELF.cpp
>>    WriterELF.cpp
>>    ReferenceKinds.cpp
>> +  HexagonReference.cpp
>>    WriterOptionsELF.cpp
>>    )
>> Index: lib/ReaderWriter/ELF/ReferenceKinds.h
>> ===================================================================
>> --- lib/ReaderWriter/ELF/ReferenceKinds.h     (revision 164787)
>> +++ lib/ReaderWriter/ELF/ReferenceKinds.h     (working copy)
>> @@ -7,11 +7,11 @@
>>  //
>>  //===----------------------------------------------------------------------===//
>>
>> -
>>  #include "lld/Core/LLVM.h"
>>  #include "lld/Core/Reference.h"
>>  #include "lld/ReaderWriter/WriterELF.h"
>>
>> +#include <map>
>>  #include <memory>
>>
>>  #ifndef LLD_READER_WRITER_ELF_REFERENCE_KINDS_H_
>> @@ -39,8 +39,9 @@
>>    virtual bool        isPointer(Kind) = 0;
>>    virtual bool        isLazyImmediate(Kind) = 0;
>>    virtual bool        isLazyTarget(Kind) = 0;
>> -  virtual void        applyFixup(Kind kind, uint64_t addend, uint8_t *location,
>> -                           uint64_t fixupAddress, uint64_t targetAddress) = 0;
>> +  virtual void        applyFixup(int32_t reloc, uint64_t addend,
>> +                             uint8_t *location,
>> +                             uint64_t fixupAddress, uint64_t targetAddress) = 0;
>
> Line up with other arguments.
>
>>
>>  protected:
>>    KindHandler();
>> @@ -49,21 +50,38 @@
>>
>>  class KindHandler_hexagon : public KindHandler {
>>  public:
>> +
>> +// Note: Reference::Kinds are a another representation of
>> +// relocation types, using negative values to represent architecture
>> +// independent reference type.
>> +// The positive values are the same ones defined in ELF.h and that
>> +// is what we are using.
>
> Doxygen comment.
>
>>    enum Kinds {
>> -    invalid,         // used to denote an error creating a Reference
>> -    none,
>> +    none            = llvm::ELF::R_HEX_NONE,
>> +    invalid=255,         // used to denote an error creating a Reference
>
> Spaces around =.
>
>>    };
>>
>> +  enum RelocationError {
>> +    NoError,
>> +    Overflow
>> +  };
>> +
>>    virtual ~KindHandler_hexagon();
>> +  KindHandler_hexagon();
>>    virtual Kind stringToKind(StringRef str);
>>    virtual StringRef kindToString(Kind);
>>    virtual bool isCallSite(Kind);
>>    virtual bool isPointer(Kind);
>>    virtual bool isLazyImmediate(Kind);
>>    virtual bool isLazyTarget(Kind);
>> -  virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
>> -                  uint64_t fixupAddress, uint64_t targetAddress);
>> +  virtual void applyFixup(int32_t reloc, uint64_t addend,
>> +                          uint8_t *location,
>> +                          uint64_t fixupAddress, uint64_t targetAddress);
>>
>> +private:
>> +  std::map<int32_t, int (*)(uint8_t *location, uint64_t fixupAddress,
>> +                 uint64_t targetAddress, uint64_t addend)> _fixupHandler;
>> +
>>  };
>>
>>
>> @@ -81,8 +99,8 @@
>>    virtual bool isPointer(Kind);
>>    virtual bool isLazyImmediate(Kind);
>>    virtual bool isLazyTarget(Kind);
>> -  virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location,
>> -                  uint64_t fixupAddress, uint64_t targetAddress);
>> +  virtual void applyFixup(int32_t reloc, uint64_t addend, uint8_t *location,
>> +                          uint64_t fixupAddress, uint64_t targetAddress);
>>
>>  };
>>
>
> - 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