From dce5977901e1771a9da6d667a95a48c440dd23a2 Mon Sep 17 00:00:00 2001 From: George Rimar Date: Tue, 11 Jun 2019 10:00:51 +0000 Subject: [PATCH] [yaml2elf] - Check we are able to set custom sh_link for .symtab/.dynsym Allow using both custom numeric and string values for Link field of the dynamic and regular symbol tables. Differential revision: https://reviews.llvm.org/D63077 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363042 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/tools/yaml2obj/dynsymtab-shlink.yaml | 97 +++++++++++++++++++++++ test/tools/yaml2obj/symtab-shlink.yaml | 94 ++++++++++++++++++++++ tools/yaml2obj/yaml2elf.cpp | 29 ++++--- 3 files changed, 210 insertions(+), 10 deletions(-) create mode 100644 test/tools/yaml2obj/dynsymtab-shlink.yaml create mode 100644 test/tools/yaml2obj/symtab-shlink.yaml diff --git a/test/tools/yaml2obj/dynsymtab-shlink.yaml b/test/tools/yaml2obj/dynsymtab-shlink.yaml new file mode 100644 index 00000000000..76c079f6d50 --- /dev/null +++ b/test/tools/yaml2obj/dynsymtab-shlink.yaml @@ -0,0 +1,97 @@ +## For implicit dynamic symbol table sections, `Link` field can also +## be specified in YAML. Here we test the behavior in different cases. + +## Check we are able to set Link = 0 for .dynsym explicitly. + +# RUN: yaml2obj --docnum=1 %s -o %t1 +# RUN: llvm-readobj %t1 -S | FileCheck %s --check-prefix=CASE1 + +# CASE1: Name: .dynsym +# CASE1: Link: +# CASE1-SAME: 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .dynsym + Type: SHT_DYNSYM + Link: 0 + +## Check that by default .dynsym will be linked to .dynstr +## if the latter exists. + +# RUN: yaml2obj --docnum=2 %s -o %t2 +# RUN: llvm-readobj %t2 -S | FileCheck %s --check-prefix=CASE2 + +# CASE2: .dynsym +# CASE2: Link: +# CASE2-SAME: 2 +# CASE2: Index: 2 +# CASE2-NEXT: Name: .dynstr + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .dynsym + Type: SHT_DYNSYM + - Name: .dynstr + Type: SHT_STRTAB + +## Even if .dynstr exists, we can explicitly link .dynsym +## to another section. + +# RUN: yaml2obj --docnum=3 %s -o %t3 +# RUN: llvm-readobj %t3 -S | FileCheck %s --check-prefix=CASE3 + +# CASE3: .dynsym +# CASE3: Link: +# CASE3-SAME: 3 +# CASE3: Index: 3 +# CASE3-NEXT: Name: .foo + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .dynsym + Type: SHT_DYNSYM + Link: 3 + - Name: .dynstr + Type: SHT_STRTAB + - Name: .foo + Type: SHT_PROGBITS + +## Check we can use a section name as a Link value for .dynsym. + +# RUN: yaml2obj --docnum=4 %s -o %t4 +# RUN: llvm-readobj %t4 -S | FileCheck %s --check-prefix=CASE4 + +# CASE4: .dynsym +# CASE4: Link: +# CASE4-SAME: 2 +# CASE4: Index: 2 +# CASE4-NEXT: Name: .foo + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .dynsym + Type: SHT_DYNSYM + Link: .foo + - Name: .foo + Type: SHT_PROGBITS diff --git a/test/tools/yaml2obj/symtab-shlink.yaml b/test/tools/yaml2obj/symtab-shlink.yaml new file mode 100644 index 00000000000..116c2dad77d --- /dev/null +++ b/test/tools/yaml2obj/symtab-shlink.yaml @@ -0,0 +1,94 @@ +## For implicit symbol table sections, `Link` field can also +## be specified in YAML. Here we test the behavior in different cases. + +## Check we are able to set Link = 0 for .symtab explicitly. + +# RUN: yaml2obj --docnum=1 %s -o %t1 +# RUN: llvm-readobj %t1 -S | FileCheck %s --check-prefix=CASE1 + +# CASE1: Name: .symtab +# CASE1: Link: +# CASE1-SAME: 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_SYMTAB + Link: 0 + +## Check that by default .symtab will be linked with .strtab. + +# RUN: yaml2obj --docnum=2 %s -o %t2 +# RUN: llvm-readobj %t2 -S | FileCheck %s --check-prefix=CASE2 + +# CASE2: .symtab +# CASE2: Link: +# CASE2-SAME: 2 +# CASE2: Index: 2 +# CASE2-NEXT: Name: .strtab + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_SYMTAB + +## Even if .strtab is defined in YAML, we can explicitly link .symtab +## to another section. + +# RUN: yaml2obj --docnum=3 %s -o %t3 +# RUN: llvm-readobj %t3 -S | FileCheck %s --check-prefix=CASE3 + +# CASE3: .symtab +# CASE3: Link: +# CASE3-SAME: 3 +# CASE3: Index: 3 +# CASE3-NEXT: Name: .foo + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_SYMTAB + Link: 3 + - Name: .strtab + Type: SHT_STRTAB + - Name: .foo + Type: SHT_PROGBITS + +## Check we can use a section name as a Link value for .symtab. + +# RUN: yaml2obj --docnum=4 %s -o %t4 +# RUN: llvm-readobj %t4 -S | FileCheck %s --check-prefix=CASE4 + +# CASE4: .symtab +# CASE4: Link: +# CASE4-SAME: 2 +# CASE4: Index: 2 +# CASE4-NEXT: Name: .foo + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_SYMTAB + Link: .foo + - Name: .foo + Type: SHT_PROGBITS diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp index a02ac8db2d0..61485820832 100644 --- a/tools/yaml2obj/yaml2elf.cpp +++ b/tools/yaml2obj/yaml2elf.cpp @@ -404,16 +404,25 @@ void ELFState::initSymtabSectionHeader(Elf_Shdr &SHeader, SHeader.sh_name = DotShStrtab.getOffset(IsStatic ? ".symtab" : ".dynsym"); SHeader.sh_type = IsStatic ? ELF::SHT_SYMTAB : ELF::SHT_DYNSYM; - // When we describe the .dynsym section in the document explicitly, it is - // allowed to omit the "DynamicSymbols" tag. In this case .dynstr is not added - // implicitly and we should be able to leave the Link zeroed if .dynstr is not - // defined. - unsigned Link = 0; - if (IsStatic) - Link = SN2I.get(".strtab"); - else - SN2I.lookup(".dynstr", Link); - SHeader.sh_link = Link; + if (RawSec && !RawSec->Link.empty()) { + // If the Link field is explicitly defined in the document, + // we should use it. + unsigned Index; + if (!convertSectionIndex(SN2I, RawSec->Name, RawSec->Link, Index)) + return; + SHeader.sh_link = Index; + } else { + // When we describe the .dynsym section in the document explicitly, it is + // allowed to omit the "DynamicSymbols" tag. In this case .dynstr is not + // added implicitly and we should be able to leave the Link zeroed if + // .dynstr is not defined. + unsigned Link = 0; + if (IsStatic) + Link = SN2I.get(".strtab"); + else + SN2I.lookup(".dynstr", Link); + SHeader.sh_link = Link; + } if (!IsStatic) SHeader.sh_flags |= ELF::SHF_ALLOC; -- 2.40.0