[llvm] r369742 - [yaml2obj] - Allow setting the symbol st_other field to any integer.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 23 02:31:08 PDT 2019


Author: grimar
Date: Fri Aug 23 02:31:07 2019
New Revision: 369742

URL: http://llvm.org/viewvc/llvm-project?rev=369742&view=rev
Log:
[yaml2obj] - Allow setting the symbol st_other field to any integer.

st_other field of a symbol usually contains its visibility.
Other bits are usually 0, though some targets, like
MIPS can set them using the named bit field values.

Problem is that there is no way to set an arbitrary value now,
though that might be useful for our test cases.

In this patch I introduced a way to set st_other to any numeric
value using the new StOther field.
I added a test and simplified the existent one to show the effect/benefit

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

Added:
    llvm/trunk/test/tools/yaml2obj/elf-symbol-stother.yaml
Modified:
    llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
    llvm/trunk/test/tools/llvm-readobj/elf-symbol-visibility.test

Modified: llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/ELFYAML.cpp?rev=369742&r1=369741&r2=369742&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/ELFYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/ELFYAML.cpp Fri Aug 23 02:31:07 2019
@@ -888,9 +888,25 @@ void MappingTraits<ELFYAML::Symbol>::map
   IO.mapOptional("Binding", Symbol.Binding, ELFYAML::ELF_STB(0));
   IO.mapOptional("Value", Symbol.Value, Hex64(0));
   IO.mapOptional("Size", Symbol.Size, Hex64(0));
