[yaml2obj][XCOFF] add the SectionIndex field for symbol.

Summary: Add the SectionIndex field for symbol.
1: a symbol can reference a section by SectionName or SectionIndex.
2: a symbol can reference a section by both SectionName and SectionIndex.
3: if both Section and SectionIndex are specified, but the two values refer
   to different sections, an error will be reported.
4: an invalid SectionIndex is allowed.
5: if a symbol references a non-existent section by SectionName, an error will be reported.

Reviewed By: jhenderson, Higuoxing

Differential Revision: https://reviews.llvm.org/D109566
This commit is contained in:
Esme-Yi 2021-09-14 06:18:03 +00:00
parent 8b4afc5aef
commit b98c3e957f
5 changed files with 104 additions and 4 deletions

View File

@ -53,7 +53,8 @@ struct Section {
struct Symbol {
StringRef SymbolName;
llvm::yaml::Hex64 Value; // Symbol value; storage class-dependent.
StringRef SectionName;
Optional<StringRef> SectionName;
Optional<uint16_t> SectionIndex;
llvm::yaml::Hex16 Type;
XCOFF::StorageClass StorageClass;
uint8_t NumberOfAuxEntries;

View File

@ -592,7 +592,9 @@ uint16_t XCOFFObjectFile::getMagic() const {
Expected<DataRefImpl> XCOFFObjectFile::getSectionByNum(int16_t Num) const {
if (Num <= 0 || Num > getNumberOfSections())
return errorCodeToError(object_error::invalid_section_index);
return createStringError(object_error::invalid_section_index,
"the section index (" + Twine(Num) +
") is invalid");
DataRefImpl DRI;
DRI.p = getWithOffset(getSectionHeaderTableAddress(),

View File

@ -387,8 +387,23 @@ bool XCOFFWriter::writeSymbols() {
}
W.write<uint32_t>(YamlSym.Value);
}
W.write<int16_t>(
YamlSym.SectionName.size() ? SectionIndexMap[YamlSym.SectionName] : 0);
if (YamlSym.SectionName) {
if (!SectionIndexMap.count(*YamlSym.SectionName)) {
ErrHandler("the SectionName " + *YamlSym.SectionName +
" specified in the symbol does not exist");
return false;
}
if (YamlSym.SectionIndex &&
SectionIndexMap[*YamlSym.SectionName] != *YamlSym.SectionIndex) {
ErrHandler("the SectionName " + *YamlSym.SectionName +
" and the SectionIndex (" + Twine(*YamlSym.SectionIndex) +
") refer to different sections");
return false;
}
W.write<int16_t>(SectionIndexMap[*YamlSym.SectionName]);
} else {
W.write<int16_t>(YamlSym.SectionIndex ? *YamlSym.SectionIndex : 0);
}
W.write<uint16_t>(YamlSym.Type);
W.write<uint8_t>(YamlSym.StorageClass);
W.write<uint8_t>(YamlSym.NumberOfAuxEntries);

View File

@ -146,6 +146,7 @@ void MappingTraits<XCOFFYAML::Symbol>::mapping(IO &IO, XCOFFYAML::Symbol &S) {
IO.mapOptional("Name", S.SymbolName);
IO.mapOptional("Value", S.Value);
IO.mapOptional("Section", S.SectionName);
IO.mapOptional("SectionIndex", S.SectionIndex);
IO.mapOptional("Type", S.Type);
IO.mapOptional("StorageClass", S.StorageClass);
IO.mapOptional("NumberOfAuxEntries", S.NumberOfAuxEntries);

View File

@ -0,0 +1,81 @@
## Test the behavior of the symbol reference section.
## Case1: a symbol can reference a section by SectionName or SectionIndex.
# RUN: yaml2obj --docnum=1 %s -o %t1
# RUN: llvm-readobj %t1 -s | FileCheck %s --check-prefix=CASE1
# CASE1: Symbols [
# CASE1-NEXT: Symbol {
# CASE1-NEXT: Index: 0
# CASE1-NEXT: Name:
# CASE1-NEXT: Value: 0x0
# CASE1-NEXT: Section: .text
# CASE1-NEXT: Type: 0x0
# CASE1-NEXT: StorageClass: C_NULL (0x0)
# CASE1-NEXT: NumberOfAuxEntries: 0
# CASE1-NEXT: }
# CASE1-NEXT: Symbol {
# CASE1-NEXT: Index: 1
# CASE1-NEXT: Name:
# CASE1-NEXT: Value: 0x0
# CASE1-NEXT: Section: .text
# CASE1-NEXT: Type: 0x0
# CASE1-NEXT: StorageClass: C_NULL (0x0)
# CASE1-NEXT: NumberOfAuxEntries: 0
# CASE1-NEXT: }
# CASE1-NEXT: ]
--- !XCOFF
FileHeader:
MagicNumber: 0x1DF
Sections:
- Name: .text
Symbols:
- Section: .text
- SectionIndex: 1
## Case 2: a symbol can reference a section by both SectionName and SectionIndex.
# RUN: yaml2obj --docnum=2 -DSECNAME='.text' -DSECINDEX=1 %s -o %t2
# RUN: llvm-readobj %t2 -s | FileCheck %s --check-prefix=CASE2
# CASE2: Symbols [
# CASE2-NEXT: Symbol {
# CASE2-NEXT: Index: 0
# CASE2-NEXT: Name:
# CASE2-NEXT: Value: 0x0
# CASE2-NEXT: Section: .text
# CASE2-NEXT: Type: 0x0
# CASE2-NEXT: StorageClass: C_NULL (0x0)
# CASE2-NEXT: NumberOfAuxEntries: 0
# CASE2-NEXT: }
# CASE2-NEXT: ]
--- !XCOFF
FileHeader:
MagicNumber: 0x1DF
Sections:
- Name: .text
Symbols:
- Section: [[SECNAME=<none>]]
SectionIndex: [[SECINDEX=<none>]]
## Case3: if both Section and SectionIndex are specified, but the two
## values refer to different sections, an error will be reported.
# RUN: not yaml2obj --docnum=2 -DSECNAME='.text' -DSECINDEX=0 %s -o %t3 2>&1 \
# RUN: | FileCheck %s --check-prefix=CASE3
# CASE3: the SectionName .text and the SectionIndex (0) refer to different sections
## Case4: yaml2obj allows the specification of an invalid SectionIndex.
## TODO: the error message should include the symbol name or index.
# RUN: yaml2obj --docnum=2 -DSECINDEX=2 %s -o %t4
# RUN: not llvm-readobj %t4 -s 2>&1 | FileCheck %s --check-prefix=CASE4
# CASE4: the section index (2) is invalid
## Case 5: if a symbol references a non-existent section by SectionName,
## an error will be reported.
# RUN: not yaml2obj --docnum=2 -DSECNAME='.data' %s -o %t5 2>&1 \
# RUN: | FileCheck %s --check-prefix=CASE5
# CASE5: the SectionName .data specified in the symbol does not exist