Coder Social home page Coder Social logo

snsystems / llvm-prepo Goto Github PK

View Code? Open in Web Editor NEW
6.0 6.0 0.0 298.14 MB

Program repository project has moved to https://github.com/SNSystems/llvm-project-prepo

License: Other

CMake 0.20% Shell 0.04% Go 0.06% C++ 33.34% OCaml 0.13% Python 0.39% C 0.36% Objective-C 0.01% LLVM 47.52% Assembly 17.89% Roff 0.01% Logos 0.01% Perl 0.01% Emacs Lisp 0.01% Batchfile 0.01% Vim Script 0.01% HTML 0.01% PHP 0.01% CSS 0.01% Dockerfile 0.01%
llvm llvm-prepo program-repository

llvm-prepo's People

Contributors

ahatanak avatar arsenm avatar asl avatar atrick avatar bob-wilson avatar chandlerc avatar chapuni avatar cunningbaldrick avatar d0k avatar ddunbar avatar dexonsmith avatar dsandersllvm avatar dwblaikie avatar echristo avatar espindola avatar isanbard avatar lattner avatar lhames avatar majnemer avatar matzeb avatar mbrukman avatar nlewycky avatar resistor avatar rksimon avatar rnk avatar rotateright avatar stoklund avatar tnorthover avatar topperc avatar tstellaramd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

llvm-prepo's Issues

repo2obj: Emit an incorrect .group section that is missing the ‘.rodata.cst4.f’ section.

Compile the following LLVM IR code:

target triple = "x86_64-pc-linux-gnu-repo"
%class.btVector3 = type { [4 x float] }
$f = comdat any

define linkonce_odr void @f(%class.btVector3* %this, float* dereferenceable(4) %s) comdat align 2 !repo_ticket !0 {
entry:
  %s.addr = alloca float*, align 8
  %ref.tmp = alloca float, align 4
  %0 = load float*, float** %s.addr, align 8
  %1 = load float, float* %0, align 4
  %div = fdiv float 1.000000e+00, %1
  store float %div, float* %ref.tmp, align 4
  ret void
}

using

$ rm clang.db
$ llc -filetype=obj %s -o %t.o
$ repo2obj %t.o -o %t.elf
$ llvm-readobj -elf-section-groups %t.elf | FileCheck %s

This produces one group section:

Groups {
  Group {
    Name: .group (24)
    Index: 3
    Type: COMDAT (0x1)
    Signature: f
    Section(s) in group [
      .text.f (4)
      .rela.text.f (5)
    ]
  }
}

However, the section ‘.rodata.cst4.f’ should belong to the group section as well.

Accumulate the debug line information to the repo hash calculation.

Compile the following code:

void t1()
{
  int a = 10;
  a++;
}

void t2()
{
	
  int b = 10;
  
  b++;
  
}

using

$ rm clang.db
$ clang -O0 -S -emit-llvm -gline-tables-only -target x86_64-pc-linux-gnu-repo -o test.ll test.c

The generated test.ll file is:

define void @t1() #0 !dbg !9 !repo_ticket !7 {
...
}
define void @t2() #0 !dbg !14 !repo_ticket !8 {
...
}
!7 = !TicketNode(name: "t1", digest: [16 x i8] c"1\C7x\C9\87\F2v\A7\C7)8n\1C\D2\9Cd", linkage: external, pruned: false)
!8 = !TicketNode(name: "t2", digest: [16 x i8] c"1\C7x\C9\87\F2v\A7\C7)8n\1C\D2\9Cd", linkage: external, pruned: false)
!9 = distinct !DISubprogram(name: "t1", scope: !1, file: !1, line: 1, type: !10, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: false, unit: !0, retainedNodes: !2)
!10 = !DISubroutineType(types: !2)
!11 = !DILocation(line: 3, column: 7, scope: !9)
!12 = !DILocation(line: 4, column: 4, scope: !9)
!13 = !DILocation(line: 5, column: 1, scope: !9)
!14 = distinct !DISubprogram(name: "t2", scope: !1, file: !1, line: 7, type: !10, isLocal: false, isDefinition: true, scopeLine: 8, isOptimized: false, unit: !0, retainedNodes: !2)
!15 = !DILocation(line: 10, column: 7, scope: !14)
!16 = !DILocation(line: 12, column: 4, scope: !14)
!17 = !DILocation(line: 14, column: 1, scope: !14)

The functions of “t1” and “t2” have the same digest, which is wrong. The digests should be different since the functions have the different debug line location.

Assertion failed in file pstore\include\pstore_mcrepo\sparse_array.hpp (line 656)

Compile the following code:

double CalculateOptimalEdits() {
	unsigned long a;
	return a + 1.9;
}

using

$ rm clang.db
$ clang -O0 -c -target x86_64-pc-linux-gnu-repo -o test.o test.c

Assertion failure is given:

Assertion failed: (mm & mask) == 0 && "The same index must not appear more than once in the " "collection of sparse indices", file C:\MyWork\git\github\llvm-prepo\tools\pstore\include\pstore_mcrepo/sparse_array.hpp, line 656

Store the target triple in the compilation record

The target triple should be recorded along with the compilation. This can then be used:

  • By pstore-dump to configure the disassembler (it's currently just hard-wired)
  • By the linker to ensure that the input compilations use the same triple, to control the fixup processing and link-time code-generation, and to setup the output binary correctly.

TLS not implementation for Repo target

Compile the following code:

__thread int errno;
int get_errno() { return errno; }

using

$ rm clang.db
$ clang -O0 -c -target x86_64-pc-linux-gnu-repo -std=gnu++11 -o test.o test.cpp

Assertion failure:

TLS not implemented for this target.

Add the TLS implementation to fix this issue.

section .tbss mismatches non-TLS reference

We are building and testing the pstore-broker-unit-tests using the llvm-prepo toolchain. When linking all elf object files, the following linking error is given:

/usr/bin/ld: _ZN6pstore7logging7details13log_streambufE: TLS definition in libpstore-support-lib.a(logging.cpp.o.elf) section .tbss mismatches non-TLS reference in libpstore-broker-lib.a(command.cpp.o.elf)
libpstore-support-lib.a: error adding symbols: Bad value

Missing the implementation of EmitCommonSymbol

Compile the following code:

int a;

using

$ rm clang.db
$ clang -O0 -c -target x86_64-pc-linux-gnu-repo -o test.o test.c

Compilation failed with the following error:

fatal error: error in backend: The digest of missing repository fragment 1dfd1a0c15d34e5f22f6d37e47077cf7 was found in a ticket member.

fatal error: error in backend: Unsupported linkage type

Compile the following code:

extern thread_local int i; 
int &get() { return i; }

using

$ rm clang.db
$ clang -O0 -c -target x86_64-pc-linux-gnu-repo -std=gnu++11 -o test.o test.cpp

Compilation failure:

fatal error: error in backend: Unsupported linkage type

Compile time (no link time) comparison between ELF and REPO targets.

Compile the pstore library using the built llvm-repo/clang-repo toolchain and compare the compile time beween ELF and Repo (not including the link time). The task invokes:

1. Build llvm-repo/clang-repo toolchain with Release configuration.
2. Build pstore library using built llvm-repo/clang-repo compiler targeted on ELF, get the compile 
   time (note: build four times and get average compile time). 
3. Build pstore library using built llvm-repo/clang-repo compiler targeted on Repo, get the compile 
   time (note: remove clang.db before build). 
4. Build pstore library again and get the compile time (note: all fragments are in the database.)

A problem with private/internal symbols

Compile the following code:

template <typename _Tp> class new_allocator {
public:
  typedef _Tp *pointer;
  ~new_allocator() {}
};
template <typename _CharT> class basic_string {
  struct _Alloc_hider : new_allocator<char> {
    _Alloc_hider(pointer __dat) : _M_p(__dat) {}
    pointer _M_p;
  };
  _Alloc_hider _M_dataplus;

public:
  basic_string(_CharT *__s) : _M_dataplus(__s) {}
};
int *MakeAndRegisterTestInfo(basic_string<char> code_location);
int *test_info_ = MakeAndRegisterTestInfo("test.cpp");

using

$ rm clang.db
$ clang -O0 -c -target x86_64-pc-linux-gnu-repo -o test.o test.cpp
$ clang -O0 -c -target x86_64-pc-linux-gnu-repo -o test1.o test.cpp

The test.cpp is compiled twice with clang.
The first time: the resulting repository fragment contains a definition for a string named "L.str", the "main" fragment contains a fixup which references a string named ".L.str". It is correct.
The Second time: the resulting repository fragment contains a definition for a string named "L.str", but the "main" fragment contains a fixup which references a string named ".str". This mismatch is obviously wrong.

Incorrect fragment generation for same functions in the translation unit.

Compile the following code:

void t1()
{
  int a = 10;
  a++;
}

void t2()
{
  int b = 10;
  b++;
}

using

$ rm clang.db
$ clang -O0 -S -emit-llvm -fno-exceptions -target x86_64-pc-linux-gnu-repo -o repo.ll test.c
$ llc -filetype=obj -o repo.o repo.ll
$ pstore-dump –all-fragments clang.db

The list of fragments in the repository is:

  fragments :
      - digest   : 649cd21c6e3829c7a776f287c978c731
        fragment :
            - type     : text
              contents :
                  align   : 16
                  data    :
                      - 0:      pushq   %rbp
                      - 1:      movq    %rsp, %rbp
                      - 4:      movl    $10, -4(%rbp)
                      - 11:     movl    -4(%rbp), %eax
                      - 14:     addl    $1, %eax
                      - 17:     movl    %eax, -4(%rbp)
                      - 20:     popq    %rbp
                      - 21:     retq
                      - 22:     nop
                      - 23:     nop
                      - 24:     nop
                      - 25:     nop
                      - 26:     nop
                      - 27:     nop
                      - 28:     nop
                      - 29:     nop
                      - 30:     nop
                      - 31:     nop
                      - 32:     pushq   %rbp
                      - 33:     movq    %rsp, %rbp
                      - 36:     movl    $10, -4(%rbp)
                      - 43:     movl    -4(%rbp), %eax
                      - 46:     addl    $1, %eax
                      - 49:     movl    %eax, -4(%rbp)
                      - 52:     popq    %rbp
                      - 53:     retq
                  ifixups : [ ]
                  xfixups : [ ]

The function t1 and t2 have been merge into a single fragment, whose data is wrong.

undefined reference to `_GLOBAL__sub_I_gtest_all.cc'

We are building and testing the pstore-support-unit-tests using the llvm-prepo toolchain by the following steps:

  1. Build the project targeted on repo using llvm-prepo toolchain.
  2. Covert repo object file to elf object file using repo2obj.exe.
  3. Link all elf object files using LLVM linker.

When linking all elf object files, the following linking error is given:

test_error.cpp.o.elf:(.init_array+0x0): undefined reference to `_GLOBAL__sub_I_gtest_all.cc'
test_file.cpp.o.elf:(.init_array+0x0): undefined reference to `_GLOBAL__sub_I_gtest_all.cc'
test_gsl.cpp.o.elf:(.init_array+0x0): undefined reference to `_GLOBAL__sub_I_gtest_all.cc'
...

A global variable should have the same digest value if it is uninitialized or zero initialized

Compile the following code:

int a;          //uninitialized
int b = 0;   //Zero initialized

using

$ rm clang.db
$ clang -O0 -c -target x86_64-pc-linux-gnu-repo -o test.o test.c

This is being stored in the repository as:

pstore-dump -ticket test.o clang.db
- file    :
      path : clang.db
      size : 4194304
  tickets :
      - id     : 5e30ae41-98a7-421e-8eee-466de7bb9e4e
        ticket :
            members :
                ticket_member :
                    - digest  : 9094c1bc4813b45686785e1a0e2bc1ca
                      name    : a
                      linkage : external
                    - digest  : 5cd1a968567ef37fcd2aa2ba0cae58b2
                      name    : b
                      linkage : common
            path    : \\\\?\\C:\\MyWork\\repo_bug\\bug19

By default, 'a' is zero initialized. The digest of 'a' is wrong and should be the same as b.

Undefined reference to 'str'

A simple IR code (test.ll):

target triple = "x86_64-pc-linux-gnu"

@.str.1 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1
@.str.2 = private unnamed_addr constant [41 x i8] c"{{ SCEBenchmark_TIMETAKEN_MS  : %llu }}\0A\00"
@.str.3 = private unnamed_addr constant [26 x i8] c"{{ SCEBenchmark_END }}\0A\1A\0A\00", align 1

declare i32 @printf(i8* nocapture readonly, ...)

define void @test() align 2 {
entry:
  %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.1, i32 0, i32 0))
  %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([41 x i8], [41 x i8]* @.str.2, i32 0, i32 0))
  %call4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str.3, i32 0, i32 0))
  ret void
}

