Skip to content

Commit 17a944a

Browse files
author
git apple-llvm automerger
committed
Merge commit '88fafbfd748d' from apple/master into swift/master-next
2 parents fb24662 + 88fafbf commit 17a944a

File tree

6 files changed

+306
-1
lines changed

6 files changed

+306
-1
lines changed

llvm/include/llvm/ObjectYAML/ELFYAML.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ struct Chunk {
147147
Symver,
148148
MipsABIFlags,
149149
Addrsig,
150-
Fill
150+
Fill,
151+
LinkerOptions,
151152
};
152153

153154
ChunkKind Kind;
@@ -349,6 +350,22 @@ struct AddrsigSection : Section {
349350
static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Addrsig; }
350351
};
351352

353+
struct LinkerOption {
354+
StringRef Key;
355+
StringRef Value;
356+
};
357+
358+
struct LinkerOptionsSection : Section {
359+
Optional<std::vector<LinkerOption>> Options;
360+
Optional<yaml::BinaryRef> Content;
361+
362+
LinkerOptionsSection() : Section(ChunkKind::LinkerOptions) {}
363+
364+
static bool classof(const Chunk *S) {
365+
return S->Kind == ChunkKind::LinkerOptions;
366+
}
367+
};
368+
352369
struct SymverSection : Section {
353370
std::vector<uint16_t> Entries;
354371

@@ -464,6 +481,7 @@ struct Object {
464481
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::AddrsigSymbol)
465482
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
466483
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
484+
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
467485
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)
468486
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
469487
LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)
@@ -631,6 +649,10 @@ template <> struct MappingTraits<ELFYAML::AddrsigSymbol> {
631649
static void mapping(IO &IO, ELFYAML::AddrsigSymbol &Sym);
632650
};
633651

652+
template <> struct MappingTraits<ELFYAML::LinkerOption> {
653+
static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
654+
};
655+
634656
template <> struct MappingTraits<ELFYAML::Relocation> {
635657
static void mapping(IO &IO, ELFYAML::Relocation &Rel);
636658
};

llvm/lib/ObjectYAML/ELFEmitter.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ template <class ELFT> class ELFState {
200200
void writeSectionContent(Elf_Shdr &SHeader,
201201
const ELFYAML::GnuHashSection &Section,
202202
ContiguousBlobAccumulator &CBA);
203+
void writeSectionContent(Elf_Shdr &SHeader,
204+
const ELFYAML::LinkerOptionsSection &Section,
205+
ContiguousBlobAccumulator &CBA);
203206

204207
void writeFill(ELFYAML::Fill &Fill, ContiguousBlobAccumulator &CBA);
205208

@@ -466,6 +469,8 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
466469
writeSectionContent(SHeader, *S, CBA);
467470
} else if (auto S = dyn_cast<ELFYAML::AddrsigSection>(Sec)) {
468471
writeSectionContent(SHeader, *S, CBA);
472+
} else if (auto S = dyn_cast<ELFYAML::LinkerOptionsSection>(Sec)) {
473+
writeSectionContent(SHeader, *S, CBA);
469474
} else if (auto S = dyn_cast<ELFYAML::NoteSection>(Sec)) {
470475
writeSectionContent(SHeader, *S, CBA);
471476
} else if (auto S = dyn_cast<ELFYAML::GnuHashSection>(Sec)) {
@@ -892,6 +897,30 @@ void ELFState<ELFT>::writeSectionContent(
892897
}
893898
}
894899

