[llvm] r231544 - [dsymutil] Apply relocations to DIE data before cloning.

Eric Christopher echristo at gmail.com
Fri Mar 6 17:36:05 PST 2015


Possible to adapt the existing RelocVisitor code to do this?

-eric

On Fri, Mar 6, 2015 at 5:29 PM Frederic Riss <friss at apple.com> wrote:

> Author: friss
> Date: Fri Mar  6 19:25:09 2015
> New Revision: 231544
>
> URL: http://llvm.org/viewvc/llvm-project?rev=231544&view=rev
> Log:
> [dsymutil] Apply relocations to DIE data before cloning.
>
> Doing this gets function's low_pc and global variable's locations right
> in the output debug info. It also could get right other attributes
> that need to be relocated (in linker terms), but I don't know of any
> other than the address attributes.
>
> This doesn't fixup low_pc attributes in compile_unit, lexical_block
> or inlined subroutine, nor does it get right high_pc attributes
> for function. This will come in a subsequent commit.
>
> Modified:
>     llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test
>     llvm/trunk/test/tools/dsymutil/X86/basic-lto-linking-x86.test
>     llvm/trunk/tools/dsymutil/DwarfLinker.cpp
>
> Modified: llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/
> dsymutil/X86/basic-linking-x86.test?rev=231544&r1=231543&
> r2=231544&view=diff
> ============================================================
> ==================
> --- llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test (original)
> +++ llvm/trunk/test/tools/dsymutil/X86/basic-linking-x86.test Fri Mar  6
> 19:25:09 2015
> @@ -3,8 +3,8 @@ RUN: llvm-dsymutil -oso-prepend-path=%p/
>  RUN: llvm-dwarfdump %t1.dwarf | FileCheck %s
>  RUN: llvm-dsymutil -o %t2 -oso-prepend-path=%p/..
> %p/../Inputs/basic.macho.x86_64
>  RUN: llvm-dwarfdump %t2 | FileCheck %s
> -RUN: llvm-dsymutil -o - -oso-prepend-path=%p/..
> %p/../Inputs/basic.macho.x86_64 | llvm-dwarfdump - | FileCheck %s
> -RUN: llvm-dsymutil -o - -oso-prepend-path=%p/..
> %p/../Inputs/basic-archive.macho.x86_64 | llvm-dwarfdump - | FileCheck %s
> +RUN: llvm-dsymutil -o - -oso-prepend-path=%p/..
> %p/../Inputs/basic.macho.x86_64 | llvm-dwarfdump - | FileCheck %s
> --check-prefix=CHECK --check-prefix=BASIC
> +RUN: llvm-dsymutil -o - -oso-prepend-path=%p/..
> %p/../Inputs/basic-archive.macho.x86_64 | llvm-dwarfdump - | FileCheck %s
> --check-prefix=CHECK --check-prefix=ARCHIVE
>
>  CHECK: file format Mach-O 64-bit x86-64
>
> @@ -24,6 +24,7 @@ CHECK:      DW_AT_prototyped [DW_FORM_fl
>  CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x0063 => {0x00000063})
>  CHECK:      DW_AT_external [DW_FORM_flag]      (0x01)
>  CHECK:      DW_AT_accessibility [DW_FORM_data1]        (DW_ACCESS_public)
> +CHECK:      DW_AT_low_pc [DW_FORM_addr]     (0x0000000100000ea0)
>  CHECK:      DW_AT_frame_base [DW_FORM_block1]  (<0x01> 56 )
>  CHECK:      DW_TAG_formal_parameter [3]
>  CHECK:        DW_AT_name [DW_FORM_strp]     ( .debug_str[0x00000056] =
> "argc")
> @@ -64,12 +65,16 @@ CHECK:      DW_AT_name [DW_FORM_strp]
>  CHECK:    DW_TAG_variable [7]
>  CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000072] =
> "private_int")
>  CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x0026 => {0x000000a7})
> +BASIC:      DW_AT_location [DW_FORM_block1] (<0x09> 03 08 10 00 00 01 00
> 00 00 )
> +ARCHIVE:    DW_AT_location [DW_FORM_block1] (<0x09> 03 04 10 00 00 01 00
> 00 00 )
>  CHECK:    DW_TAG_variable [7]
>  CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x0000007e] =
> "baz")
>  CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x0026 => {0x000000a7})
> +CHECK:      DW_AT_location [DW_FORM_block1] (<0x09> 03 00 10 00 00 01 00
> 00 00 )
>  CHECK:    DW_TAG_subprogram [2] *
>  CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000082] =
> "foo")
>  CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x0026 => {0x000000a7})
> +CHECK:      DW_AT_low_pc [DW_FORM_addr]     (0x0000000100000ed0)
>  CHECK:      DW_AT_frame_base [DW_FORM_block1]  (<0x01> 56 )
>  CHECK:      DW_TAG_formal_parameter [3]
>  CHECK:        DW_AT_name [DW_FORM_strp]     ( .debug_str[0x00000086] =
> "arg")
> @@ -79,6 +84,7 @@ CHECK:      NULL
>  CHECK:    DW_TAG_subprogram [8]
>  CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x0000008a] =
> "inc")
>  CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x0026 => {0x000000a7})
> +CHECK:      DW_AT_low_pc [DW_FORM_addr]     (0x0000000100000f20)
>  CHECK:      DW_AT_frame_base [DW_FORM_block1]  (<0x01> 56 )
>  CHECK:    NULL
>
> @@ -91,6 +97,8 @@ CHECK:    DW_AT_comp_dir [DW_FORM_strp]
>  CHECK:    DW_TAG_variable [9]
>  CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000097] =
> "val")
>  CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x003c => {0x00000162})
> +BASIC:      DW_AT_location [DW_FORM_block1] (<0x09> 03 04 10 00 00 01 00
> 00 00 )
> +ARCHIVE:    DW_AT_location [DW_FORM_block1] (<0x09> 03 08 10 00 00 01 00
> 00 00 )
>  CHECK:    DW_TAG_volatile_type [10]
>  CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x0041 => {0x00000167})
>  CHECK:    DW_TAG_base_type [4]
> @@ -98,6 +106,7 @@ CHACK:      DW_AT_name [DW_FORM_strp]
>  CHECK:    DW_TAG_subprogram [2] *
>  CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x0000009b] =
> "bar")
>  CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x0041 => {0x00000167})
> +CHECK:      DW_AT_low_pc [DW_FORM_addr]     (0x0000000100000f40)
>  CHECK:      DW_AT_frame_base [DW_FORM_block1]  (<0x01> 56 )
>  CHECK:      DW_TAG_formal_parameter [3]
>  CHECK:        DW_AT_name [DW_FORM_strp]     ( .debug_str[0x00000086] =
> "arg")
> @@ -107,6 +116,7 @@ CHECK:      NULL
>  CHECK:    DW_TAG_subprogram [8]
>  CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x0000008a] =
> "inc")
>  CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x0041 => {0x00000167})
> +CHECK:      DW_AT_low_pc [DW_FORM_addr]     (0x0000000100000f90)
>  CHECK:      DW_AT_frame_base [DW_FORM_block1]  (<0x01> 56 )
>
>  CHECK:    NULL
>
> Modified: llvm/trunk/test/tools/dsymutil/X86/basic-lto-linking-x86.test
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/
> dsymutil/X86/basic-lto-linking-x86.test?rev=231544&
> r1=231543&r2=231544&view=diff
> ============================================================
> ==================
> --- llvm/trunk/test/tools/dsymutil/X86/basic-lto-linking-x86.test
> (original)
> +++ llvm/trunk/test/tools/dsymutil/X86/basic-lto-linking-x86.test Fri
> Mar  6 19:25:09 2015
> @@ -18,6 +18,7 @@ CHECK:      DW_AT_prototyped [DW_FORM_fl
>  CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x0063 => {0x00000063})
>  CHECK:      DW_AT_external [DW_FORM_flag]      (0x01)
>  CHECK:      DW_AT_accessibility [DW_FORM_data1]        (DW_ACCESS_public)
> +CHECK:      DW_AT_low_pc [DW_FORM_addr]     (0x0000000100000f40)
>  CHECK:      DW_AT_frame_base [DW_FORM_block1]  (<0x01> 56 )
>  CHECK:      DW_TAG_formal_parameter [3]
>  CHECK:        DW_AT_name [DW_FORM_strp]     ( .debug_str[0x00000056] =
> "argc")
> @@ -53,12 +54,15 @@ CHECK:    DW_AT_comp_dir [DW_FORM_strp]
>  CHECK:    DW_TAG_variable [7]
>  CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000072] =
> "private_int")
>  CHECK:      DW_AT_type [DW_FORM_ref_addr]   (0x0000000000000063)
> +CHECK:      DW_AT_location [DW_FORM_block1] (<0x09> 03 08 10 00 00 01 00
> 00 00 )
>  CHECK:    DW_TAG_variable [7]
>  CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x0000007e] =
> "baz")
>  CHECK:      DW_AT_type [DW_FORM_ref_addr]   (0x0000000000000063)
> +CHECK:      DW_AT_location [DW_FORM_block1] (<0x09> 03 00 10 00 00 01 00
> 00 00 )
>  CHECK:    DW_TAG_subprogram [8] *
>  CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000082] =
> "foo")
>  CHECK:      DW_AT_type [DW_FORM_ref_addr]   (0x0000000000000063)
> +CHECK:      DW_AT_low_pc [DW_FORM_addr]     (0x0000000100000f50)
>  CHECK:      DW_AT_frame_base [DW_FORM_block1]  (<0x01> 56 )
>  CHECK:      DW_TAG_formal_parameter [9]
>  CHECK:        DW_AT_name [DW_FORM_strp]     ( .debug_str[0x00000086] =
> "arg")
> @@ -82,11 +86,13 @@ CHECK:    DW_AT_comp_dir [DW_FORM_strp]
>  CHECK:    DW_TAG_variable [12]
>  CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x00000097] =
> "val")
>  CHECK:      DW_AT_type [DW_FORM_ref4]       (cu + 0x003c => {0x00000176})
> +CHECK:      DW_AT_location [DW_FORM_block1] (<0x09> 03 04 10 00 00 01 00
> 00 00 )
>  CHECK:    DW_TAG_volatile_type [13]
>  CHECK:      DW_AT_type [DW_FORM_ref_addr]   (0x0000000000000063)
>  CHECK:    DW_TAG_subprogram [8] *
>  CHECK:      DW_AT_name [DW_FORM_strp]       ( .debug_str[0x0000009b] =
> "bar")
>  CHECK:      DW_AT_type [DW_FORM_ref_addr]   (0x0000000000000063)
> +CHECK:      DW_AT_low_pc [DW_FORM_addr]     (0x0000000100000f90)
>  CHECK:      DW_AT_frame_base [DW_FORM_block1]  (<0x01> 56 )
>  CHECK:      DW_TAG_formal_parameter [9]
>  CHECK:        DW_AT_name [DW_FORM_strp]     ( .debug_str[0x00000086] =
> "arg")
>
> Modified: llvm/trunk/tools/dsymutil/DwarfLinker.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/
> dsymutil/DwarfLinker.cpp?rev=231544&r1=231543&r2=231544&view=diff
> ============================================================
> ==================
> --- llvm/trunk/tools/dsymutil/DwarfLinker.cpp (original)
> +++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp Fri Mar  6 19:25:09 2015
> @@ -463,7 +463,7 @@ private:
>    /// consider. As we walk the DIEs in acsending file offset and as
>    /// ValidRelocs is sorted by file offset, keeping this index
>    /// uptodate is all we have to do to have a cheap lookup during the
> -  /// root DIE selection.
> +  /// root DIE selection and during DIE cloning.
>    unsigned NextValidReloc;
>
>    bool findValidRelocsInDebugInfo(const object::ObjectFile &Obj,
> @@ -562,6 +562,10 @@ private:
>                                  const DWARFUnit &U, AttributeSpec
> AttrSpec,
>                                  const DWARFFormValue &Val, unsigned
> AttrSize);
>
> +  /// \brief Helper for cloneDIE.
> +  bool applyValidRelocs(MutableArrayRef<char> Data, uint32_t BaseOffset,
> +                        bool isLittleEndian);
> +
>    /// \brief Assign an abbreviation number to \p Abbrev
>    void AssignAbbrev(DIEAbbrev &Abbrev);
>
> @@ -1256,6 +1260,50 @@ unsigned DwarfLinker::cloneAttribute(DIE
>    return 0;
>  }
>
> +/// \brief Apply the valid relocations found by findValidRelocs() to
> +/// the buffer \p Data, taking into account that Data is at \p BaseOffset
> +/// in the debug_info section.
> +///
> +/// Like for findValidRelocs(), this function must be called with
> +/// monotonic \p BaseOffset values.
> +///
> +/// \returns wether any reloc has been applied.
> +bool DwarfLinker::applyValidRelocs(MutableArrayRef<char> Data,
> +                                   uint32_t BaseOffset, bool
> isLittleEndian) {
> +  assert(NextValidReloc == 0 ||
> +         BaseOffset > ValidRelocs[NextValidReloc - 1].Offset &&
> +             "BaseOffset should only be increasing.");
> +  if (NextValidReloc >= ValidRelocs.size())
> +    return false;
> +
> +  // Skip relocs that haven't been applied.
> +  while (NextValidReloc < ValidRelocs.size() &&
> +         ValidRelocs[NextValidReloc].Offset < BaseOffset)
> +    ++NextValidReloc;
> +
> +  bool Applied = false;
> +  uint64_t EndOffset = BaseOffset + Data.size();
> +  while (NextValidReloc < ValidRelocs.size() &&
> +         ValidRelocs[NextValidReloc].Offset >= BaseOffset &&
> +         ValidRelocs[NextValidReloc].Offset < EndOffset) {
> +    const auto &ValidReloc = ValidRelocs[NextValidReloc++];
> +    assert(ValidReloc.Offset - BaseOffset < Data.size());
> +    assert(ValidReloc.Offset - BaseOffset + ValidReloc.Size <=
> Data.size());
> +    char Buf[8];
> +    uint64_t Value = ValidReloc.Mapping->getValue().BinaryAddress;
> +    Value += ValidReloc.Addend;
> +    for (unsigned i = 0; i != ValidReloc.Size; ++i) {
> +      unsigned Index = isLittleEndian ? i : (ValidReloc.Size - i - 1);
> +      Buf[i] = uint8_t(Value >> (Index * 8));
> +    }
> +    assert(ValidReloc.Size <= sizeof(Buf));
> +    memcpy(&Data[ValidReloc.Offset - BaseOffset], Buf, ValidReloc.Size);
> +    Applied = true;
> +  }
> +
> +  return Applied;
> +}
> +
>  /// \brief Recursively clone \p InputDIE's subtrees that have been
>  /// selected to appear in the linked output.
>  ///
> @@ -1284,6 +1332,20 @@ DIE *DwarfLinker::cloneDIE(const DWARFDe
>
>    // Extract and clone every attribute.
>    DataExtractor Data = U.getDebugInfoExtractor();
> +  uint32_t NextOffset = U.getDIEAtIndex(Idx + 1)->getOffset();
> +
> +  // We could copy the data only if we need to aply a relocation to
> +  // it. After testing, it seems there is no performance downside to
> +  // doing the copy unconditionally, and it makes the code simpler.
> +  SmallString<40> DIECopy(Data.getData().substr(Offset, NextOffset -
> Offset));
> +  Data = DataExtractor(DIECopy, Data.isLittleEndian(),
> Data.getAddressSize());
> +  // Modify the copy with relocated addresses.
> +  applyValidRelocs(DIECopy, Offset, Data.isLittleEndian());
> +
> +  // Reset the Offset to 0 as we will be working on the local copy of
> +  // the data.
> +  Offset = 0;
> +
>    const auto *Abbrev = InputDIE.getAbbreviationDeclarationPtr();
>    Offset += getULEB128Size(Abbrev->getCode());
>
> @@ -1386,6 +1448,11 @@ bool DwarfLinker::link(const DebugMap &M
>        lookForDIEsToKeep(*CurrentUnit.getOrigUnit().getCompileUnitDIE(),
> *Obj,
>                          CurrentUnit, 0);
>
> +    // The calls to applyValidRelocs inside cloneDIE will walk the
> +    // reloc array again (in the same way findValidRelocsInDebugInfo()
> +    // did). We need to reset the NextValidReloc index to the beginning.
> +    NextValidReloc = 0;
> +
>      // Construct the output DIE tree by cloning the DIEs we chose to
>      // keep above. If there are no valid relocs, then there's nothing
>      // to clone/emit.
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150307/8e6c56e5/attachment.html>


More information about the llvm-commits mailing list