-  MappingNormalization<NormalizedOther, uint8_t> Keys(IO, Symbol.Other);
-  IO.mapOptional("Visibility", Keys->Visibility, ELFYAML::ELF_STV(0));
-  IO.mapOptional("Other", Keys->Other, ELFYAML::ELF_STO(0));
+
+  // Symbol's Other field is a bit special. It is a bit field that represents
+  // st_other and usually holds symbol visibility. When we write a YAML document
+  // we split it into two fields named "Visibility" and "Other". The latter one
+  // usually holds no value, and so is almost never printed, although some
+  // targets (e.g. MIPS) may use it to specify the named bits to set (e.g.
+  // STO_MIPS_OPTIONAL). For producing broken objects we want to allow writing
+  // any value to st_other. To do this we allow one more field called "StOther".
+  // If it is present in a YAML document, we set st_other to that integer,
+  // ignoring the other fields.
+  Optional<llvm::yaml::Hex64> Other;
+  IO.mapOptional("StOther", Other);
+  if (Other) {
+    Symbol.Other = *Other;
+  } else {
+    MappingNormalization<NormalizedOther, uint8_t> Keys(IO, Symbol.Other);
+    IO.mapOptional("Visibility", Keys->Visibility, ELFYAML::ELF_STV(0));
+    IO.mapOptional("Other", Keys->Other, ELFYAML::ELF_STO(0));
+  }
 }
 
 StringRef MappingTraits<ELFYAML::Symbol>::validate(IO &IO,

Modified: llvm/trunk/test/tools/llvm-readobj/elf-symbol-visibility.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/elf-symbol-visibility.test?rev=369742&r1=369741&r2=369742&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/elf-symbol-visibility.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/elf-symbol-visibility.test Fri Aug 23 02:31:07 2019
@@ -1,11 +1,9 @@
 # Show that llvm-readobj prints the symbol visibility where recognised, or
 # something sensible when not, for both GNU and LLVM output.
 
-# Use --dyn-symbols because it is only possible to hand-craft symbols with
-# non-standard st_other values for .dynsym.
 # RUN: yaml2obj %s > %t
-# RUN: llvm-readobj --symbols --dyn-symbols %t | FileCheck %s --check-prefix=LLVM
-# RUN: llvm-readelf --symbols --dyn-symbols %t | FileCheck %s --check-prefix=GNU
+# RUN: llvm-readobj --symbols %t | FileCheck %s --check-prefix=LLVM
+# RUN: llvm-readelf --symbols %t | FileCheck %s --check-prefix=GNU
 
 # LLVM:      Name: default
 # LLVM:      Other: 0
@@ -27,11 +25,11 @@
 
 # FIXME - the "other" symbol should print something indicating its non-zero st_other value.
 # See https://bugs.llvm.org/show_bug.cgi?id=40785.
-# GNU:      DEFAULT   {{.*}} other
 # GNU:      DEFAULT   {{.*}} default
 # GNU-NEXT: INTERNAL  {{.*}} internal
 # GNU-NEXT: HIDDEN    {{.*}} hidden
 # GNU-NEXT: PROTECTED {{.*}} protected
+# GNU-NEXT: DEFAULT   {{.*}} other
 
 !ELF
 FileHeader:
@@ -39,18 +37,6 @@ FileHeader:
   Data:    ELFDATA2LSB
   Type:    ET_REL
   Machine: EM_386
-Sections:
-  - Name: .dynstr
-    Type: SHT_STRTAB
-    #\0other\0
-    Content: "006f7468657200"
-  - Name: .dynsym
-    Type: SHT_DYNSYM
-    Link: .dynstr
-    EntSize: 16
-    # Null symbol
-    # Symbol with st_name = 1, st_other = 0x4
-    Content: "0000000000000000000000000000000001000000000000000000000000040000"
 Symbols:
   - Name: default
     Visibility: STV_DEFAULT
@@ -64,3 +50,6 @@ Symbols:
   - Name: protected
     Visibility: STV_PROTECTED
     Binding: STB_GLOBAL
+  - Name: other
+    Binding: STB_GLOBAL
+    StOther: 4

Added: llvm/trunk/test/tools/yaml2obj/elf-symbol-stother.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/yaml2obj/elf-symbol-stother.yaml?rev=369742&view=auto
==============================================================================
--- llvm/trunk/test/tools/yaml2obj/elf-symbol-stother.yaml (added)
+++ llvm/trunk/test/tools/yaml2obj/elf-symbol-stother.yaml Fri Aug 23 02:31:07 2019
@@ -0,0 +1,79 @@
+## Test how yaml2obj sets the value of a symbol's st_other fields.
+
+## Show that yaml2obj reports an error when using an STO_* flag that belongs
+## to a different machine type to what is specified by the YAML.
+
+# RUN: not yaml2obj --docnum=1 2>&1 %s | FileCheck %s --check-prefix=ERR
+# ERR:      error: unknown bit value
+# ERR-NEXT: Other: [ STO_MIPS_OPTIONAL ]
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_386
+Symbols:
+  - Name:  foo
+    Other: [ STO_MIPS_OPTIONAL ]
+
+## Test that STO_* can be used with their correct machine type.
+## We use the same YAML as above, but with a change of machine type.
+
+# RUN: yaml2obj --docnum=2 %s > %t2
+# RUN: llvm-readobj --symbols %t2 | FileCheck %s --check-prefix=USE-OTHER
+
+# USE-OTHER:      Name: foo
+# USE-OTHER:      Other [ (0x4)
+# USE-OTHER-NEXT:   STO_MIPS_OPTIONAL (0x4)
+# USE-OTHER-NEXT: ]
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+Symbols:
+  - Name:  foo
+    Other: [ STO_MIPS_OPTIONAL ]
+
+## Test that instead of using the "Other" field we can use the "StOther" field
+## to set st_other to any arbitrary value.
+
+# RUN: yaml2obj --docnum=3 %s > %t3
+# RUN: llvm-readobj --symbols %t3 | FileCheck %s --check-prefix=USE-STOTHER
+# RUN: yaml2obj --docnum=4 %s > %t4
+# RUN: llvm-readobj --symbols %t4 | FileCheck %s --check-prefix=USE-STOTHER
+
+# USE-STOTHER:      Name: foo
+# USE-STOTHER:      Other [
+# USE-STOTHER-SAME: (0x4)
+
+# USE-STOTHER:      Name: bar
+# USE-STOTHER:      Other [
+# USE-STOTHER-SAME: (0xFF)
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_MIPS
+Symbols:
+  - Name:    foo
+    StOther: 4
+  - Name:    bar
+    StOther: 0xff
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS32
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_386
+Symbols:
+  - Name:    foo
+    StOther: 4
+  - Name:    bar
+    StOther: 0xff




More information about the llvm-commits mailing list