900+
template <class ELFT>
901+
void ELFState<ELFT>::writeSectionContent(
902+
Elf_Shdr &SHeader, const ELFYAML::LinkerOptionsSection &Section,
903+
ContiguousBlobAccumulator &CBA) {
904+
raw_ostream &OS =
905+
CBA.getOSAndAlignedOffset(SHeader.sh_offset, SHeader.sh_addralign);
906+
907+
if (Section.Content) {
908+
SHeader.sh_size = writeContent(OS, Section.Content, None);
909+
return;
910+
}
911+
912+
if (!Section.Options)
913+
return;
914+
915+
for (const ELFYAML::LinkerOption &LO : *Section.Options) {
916+
OS.write(LO.Key.data(), LO.Key.size());
917+
OS.write('\0');
918+
OS.write(LO.Value.data(), LO.Value.size());
919+
OS.write('\0');
920+
SHeader.sh_size += (LO.Key.size() + LO.Value.size() + 2);
921+
}
922+
}
923+
895924
template <class ELFT>
896925
void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
897926
const ELFYAML::HashSection &Section,

llvm/lib/ObjectYAML/ELFYAML.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,12 @@ static void fillMapping(IO &IO, ELFYAML::Fill &Fill) {
11001100
IO.mapRequired("Size", Fill.Size);
11011101
}
11021102

