Skip to content

Commit

Permalink
[llvm-ifs][IFS] llvm Interface Stubs merging + object file generation…
Browse files Browse the repository at this point in the history
… tool.

This tool merges interface stub files to produce a merged interface stub file
or a stub library. Currently it for stub library generation it can produce an
ELF .so stub file, or a TBD file (experimental). It will be used by the clang
-emit-interface-stubs compilation pipeline to merge and assemble the per-CU
stub files into a stub library.

The new IFS format is as follows:

--- !experimental-ifs-v1
IfsVersion:      1.0
Triple:          <llvm triple>
ObjectFileFormat: <ELF | TBD>
Symbols:
  _ZSymbolName: { Type: <type>, etc... }
...

Differential Revision: https://reviews.llvm.org/D66405

llvm-svn: 370499
  • Loading branch information
plotfi committed Aug 30, 2019
1 parent 3be7081 commit d719c50
Show file tree
Hide file tree
Showing 17 changed files with 793 additions and 1 deletion.
1 change: 1 addition & 0 deletions llvm/test/CMakeLists.txt
Expand Up @@ -69,6 +69,7 @@ set(LLVM_TEST_DEPENDS
llvm-exegesis
llvm-extract
llvm-isel-fuzzer
llvm-ifs
llvm-jitlink
llvm-lib
llvm-link
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/lit.cfg.py
Expand Up @@ -142,7 +142,7 @@ def get_asan_rtlib():
'dsymutil', 'lli', 'lli-child-target', 'llvm-ar', 'llvm-as',
'llvm-bcanalyzer', 'llvm-config', 'llvm-cov', 'llvm-cxxdump', 'llvm-cvtres',
'llvm-diff', 'llvm-dis', 'llvm-dwarfdump', 'llvm-exegesis', 'llvm-extract',
'llvm-isel-fuzzer', 'llvm-jitlink', 'llvm-opt-fuzzer', 'llvm-lib',
'llvm-isel-fuzzer', 'llvm-ifs', 'llvm-jitlink', 'llvm-opt-fuzzer', 'llvm-lib',
'llvm-link', 'llvm-lto', 'llvm-lto2', 'llvm-mc', 'llvm-mca',
'llvm-modextract', 'llvm-nm', 'llvm-objcopy', 'llvm-objdump',
'llvm-pdbutil', 'llvm-profdata', 'llvm-ranlib', 'llvm-rc', 'llvm-readelf',
Expand Down
14 changes: 14 additions & 0 deletions llvm/test/tools/llvm-ifs/conflict-header-format.ifs
@@ -0,0 +1,14 @@
# RUN: not llvm-ifs -action write-ifs -o - %s %S/object.ifs 2>&1 | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# CHECK-IFS: error: Interface Stub: ObjectFileFormat Mismatch.
# CHECK-IFS-NEXT: Filenames:
# CHECK-IFS-NEXT: ObjectFileFormat Values: TBD ELF

--- !experimental-ifs-v1
IfsVersion: 1.0
Triple: x86_64-apple-unknown
ObjectFileFormat: TBD
Symbols:
a: { Type: Func }
...
14 changes: 14 additions & 0 deletions llvm/test/tools/llvm-ifs/conflict-header-triple.ifs
@@ -0,0 +1,14 @@
# RUN: not llvm-ifs -action write-ifs -o - %s %S/object.ifs 2>&1 | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# CHECK-IFS: error: Interface Stub: Triple Mismatch.
# CHECK-IFS-NEXT: Filenames:
# CHECK-IFS-NEXT: Triple Values: mips-unknown-linux x86_64-unknown-linux-gnu

--- !experimental-ifs-v1
IfsVersion: 1.0
Triple: mips-unknown-linux
ObjectFileFormat: ELF
Symbols:
a: { Type: Func }
...
16 changes: 16 additions & 0 deletions llvm/test/tools/llvm-ifs/conflict-header-version.ifs
@@ -0,0 +1,16 @@
# RUN: not llvm-ifs -action write-ifs -o - %s %S/object.ifs 2>&1 | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# RUN: not llvm-ifs -action write-ifs -o - %s 2>&1 | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS2

# CHECK-IFS: error: Interface Stub: IfsVersion Mismatch.
# CHECK-IFS2: error: Interface Stub: Bad IfsVersion: 0.0, llvm-ifs supported version: 1.2.

--- !experimental-ifs-v1
IfsVersion: 0.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
Symbols:
a: { Type: Func }
...
16 changes: 16 additions & 0 deletions llvm/test/tools/llvm-ifs/conflict-size.ifs
@@ -0,0 +1,16 @@
# RUN: not llvm-ifs -action write-ifs -o - %s %S/object.ifs 2>&1 | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# Here we are testing to see if two symbols with identical names will fail to
# merge in conflict due to mismatching sizes.
# CHECK-IFS: error: Interface Stub: Size Mismatch for b.
# CHECK-IFS-NEXT: Filename:
# CHECK-IFS-NEXT: Size Values: 1 4

--- !experimental-ifs-v1
IfsVersion: 1.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
Symbols:
b: { Type: Object, Size: 1 }
...
16 changes: 16 additions & 0 deletions llvm/test/tools/llvm-ifs/conflict-type.ifs
@@ -0,0 +1,16 @@
# RUN: not llvm-ifs -action write-ifs -o - %s %S/func.ifs 2>&1 | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# Here we are testing to see if two symbols with identical names will fail to
# merge in conflict due to mismatched types.
# CHECK-IFS: error: Interface Stub: Type Mismatch for a.
# CHECK-IFS-NEXT: Filename:
# CHECK-IFS-NEXT: Type Values: Object Func

--- !experimental-ifs-v1
IfsVersion: 1.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
Symbols:
a: { Type: Object, Size: 1 }
...
17 changes: 17 additions & 0 deletions llvm/test/tools/llvm-ifs/conflict-weak.ifs
@@ -0,0 +1,17 @@
# RUN: not llvm-ifs -action write-ifs -o - %s %S/func.ifs 2>&1 | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# Here we are testing to see if two symbols with identical names will fail to
# merge in conflict due to one being weak and one not. Eventually this will work
# when llvm-ifs has support for resolving these kinds of conflicts.
# CHECK-IFS: error: Interface Stub: Weak Mismatch for a.
# CHECK-IFS-NEXT: Filename:
# CHECK-IFS-NEXT: Weak Values: 1 0

--- !experimental-ifs-v1
IfsVersion: 1.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
Symbols:
a: { Type: Func, Weak: true }
...
56 changes: 56 additions & 0 deletions llvm/test/tools/llvm-ifs/func.ifs
@@ -0,0 +1,56 @@
# RUN: llvm-ifs -action write-ifs -o - %s %S/object.ifs | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# RUN: llvm-ifs -action write-bin -o - %s %S/object.ifs | \
# RUN: llvm-readelf --all | FileCheck %s --check-prefixes=CHECK-ELF

# RUN: llvm-ifs -action write-bin -force-format TBD -o - %s %S/object.ifs | \
# RUN: FileCheck %s --check-prefixes=CHECK-DARWIN-TBD3

# RUN: llvm-ifs -action write-ifs -o - %s %s | \
# RUN: FileCheck %s --check-prefixes=CHECK-MERGE-IFS

# CHECK-IFS: --- !experimental-ifs-v1
# CHECK-IFS-NEXT: IfsVersion: 1.0
# CHECK-IFS-NEXT: Triple: x86_64-unknown-linux-gnu
# CHECK-IFS-NEXT: ObjectFileFormat: ELF
# CHECK-IFS-NEXT: Symbols:
# CHECK-IFS-DAG: a: { Type: Func }
# CHECK-IFS-DAG: b: { Type: Object, Size: 4 }
# CHECK-IFS: ...

# CHECK-ELF: ELF Header:
# CHECK-ELF: Class: ELF64
# CHECK-ELF: Type: DYN (Shared object file)
# CHECK-ELF: FUNC GLOBAL DEFAULT 1 a
# CHECK-ELF: OBJECT GLOBAL DEFAULT 1 b

# CHECK-DARWIN-TBD3: --- !tapi-tbd-v3
# CHECK-DARWIN-TBD3-NEXT: archs: [ x86_64 ]
# CHECK-DARWIN-TBD3-NEXT: platform: macosx
# CHECK-DARWIN-TBD3-NEXT: flags: [ flat_namespace, not_app_extension_safe ]
# CHECK-DARWIN-TBD3-NEXT: install-name: ''
# CHECK-DARWIN-TBD3-NEXT: current-version: 0
# CHECK-DARWIN-TBD3-NEXT: compatibility-version: 0
# CHECK-DARWIN-TBD3-NEXT: objc-constraint: none
# CHECK-DARWIN-TBD3-NEXT: exports:
# CHECK-DARWIN-TBD3-NEXT: - archs: [ x86_64 ]
# CHECK-DARWIN-TBD3-NEXT: symbols: [ a, b ]
# CHECK-DARWIN-TBD3-NEXT: ...

# Here we are testing to see if two identical symbols will merge.
# CHECK-MERGE-IFS: --- !experimental-ifs-v1
# CHECK-MERGE-IFS-NEXT: IfsVersion: 1.0
# CHECK-MERGE-IFS-NEXT: Triple: x86_64-unknown-linux-gnu
# CHECK-MERGE-IFS-NEXT: ObjectFileFormat: ELF
# CHECK-MERGE-IFS-NEXT: Symbols:
# CHECK-MERGE-IFS-NEXT: a: { Type: Func }
# CHECK-MERGE-IFS-NEXT: ...

--- !experimental-ifs-v1
IfsVersion: 1.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
Symbols:
a: { Type: Func }
...
34 changes: 34 additions & 0 deletions llvm/test/tools/llvm-ifs/object-function-size-weak-combo.ifs
@@ -0,0 +1,34 @@
# RUN: llvm-ifs -action write-ifs -o - %s %S/func.ifs %S/object.ifs %S/weak.ifs | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# RUN: llvm-ifs -action write-bin -o - %s %S/func.ifs %S/object.ifs %S/weak.ifs | \
# RUN: llvm-readelf --all | FileCheck %s --check-prefixes=CHECK-ELF

# CHECK-IFS: --- !experimental-ifs-v1
# CHECK-IFS-NEXT: IfsVersion: 1.0
# CHECK-IFS-NEXT: Triple: x86_64-unknown-linux-gnu
# CHECK-IFS-NEXT: ObjectFileFormat: ELF
# CHECK-IFS-NEXT: Symbols:
# CHECK-IFS-DAG: e: { Type: Object, Size: 8 }
# CHECK-IFS-DAG: a: { Type: Func }
# CHECK-IFS-DAG: f: { Type: Object, Size: 2 }
# CHECK-IFS-DAG: _Z10strongFuncv: { Type: Func }
# CHECK-IFS-DAG: _Z8weakFuncv: { Type: Func, Weak: true }
# CHECK-IFS-DAG: b: { Type: Object, Size: 4 }
# CHECK-IFS: ...

# CHECK-ELF: FUNC GLOBAL DEFAULT 1 _Z10strongFuncv
# CHECK-ELF: FUNC WEAK DEFAULT 1 _Z8weakFuncv
# CHECK-ELF: FUNC GLOBAL DEFAULT 1 a
# CHECK-ELF: OBJECT GLOBAL DEFAULT 1 b
# CHECK-ELF: OBJECT GLOBAL DEFAULT 1 e
# CHECK-ELF: OBJECT GLOBAL DEFAULT 1 f

--- !experimental-ifs-v1
IfsVersion: 1.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
Symbols:
e: { Type: Object, Size: 8 }
f: { Type: Object, Size: 2 }
...
28 changes: 28 additions & 0 deletions llvm/test/tools/llvm-ifs/object.ifs
@@ -0,0 +1,28 @@
# RUN: llvm-ifs -action write-ifs -o - %s | \
# RUN: FileCheck %s --check-prefixes=CHECK-IFS

# RUN: llvm-ifs -action write-bin -o - %s | \
# RUN: llvm-readelf --all | FileCheck %s --check-prefixes=CHECK-ELF

# CHECK-IFS: --- !experimental-ifs-v1
# CHECK-IFS-NEXT: IfsVersion: 1.0
# CHECK-IFS-NEXT: Triple: x86_64-unknown-linux-gnu
# CHECK-IFS-NEXT: ObjectFileFormat: ELF
# CHECK-IFS-NEXT: Symbols:
# CHECK-IFS-NEXT: b: { Type: Object, Size: 4 }
# CHECK-IFS-NEXT: ...

# CHECK-ELF: ELF Header:
# CHECK-ELF: Class: ELF64
# CHECK-ELF: Data: 2's complement, little endian
# CHECK-ELF: Type: DYN (Shared object file)
# CHECK-ELF-NOT: FUNC GLOBAL DEFAULT 1 a
# CHECK-ELF: OBJECT GLOBAL DEFAULT 1 b

--- !experimental-ifs-v1
IfsVersion: 1.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
Symbols:
b: { Type: Object, Size: 4 }
...
9 changes: 9 additions & 0 deletions llvm/test/tools/llvm-ifs/version-ok.ifs
@@ -0,0 +1,9 @@
# RUN: llvm-ifs -action write-ifs -o - %s %S/object.ifs

--- !experimental-ifs-v1
IfsVersion: 1.1
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
Symbols:
a: { Type: Func }
...
19 changes: 19 additions & 0 deletions llvm/test/tools/llvm-ifs/weak.ifs
@@ -0,0 +1,19 @@
# RUN: llvm-ifs -action write-ifs -o - %s | FileCheck %s --check-prefixes=CHECK-IFS

# CHECK-IFS: --- !experimental-ifs-v1
# CHECK-IFS-NEXT: IfsVersion: 1.0
# CHECK-IFS-NEXT: Triple: x86_64-unknown-linux-gnu
# CHECK-IFS-NEXT: ObjectFileFormat: ELF
# CHECK-IFS-NEXT: Symbols:
# CHECK-IFS-DAG: _Z8weakFuncv: { Type: Func, Weak: true }
# CHECK-IFS-DAG: _Z10strongFuncv: { Type: Func }
# CHECK-IFS: ...

--- !experimental-ifs-v1
IfsVersion: 1.0
Triple: x86_64-unknown-linux-gnu
ObjectFileFormat: ELF
Symbols:
_Z8weakFuncv: { Type: Func, Weak: true }
_Z10strongFuncv: { Type: Func }
...
1 change: 1 addition & 0 deletions llvm/tools/LLVMBuild.txt
Expand Up @@ -32,6 +32,7 @@ subdirectories =
llvm-dwarfdump
llvm-dwp
llvm-elfabi
llvm-ifs
llvm-exegesis
llvm-extract
llvm-jitlistener
Expand Down
10 changes: 10 additions & 0 deletions llvm/tools/llvm-ifs/CMakeLists.txt
@@ -0,0 +1,10 @@
set(LLVM_LINK_COMPONENTS
Object
Support
TextAPI
ObjectYAML
)

add_llvm_tool(llvm-ifs
llvm-ifs.cpp
)
21 changes: 21 additions & 0 deletions llvm/tools/llvm-ifs/LLVMBuild.txt
@@ -0,0 +1,21 @@
;===- ./tools/llvm-ifs/LLVMBuild.txt ---------------------------*- Conf -*--===;
;
; Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
; See https://llvm.org/LICENSE.txt for license information.
; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
;
;===------------------------------------------------------------------------===;
;
; This is an LLVMBuild description file for the components in this subdirectory.
;
; For more information on the LLVMBuild system, please see:
;
; http://llvm.org/docs/LLVMBuild.html
;
;===------------------------------------------------------------------------===;

[component_0]
type = Tool
name = llvm-ifs
parent = Tools
required_libraries = Object Support TextAPI

0 comments on commit d719c50

Please sign in to comment.