define i32 @foo() {
entry:
  ret i32 1
}

Compiled to the repo with a command something like:

$ rm clang.db
$ clang -O3 -c -target x86_64-pc-linux-gnu-repo test.ll -o test.first.o

Produces ticket members in ticket file.

$ pstore-dump -all-tickets clang.db
---

- file    :
      path : clang.db
      size : 4194304
  tickets :
      - digest : ca35124551f17daa8911fd4af33fbaf1
        ticket :
            members :
                - digest  : 28a6c73189942642754546213fc3c3a4
                  name    : test
                  linkage : external
                - digest  : 9379e47d32813ce7d140c5bf233fe11f
                  name    : foo
                  linkage : external
                - digest  : 4f8f724974d0cf544b2f61d400896a0c
                  name    : .str.2
                  linkage : internal
                - digest  : 88dfbeb7f039a7c77d5b7ddec82cfefa
                  name    : str
                  linkage : internal
            path    : \\\\?\\C:\\MyWork\\repo_bug\\remove-global-object
...

Modify the source file (test.ll) and change the function foo only:

...
define i32 @foo() {
entry:
  ret i32 2
}

Produces a new ticket (5252b9fa7d80e491defdc255500b1171).

$ pstore-dump -all-tickets clang.db
---
- file    :
      path : clang.db
      size : 4194304
  tickets :
      - digest : 5252b9fa7d80e491defdc255500b1171
        ticket :
            members :
                - digest  : 28a6c73189942642754546213fc3c3a4
                  name    : test
                  linkage : external
                - digest  : 7dc81a03aa5d65c469c71c77ff9f345c
                  name    : foo
                  linkage : external
                - digest  : 4f8f724974d0cf544b2f61d400896a0c
                  name    : .str.2
                  linkage : internal
            path    : \\\\?\\C:\\MyWork\\repo_bug\\remove-global-object
      - digest : ca35124551f17daa8911fd4af33fbaf1
        ticket :
            members :
                - digest  : 28a6c73189942642754546213fc3c3a4
                  name    : test
                  linkage : external
...

The fragment of function 'test' (28a6c73189942642754546213fc3c3a4):

$ pstore-dump -all-fragments clang.db
---
  ...
  fragments :
      - digest   : 28a6c73189942642754546213fc3c3a4
        fragment :
            - type     : text
              contents :
                  align   : 16
                  data    :
                      - 0:      pushq   %rax
                      - 1:      movl    $10, %edi
                      - 6:      callq   0
                      - 11:     movl    $0, %edi
                      - 16:     xorl    %eax, %eax
                      - 18:     callq   0
                      - 23:     movl    $0, %edi
                      - 28:     popq    %rax
                      - 29:     jmp     0
                  ifixups : [ ]
                  xfixups :
                      - name   : putchar
                        type   : 2
                        offset : 7
                        addend : 18446744073709551612
                      - name   : .str.2
                        type   : 10
                        offset : 12
                        addend : 0
                      - name   : printf
                        type   : 2
                        offset : 19
                        addend : 18446744073709551612
                      - name   : str
                        type   : 10
                        offset : 24
                        addend : 0
                      - name   : puts
                        type   : 2
                        offset : 30
                        addend : 18446744073709551612

There is external relocation to symbol 'str', but 'str' is not in the ticket (5252b9fa7d80e491defdc255500b1171).
This caused a link error: undefined reference to 'str'.

repo2obj relocation sections are named after the base rather than the actual target section

Take the following little example (repo.cpp):

int bar = 1;
template <typename T>
T foo (T t) { return t + bar; }
int qaz (int t) { return foo (t); }

After compiling and running through repo2obj, we get the following sections in the ELF file:

$ clang++ -O0 -c -target x86_64-pc-linux-gnu-repo -o rela.o rela.cpp
$ repo2obj -o rela.elf.o rela.o
$ llvm-objdump -section-headers rela.elf.o

rela.elf.o:	file format ELF64-x86-64

Sections:
Idx Name          Size      Address          Type
  0               00000000 0000000000000000 
  1 .shstrtab     0000004e 0000000000000000 
  2 .strtab       0000001c 0000000000000000 
  3 .symtab       00000060 0000000000000000 
  4 .group        0000000c 0000000000000000 
  5 .text         00000019 0000000000000000 TEXT DATA 
  6 .rela.text    00000018 0000000000000000 
  7 .text._Z3fooIiET_S0_ 00000015 0000000000000000 TEXT DATA 
  8 .rela.text    00000018 0000000000000000 
  9 .data         00000004 0000000000000000 DATA 
$ 

Sections 6 and 8 are both named .rela.text (6 targets .text and 8 targets .text. _Z3fooIiET_S0_). Although it's slightly less space-efficient, as an aid to debugging with this stuff it would be useful if section 8 was named .rela.text. _Z3fooIiET_S0_.

Backend Error: The digest of missing repository fragment was found in a ticket member.

Compile the following code:

namespace pstore {
template <typename ProcessPathFunction, typename BufferType>
int process_file_name(ProcessPathFunction, BufferType &p2) {
  p2.capacity();
}
template <typename, int = 256> class small_vector {
public:
  void capacity();
};
void process_file_name() {
  auto read_link = [] {};
  small_vector<char> buffer;
  process_file_name(read_link, buffer);
}
} // namespace pstore

using

$ rm clang.db
$ clang -O2 -c -target x86_64-pc-linux-gnu-repo  -std=gnu++11 -o test.o test.cpp

Compilation failed with the following error:

fatal error: error in backend: The digest of missing repository fragment 99effd5b5772b7cf34cc3b757a620c1c was found in a ticket member.

Global constant data emitted as readonly section rather than mergeable-const-X

Compile a small example such as:

double const d = 1.0;

Compile it:

$ rm clang.db
$ clang -c -O0 -target x86_64-pc-linux-gnu-repo double.c

This is being stored in the repository as:

$ pstore-dump --fragments clang.db 
---
- file      : 
      path : clang.db
      size : 4194304
  fragments : 
      - digest   : be21f32fb7eefb5c5d6fb94c7e481974
        fragment : 
            - type     : ReadOnly
              contents : 
                  data    : !!binary |
                      AAAAAAAA8D8=
                  ifixups : [ ]
                  xfixups : [ ]
...
$

The data ought to be in a section of type mergeable-const-8 rather than read-only.

Assertion failed: Val && "isa<> used on a null pointer"

Compile the following code:

template <typename _CharT>
class basic_ostream;

typedef basic_ostream<char> ostream;
template <typename _CharT>
basic_ostream<_CharT> &__ostream_insert(basic_ostream<_CharT> &__out,
                                        _CharT *__s);
inline basic_ostream<char> &operator<<(basic_ostream<char> &__out, char *__s) {
  __ostream_insert(__out, __s);
}

ostream &operator<<(ostream &stream, int version) {	
  char *str = "";
  switch (version) {
  case 1:
    str = "time_based";
    break;
  case 2:
    str;
  case 3:
    str = "name_based_md5";
  }
  return stream << str;
}

using

$ rm clang.db
$ clang++ -target x86_64-pc-linux-gnu-repo -O2 -std=gnu++11 -c test.cpp

Compilation failed with the following error:

Assertion failed: Val && "isa<> used on a null pointer", file C:\MyWork\git\github\llvm-prepo\include\llvm/Support/Casting.h, line 106

External fragment using a missing name to refer to a section within the same fragment

Compile the following code:

extern int printf (char const * format, ...);
int main () {
    printf ("%f\n", 1.0);
}

using

$ rm clang.db
$ clang -O0 -c -target x86_64-pc-linux-gnu-repo -o double.o double.c
$ pstore-dump --fragments --tickets clang.db

This produces a fragment (947261b89ef2fd43da823ee4f676e2c9) which contains two sections:

- file      : 
      path : clang.db
      size : 4194304
  fragments : 
      - digest   : 947261b89ef2fd43da823ee4f676e2c9
        fragment : 
            - type     : Text
              contents : 
                  data    : !!binary |
                      VUiJ5UiD7BBIvwAAAAAAAAAA8g8QBQAAAACwAegAAAAAMcmJRfyJyEiDxBBdww==
                  ifixups : [ ]
                  xfixups : 
                      - name   : .L.str
                        type   : 1
                        offset : 10
                        addend : 0
                      - name   : .LCPI0_0
                        type   : 2
                        offset : 22
                        addend : 18446744073709551612
                      - name   : printf
                        type   : 2
                        offset : 29
                        addend : 18446744073709551612
            - type     : MergeableConst8
              contents : 
                  data    : !!binary |
                      AAAAAAAA8D8=
                  ifixups : [ ]
                  xfixups : [ ]
      - digest   : 636a38b68cbba28666408b4cf3bc4620
        fragment : 
            - type     : ReadOnly
              contents : 
                  data    : !!binary |
                      JWYKAA==
                  ifixups : [ ]
                  xfixups : [ ]
  tickets   : 
      - uuid   : 40440bb0-4741-4e2a-913f-ad6a6b9c89a8
        ticket : 
            members : 
                ticket_member : 
                    - digest  : 636a38b68cbba28666408b4cf3bc4620
                      name    : .L.str
                      linkage : internal
                    - digest  : 947261b89ef2fd43da823ee4f676e2c9
                      name    : main
                      linkage : external
            path    : ...
...

The ticket associated with this compilation does not contain a definition of the .LCPI0_0 symbol which is referenced from one of the main fragment's text-section external fixups. This should really be an internal fixup referring to the MergeableConst8 section.

Ticket file digests are different between two time builds

Compile the following code:

template <typename _CharT>
class basic_ostream;

typedef basic_ostream<char> ostream;
template <typename _CharT>
basic_ostream<_CharT> &__ostream_insert(basic_ostream<_CharT> &__out,
                                        _CharT *__s);
inline basic_ostream<char> &operator<<(basic_ostream<char> &__out, char *__s) {
  __ostream_insert(__out, __s);
}

ostream &operator<<(ostream &stream, int version) {	
  char *str = "";
  switch (version) {
  case 1:
    str = "time_based";
    break;
  case 2:
    str;
  case 3:
    str = "name_based_md5";
  }
  return stream << str;
}

using

$ rm clang.db
$ clang++ -target x86_64-pc-linux-gnu-repo -O2 -std=gnu++11 -c test.cpp
$ clang++ -target x86_64-pc-linux-gnu-repo -O2 -std=gnu++11 -c test.cpp

The list of generations in the repository is:

- file :
      path : clang.db
      size : 4194304
  log  :
      - { number: 2, size: 208, time: 2018-03-01T09:36:37Z }
      - { number: 1, size: 1176, time: 2018-03-01T09:36:36Z }
      - { number: 0, size: 0, time: 2018-03-01T09:36:36Z }
...

During the second time build, there is no database transaction since the source file keeps the same. The latest revision number should be 1 instead of 2.

repo2obj: Emit .group sections immediately prior to the sections they reference.

At the moment, the repo2obj tool gathers all of the .group sections together at the front of the section-header table. This was a simple way of satisfying ELF's constraint that GROUP sections must appear before the sections that they reference.

