[llvm] [llvm][yaml2obj] Modify section header overriding timing (PR #130942)

Ruoyu Qiu via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 17 04:22:32 PDT 2025


https://github.com/cabbaken updated https://github.com/llvm/llvm-project/pull/130942

>From 701efbe96d8d2bdad6df3d91e2c1bcd6adfc2f8c Mon Sep 17 00:00:00 2001
From: Ruoyu Qiu <cabbaken at outlook.com>
Date: Wed, 12 Mar 2025 18:37:50 +0800
Subject: [PATCH 1/4] [llvm][yaml2obj] Modify section header overriding timing

Signed-off-by: Ruoyu Qiu <cabbaken at outlook.com>
---
 llvm/lib/ObjectYAML/ELFEmitter.cpp | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 9ae76a71ede5e..48d5d58beea86 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -206,6 +206,9 @@ template <class ELFT> class ELFState {
   NameToIdxMap DynSymN2I;
   ELFYAML::Object &Doc;
 
+  std::vector<std::pair<unsigned, ELFYAML::Section>>
+      SectionHeadersOverrideHelper;
+
   StringSet<> ExcludedSectionHeaders;
 
   uint64_t LocationCounter = 0;
@@ -226,6 +229,7 @@ template <class ELFT> class ELFState {
                           StringRef SecName, ELFYAML::Section *YAMLSec);
   void initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
                           ContiguousBlobAccumulator &CBA);
+  void overrideSectionHeaders(std::vector<Elf_Shdr> &SHeaders);
   void initSymtabSectionHeader(Elf_Shdr &SHeader, SymtabType STType,
                                ContiguousBlobAccumulator &CBA,
                                ELFYAML::Section *YAMLSec);
@@ -845,7 +849,7 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
       }
 
       LocationCounter += SHeader.sh_size;
-      overrideFields<ELFT>(Sec, SHeader);
+      SectionHeadersOverrideHelper.push_back({SN2I.get(Sec->Name), *Sec});
       continue;
     }
 
@@ -899,12 +903,17 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
     }
 
     LocationCounter += SHeader.sh_size;
-
-    // Override section fields if requested.
-    overrideFields<ELFT>(Sec, SHeader);
+    SectionHeadersOverrideHelper.push_back({SN2I.get(Sec->Name), *Sec});
   }
 }
 
