[llvm] 31f2ad9 - [yaml2obj] - Automatically assign sh_addr for allocatable sections.

Georgii Rymar via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 22 04:38:36 PST 2020


Author: Georgii Rymar
Date: 2020-02-22T14:43:54+03:00
New Revision: 31f2ad9c368d47721508cbd0d120d626f9041715

URL: https://github.com/llvm/llvm-project/commit/31f2ad9c368d47721508cbd0d120d626f9041715
DIFF: https://github.com/llvm/llvm-project/commit/31f2ad9c368d47721508cbd0d120d626f9041715.diff

LOG: [yaml2obj] - Automatically assign sh_addr for allocatable sections.

I've noticed that it is not convenient to create YAMLs from
binaries (using obj2yaml) that have to be test cases for obj2yaml
later (after applying yaml2obj).

The problem, for example is that obj2yaml emits "DynamicSymbols:"
key instead of .dynsym. It also does not create .dynstr.
And when a YAML document without explicitly defined .dynsym/.dynstr
is given to yaml2obj, we have issues:

1) These sections are placed after non-allocatable sections (I've fixed it in D74756).
2) They have VA == 0. User needs create descriptions for such sections explicitly manually
    to set a VA.

This patch addresses (2). I suggest to let yaml2obj assign virtual addresses by itself.
It makes an output binary to be much closer to "normal" ELF.
(It is still possible to use "Address: 0x0" for a section to get the original behavior
if it is needed)

Differential revision: https://reviews.llvm.org/D74764

Added: 
    llvm/test/tools/yaml2obj/ELF/section-address-assign.yaml

Modified: 
    llvm/include/llvm/ObjectYAML/ELFYAML.h
    llvm/lib/ObjectYAML/ELFEmitter.cpp
    llvm/lib/ObjectYAML/ELFYAML.cpp
    llvm/test/tools/llvm-objcopy/ELF/only-keep-debug.test
    llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test
    llvm/test/tools/llvm-readobj/ELF/versioninfo.test
    llvm/test/tools/obj2yaml/elf-gnu-hash-section.yaml
    llvm/tools/obj2yaml/elf2yaml.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h