1103+
static void sectionMapping(IO &IO, ELFYAML::LinkerOptionsSection &Section) {
1104+
commonSectionMapping(IO, Section);
1105+
IO.mapOptional("Options", Section.Options);
1106+
IO.mapOptional("Content", Section.Content);
1107+
}
1108+
11031109
void MappingTraits<ELFYAML::SectionOrType>::mapping(
11041110
IO &IO, ELFYAML::SectionOrType &sectionOrType) {
11051111
IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType);
@@ -1217,6 +1223,11 @@ void MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::mapping(
12171223
Section.reset(new ELFYAML::AddrsigSection());
12181224
sectionMapping(IO, *cast<ELFYAML::AddrsigSection>(Section.get()));
12191225
break;
1226+
case ELF::SHT_LLVM_LINKER_OPTIONS:
1227+
if (!IO.outputting())
1228+
Section.reset(new ELFYAML::LinkerOptionsSection());
1229+
sectionMapping(IO, *cast<ELFYAML::LinkerOptionsSection>(Section.get()));
1230+
break;
12201231
default:
12211232
if (!IO.outputting()) {
12221233
StringRef Name;
@@ -1355,6 +1366,12 @@ StringRef MappingTraits<std::unique_ptr<ELFYAML::Chunk>>::validate(
13551366
return {};
13561367
}
13571368

1369+
if (const auto *Sec = dyn_cast<ELFYAML::LinkerOptionsSection>(C.get())) {
1370+
if (Sec->Options && Sec->Content)
1371+
return "\"Options\" and \"Content\" can't be used together";
1372+
return {};
1373+
}
1374+
13581375
if (const auto *F = dyn_cast<ELFYAML::Fill>(C.get())) {
13591376
if (!F->Pattern)
13601377
return {};
@@ -1493,6 +1510,13 @@ void MappingTraits<ELFYAML::AddrsigSymbol>::mapping(IO &IO, ELFYAML::AddrsigSymb
14931510
IO.mapOptional("Index", Sym.Index);
14941511
}
14951512

1513+
void MappingTraits<ELFYAML::LinkerOption>::mapping(IO &IO,
1514+
ELFYAML::LinkerOption &Opt) {
1515+
assert(IO.getContext() && "The IO context is not initialized");
1516+
IO.mapRequired("Name", Opt.Key);
1517+
IO.mapRequired("Value", Opt.Value);
1518+
}
1519+
14961520
LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
14971521
LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
14981522
LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
## Check how obj2yaml produces SHT_LLVM_LINKER_OPTIONS section descriptions.
2+
3+
## Check we dump valid sections using pairs of "Name" and "Value" strings.
4+
5+
# RUN: yaml2obj --docnum=1 %s -o %t1
6+
# RUN: obj2yaml %t1 | FileCheck %s --check-prefix=VALID
7+
8+
# VALID: - Name: .linker-options-valid1
9+
# VALID-NEXT: Type: SHT_LLVM_LINKER_OPTIONS
10+
# VALID-NEXT: Options:
11+
# VALID-NEXT: - Name: a
12+
# VALID-NEXT: Value: b
13+
# VALID-NEXT: - Name: .linker-options-valid2
14+
# VALID-NEXT: Type: SHT_LLVM_LINKER_OPTIONS
15+
# VALID-NEXT: Options:
16+
# VALID-NEXT: - Name: a
17+
# VALID-NEXT: Value: b
18+
# VALID-NEXT: - Name: c
19+
# VALID-NEXT: Value: d
20+
21+
--- !ELF
22+
FileHeader:
23+
Class: ELFCLASS64
24+
Data: ELFDATA2LSB
25+
Type: ET_REL
26+
Machine: EM_X86_64
27+
Sections:
28+
- Name: .linker-options-valid1
29+
Type: SHT_LLVM_LINKER_OPTIONS
30+
Content: "61006200"
31+
- Name: .linker-options-valid2
32+
Type: SHT_LLVM_LINKER_OPTIONS
33+
Content: "6100620063006400"
34+
35+
## Check we dump corrupt sections using the "Content" key.
36+
37+
# RUN: yaml2obj --docnum=2 %s -o %t2
38+
# RUN: obj2yaml %t2 | FileCheck %s --check-prefix=CORRUPT
39+
40+
# CORRUPT: - Name: .linker-options-empty
41+
# CORRUPT-NEXT: Type: SHT_LLVM_LINKER_OPTIONS
42+
# CORRUPT-NEXT: Content: ''
43+
# CORRUPT-NEXT: - Name: .linker-options-no-null
44+
# CORRUPT-NEXT: Type: SHT_LLVM_LINKER_OPTIONS
45+
# CORRUPT-NEXT: Content: '610062'
46+
# CORRUPT-NEXT: - Name: .linker-options-incomplete
47+
# CORRUPT-NEXT: Type: SHT_LLVM_LINKER_OPTIONS
48+
# CORRUPT-NEXT: Content: '6100'
49+
50+
--- !ELF
51+
FileHeader:
52+
Class: ELFCLASS64
53+
Data: ELFDATA2LSB
54+
Type: ET_REL
55+
Machine: EM_X86_64
56+
Sections:
57+
## 1) Empty content.
58+
- Name: .linker-options-empty
59+
Type: SHT_LLVM_LINKER_OPTIONS
60+
Content: ""
61+
## 2) Non-null terminated content.
62+
- Name: .linker-options-no-null
63+
Type: SHT_LLVM_LINKER_OPTIONS
64+
Content: "610062"
65+
## 3) Odd number of strings in the section.
66+
## (Hence it contains an incomplete key-value pair).
67+
- Name: .linker-options-incomplete
68+
Type: SHT_LLVM_LINKER_OPTIONS
69+
Content: "6100"
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
## Check we are able to produce a valid SHT_LLVM_LINKER_OPTIONS
2+
## section from its description.
3+
4+
## Check we can use either "Options" or "Content" to describe the data.
5+
6+
# RUN: yaml2obj --docnum=1 %s -o %t1
7+
# RUN: llvm-readobj --string-dump .linker-options1 --sections --section-data %t1 \
8+
# RUN: | FileCheck %s --check-prefix=OPTIONS
9+
10+
# OPTIONS: Name: .linker-options1
11+
# OPTIONS-NEXT: Type: SHT_LLVM_LINKER_OPTIONS
12+
# OPTIONS-NEXT: Flags [
13+
# OPTIONS-NEXT: ]
14+
# OPTIONS-NEXT: Address: 0x0
15+
# OPTIONS-NEXT: Offset: 0x40
16+
# OPTIONS-NEXT: Size: 34
17+
# OPTIONS-NEXT: Link: 0
18+
# OPTIONS-NEXT: Info: 0
19+
# OPTIONS-NEXT: AddressAlignment: 0
20+
# OPTIONS-NEXT: EntrySize: 0
21+
22+
# OPTIONS: Name: .linker-options2
23+
# OPTIONS-NEXT: Type: SHT_LLVM_LINKER_OPTIONS
24+
# OPTIONS: SectionData (
25+
# OPTIONS-NEXT: 0000: 00112233 |
26+
# OPTIONS-NEXT: )
27+
28+
# OPTIONS: String dump of section '.linker-options1':
29+
# OPTIONS-NEXT: [ 0] option 0
30+
# OPTIONS-NEXT: [ 9] value 0
31+
# OPTIONS-NEXT: [ 11] option 1
32+
# OPTIONS-NEXT: [ 1a] value 1
33+
34+
--- !ELF
35+
FileHeader:
36+
Class: ELFCLASS64
37+
Data: ELFDATA2LSB
38+
Type: ET_REL
39+
Machine: EM_X86_64
40+
Sections:
41+
- Name: .linker-options1
42+
Type: SHT_LLVM_LINKER_OPTIONS
43+
Options:
44+
- Name: option 0
45+
Value: value 0
46+
- Name: option 1
47+
Value: value 1
48+
- Name: .linker-options2
49+
Type: SHT_LLVM_LINKER_OPTIONS
50+
Content: "00112233"
51+
52+
## Check that "Value" and "Name" fields are mandatory when using "Options" key.
53+
54+
# RUN: not yaml2obj --docnum=2 %s 2>&1 | FileCheck %s --check-prefix=NOVALUE
55+
# RUN: not yaml2obj --docnum=3 %s 2>&1 | FileCheck %s --check-prefix=NONAME
56+
57+
# NOVALUE: error: missing required key 'Value'
58+
# NONAME: error: missing required key 'Name'
59+
60+
--- !ELF
61+
FileHeader:
62+
Class: ELFCLASS64
63+
Data: ELFDATA2LSB
64+
Type: ET_REL
65+
Machine: EM_X86_64
66+
Sections:
67+
- Name: .linker-options
68+
Type: SHT_LLVM_LINKER_OPTIONS
69+
Options:
70+
- Name: name
71+
72+
--- !ELF
73+
FileHeader:
74+
Class: ELFCLASS64
75+
Data: ELFDATA2LSB
76+
Type: ET_REL
77+
Machine: EM_X86_64
78+
Sections:
79+
- Name: .linker-options
80+
Type: SHT_LLVM_LINKER_OPTIONS
81+
Options:
82+
- Value: value
83+
84+
## Check we can't use both "Options" and "Content" together.
85+
86+
# RUN: not yaml2obj %s --docnum=4 2>&1 | FileCheck %s --check-prefix=BOTH
87+
88+
# BOTH: error: "Options" and "Content" can't be used together
89+
90+
--- !ELF
91+
FileHeader:
92+
Class: ELFCLASS64
93+
Data: ELFDATA2LSB
94+
Type: ET_REL
95+
Machine: EM_X86_64
96+
Sections:
97+
- Name: .linker-options
98+
Type: SHT_LLVM_LINKER_OPTIONS
99+
Options:
100+
- Name: name
101+
Value: value
102+
Content: "00112233"
103+
104+
## Check we can omit both "Options" and "Content". This produces an empty section.
105+
106+
# RUN: yaml2obj %s --docnum=5 2>&1 -o %t5
107+
# RUN: llvm-readelf --sections %t5 | FileCheck %s --check-prefix=NONE
108+
109+
# NONE: [Nr] Name Type Address Off Size
110+
# NONE: [ 1] .linker-options LLVM_LINKER_OPTIONS 0000000000000000 000040 000000
111+
112+
--- !ELF
113+
FileHeader:
114+
Class: ELFCLASS64
115+
Data: ELFDATA2LSB
116+
Type: ET_REL
117+
Machine: EM_X86_64
118+
Sections:
119+
- Name: .linker-options
120+
Type: SHT_LLVM_LINKER_OPTIONS

0 commit comments

Comments
 (0)