In contrast, the compiler's ELF emission code places a GROUP section immediately prior to the sections that it references. This makes the typical output order something ".group"/".text.foo"/".rela.text.foo".

To make problem diagnosis easier, I'd like to arrange for the repo2obj files to match the compiler's files as closely as possible so that any important differences can be spotted easily.

llvm-prepo test: the pstore unit and system tests

Test the llvm-prepo toolchain using the pstore unit tests. The task invokes:

1. Build llvm-repo/clang-repo toolchain with Debug configuration.
2. Compile the pstore unit tests targeted on Repo using the built llvm-repo/clang-repo compiler. 
3. Convert the Repo object files to the ELF object files by using repo2obj.
4. Link the ELF object files to generate an executable ELF file. 
5. Run the generated executable file and expect to pass the unit tests.
6. Repeat the steps 2 to 5 (note: all fragments are in the database.)

Switch ticket files from UUID to digest of contents

The repository uses a ticket file to represent the results of a particular compilation. At the moment a UUID is used as the key to the ticket index. This is simple to implement but means that a recompilation will always result in data being recorded in the data store (since a UUID is by definition unique).

This now seems a little silly, so compute a hash of the ticket contents and use this as the key to the ticket index.

llvm-prepo: Incorrect hash calculation for the ‘CallInst’ instruction.

This bug is spinning out from bug 32.

Compile the following code:

target datalayout = "e-m:r-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-linux-repo"

%struct._xmlParserCtxt = type opaque
%struct._xmlHashTable = type opaque
%struct._xmlEntity = type opaque

define void @htmlFreeParserCtxt(%struct._xmlParserCtxt* %ctxt) {
entry:
  %ctxt.addr = alloca %struct._xmlParserCtxt*, align 8
  store %struct._xmlParserCtxt* %ctxt, %struct._xmlParserCtxt** %ctxt.addr, align 8
  %0 = load %struct._xmlParserCtxt*, %struct._xmlParserCtxt** %ctxt.addr, align 8
  call void @xmlFreeParserCtxt(%struct._xmlParserCtxt* %0)
  ret void
}
declare void @xmlFreeParserCtxt(%struct._xmlParserCtxt*)

define void @xmlFreeEntitiesTable(%struct._xmlHashTable* %table) {
entry:
  %table.addr = alloca %struct._xmlHashTable*, align 8
  store %struct._xmlHashTable* %table, %struct._xmlHashTable** %table.addr, align 8
  %0 = load %struct._xmlHashTable*, %struct._xmlHashTable** %table.addr, align 8
  call void @xmlHashFree(%struct._xmlHashTable* %0, void (i8*, i8*)* bitcast (void (%struct._xmlEntity*, i8*)* @xmlFreeEntityWrapper to void (i8*, i8*)*))
  ret void
}
declare void @xmlHashFree(%struct._xmlHashTable*, void (i8*, i8*)*)
declare void @xmlFreeEntityWrapper(%struct._xmlEntity* %entity, i8* %name)

using

$ rm clang.db
$ opt test.ll -S -o  test.opt.ll

The generated optimised test.opt.ll file is:

define void @htmlFreeParserCtxt(%struct._xmlParserCtxt* %ctxt) !repo_ticket !0 {
...
}
define void @xmlFreeEntitiesTable(%struct._xmlHashTable* %table) !repo_ticket !1 {
...
}
!0 = !TicketNode(name: "htmlFreeParserCtxt", digest: [16 x i8] c"\CF\B3\F7h\E8\F9\E7\0C~&\92\F0\1AG\A2\E5", linkage: external, pruned: false)
!1 = !TicketNode(name: "xmlFreeEntitiesTable", digest: [16 x i8] c"\CF\B3\F7h\E8\F9\E7\0C~&\92\F0\1AG\A2\E5", linkage: external, pruned: false)

The functions of “htmlFreeParserCtxt” and “xmlFreeEntitiesTable” have the same digest, which is wrong. The digests should be different.

UNREACHABLE executed at /mnt/e/work/prepo/llvm/lib/IR/RepoHashCalculator.cpp:131!

$ cat 1.cpp
typedef char a __attribute__((__vector_size__(8)));
void b() { __builtin_ia32_palignr((a)0L, (a)0L, 0); }

$ ./clang++ -c 1.cpp -march=btver2 -target x86_64-pc-gnu-linux
$ ./clang++ -c 1.cpp -march=btver2 -target x86_64-pc-gnu-linux-repo
Unknown type!
UNREACHABLE executed at /mnt/e/work/prepo/llvm/lib/IR/RepoHashCalculator.cpp:131!
#0 0x00007f14fc63d6aa llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x243d6aa)
#1 0x00007f14fc63b2d6 llvm::sys::RunSignalHandlers() (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x243b2d6)
#2 0x00007f14fc63b675 SignalHandler(int) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x243b675)
#3 0x00007f14f9bf2890 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x12890)
#4 0x00007f14f887ee97 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x3ee97)
#5 0x00007f14f8880801 abort (/lib/x86_64-linux-gnu/libc.so.6+0x40801)
#6 0x00007f14fc5dc6ba (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x23dc6ba)
#7 0x00007f14fc170e87 llvm::HashCalculator::hashType(llvm::Type*) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x1f70e87)
#8 0x00007f14fc173b44 llvm::FunctionHashCalculator::hashInstruction(llvm::Instruction const*) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x1f73b44)
#9 0x00007f14fc1741a9 llvm::FunctionHashCalculator::hashBasicBlock(llvm::BasicBlock const*) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x1f741a9)
#10 0x00007f14fc174304 llvm::FunctionHashCalculator::hashFunction() (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x1f74304)
#11 0x00007f14fc174732 llvm::FunctionHashCalculator::calculateHash() (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x1f74732)
#12 0x00007f14fc139e72 llvm::DenseMapIterator<llvm::GlobalObject const*, llvm::ticketmd::GOInfo, llvm::DenseMapInfo<llvm::GlobalObject const*>, llvm::detail::DenseMapPair<llvm::GlobalObject const*, llvm::ticketmd::GOInfo>, true> llvm::ticketmd::calculateInitialDigestAndDependencies<llvm::Function>(llvm::Function const*, llvm::DenseMap<llvm::GlobalObject const*, llvm::ticketmd::GOInfo, llvm::DenseMapInfo<llvm::GlobalObject const*>, llvm::detail::DenseMapPair<llvm::GlobalObject const*, llvm::ticketmd::GOInfo> >&) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x1f39e72)
#13 0x00007f14fc13a7e4 llvm::ticketmd::updateInitialDigestAndGetDependencies(llvm::GlobalObject const*, llvm::MD5&, llvm::DenseMap<llvm::GlobalObject const*, llvm::ticketmd::GOInfo, llvm::DenseMapInfo<llvm::GlobalObject const*>, llvm::detail::DenseMapPair<llvm::GlobalObject const*, llvm::ticketmd::GOInfo> >&, llvm::ticketmd::GONumber&) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x1f3a7e4)
#14 0x00007f14fc13b67c void llvm::ticketmd::updateDigestUseCallDependencies<llvm::ticketmd::generateTicketMDs(llvm::Module&)::{lambda(llvm::GlobalObject const*, llvm::MD5&, llvm::DenseMap<llvm::GlobalObject const*, llvm::ticketmd::GOInfo, llvm::DenseMapInfo<llvm::GlobalObject const*>, llvm::detail::DenseMapPair<llvm::GlobalObject const*, llvm::ticketmd::GOInfo> >&)#1}>(llvm::GlobalObject const*, llvm::MD5&, llvm::DenseMap<llvm::GlobalObject const*, unsigned int, llvm::DenseMapInfo<llvm::GlobalObject const*>, llvm::detail::DenseMapPair<llvm::GlobalObject const*, unsigned int> >&, llvm::DenseMap<llvm::GlobalObject const*, llvm::ticketmd::GOInfo, llvm::DenseMapInfo<llvm::GlobalObject const*>, llvm::detail::DenseMapPair<llvm::GlobalObject const*, llvm::ticketmd::GOInfo> >&, llvm::ticketmd::generateTicketMDs(llvm::Module&)::{lambda(llvm::GlobalObject const*, llvm::MD5&, llvm::DenseMap<llvm::GlobalObject const*, llvm::ticketmd::GOInfo, llvm::DenseMapInfo<llvm::GlobalObject const*>, llvm::detail::DenseMapPair<llvm::GlobalObject const*, llvm::ticketmd::GOInfo> >&)#1}) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x1f3b67c)
#15 0x00007f14fc13bf05 llvm::ticketmd::generateTicketMDs(llvm::Module&) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x1f3bf05)
#16 0x00007f14fc1e8481 (anonymous namespace)::RepoTicketGeneration::runOnModule(llvm::Module&) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x1fe8481)
#17 0x00007f14fc0f79a1 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x1ef79a1)
#18 0x00007f14fc80dc24 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::DataLayout const&, llvm::Module*, clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream> >) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x260dc24)
#19 0x00007f14fcf69b48 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x2d69b48)
#20 0x00007f14fd38214a clang::ParseAST(clang::Sema&, bool, bool) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x318214a)
#21 0x00007f14fcf665f8 clang::CodeGenAction::ExecuteAction() (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x2d665f8)
#22 0x00007f14fcbef7a6 clang::FrontendAction::Execute() (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x29ef7a6)
#23 0x00007f14fcbb88ce clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x29b88ce)
#24 0x00007f14fcc8b72a clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0x2a8b72a)
#25 0x00007f14faeafff8 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0xcafff8)
#26 0x00007f14fae380dc main (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0xc380dc)
#27 0x00007f14f8861b97 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b97)
#28 0x00007f14faeac24a _start (/mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0+0xcac24a)
Stack dump:
0.      Program arguments: /mnt/e/work/prepo/build-gcc-native-ninja/bin/clang-6.0 -cc1 -triple x86_64-pc-linux-gnu-repo -emit-obj -mrelax-all -disable-free -main-file-name 1.cpp -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -munwind-tables -fuse-init-array -target-cpu btver2 -dwarf-column-info -debugger-tuning=gdb -coverage-notes-file /mnt/e/work/prepo/build-gcc-native-ninja/bin/1.gcno -resource-dir /mnt/e/work/prepo/build-gcc-native-ninja/lib/clang/6.0.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/local/include -internal-isystem /mnt/e/work/prepo/build-gcc-native-ninja/lib/clang/6.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdeprecated-macro -fdebug-compilation-dir /mnt/e/work/prepo/build-gcc-native-ninja/bin -ferror-limit 19 -fmessage-length 237 -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o 1.o -x c++ 1.cpp
1.      <eof> parser at end of file
2.      Per-module optimization passes
3.      Running pass 'RepoTicketGenerationPass' on module '1.cpp'.
clang-6.0: error: unable to execute command: Aborted (core dumped)
clang-6.0: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 6.0.0 (https://github.com/SNSystems/clang-prepo.git 85663ce2d0e357504b3b92e3cdf53b39056d1f7e) (https://github.com/SNSystems/llvm-prepo.git 1bfded74475ead9e577569905e185799c998863f)
Target: x86_64-pc-linux-gnu-repo
Thread model: posix
InstalledDir: /mnt/e/work/prepo/build-gcc-native-ninja/bin/.
clang-6.0: note: diagnostic msg: PLEASE submit a bug report to http://llvm.org/bugs/ and include the crash backtrace, preprocessed source, and associated run script.
clang-6.0: note: diagnostic msg:
********************

Fatal error: invalid linkage for intrinsic global variable

Compile the following code (test.ll):

target triple = "x86_64-pc-linux-gnu-repo"
@llvm.global_ctors = appending global [1 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @__mf_init } ]
@llvm.global_dtors = appending global [1 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @__mf_fini } ]

define void @__mf_init() {
entry:
        ret void
}

define void @__mf_fini() {
entry:
        ret void
}

using

$ rm clang.db
$ clang test.ll -target x86_64-pc-linux-gnu-repo -c -o repo.o
$ clang test.ll -target x86_64-pc-linux-gnu-repo -c -o repo.o

The test.ll is compiled with clang twice.
The first time success and second time failed with following error:

invalid linkage for intrinsic global variable
[1 x { i32, void ()* }]* @llvm.global_ctors
invalid linkage for intrinsic global variable
[1 x { i32, void ()* }]* @llvm.global_dtors
fatal error: error in backend: Broken module found, compilation aborted! 

The Repo section alignment is wrong and should be “log2(align) + 1”.

Compile the following code:

double test() {
	return 1.9;
}

using

$ rm clang.db
$ clang -O0 -c -target x86_64-pc-linux-gnu-repo -o test.o test.cpp
$ pstore-dump --fragments clang.db

This produces a fragment (8861d2b57f667812d77e50c2bd0a8cb1) which contains two sections (Text and MergeableConst8):

---
- file      :
      path : clang.db
      size : 4194304
  fragments :
      - digest   : 8861d2b57f667812d77e50c2bd0a8cb1
        fragment :
            - type     : Text
              contents :
                  align   : 65536
                  data    : !!binary |
                      VUiJ5fIPEAUAAAAAXcM=
                  ifixups :
                      - section : MergeableConst8
                        type    : 2
                        offset  : 8
                        addend  : 18446744073709551612
                  xfixups : [ ]
            - type     : MergeableConst8
              contents :
                  align   : 256
                  data    : !!binary |
                      ZmZmZmZm/j8=
                  ifixups : [ ]
                  xfixups : [ ]
...

The section alignment is wrong. The section alignment of the Repo file is different from the ELF Section alignment. The section alignment of the ELF file should be a positive, integral power of 2 (align). However, the Repo section alignment should be stored as “log2(align) + 1”.

Incorrect hash calculation for llvm.global_ctors

Compile the following code:

@x = global i32 0, align 4
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_global-ctor.ll, i8* null }]

define internal void @__cxx_global_var_init() section ".text.startup" {
entry:
  %call = call i32 @_Z1fv()
  store i32 %call, i32* @x, align 4
  ret void
}

declare i32 @_Z1fv()

define internal void @_GLOBAL__sub_I_global-ctor.ll() section ".text.startup" {
entry:
  call void @__cxx_global_var_init()
  ret void
}

using

$ rm clang.db
$ opt -mtriple x86_64-pcplinux-repo -S -O3 global-ctor.ll -o first.ll
$ llc -filetype=obj first.ll

Modify the initial value of global variable x from 0 to 8:

@x = global i32 8, align 4
...

Compile the code again using:

$ opt -mtriple x86_64-pcplinux-repo -S -O3 global-ctor.ll -o second.ll

The first.ll IR code:

source_filename = "global-ctor.ll"
target triple = "x86_64-pcplinux--repo"

@x = local_unnamed_addr global i32 0, align 4, !repo_ticket !0
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_global-ctor.ll, i8* null }], !repo_ticket !1

declare i32 @_Z1fv() local_unnamed_addr

define internal void @_GLOBAL__sub_I_global-ctor.ll() section ".text.startup" !repo_ticket !3 {
entry:
  %call.i = tail call i32 @_Z1fv()
  store i32 %call.i, i32* @x, align 4
  ret void
}

!repo.tickets = !{!2, !3, !0, !1}

!0 = !TicketNode(name: "x", digest: [16 x i8] c"U]\B8\E2'\DF\DC\15\9D\84\D0\1FY\07\C2\19", linkage: external, pruned: false)
!1 = !TicketNode(name: "llvm.global_ctors", digest: [16 x i8] c"^\08\8Eo\DD\DB\A3\CA\01\16\FE\86\C3q\A2N", linkage: appending, pruned: false)
!2 = !TicketNode(name: "__cxx_global_var_init", digest: [16 x i8] c"[\16\E1\B1\E9\919\A9\8Et\82\A5Nh\D9\F8", linkage: internal, pruned: false)
!3 = !TicketNode(name: "_GLOBAL__sub_I_global-ctor.ll", digest: [16 x i8] c"\13\B0 \CAc?_\E9\17\99W=O\0Dv#", linkage: internal, pruned: false)

The second.ll IR code:

source_filename = "global-ctor.ll"
target triple = "x86_64-pcplinux--repo"

@x = local_unnamed_addr global i32 8, align 4, !repo_ticket !0

!repo.tickets = !{!1, !2, !0, !3}

!0 = !TicketNode(name: "x", digest: [16 x i8] c"\E2\CB=\E1\FET\F5>e6\AE\B3\16\88\0D=", linkage: external, pruned: false)
!1 = !TicketNode(name: "__cxx_global_var_init", digest: [16 x i8] c"\E4\A0\F0\9D\01\E9\D8\A8(`P\C26\C9\D4\ED", linkage: internal, pruned: false)
!2 = !TicketNode(name: "_GLOBAL__sub_I_global-ctor.ll", digest: [16 x i8] c"0\0C\F6\F4\84,\14q>~4%cy\93\FB", linkage: internal, pruned: false)
!3 = !TicketNode(name: "llvm.global_ctors", digest: [16 x i8] c"^\08\8Eo\DD\DB\A3\CA\01\16\FE\86\C3q\A2N", linkage: appending, pruned: true)

The digest value of llvm.global_ctors is wrong and should be different between two time compilations since the initial value of global variable 'x' is changed.

