Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BOLT] Ignore special symbols as function aliases in updateELFSymbolTable #92713

Conversation

aaupov
Copy link
Contributor

@aaupov aaupov commented May 20, 2024

Exempt special symbols (hot text/data and _end symbol) from normal
handling. We only need to set their value and make them absolute.

If these symbols are handled as normal symbols and if they alias
functions we may create non-sensical symbols, e.g. __hot_start.cold.

Test Plan: updated hot-end-symbol.s

Created using spr 1.3.4
@llvmbot
Copy link
Collaborator

llvmbot commented May 20, 2024

@llvm/pr-subscribers-bolt

Author: Amir Ayupov (aaupov)

Changes

If __hot_start marker aliases split function, we create non-sensical
__hot_start.cold symbols. Similar to how hot markers are ignored when
reading symbol table, explicitly ignore them as function references in
updating the symbol table and only update their values.

Test Plan: updated hot-end-symbol.s


Full diff: https://github.com/llvm/llvm-project/pull/92713.diff

2 Files Affected:

  • (modified) bolt/lib/Rewrite/RewriteInstance.cpp (+9-2)
  • (modified) bolt/test/runtime/X86/hot-end-symbol.s (+3-2)
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index fa5167490923c..0d11bdc46fa5a 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -4788,6 +4788,9 @@ void RewriteInstance::updateELFSymbolTable(
     if (!IsDynSym && shouldStrip(Symbol))
       continue;
 
+    Expected<StringRef> SymbolName = Symbol.getName(StringSection);
+    assert(SymbolName && "cannot get symbol name");
+
     const BinaryFunction *Function =
         BC->getBinaryFunctionAtAddress(Symbol.st_value);
     // Ignore false function references, e.g. when the section address matches
@@ -4795,6 +4798,12 @@ void RewriteInstance::updateELFSymbolTable(
     if (Function && Symbol.getType() == ELF::STT_SECTION)
       Function = nullptr;
 
+    // Ignore input hot markers as function aliases – markers are handled
+    // separately.
+    if (Function &&
+        (*SymbolName == "__hot_start" || *SymbolName == "__hot_end"))
+      Function = nullptr;
+
     // For non-dynamic symtab, make sure the symbol section matches that of
     // the function. It can mismatch e.g. if the symbol is a section marker
     // in which case we treat the symbol separately from the function.
@@ -4906,8 +4915,6 @@ void RewriteInstance::updateELFSymbolTable(
     }
 
     // Handle special symbols based on their name.
-    Expected<StringRef> SymbolName = Symbol.getName(StringSection);
-    assert(SymbolName && "cannot get symbol name");
 
     auto updateSymbolValue = [&](const StringRef Name,
                                  std::optional<uint64_t> Value = std::nullopt) {
diff --git a/bolt/test/runtime/X86/hot-end-symbol.s b/bolt/test/runtime/X86/hot-end-symbol.s
index e6d83d77167ac..f973013b1b3de 100755
--- a/bolt/test/runtime/X86/hot-end-symbol.s
+++ b/bolt/test/runtime/X86/hot-end-symbol.s
@@ -12,7 +12,8 @@
 # RUN: %clang %cflags -no-pie %t.o -o %t.exe -Wl,-q
 
 # RUN: llvm-bolt %t.exe --relocs=1 --hot-text --reorder-functions=hfsort \
-# RUN:    --data %t.fdata -o %t.out | FileCheck %s
+# RUN:    --data %t.fdata -o %t.out --split-functions --split-strategy=all \
+# RUN:    | FileCheck %s
 
 # RUN: %t.out 1
 
@@ -30,12 +31,12 @@
 # CHECK-OUTPUT:       __hot_start
 # CHECK-OUTPUT-NEXT:  main
 # CHECK-OUTPUT-NEXT:  __hot_end
+# CHECK-OUTPUT-NOT:   __hot_start.cold
 
   .text
   .globl  main
   .type main, %function
   .globl  __hot_start
-  .type __hot_start, %object
   .p2align  4
 main:
 __hot_start:

Copy link
Member

@dcci dcci left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments, thanks for working o this.

@@ -4788,13 +4788,22 @@ void RewriteInstance::updateELFSymbolTable(
if (!IsDynSym && shouldStrip(Symbol))
continue;

Expected<StringRef> SymbolName = Symbol.getName(StringSection);
assert(SymbolName && "cannot get symbol name");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this assert needed? if Expected returns null, it will blow up, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really. Let me drop it. Yes, Expected will blow up upon null access, and the assertion message is not more insightful than SymbolName variable itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expected values in success mode must still be checked prior to being destroyed

So we must keep the assertion.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SG

// Ignore input hot markers as function aliases – markers are handled
// separately.
if (Function &&
(*SymbolName == "__hot_start" || *SymbolName == "__hot_end"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you expand this comment -- explaining why we ignore input hot markers?


.text
.globl main
.type main, %function
.globl __hot_start
.type __hot_start, %object
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are you removing this?

Copy link
Contributor Author

@aaupov aaupov May 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If __hot_start has %object type, it will be an absolute symbol and won't belong to .text section. When updating symbols, we check that symbol section matches that of the function. So we need hot_start to be a global symbol in .text section.

Created using spr 1.3.4
Copy link
Member

@dcci dcci left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG

Created using spr 1.3.4
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
Created using spr 1.3.4
@aaupov aaupov changed the title [BOLT] Ignore hot markers as function references in updateELFSymbolTable [BOLT] Ignore special symbols as function references in updateELFSymbolTable May 20, 2024
@aaupov aaupov changed the title [BOLT] Ignore special symbols as function references in updateELFSymbolTable [BOLT] Ignore special symbols as function aliases in updateELFSymbolTable May 20, 2024
Copy link
Contributor

@maksfb maksfb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks.

Endilll and others added 2 commits May 20, 2024 16:50
Created using spr 1.3.4

[skip ci]
Created using spr 1.3.4
@aaupov aaupov changed the base branch from users/aaupov/spr/main.bolt-ignore-hot-markers-as-function-references-in-updateelfsymboltable to main May 20, 2024 23:51
@aaupov aaupov merged commit bb627b0 into main May 20, 2024
4 of 5 checks passed
@aaupov aaupov deleted the users/aaupov/spr/bolt-ignore-hot-markers-as-function-references-in-updateelfsymboltable branch May 20, 2024 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants