Skip to content

Commit 10c24f3

Browse files
committed
Add initial support for creating shared library with symbol versioning
This commit adds initial support for building shared libraries with symbol versioning information. Symbol versioning allows to add version information to symbols. It is used to provide multiple definitions of the same symbol for backward compatibility. This commit adds the support such that the functionality can be enabled conditionally at build time by specifying ELD_ENABLE_SYMBOL_VERSIONING CMake option. This commit also updates the PR checkin builder to enable symbol versioning functionality. Symbol versioning is a target-independent feature but requires support from compiler, linker and the loader. From the ELF perspective, symbol versioning is implemented using 3 sections: .gnu.version(SHT_GNU_versym), .gnu.version_d(SHT_GNU_verdef), and .gnu.version_r(SHT_GNU_verneed). This commit only provides support for .gnu.version and .gnu.version_d sections because only they are required when building a shared library. .gnu.version_r is required when using a shared library. Briefly, these sections can be descrbed as: - .gnu.version: An array of version IDs. i'th entry of this array stores the version ID of the i'th symbol in the dynamic symbol table. - .gnu.version_d: Stores the version definitions of the symbols that are defined by this module. - .gnu.version_r: Stores the version definitions of the undefined symbols that are used by this module. To add the support for creating shared libraries with symbol versioning information, this commit: - Adds support for creating symbol versioning sections .gnu.version and .gnu.version_d - Improve version script support to properly handle versioned nodes. - Add logic to properly assign output version IDs to symbols. - Update dynamic symbol table and .hash section to properly emit versioned symbols. - Emit symbol versioning sections and correctly fill symbol versioning information in the .dynamic section. Additionally, this commit adds the trace flag --trace=symbol-versioning. Resolves #646 Signed-off-by: Parth Arora <[email protected]>
1 parent 885297a commit 10c24f3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1136
-44
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ jobs:
8989
-DLLVM_TARGETS_TO_BUILD="ARM;AArch64;RISCV;Hexagon;X86" \
9090
-DELD_TARGETS_TO_BUILD="ARM;AArch64;RISCV;Hexagon;x86_64" \
9191
-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
92+
-DELD_ENABLE_SYMBOL_VERSIONING=ON \
9293
../llvm-project/llvm
9394
9495
- name: Cache Usage before build

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,11 @@ if(LLVM_USE_SANITIZER OR ELD_SANITIZE)
175175
endif()
176176
endif()
177177

178+
option(ELD_ENABLE_SYMBOL_VERSIONING "Enable Eld symbol versioning support" OFF)
179+
if(ELD_ENABLE_SYMBOL_VERSIONING)
180+
add_compile_definitions(ELD_ENABLE_SYMBOL_VERSIONING)
181+
endif()
182+
178183
set(CMAKE_INCLUDE_CURRENT_DIR ON)
179184
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include
180185
${CMAKE_CURRENT_SOURCE_DIR}/include)

cmake/modules/LITModules.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ function(generate_ext_lit ARCH OPTIONNAME LIT_CFG_PATH)
5959
"${CMAKE_CURRENT_BINARY_DIR}/llvm-lit-${ARCH_LOWER}-${OPTIONNAME}")
6060
endfunction()
6161

62+
if(ELD_ENABLE_SYMBOL_VERSIONING)
63+
set(ELD_ENABLE_SYMBOL_VERSIONING_TESTS "true")
64+
endif()
65+
6266
function(add_eld_lit_cfg ARCH OPTION OPTIONNAME)
6367
set(ELD_CURRENT_TARGET "${ARCH}_${OPTIONNAME}")
6468
set(ELD_OPTION ${OPTION})