+template <class ELFT>
+void ELFState<ELFT>::overrideSectionHeaders(std::vector<Elf_Shdr> &SHeaders) {
+  for (std::pair<unsigned, ELFYAML::Section> &IndexAndSec :
+       SectionHeadersOverrideHelper)
+    overrideFields<ELFT>(&IndexAndSec.second, SHeaders[IndexAndSec.first]);
+}
+
 template <class ELFT>
 void ELFState<ELFT>::assignSectionAddress(Elf_Shdr &SHeader,
                                           ELFYAML::Section *YAMLSec) {
@@ -2090,6 +2099,9 @@ bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
   // Now we can decide segment offsets.
   State.setProgramHeaderLayout(PHeaders, SHeaders);
 
+  // Override section fields if requested.
+  State.overrideSectionHeaders(SHeaders);
+
   bool ReachedLimit = CBA.getOffset() > MaxSize;
   if (Error E = CBA.takeLimitError()) {
     // We report a custom error message instead below.

>From f079240875cfedbdd7b02a7c72301d990421b415 Mon Sep 17 00:00:00 2001
From: Ruoyu Qiu <cabbaken at outlook.com>
Date: Mon, 17 Mar 2025 13:27:08 +0800
Subject: [PATCH 2/4] Distinguish ShOffset and Offset in
 program-header-size-offset.yaml, remove unneed test

Signed-off-by: Ruoyu Qiu <cabbaken at outlook.com>
---
 .../ELF/program-header-size-offset.yaml       | 39 +++----------------
 1 file changed, 5 insertions(+), 34 deletions(-)

diff --git a/llvm/test/tools/yaml2obj/ELF/program-header-size-offset.yaml b/llvm/test/tools/yaml2obj/ELF/program-header-size-offset.yaml
index add260d5972eb..fa9ee312f3e5e 100644
--- a/llvm/test/tools/yaml2obj/ELF/program-header-size-offset.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/program-header-size-offset.yaml
@@ -44,25 +44,25 @@ Sections:
   - Name: .text
     Type: SHT_PROGBITS
     Size: 4
-    ShOffset: 0x1000
+    Offset: 0x1000
     AddressAlign: 0x1000
   - Name: .rodata
     Type: SHT_PROGBITS
     Size: 4
-    ShOffset: 0x2000
+    Offset: 0x2000
     AddressAlign: 0x1000
   - Name: .data
     Type: SHT_PROGBITS
-    ShOffset: 0x2004
+    Offset: 0x2004
     Size: 4
   - Name: .nobits1
     Type: SHT_NOBITS
-    ShOffset: 0x2008
+    Offset: 0x2008
     Size: 1
   - Name: .nobits2
     Type: SHT_NOBITS
     # Intentionally set to 0x2009 though the previous section is SHT_NOBITS.
-    ShOffset: 0x2009
+    Offset: 0x2009
     Size: 1
 ProgramHeaders:
   # Program header with no sections.
@@ -179,32 +179,3 @@ ProgramHeaders:
 # RUN:   FileCheck %s --check-prefix=INVALID-OFFSET
 
 # INVALID-OFFSET: yaml2obj: error: 'Offset' for segment with index 1 must be less than or equal to the minimum file offset of all included sections (0x78)
-
-## Document that the "Offset" value is checked after the section offset is overriden using "ShOffset".
-# RUN: yaml2obj --docnum=4 %s -o %t5
-# RUN: llvm-readelf %t5 --sections --program-headers | FileCheck %s --check-prefix=SHOFFSET
-
-# SHOFFSET: [Nr] Name Type     Address          Off
-# SHOFFSET: [ 1] .foo PROGBITS 0000000000000000 ffffffff
-
-# SHOFFSET:      Type Offset
-# SHOFFSET-NEXT: LOAD 0xffffff00
-
---- !ELF
-FileHeader:
-  Class: ELFCLASS64
-  Data:  ELFDATA2LSB
-  Type:  ET_EXEC
-Sections:
-  - Name:     .foo
-    Type:     SHT_PROGBITS
-    Flags:    [ SHF_ALLOC ]
-    Size:     0x1
-## Note: the real .foo offset is much less than 0xFFFFFFFF or
-##       0xFFFFFF00, but no error is reported.
-    ShOffset: 0xFFFFFFFF
-ProgramHeaders:
-  - Type:     PT_LOAD
-    Offset:   0xFFFFFF00
-    FirstSec: .foo
-    LastSec:  .foo

>From 9260c30a92345636fb29190b44022fe5a8e5bddf Mon Sep 17 00:00:00 2001
From: Ruoyu Qiu <cabbaken at outlook.com>
Date: Mon, 17 Mar 2025 18:24:42 +0800
Subject: [PATCH 3/4] Modify malformed-pt-dynamic.test to fix program header
 offset

Signed-off-by: Ruoyu Qiu <cabbaken at outlook.com>
---
 llvm/test/tools/llvm-readobj/ELF/malformed-pt-dynamic.test | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/tools/llvm-readobj/ELF/malformed-pt-dynamic.test b/llvm/test/tools/llvm-readobj/ELF/malformed-pt-dynamic.test
index 0666674b43d5f..07b3d62ef5764 100644
--- a/llvm/test/tools/llvm-readobj/ELF/malformed-pt-dynamic.test
+++ b/llvm/test/tools/llvm-readobj/ELF/malformed-pt-dynamic.test
@@ -133,7 +133,6 @@ Sections:
     Type:     SHT_DYNAMIC
     Address:  0x1000
     Offset:   0x1000
-    ShOffset: [[OFFSET=<none>]]
     Entries:
       - Tag:   DT_NULL
         Value: 0
@@ -142,5 +141,6 @@ Sections:
 ProgramHeaders:
   - Type:     PT_DYNAMIC
     FileSize: [[FILESIZE=<none>]]
+    Offset: [[OFFSET=<none>]]
     FirstSec: .dynamic
     LastSec:  .dynamic

>From 052b1a0327571b24e91d1da3efffe67f61fdd3cf Mon Sep 17 00:00:00 2001
From: Ruoyu Qiu <cabbaken at outlook.com>
Date: Mon, 17 Mar 2025 19:21:47 +0800
Subject: [PATCH 4/4] Optimize code style

Signed-off-by: Ruoyu Qiu <cabbaken at outlook.com>
---
 llvm/lib/ObjectYAML/ELFEmitter.cpp | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 48d5d58beea86..e616e710db803 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -206,7 +206,7 @@ template <class ELFT> class ELFState {
   NameToIdxMap DynSymN2I;
   ELFYAML::Object &Doc;
 
-  std::vector<std::pair<unsigned, ELFYAML::Section>>
+  std::vector<std::pair<Elf_Shdr*, ELFYAML::Section>>
       SectionHeadersOverrideHelper;
 
   StringSet<> ExcludedSectionHeaders;
@@ -849,7 +849,7 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
       }
 
       LocationCounter += SHeader.sh_size;
-      SectionHeadersOverrideHelper.push_back({SN2I.get(Sec->Name), *Sec});
+      SectionHeadersOverrideHelper.push_back({&SHeader, *Sec});
       continue;
     }
 
@@ -903,15 +903,15 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
     }
 
     LocationCounter += SHeader.sh_size;
-    SectionHeadersOverrideHelper.push_back({SN2I.get(Sec->Name), *Sec});
+    SectionHeadersOverrideHelper.push_back({&SHeader, *Sec});
   }
 }
 
 template <class ELFT>
 void ELFState<ELFT>::overrideSectionHeaders(std::vector<Elf_Shdr> &SHeaders) {
-  for (std::pair<unsigned, ELFYAML::Section> &IndexAndSec :
+  for (std::pair<Elf_Shdr*, ELFYAML::Section> &HeaderAndSec :
        SectionHeadersOverrideHelper)
-    overrideFields<ELFT>(&IndexAndSec.second, SHeaders[IndexAndSec.first]);
+    overrideFields<ELFT>(&HeaderAndSec.second, *HeaderAndSec.first);
 }
 
 template <class ELFT>
@@ -2099,7 +2099,9 @@ bool ELFState<ELFT>::writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
   // Now we can decide segment offsets.
   State.setProgramHeaderLayout(PHeaders, SHeaders);
 
-  // Override section fields if requested.
+  // Override section fields, if requested. This needs to happen after program
+  // header layout happens, because otherwise the layout will use the new
+  // values.
   State.overrideSectionHeaders(SHeaders);
 
   bool ReachedLimit = CBA.getOffset() > MaxSize;



More information about the llvm-commits mailing list