multiple definition of `llvm.global_ctors'

We are building and testing the pstore-support-unit-tests using the llvm-prepo toolchain by the following steps:

  1. Build the project targeted on repo using llvm-prepo toolchain.
  2. Covert repo object file to elf object file using repo2obj.exe.
  3. Link all elf object files using LLVM linker.

When linking all elf object files, the following linking error is given:

test_file.cpp.o.elf:(.init_array+0x0): multiple definition of `llvm.global_ctors'
test_error.cpp.o.elf:(.init_array+0x0): first defined here
test_gsl.cpp.o.elf:(.init_array+0x0): multiple definition of `llvm.global_ctors'
test_error.cpp.o.elf:(.init_array+0x0): first defined here
test_small_vector.cpp.o.elf:(.init_array+0x0): multiple definition of `llvm.global_ctors'
test_error.cpp.o.elf:(.init_array+0x0): first defined here
test_utf.cpp.o.elf:(.init_array+0x0): multiple definition of `llvm.global_ctors'
test_error.cpp.o.elf:(.init_array+0x0): first defined here
libgmock_main.a(gmock-all.cc.o.elf):(.init_array+0x0): multiple definition of `llvm.global_ctors'
test_error.cpp.o.elf:(.init_array+0x0): first defined here
libgmock_main.a(gmock_main.cc.o.elf):(.init_array+0x0): multiple definition of `llvm.global_ctors'
test_error.cpp.o.elf:(.init_array+0x0): first defined here
libgmock_main.a(gtest-all.cc.o.elf):(.init_array+0x0): multiple definition of `llvm.global_ctors'
test_error.cpp.o.elf:(.init_array+0x0): first defined here

Wrong file path is stored in the ticket path

Compile a small example (double.c) such as:

double const d = 1.0;

Compile it:

$ rm clang.db
$ clang -c -O0 -target x86_64-pc-linux-gnu-repo double.c -o double.o

This is being stored in the repository as:

$ pstore-dump --tickets clang.db 
---
- file    :
      path : clang.db
      size : 4194304
  tickets :
      - uuid   : a4d24b49-c3d3-433f-835c-771b067c8483
        ticket :
            members :
                ticket_member :
                    - digest  : be21f32fb7eefb5c5d6fb94c7e481974
                      name    : d
                      linkage : external
            path    : \\\\?\\C:\\test\\double-78171c5e.o.tmp
$
...

The ticket path should be \\?\C:\MyWork\test\double.o instead of \\?\test\double-78171c5e.o.tmp.

Use 'available_externally' linkage in the RepoPruning pass

The RepoPruning pass removes unchanged GOs whose definitions already have binary representations in the repository. If a GO is pruned, it is currently changed from a definition to a declaration to avoid the later phases of the compiling process. However, this method will prevent inlining and other optimizations to take place.

Globals with “available_externally” linkage are never emitted into the object file corresponding to the LLVM module. They exist to allow code optimizations to take place given knowledge of the definition of the global.

The ‘available_externally’ linkage could be used in the RepoPruning pass to avoid the issue.

Incorrect representation of jump tables

A simple switch statement such as:

int foo (int mode) {
    switch (mode) {
    case 1: return 5;
    case 2: return 6;
    case 3: return 7;
    case 4: return 8;
    default: return 9;
    }
}

Compiled to the repo with a command something like:

clang -O0 -c -target x86_64-pc-linux-gnu-repo -o switch.o switch.c

Produces ifixup records in foo’s fragment which to do not have the correct addend value:

$ dumpfragment switch.o foo 
---

- file      : 
      path : ./clang.db
      size : 4194304
  fragments : 
      - digest   : c2db93450e69f48bc49f046cccaf6548
        fragment : 
            - type     : text
              contents : 
                  align   : 16
                  data    : <snip instructions>
                  ifixups : 
                      - { section: read_only, type: 11, offset: 39, addend: 0 }
                  xfixups : [ ]
            - type     : read_only
              contents : 
                  align   : 8
                  data    : <snip 32 zero bytes>
                  ifixups : 
                      - { section: text, type: 1, offset: 0, addend: 0 }
                      - { section: text, type: 1, offset: 8, addend: 0 }
                      - { section: text, type: 1, offset: 16, addend: 0 }
                      - { section: text, type: 1, offset: 24, addend: 0 }
                  xfixups : [ ]
...

These lines are: the interesting ones: "- { section: text, type: 1, offset: 0, addend: 0}".

This contrasts with the same file compiled directly to ELF:

$ llvm-readobj --relocations switch.elf

File: switch.elf
Format: ELF64-x86-64
Arch: x86_64
AddressSize: 64bit
LoadName: 
Relocations [
  Section (3) .rela.text {
    0x27 R_X86_64_32S .rodata 0x0
  }
  Section (5) .rela.rodata {
    0x0 R_X86_64_64 .text 0x2D
    0x8 R_X86_64_64 .text 0x39
    0x10 R_X86_64_64 .text 0x45
    0x18 R_X86_64_64 .text 0x51
  }
  Section (9) .rela.eh_frame {
    0x20 R_X86_64_PC32 .text 0x0
  }
]

Incorrect hash calculation for a global object (GO) that calls another GO with an available_externally linkage type.

Compile the following code:

target triple = "x86_64-pc-linux-gnu-repo"

define available_externally i32 @foo() {
  ret i32 1
}

define void @bar() {
  %call = call i32 @foo()
  ret void
}

using

$ rm clang.db
$ opt -mtriple x86_64-pcplinux-repo -S -O3 test.ll -o first.ll
$ llc -filetype=obj first.ll

Modify the function ‘foo’ return value from 1 to 2:

define available_externally i32 @foo() {
  ret i32 2
}
...

Compile the code again using:

$ opt -mtriple x86_64-pcplinux-repo -S -O3 test.ll -o second.ll

The first.ll IR code:

…
define void @bar() local_unnamed_addr #0 !repo_ticket !0 {
  ret void
}

!repo.tickets = !{!0}

!0 = !TicketNode(name: "bar", digest: [16 x i8] c"\A4\ADB\9B\02\D8\EB\96\FD\A0\1A>\82\09\82#", linkage: external, pruned: false)

The second.ll IR code:


!repo.tickets = !{!0}

!0 = !TicketNode(name: " bar ", digest: [16 x i8] c"\A4\ADB\9B\02\D8\EB\96\FD\A0\1A>\82\09\82#", linkage: external, pruned: true)

The digest values of function ‘bar’ is wrong and should be different between two time compilations since its return value is changed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.