include/eld/Config/LinkerConfig.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,12 @@ class LinkerConfig {
420420

421421
std::string getSymDefString() const;
422422

423+
/// Returns true if the link should build a dynamic object file
424+
/// or a dynamic executable file.
425+
#ifdef ELD_ENABLE_SYMBOL_VERSIONING
426+
bool shouldBuildDynamicArtifact() const;
427+
#endif
428+
423429
protected:
424430
CommandLineVectorT CommandLineVector;
425431

include/eld/Core/Module.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,10 @@ class Module {
9898
Trampoline,
9999
GlobalDataSymbols,
100100
GNUBuildID,
101-
MAX,
101+
#ifdef ELD_ENABLE_SYMBOL_VERSIONING
102+
SymbolVersioning,
103+
#endif
104+
MAX
102105
} InternalInputType;
103106

104107
typedef std::vector<InputFile *> ObjectList;

include/eld/Diagnostics/DiagCommonKinds.inc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ DIAG(mismatched_group, DiagnosticEngine::Fatal,
8383
DIAG(unsupported_version_node, DiagnosticEngine::Warning,
8484
"Only anonymous version nodes are supported. Ignoring version script `%0'")
8585
DIAG(unsupported_dependent_node, DiagnosticEngine::Warning,
86-
"Dependent nodes are not supported. Ignoring version script `%0'")
86+
"Dependent nodes are not supported. Ignoring dependency for node '%0' "
87+
"in version script '%1'")
8788
DIAG(unable_to_write_output_file, DiagnosticEngine::Error,
8889
"Unable to write output file %0 because of error %1")
8990
DIAG(unable_to_write_temporary_file, DiagnosticEngine::Fatal,
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//===- DiagSymbolVersioning.inc--------------------------------------------===//
2+
// Part of the eld Project, under the BSD License
3+
// See https://github.com/qualcomm/eld/LICENSE.txt for license information.
4+
// SPDX-License-Identifier: BSD-3-Clause
5+
//===----------------------------------------------------------------------===//
6+
//
7+
// The MCLinker Project
8+
//
9+
// This file is distributed under the University of Illinois Open Source
10+
// License. See LICENSE.TXT for details.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
DIAG(trace_creating_symbol_versioning_section, DiagnosticEngine::Trace,
14+
"Creating symbol versioning section: %0")
15+
DIAG(trace_creating_symbol_versioning_fragment, DiagnosticEngine::Trace,
16+
"Creating symbol versioning fragment: %0")
17+
DIAG(trace_version_script_matched_scope, DiagnosticEngine::Trace,
18+
"Version script node matched %0 symbol '%1'")
19+
DIAG(trace_clear_export_due_to_local_scope, DiagnosticEngine::Trace,
20+
"Clearing export for symbol '%0' due to local scope")
21+
DIAG(error_missing_version_node, DiagnosticEngine::Error,
22+
"%0: symbol %1 has undefined version %2")
23+
DIAG(trace_assign_output_version_ids, DiagnosticEngine::Trace,
24+
"Assigning version IDs to output symbols")

include/eld/Diagnostics/DiagnosticEngine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ class Diag {
301301
#include "eld/Diagnostics/DiagRelocations.inc"
302302
#include "eld/Diagnostics/DiagStats.inc"
303303
#include "eld/Diagnostics/DiagSymbolResolutions.inc"
304+
#include "eld/Diagnostics/DiagSymbolVersioning.inc"
304305
#include "eld/Diagnostics/DiagTraceAssignments.inc"
305306
#include "eld/Diagnostics/DiagTraceFiles.inc"
306307
#include "eld/Diagnostics/DiagTraceGC.inc"

include/eld/Diagnostics/DiagnosticPrinter.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ class DiagnosticPrinter {
4747
TraceMergeStrings = 0x8000,
4848
TraceLinkerScript = 0x10000,
4949
TraceSymDef = 0x100000,
50+
#ifdef ELD_ENABLE_SYMBOL_VERSIONING
51+
TraceSymbolVersioning = 0x200000
52+
#endif
5053
};
5154

5255
enum Verbose : uint16_t { None = 0x0, Default = 0x1 };
@@ -98,6 +101,12 @@ class DiagnosticPrinter {
98101

99102
bool traceSymDef() { return (Trace & TraceSymDef); }
100103

104+
#ifdef ELD_ENABLE_SYMBOL_VERSIONING
105+
bool traceSymbolVersioning() const { return (Trace & TraceSymbolVersioning); }
106+
#else
107+
bool traceSymbolVersioning() const { return false; }
108+
#endif
109+
101110
uint32_t trace() { return Trace; }
102111

103112
uint32_t isVerbose() const { return VerboseLevel & Verbose::Default; }

include/eld/Driver/GnuLinkerOptions.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,8 @@ defm trace
688688
"\t\t\t --trace=trampolines : trace trampolines\n"
689689
"\t\t\t --trace=wrap-symbols : trace symbol wrap options\n"
690690
"\t\t\t --trace=symdef : trace symbol resolution from symdef files\n"
691-
"\t\t\t --trace=dynamic-linking : trace dynamic linking">,
691+
"\t\t\t --trace=dynamic-linking : trace dynamic linking\n"
692+
"\t\t\t --trace=symbol-versioning : trace symbol versioning">,
692693
MetaVarName<"<trace-type>">,
693694
Group<grp_diagopts>;
694695
defm trace_symbol : smDashTwoWithOpt<"y", "trace-symbol", "trace_symbol",

0 commit comments

Comments
 (0)