index 0d808b660e15..60bb2375901b 100644
--- a/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -167,7 +167,7 @@ struct Chunk {
 struct Section : public Chunk {
   ELF_SHT Type;
   Optional<ELF_SHF> Flags;
-  llvm::yaml::Hex64 Address;
+  Optional<llvm::yaml::Hex64> Address;
   StringRef Link;
   llvm::yaml::Hex64 AddressAlign;
   Optional<llvm::yaml::Hex64> EntSize;

diff  --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index a07b83a6efcf..78684883da1a 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -128,6 +128,7 @@ template <class ELFT> class ELFState {
   NameToIdxMap DynSymN2I;
   ELFYAML::Object &Doc;
 
+  uint64_t LocationCounter = 0;
   bool HasError = false;
   yaml::ErrorHandler ErrHandler;
   void reportError(const Twine &Msg);
@@ -218,6 +219,8 @@ template <class ELFT> class ELFState {
 
   ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH);
 
+  void assignSectionAddress(Elf_Shdr &SHeader, ELFYAML::Section *YAMLSec);
+
 public:
   static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc,
                        yaml::ErrorHandler EH);
@@ -390,6 +393,8 @@ bool ELFState<ELFT>::initImplicitHeader(ContiguousBlobAccumulator &CBA,
   else
     return false;
 
+  LocationCounter += Header.sh_size;
+
   // Override section fields if requested.
   overrideFields<ELFT>(YAMLSec, Header);
   return true;
@@ -413,6 +418,7 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
   for (const std::unique_ptr<ELFYAML::Chunk> &D : Doc.Chunks) {
     if (auto S = dyn_cast<ELFYAML::Fill>(D.get())) {
       writeFill(*S, CBA);
+      LocationCounter += S->Size;
       continue;
     }
 
@@ -438,9 +444,10 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
     SHeader.sh_type = Sec->Type;
     if (Sec->Flags)
       SHeader.sh_flags = *Sec->Flags;
-    SHeader.sh_addr = Sec->Address;
     SHeader.sh_addralign = Sec->AddressAlign;
 
+    assignSectionAddress(SHeader, Sec);
+
     if (!Sec->Link.empty())
       SHeader.sh_link = toSectionIndex(Sec->Link, Sec->Name);
 
@@ -500,11 +507,34 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
       llvm_unreachable("Unknown section type");
     }
 
+    LocationCounter += SHeader.sh_size;
+
     // Override section fields if requested.
     overrideFields<ELFT>(Sec, SHeader);
   }
 }
 
+template <class ELFT>
+void ELFState<ELFT>::assignSectionAddress(Elf_Shdr &SHeader,
+                                          ELFYAML::Section *YAMLSec) {
+  if (YAMLSec && YAMLSec->Address) {
+    SHeader.sh_addr = *YAMLSec->Address;
+    LocationCounter = *YAMLSec->Address;
+    return;
+  }
+
+  // sh_addr represents the address in the memory image of a process. Sections
+  // in a relocatable object file or non-allocatable sections do not need
+  // sh_addr assignment.
+  if (Doc.Header.Type.value == ELF::ET_REL ||
+      !(SHeader.sh_flags & ELF::SHF_ALLOC))
+    return;
+
+  LocationCounter =
+      alignTo(LocationCounter, SHeader.sh_addralign ? SHeader.sh_addralign : 1);
+  SHeader.sh_addr = LocationCounter;
+}
+
 static size_t findFirstNonGlobal(ArrayRef<ELFYAML::Symbol> Symbols) {
   for (size_t I = 0; I < Symbols.size(); ++I)
     if (Symbols[I].Binding.value != ELF::STB_LOCAL)
@@ -629,7 +659,8 @@ void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
                            ? (uint64_t)(*YAMLSec->EntSize)
                            : sizeof(Elf_Sym);
   SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 8;
-  SHeader.sh_addr = YAMLSec ? (uint64_t)YAMLSec->Address : 0;
+
+  assignSectionAddress(SHeader, YAMLSec);
 
   auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
   if (RawSec && (RawSec->Content || RawSec->Size)) {
@@ -678,8 +709,7 @@ void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
 
   // If the section is explicitly described in the YAML
   // then we want to use its section address.
-  if (YAMLSec)
-    SHeader.sh_addr = YAMLSec->Address;
+  assignSectionAddress(SHeader, YAMLSec);
 }
 
 template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) {

diff  --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index 6a553a7a9854..58f87b2708e3 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -1013,7 +1013,7 @@ static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
   IO.mapOptional("Name", Section.Name, StringRef());
   IO.mapRequired("Type", Section.Type);
   IO.mapOptional("Flags", Section.Flags);
-  IO.mapOptional("Address", Section.Address, Hex64(0));
+  IO.mapOptional("Address", Section.Address);
   IO.mapOptional("Link", Section.Link, StringRef());
   IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
   IO.mapOptional("EntSize", Section.EntSize);

diff  --git a/llvm/test/tools/llvm-objcopy/ELF/only-keep-debug.test b/llvm/test/tools/llvm-objcopy/ELF/only-keep-debug.test
index 1dc29c973658..8f21bce57823 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/only-keep-debug.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/only-keep-debug.test
@@ -193,9 +193,9 @@ ProgramHeaders:
 
 # CHECK3:      [Nr] Name          Type     Address          Off    Size   ES Flg Lk Inf Al
 # CHECK3:      [ 1] .dynsym       NOBITS   0000000000000000 000040 000018 18   A  2   1 1024
-# CHECK3-NEXT: [ 2] .dynstr       NOBITS   0000000000000000 000040 000001 00   A  0   0  0
-# CHECK3-NEXT: [ 3] .symtab       NOBITS   0000000000000000 000040 000018 18   A  4   1  0
-# CHECK3-NEXT: [ 4] .strtab       NOBITS   0000000000000000 000040 000001 00   A  0   0  0
+# CHECK3-NEXT: [ 2] .dynstr       NOBITS   0000000000000018 000040 000001 00   A  0   0  0
+# CHECK3-NEXT: [ 3] .symtab       NOBITS   0000000000000019 000040 000018 18   A  4   1  0
+# CHECK3-NEXT: [ 4] .strtab       NOBITS   0000000000000031 000040 000001 00   A  0   0  0
 # CHECK3-NEXT: [ 5] .shstrtab     STRTAB   0000000000000000 000040 00002b 00      0   0  1
 
 --- !ELF

diff  --git a/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test b/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test
index 9c6148338d3f..2988adcce8da 100644
--- a/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test
+++ b/llvm/test/tools/llvm-readobj/ELF/verneed-invalid.test
@@ -13,7 +13,7 @@
 # GNU-VERNEED-NAME-NEXT:   000:   0 (*local*)       2 ()
 
 # GNU-VERNEED-NAME:      Version needs section '.gnu.version_r' contains 1 entries:
-# GNU-VERNEED-NAME-NEXT:  Addr: 0000000000000000  Offset: 0x000044  Link: 4 (.dynstr)
+# GNU-VERNEED-NAME-NEXT:  Addr: 0000000000200214  Offset: 0x000044  Link: 4 (.dynstr)
 # GNU-VERNEED-NAME-NEXT:   0x0000: Version: 1  File: somefile  Cnt: 1
 # GNU-VERNEED-NAME-NEXT:   0x0010:   Name:   Flags: none  Version: 2
 
@@ -89,7 +89,7 @@ DynamicSymbols:
 # GNU-NOLINK-NEXT: warning: '[[FILE]]': invalid string table linked to SHT_GNU_verneed section with index 2: invalid sh_type for string table section [index 0]: expected SHT_STRTAB, but got SHT_NULL
 # GNU-NOLINK-NEXT:   000:   0 (*local*) 2 (<corrupt>)
 # GNU-NOLINK:      Version needs section '.gnu.version_r' contains 1 entries:
-# GNU-NOLINK-NEXT:  Addr: 0000000000000000  Offset: 0x000044  Link: 0 ()
+# GNU-NOLINK-NEXT:  Addr: 0000000000000004  Offset: 0x000044  Link: 0 ()
 # GNU-NOLINK-NEXT:   0x0000: Version: 1  File: <corrupt vn_file: 9>  Cnt: 1
 # GNU-NOLINK-NEXT:   0x0010:   Name: <corrupt>  Flags: none Version: 2
 
@@ -231,7 +231,7 @@ DynamicSymbols: []
 # LLVM-OFFSET-EQ-NEXT: ]
 
 # GNU-OFFSET-EQ:      Version needs section '.gnu.version_r' contains 1 entries:
-# GNU-OFFSET-EQ-NEXT:  Addr: 0000000000000000  Offset: 0x000044  Link: 1 (.mystrtab)
+# GNU-OFFSET-EQ-NEXT:  Addr: 0000000000000004  Offset: 0x000044  Link: 1 (.mystrtab)
 # GNU-OFFSET-EQ-NEXT:   0x0000: Version: 1  File: <corrupt vn_file: 1>  Cnt: 1
 # GNU-OFFSET-EQ-NEXT:   0x0010:   Name: <corrupt>  Flags: none  Version: 0
 
@@ -562,7 +562,7 @@ DynamicSymbols:
 # GNU-CUSTOM-DYNSTR-NEXT:  Addr: 0000000000000000  Offset: 0x000040  Link: 4 (.dynsym)
 # GNU-CUSTOM-DYNSTR-NEXT:   000:   0 (*local*)       2 (bcdefghij)
 # GNU-CUSTOM-DYNSTR:      Version needs section '.gnu.version_r' contains 1 entries:
-# GNU-CUSTOM-DYNSTR-NEXT:  Addr: 0000000000000000  Offset: 0x000044  Link: 3 (.custom.dynstr)
+# GNU-CUSTOM-DYNSTR-NEXT:  Addr: 0000000000000004  Offset: 0x000044  Link: 3 (.custom.dynstr)
 # GNU-CUSTOM-DYNSTR-NEXT:   0x0000: Version: 1  File: j  Cnt: 1
 # GNU-CUSTOM-DYNSTR-NEXT:   0x0010:   Name: bcdefghij  Flags: none  Version: 2
 

diff  --git a/llvm/test/tools/llvm-readobj/ELF/versioninfo.test b/llvm/test/tools/llvm-readobj/ELF/versioninfo.test
index 34ed7cd42d5d..da9e3eef087d 100644
--- a/llvm/test/tools/llvm-readobj/ELF/versioninfo.test
+++ b/llvm/test/tools/llvm-readobj/ELF/versioninfo.test
@@ -275,7 +275,7 @@ DynamicSymbols:
 # GNU-NEXT:   004:   5 (v2)      6 (v3)
 # GNU-EMPTY:
 # GNU-NEXT:  Version definition section '.gnu.version_d' contains 6 entries:
-# GNU-NEXT:   Addr: 0000000000000000  Offset: 0x00004c  Link: 5 (.dynstr)
+# GNU-NEXT:   Addr: 000000000000000c  Offset: 0x00004c  Link: 5 (.dynstr)
 # GNU-NEXT:    0x0000: Rev: 1  Flags: none  Index: 0  Cnt: 1  Name: VERSION1
 # GNU-NEXT:    0x001c: Rev: 1  Flags: BASE  Index: 0  Cnt: 1  Name: VERSION1
 # GNU-NEXT:    0x0038: Rev: 1  Flags: WEAK  Index: 0  Cnt: 1  Name: VERSION1
@@ -286,7 +286,7 @@ DynamicSymbols:
 # GNU-NEXT:    0x00b0: Parent 2: VERSION3
 # GNU-EMPTY:
 # GNU-NEXT:  Version needs section '.gnu.version_r' contains 2 entries:
-# GNU-NEXT:   Addr: 0000000000000000  Offset: 0x000104  Link: 5 (.dynstr)
+# GNU-NEXT:   Addr: 00000000000000c4  Offset: 0x000104  Link: 5 (.dynstr)
 # GNU-NEXT:    0x0000: Version: 1  File: verneed1.so.0  Cnt: 5
 # GNU-NEXT:    0x0010:   Name: v1  Flags: BASE  Version: 0
 # GNU-NEXT:    0x0020:   Name: v1  Flags: WEAK  Version: 0

diff  --git a/llvm/test/tools/obj2yaml/elf-gnu-hash-section.yaml b/llvm/test/tools/obj2yaml/elf-gnu-hash-section.yaml
index 24f087b68812..85492c9f1aad 100644
--- a/llvm/test/tools/obj2yaml/elf-gnu-hash-section.yaml
+++ b/llvm/test/tools/obj2yaml/elf-gnu-hash-section.yaml
@@ -45,6 +45,7 @@ Sections:
 # INVALID-NEXT: - Name:        .gnu.hash.empty
 # INVALID-NEXT:   Type:        SHT_GNU_HASH
 # INVALID-NEXT:   Flags:       [ SHF_ALLOC ]
+# INVALID-NEXT:   Address:     0x000000000000000F
 # INVALID-NEXT:   Header:
 # INVALID-NEXT:     SymNdx:      0x00000000
 # INVALID-NEXT:     Shift2:      0x00000000

diff  --git a/llvm/test/tools/yaml2obj/ELF/section-address-assign.yaml b/llvm/test/tools/yaml2obj/ELF/section-address-assign.yaml
new file mode 100644
index 000000000000..e163ee80f295
--- /dev/null
+++ b/llvm/test/tools/yaml2obj/ELF/section-address-assign.yaml
@@ -0,0 +1,98 @@
+## Test that yaml2obj automatically assigns sh_addr to allocatable sections for ET_EXEC/ET_DYN files.
+
+# RUN: yaml2obj %s -o %t.so -D TYPE=ET_DYN
+# RUN: llvm-readelf --sections %t.so | FileCheck %s --check-prefix=EXE-DSO
+
+# RUN: yaml2obj %s -o %t -D TYPE=ET_EXEC
+# RUN: llvm-readelf --sections %t | FileCheck %s --check-prefix=EXE-DSO
+
+# RUN: yaml2obj %s -o %t.o -D TYPE=ET_REL
+# RUN: llvm-readelf --sections %t.o | FileCheck %s --check-prefix=REL
+
+## We assign virtual addresses to allocatable sections automatically for executables and shared libraries.
+
+# EXE-DSO:      Section Headers:
+# EXE-DSO-NEXT:   [Nr] Name                  Type     Address          Off    Size   ES Flg Lk Inf Al
+# EXE-DSO-NEXT:   [ 0]                       NULL     0000000000000000 000000 000000 00     0   0  0
+# EXE-DSO-NEXT:   [ 1] .text.any.addr        PROGBITS 0000000000001000 000040 000003 00   A 0   0  0
+# EXE-DSO-NEXT:   [ 2] .text.shsize          PROGBITS 0000000000001003 000043 001234 00   A 0   0  0
+# EXE-DSO-NEXT:   [ 3] .text.align           PROGBITS 0000000000001100 000100 000004 00   A 0   0  256
+# EXE-DSO-NEXT:   [ 4] .data.any.addr        PROGBITS 0000000000002000 000104 000001 00   A 0   0  0
+# EXE-DSO-NEXT:   [ 5] .data.after.fill      PROGBITS 0000000000002101 000205 000001 00   A 0   0  0
+# EXE-DSO-NEXT:   [ 6] .data.return.back     PROGBITS 0000000000001500 000206 000001 00   A 0   0  0
+# EXE-DSO-NEXT:   [ 7] .data.return.back.foo PROGBITS 0000000000001501 000207 000000 00   A 0   0  0
+# EXE-DSO-NEXT:   [ 8] .dynsym               DYNSYM   0000000000001508 000208 000018 18   A 9   1  8
+# EXE-DSO-NEXT:   [ 9] .dynstr               STRTAB   0000000000001520 000220 000001 00   A 0   0  1
+# EXE-DSO-NEXT:   [10] .strtab               STRTAB   0000000000000000 000221 000001 00     0   0  1
+# EXE-DSO-NEXT:   [11] .shstrtab             STRTAB   0000000000000000 000222 000093 00     0   0  1
+
+## We do not assign virtual addresses to allocatable sections in a relocatable object
+## unless YAML document has an explicit request.
+
+# REL:      Section Headers:
+# REL-NEXT:   [Nr] Name                  Type     Address          Off    Size   ES Flg Lk Inf Al
+# REL-NEXT:   [ 0]                       NULL     0000000000000000 000000 000000 00     0   0  0
+# REL-NEXT:   [ 1] .text.any.addr        PROGBITS 0000000000001000 000040 000003 00   A 0   0  0
+# REL-NEXT:   [ 2] .text.shsize          PROGBITS 0000000000000000 000043 001234 00   A 0   0  0
+# REL-NEXT:   [ 3] .text.align           PROGBITS 0000000000000000 000100 000004 00   A 0   0  256
+# REL-NEXT:   [ 4] .data.any.addr        PROGBITS 0000000000002000 000104 000001 00   A 0   0  0
+# REL-NEXT:   [ 5] .data.after.fill      PROGBITS 0000000000000000 000205 000001 00   A 0   0  0
+# REL-NEXT:   [ 6] .data.return.back     PROGBITS 0000000000001500 000206 000001 00   A 0   0  0
+# REL-NEXT:   [ 7] .data.return.back.foo PROGBITS 0000000000000000 000207 000000 00   A 0   0  0
+# REL-NEXT:   [ 8] .dynsym               DYNSYM   0000000000000000 000208 000018 18   A 9   1  8
+# REL-NEXT:   [ 9] .dynstr               STRTAB   0000000000000000 000220 000001 00   A 0   0  1
+# REL-NEXT:   [10] .strtab               STRTAB   0000000000000000 000221 000001 00     0   0  1
+# REL-NEXT:   [11] .shstrtab             STRTAB   0000000000000000 000222 000093 00     0   0  1
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    [[TYPE]]
+  Machine: EM_X86_64
+Sections:
+## Show we can place a section at any address.
+  - Name:    .text.any.addr
+    Type:    SHT_PROGBITS
+    Flags:   [ SHF_ALLOC ]
+    Address: 0x1000
+    Size:    0x3
+## Test that ShSize does not affect virtual addresses.
+  - Name:   .text.shsize
+    Type:   SHT_PROGBITS
+    Flags:  [ SHF_ALLOC ]
+    ShSize: 0x1234
+## Show we respect an address align when automatically
+## assign virtual addresses.
+  - Name:         .text.align
+    Type:         SHT_PROGBITS
+    Flags:        [ SHF_ALLOC ]
+    AddressAlign: 0x100
+    Size:         0x4
+## We can set another address for a subsequent section.
+  - Name:    .data.any.addr
+    Type:    SHT_PROGBITS
+    Flags:   [ SHF_ALLOC ]
+    Address: 0x2000
+    Size:    0x1
+## Show that Fill occupies VA space.
+  - Type:    Fill
+    Pattern: "AABB"
+    Size:    0x100
+  - Name:  .data.after.fill
+    Type:  SHT_PROGBITS
+    Flags: [ SHF_ALLOC ]
+    Size:  0x1
+## Show we can return back in the address space and
+## continue placing sections. The order of sections in the
+## section header table will match the order in the YAML description.
+  - Name:    .data.return.back
+    Address: 0x1500
+    Type:    SHT_PROGBITS
+    Flags:   [ SHF_ALLOC ]
+    Size:    0x1
+  - Name:    .data.return.back.foo
+    Type:    SHT_PROGBITS
+    Flags:   [ SHF_ALLOC ]
+## Used to trigger creation of .dynsym and .dynstr.
+DynamicSymbols: []

diff  --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index cb06e093a2bf..08c3587a821d 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -502,7 +502,8 @@ Error ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
   S.Type = Shdr->sh_type;
   if (Shdr->sh_flags)
     S.Flags = static_cast<ELFYAML::ELF_SHF>(Shdr->sh_flags);
-  S.Address = Shdr->sh_addr;
+  if (Shdr->sh_addr)
+    S.Address = static_cast<uint64_t>(Shdr->sh_addr);
   S.AddressAlign = Shdr->sh_addralign;
   if (Shdr->sh_entsize)
     S.EntSize = static_cast<llvm::yaml::Hex64>(Shdr->sh_entsize);


        


More information about the llvm-commits mailing list