Skip to content

Commit d396305

Browse files
author
George Rimar
committed
[yaml2obj/obj2yaml] - Add a basic support for extended section indexes.
In some cases a symbol might have section index == SHN_XINDEX. This is an escape value indicating that the actual section header index is too large to fit in the containing field. Then the SHT_SYMTAB_SHNDX section is used. It contains the 32bit values that stores section indexes. ELF gABI says that there can be multiple SHT_SYMTAB_SHNDX sections, i.e. for example one for .symtab and one for .dynsym (1) https://groups.google.com/forum/#!topic/generic-abi/-XJAV5d8PRg (2) DT_SYMTAB_SHNDX: http://www.sco.com/developers/gabi/latest/ch5.dynamic.html In this patch I am only supporting a single SHT_SYMTAB_SHNDX associated with a .symtab. This is a more or less common case which is used a few tests I saw in LLVM. I decided not to create the SHT_SYMTAB_SHNDX section as "implicit", but implement is like a kind of regular section for now. i.e. tools do not recreate this section or its content, like they do for symbol table sections, for example. That should allow to write all kind of possible broken test cases for our needs and keep the output closer to requested. Differential revision: https://reviews.llvm.org/D65446 llvm-svn: 368272
1 parent 6db975b commit d396305

File tree

11 files changed

+428
-29
lines changed

11 files changed

+428
-29
lines changed

