Index: test/tools/yaml2obj/dynsymtab-shlink.yaml =================================================================== --- /dev/null +++ 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 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 Index: test/tools/yaml2obj/symtab-shlink.yaml =================================================================== --- /dev/null +++ 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 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 Index: tools/yaml2obj/yaml2elf.cpp =================================================================== --- tools/yaml2obj/yaml2elf.cpp +++ tools/yaml2obj/yaml2elf.cpp @@ -404,16 +404,24 @@ 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 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;