llvm/include/llvm/Object/ELF.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,8 +635,11 @@ ELFFile<ELFT>::getSHNDXTable(const Elf_Shdr &Section,
635635
const Elf_Shdr &SymTable = **SymTableOrErr;
636636
if (SymTable.sh_type != ELF::SHT_SYMTAB &&
637637
SymTable.sh_type != ELF::SHT_DYNSYM)
638-
// TODO: this error is untested.
639-
return createError("invalid sh_type");
638+
return createError("SHT_SYMTAB_SHNDX section is linked with " +
639+
object::getELFSectionTypeName(getHeader()->e_machine,
640+
SymTable.sh_type) +
641+
" section (expected SHT_SYMTAB/SHT_DYNSYM)");
642+
640643
if (V.size() != (SymTable.sh_size / sizeof(Elf_Sym)))
641644
return createError("SHT_SYMTAB_SHNDX section has sh_size (" +
642645
Twine(SymTable.sh_size) +

llvm/include/llvm/ObjectYAML/ELFYAML.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ struct Section {
128128
NoBits,
129129
Verdef,
130130
Verneed,
131+
SymtabShndxSection,
131132
Symver,
132133
MipsABIFlags
133134
};
@@ -274,6 +275,16 @@ struct RelocationSection : Section {
274275
}
275276
};
276277

278+
struct SymtabShndxSection : Section {
279+
std::vector<uint32_t> Entries;
280+
281+
SymtabShndxSection() : Section(SectionKind::SymtabShndxSection) {}
282+
283+
static bool classof(const Section *S) {
284+
return S->Kind == SectionKind::SymtabShndxSection;
285+
}
286+
};
287+
277288
// Represents .MIPS.abiflags section
278289
struct MipsABIFlags : Section {
279290
llvm::yaml::Hex16 Version;

llvm/lib/ObjectYAML/ELFEmitter.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ template <class ELFT> class ELFState {
140140
ContiguousBlobAccumulator &CBA);
141141
bool writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::Group &Group,
142142
ContiguousBlobAccumulator &CBA);
143+
bool writeSectionContent(Elf_Shdr &SHeader,
144+
const ELFYAML::SymtabShndxSection &Shndx,
145+
ContiguousBlobAccumulator &CBA);
143146
bool writeSectionContent(Elf_Shdr &SHeader,
144147
const ELFYAML::SymverSection &Section,
145148
ContiguousBlobAccumulator &CBA);
@@ -358,6 +361,9 @@ bool ELFState<ELFT>::initSectionHeaders(ELFState<ELFT> &State,
358361
} else if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec)) {
359362
if (!writeSectionContent(SHeader, *S, CBA))
360363
return false;
364+
} else if (auto S = dyn_cast<ELFYAML::SymtabShndxSection>(Sec)) {
365+
if (!writeSectionContent(SHeader, *S, CBA))
366+
return false;
361367
} else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Sec)) {
362368
if (!writeSectionContent(SHeader, *S, CBA))
363369
return false;
@@ -740,6 +746,21 @@ bool ELFState<ELFT>::writeSectionContent(
740746
return true;
741747
}
742748

749+
template <class ELFT>
750+
bool ELFState<ELFT>::writeSectionContent(
751+
Elf_Shdr &SHeader, const ELFYAML::SymtabShndxSection &Shndx,
752+
ContiguousBlobAccumulator &CBA) {
753+
raw_ostream &OS =
754+
CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
755+
756+
for (uint32_t E : Shndx.Entries)
757+
support::endian::write<uint32_t>(OS, E, ELFT::TargetEndianness);
758+
759+
SHeader.sh_entsize = Shndx.EntSize ? (uint64_t)*Shndx.EntSize : 4;
760+
SHeader.sh_size = Shndx.Entries.size() * SHeader.sh_entsize;
761+
return true;
762+
}
763+
743764
template <class ELFT>
744765
bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
745766
const ELFYAML::Group &Section,

llvm/lib/ObjectYAML/ELFYAML.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHN>::enumeration(
563563
ECase(SHN_HEXAGON_SCOMMON_4);
564564
ECase(SHN_HEXAGON_SCOMMON_8);
565565
#undef ECase
566-
IO.enumFallback<Hex32>(Value);
566+
IO.enumFallback<Hex16>(Value);
567567
}
568568

569569
void ScalarEnumerationTraits<ELFYAML::ELF_STB>::enumeration(
@@ -897,8 +897,6 @@ StringRef MappingTraits<ELFYAML::Symbol>::validate(IO &IO,
897897
ELFYAML::Symbol &Symbol) {
898898
if (Symbol.Index && Symbol.Section.data())
899899
return "Index and Section cannot both be specified for Symbol";
900-
if (Symbol.Index && *Symbol.Index == ELFYAML::ELF_SHN(ELF::SHN_XINDEX))
901-
return "Large indexes are not supported";
902900
if (Symbol.NameIndex && !Symbol.Name.empty())
903901
return "Name and NameIndex cannot both be specified for Symbol";
904902
return StringRef();
@@ -969,6 +967,11 @@ static void groupSectionMapping(IO &IO, ELFYAML::Group &Group) {
969967
IO.mapRequired("Members", Group.Members);
970968
}
971969

970+
static void sectionMapping(IO &IO, ELFYAML::SymtabShndxSection &Section) {
971+
commonSectionMapping(IO, Section);
972+
IO.mapRequired("Entries", Section.Entries);
973+
}
974+
972975
void MappingTraits<ELFYAML::SectionOrType>::mapping(
973976
IO &IO, ELFYAML::SectionOrType &sectionOrType) {
974977
IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType);
@@ -1049,6 +1052,11 @@ void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping(
10491052
Section.reset(new ELFYAML::VerneedSection());
10501053
sectionMapping(IO, *cast<ELFYAML::VerneedSection>(Section.get()));
10511054
break;
1055+
case ELF::SHT_SYMTAB_SHNDX:
1056+
if (!IO.outputting())
1057+
Section.reset(new ELFYAML::SymtabShndxSection());
1058+
sectionMapping(IO, *cast<ELFYAML::SymtabShndxSection>(Section.get()));
1059+
break;
10521060
default:
10531061
if (!IO.outputting())
10541062
Section.reset(new ELFYAML::RawContentSection());

llvm/test/Object/invalid.test

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ Sections:
207207
# RUN: yaml2obj %s --docnum=11 -o %t11
208208
# RUN: not llvm-readobj --symbols %t11 2>&1 | FileCheck --check-prefix=INVALID-XINDEX-SIZE %s
209209

210-
# INVALID-XINDEX-SIZE: error: {{.*}}: SHT_SYMTAB_SHNDX section has sh_size (24) which is not equal to the number of symbols (6)
210+
# INVALID-XINDEX-SIZE: error: {{.*}}: SHT_SYMTAB_SHNDX section has sh_size (24) which is not equal to the number of symbols (2)
211211

212212
--- !ELF
213213
FileHeader:
@@ -218,8 +218,7 @@ FileHeader:
218218
Sections:
219219
- Name: .symtab_shndx
220220
Type: SHT_SYMTAB_SHNDX
221-
Size: 0x18
222-
EntSize: 4
221+
Entries: [ 0, 1 ]
223222
Link: .symtab
224223

225224
## Check that llvm-readobj reports an error if the e_phentsize field is broken.

llvm/test/tools/llvm-readobj/elf-section-types.test

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,7 @@ Sections:
166166
- Name: symtab_shndx
167167
Type: SHT_SYMTAB_SHNDX
168168
Link: .symtab
169-
EntSize: 0x4
170-
Content: "0000000000000000"
169+
Entries: [ 0, 1 ]
171170
- Name: relr
172171
Type: SHT_RELR
173172
- Name: android_rel
-403 Bytes
Binary file not shown.
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
## Check that obj2yaml is able to dump a normal object which
2+
## contains the SHT_SYMTAB_SHNDX section and symbols with
3+
## section index == SHN_XINDEX.
4+
5+
# RUN: yaml2obj --docnum=1 %s -o %t1
6+
# RUN: obj2yaml %t1 | FileCheck %s --check-prefix=CASE1
7+
8+
# CASE1: --- !ELF
9+
# CASE1-NEXT: FileHeader:
10+
# CASE1-NEXT: Class: ELFCLASS64
11+
# CASE1-NEXT: Data: ELFDATA2LSB
12+
# CASE1-NEXT: Type: ET_REL
13+
# CASE1-NEXT: Machine: EM_X86_64
14+
# CASE1-NEXT: Sections:
15+
# CASE1-NEXT: - Name: bar
16+
# CASE1-NEXT: Type: SHT_PROGBITS
17+
# CASE1-NEXT: - Name: .symtab_shndx
18+
# CASE1-NEXT: Type: SHT_SYMTAB_SHNDX
19+
# CASE1-NEXT: Link: .symtab
20+
# CASE1-NEXT: EntSize: 0x0000000000000004
21+
# CASE1-NEXT: Entries: [ 0, 1, 2 ]
22+
# CASE1-NEXT: Symbols:
23+
# CASE1-NEXT: - Name: bar
24+
# CASE1-NEXT: Type: STT_SECTION
25+
# CASE1-NEXT: Index: SHN_XINDEX
26+
# CASE1-NEXT: - Name: .symtab_shndx
27+
# CASE1-NEXT: Type: STT_SECTION
28+
# CASE1-NEXT: Index: SHN_XINDEX
29+
# CASE1-NEXT: ...
30+
31+
--- !ELF
32+
FileHeader:
33+
Class: ELFCLASS64
34+
Data: ELFDATA2LSB
35+
Type: ET_REL
36+
Machine: EM_X86_64
37+
Sections:
38+
- Name: bar
39+
Type: SHT_PROGBITS
40+
- Name: .symtab_shndx
41+
Type: SHT_SYMTAB_SHNDX
42+
Entries: [ 0, 1, 2 ]
43+
Link: .symtab
44+
Symbols:
45+
- Type: STT_SECTION
46+
Index: SHN_XINDEX
47+
- Type: STT_SECTION
48+
Index: SHN_XINDEX
49+
50+
## Check that yaml2obj is unable to dump an object, which has
51+
## symbols with section index == SHN_XINDEX, but no SHT_SYMTAB_SHNDX section.
52+
53+
# RUN: yaml2obj --docnum=2 %s -o %t2
54+
# RUN: not obj2yaml %t2 2>&1 | FileCheck %s -DFILE=%t2 --check-prefix=CASE2
55+
56+
# CASE2: Error reading file: [[FILE]]: extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0
57+
58+
--- !ELF
59+
FileHeader:
60+
Class: ELFCLASS64
61+
Data: ELFDATA2LSB
62+
Type: ET_REL
63+
Machine: EM_X86_64
64+
Symbols:
65+
- Type: STT_SECTION
66+
Index: SHN_XINDEX
67+
68+
## Check that yaml2obj is unable to dump an object, which has symbols with
69+
## section index == SHN_XINDEX, but SHT_SYMTAB_SHNDX table contains invalid indices
70+
## that are larger than total number of the sections.
71+
72+
# RUN: yaml2obj --docnum=3 %s -o %t3
73+
# RUN: not obj2yaml %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=CASE3
74+
75+
# CASE3: Error reading file: [[FILE]]: invalid section index: 254
76+
77+
--- !ELF
78+
FileHeader:
79+
Class: ELFCLASS64
80+
Data: ELFDATA2LSB
81+
Type: ET_REL
82+
Machine: EM_X86_64
83+
Sections:
84+
- Name: bar
85+
Type: SHT_PROGBITS
86+
- Name: .symtab_shndx
87+
Type: SHT_SYMTAB_SHNDX
88+
Entries: [ 0, 254 ]
89+
Link: .symtab
90+
Symbols:
91+
- Type: STT_SECTION
92+
Index: SHN_XINDEX
93+
94+
## Check that yaml2obj is unable to dump an object, which has symbols with
95+
## section index == SHN_XINDEX, but SHT_SYMTAB_SHNDX table contains more
96+
## entries than the number of symbols in .symtab.
97+
98+
# RUN: yaml2obj --docnum=4 %s -o %t4
99+
# RUN: not obj2yaml %t4 2>&1 | FileCheck %s -DFILE=%t4 --check-prefix=CASE4
100+
101+
## FIXME: The error message below needs rewording. Size should not be equal to the number of symbols.
102+
## CASE4: Error reading file: [[FILE]]: SHT_SYMTAB_SHNDX section has sh_size (48) which is not equal to the number of symbols (3)
103+
104+
--- !ELF
105+
FileHeader:
106+
Class: ELFCLASS64
107+
Data: ELFDATA2LSB
108+
Type: ET_REL
109+
Machine: EM_X86_64
110+
Sections:
111+
- Name: bar
112+
Type: SHT_PROGBITS
113+
- Name: .symtab_shndx
114+
Type: SHT_SYMTAB_SHNDX
115+
Entries: [ 0, 1, 2 ]
116+
Link: .symtab
117+
Symbols:
118+
- Type: STT_SECTION
119+
Index: SHN_XINDEX
120+
121+
## ELF gABI allows having multiple SHT_SYMTAB_SHNDX sections.
122+
## We only support having one associated with .symtab now.
123+
124+
# RUN: yaml2obj --docnum=5 %s -o %t5
125+
# RUN: not obj2yaml %t5 2>&1 | FileCheck %s -DFILE=%t5 --check-prefix=CASE5
126+
127+
# CASE5: Error reading file: [[FILE]]: multiple SHT_SYMTAB_SHNDX sections are not supported
128+
129+
--- !ELF
130+
FileHeader:
131+
Class: ELFCLASS64
132+
Data: ELFDATA2LSB
133+
Type: ET_REL
134+
Machine: EM_X86_64
135+
Sections:
136+
- Name: .symtab_shndx1
137+
Type: SHT_SYMTAB_SHNDX
138+
Entries: [ 0 ]
139+
EntSize: 4
140+
Link: .symtab
141+
- Name: .symtab_shndx2
142+
Type: SHT_SYMTAB_SHNDX
143+
Entries: [ 0 ]
144+
Link: .symtab
145+
146+
## Check that yaml2obj can't dump the object if SHT_SYMTAB_SHNDX is
147+
## not associated with a SHT_SYMTAB section (this case is illegal).
148+
149+
# RUN: yaml2obj --docnum=6 %s -o %t6
150+
# RUN: not obj2yaml %t6 2>&1 | FileCheck %s -DFILE=%t6 --check-prefix=CASE6
151+
152+
# CASE6: Error reading file: [[FILE]]: SHT_SYMTAB_SHNDX section is linked with SHT_PROGBITS section (expected SHT_SYMTAB/SHT_DYNSYM)
153+
154+
--- !ELF
155+
FileHeader:
156+
Class: ELFCLASS64
157+
Data: ELFDATA2LSB
158+
Type: ET_REL
159+
Machine: EM_X86_64
160+
Sections:
161+
- Name: .symtab_shndx
162+
Type: SHT_SYMTAB_SHNDX
163+
Entries: [ 0 ]
164+
Link: .foo
165+
- Name: .foo
166+
Type: SHT_PROGBITS
167+
168+
## Check that yaml2obj can't dump the object if SHT_SYMTAB_SHNDX is
169+
## associated with a SHT_DYNSYM section (not implemented yet).
170+
171+
# RUN: yaml2obj --docnum=7 %s -o %t7
172+
# RUN: not obj2yaml %t7 2>&1 | FileCheck %s -DFILE=%t7 --check-prefix=CASE7
173+
174+
# CASE7: Error reading file: [[FILE]]: only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported
175+
176+
--- !ELF
177+
FileHeader:
178+
Class: ELFCLASS64
179+
Data: ELFDATA2LSB
180+
Type: ET_REL
181+
Machine: EM_X86_64
182+
Sections:
183+
- Name: .symtab_shndx
184+
Type: SHT_SYMTAB_SHNDX
185+
Entries: [ 0, 1 ]
186+
Link: .dynsym
187+
DynamicSymbols:
188+
- Type: STT_SECTION
189+
Index: SHN_XINDEX

llvm/test/tools/obj2yaml/special-symbol-indices.yaml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# CHECK-NEXT: Index: SHN_HEXAGON_SCOMMON_1
1919
# CHECK-NEXT: Binding: STB_GLOBAL
2020
# CHECK-NEXT: - Name: unknown_index
21-
# CHECK-NEXT: Index: 0x0000FFFE
21+
# CHECK-NEXT: Index: 0xFFFE
2222
# CHECK-NEXT: Binding: STB_GLOBAL
2323

2424
!ELF
@@ -47,8 +47,3 @@ Symbols:
4747
- Name: unknown_index
4848
Index: 0xfffe
4949
Binding: STB_GLOBAL
50-
51-
## shn_xindex.o contains a symbol with st_shndx == SHN_XINDEX.
52-
## We do not support it at this moment.
53-
# RUN: not obj2yaml %S/Inputs/shn_xindex.o 2>&1 | FileCheck %s --check-prefix=ERR
54-
# ERR: Error reading file: {{.*}}shn_xindex.o: SHN_XINDEX symbols are not supported

0 commit comments

Comments
 (0)