}
bool XCOFFWriter::nameShouldBeInStringTable(StringRef SymbolName) {
- return SymbolName.size() > XCOFF::NameSize;
+ // For XCOFF64: The symbol name is always in the string table.
+ return (SymbolName.size() > XCOFF::NameSize) || Is64Bit;
}
bool XCOFFWriter::initRelocations(uint64_t &CurrentOffset) {
if (!InitSections[I].Relocations.empty()) {
InitSections[I].NumberOfRelocations = InitSections[I].Relocations.size();
InitSections[I].FileOffsetToRelocations = CurrentOffset;
- CurrentOffset += InitSections[I].NumberOfRelocations *
- XCOFF::RelocationSerializationSize32;
+ uint64_t RelSize = Is64Bit ? XCOFF::RelocationSerializationSize64
+ : XCOFF::RelocationSerializationSize32;
+ CurrentOffset += InitSections[I].NumberOfRelocations * RelSize;
if (CurrentOffset > MaxRawDataSize) {
ErrHandler("maximum object size of" + Twine(MaxRawDataSize) +
"exceeded when writing relocation data");
bool XCOFFWriter::assignAddressesAndIndices() {
Strings.clear();
- uint64_t CurrentOffset =
- XCOFF::FileHeaderSize32 /* TODO: + auxiliaryHeaderSize() */ +
- InitSections.size() * XCOFF::SectionHeaderSize32;
+ uint64_t FileHdrSize =
+ Is64Bit ? XCOFF::FileHeaderSize64 : XCOFF::FileHeaderSize32;
+ uint64_t SecHdrSize =
+ Is64Bit ? XCOFF::SectionHeaderSize64 : XCOFF::SectionHeaderSize32;
+ uint64_t CurrentOffset = FileHdrSize /* TODO: + auxiliaryHeaderSize() */ +
+ InitSections.size() * SecHdrSize;
// Calculate section header info.
if (!initSectionHeader(CurrentOffset))
W.write<uint16_t>(Obj.Header.NumberOfSections ? Obj.Header.NumberOfSections
: InitFileHdr.NumberOfSections);
W.write<int32_t>(Obj.Header.TimeStamp);
- W.write<uint32_t>(Obj.Header.SymbolTableOffset
- ? Obj.Header.SymbolTableOffset
- : InitFileHdr.SymbolTableOffset);
- W.write<int32_t>(Obj.Header.NumberOfSymTableEntries
- ? Obj.Header.NumberOfSymTableEntries
- : InitFileHdr.NumberOfSymTableEntries);
- W.write<uint16_t>(Obj.Header.AuxHeaderSize);
- W.write<uint16_t>(Obj.Header.Flags);
+ if (Is64Bit) {
+ W.write<uint64_t>(Obj.Header.SymbolTableOffset
+ ? Obj.Header.SymbolTableOffset
+ : InitFileHdr.SymbolTableOffset);
+ W.write<uint16_t>(Obj.Header.AuxHeaderSize);
+ W.write<uint16_t>(Obj.Header.Flags);
+ W.write<int32_t>(Obj.Header.NumberOfSymTableEntries
+ ? Obj.Header.NumberOfSymTableEntries
+ : InitFileHdr.NumberOfSymTableEntries);
+ } else {
+ W.write<uint32_t>(Obj.Header.SymbolTableOffset
+ ? Obj.Header.SymbolTableOffset
+ : InitFileHdr.SymbolTableOffset);
+ W.write<int32_t>(Obj.Header.NumberOfSymTableEntries
+ ? Obj.Header.NumberOfSymTableEntries
+ : InitFileHdr.NumberOfSymTableEntries);
+ W.write<uint16_t>(Obj.Header.AuxHeaderSize);
+ W.write<uint16_t>(Obj.Header.Flags);
+ }
}
void XCOFFWriter::writeSectionHeader() {
XCOFFYAML::Section DerivedSec = InitSections[I];
writeName(YamlSec.SectionName, W);
// Virtual address is the same as physical address.
- uint32_t SectionAddress =
+ uint64_t SectionAddress =
YamlSec.Address ? YamlSec.Address : DerivedSec.Address;
- W.write<uint32_t>(SectionAddress); // Physical address
- W.write<uint32_t>(SectionAddress); // Virtual address
- W.write<uint32_t>(YamlSec.Size ? YamlSec.Size : DerivedSec.Size);
- W.write<uint32_t>(YamlSec.FileOffsetToData ? YamlSec.FileOffsetToData
- : DerivedSec.FileOffsetToData);
- W.write<uint32_t>(YamlSec.FileOffsetToRelocations
- ? YamlSec.FileOffsetToRelocations
- : DerivedSec.FileOffsetToRelocations);
- W.write<uint32_t>(YamlSec.FileOffsetToLineNumbers);
- W.write<uint16_t>(YamlSec.NumberOfRelocations
- ? YamlSec.NumberOfRelocations
- : DerivedSec.NumberOfRelocations);
- W.write<uint16_t>(YamlSec.NumberOfLineNumbers);
- W.write<int32_t>(YamlSec.Flags);
+ if (Is64Bit) {
+ W.write<uint64_t>(SectionAddress); // Physical address
+ W.write<uint64_t>(SectionAddress); // Virtual address
+ W.write<uint64_t>(YamlSec.Size ? YamlSec.Size : DerivedSec.Size);
+ W.write<uint64_t>(YamlSec.FileOffsetToData ? YamlSec.FileOffsetToData
+ : DerivedSec.FileOffsetToData);
+ W.write<uint64_t>(YamlSec.FileOffsetToRelocations
+ ? YamlSec.FileOffsetToRelocations
+ : DerivedSec.FileOffsetToRelocations);
+ W.write<uint64_t>(YamlSec.FileOffsetToLineNumbers);
+ W.write<uint32_t>(YamlSec.NumberOfRelocations
+ ? YamlSec.NumberOfRelocations
+ : DerivedSec.NumberOfRelocations);
+ W.write<uint32_t>(YamlSec.NumberOfLineNumbers);
+ W.write<int32_t>(YamlSec.Flags);
+ W.OS.write_zeros(4);
+ } else {
+ W.write<uint32_t>(SectionAddress); // Physical address
+ W.write<uint32_t>(SectionAddress); // Virtual address
+ W.write<uint32_t>(YamlSec.Size ? YamlSec.Size : DerivedSec.Size);
+ W.write<uint32_t>(YamlSec.FileOffsetToData ? YamlSec.FileOffsetToData
+ : DerivedSec.FileOffsetToData);
+ W.write<uint32_t>(YamlSec.FileOffsetToRelocations
+ ? YamlSec.FileOffsetToRelocations
+ : DerivedSec.FileOffsetToRelocations);
+ W.write<uint32_t>(YamlSec.FileOffsetToLineNumbers);
+ W.write<uint16_t>(YamlSec.NumberOfRelocations
+ ? YamlSec.NumberOfRelocations
+ : DerivedSec.NumberOfRelocations);
+ W.write<uint16_t>(YamlSec.NumberOfLineNumbers);
+ W.write<int32_t>(YamlSec.Flags);
+ }
}
}
ErrHandler("redundant data was written before section data");
return false;
}
- if (PaddingSize > 0)
- W.OS.write_zeros(PaddingSize);
+ W.OS.write_zeros(PaddingSize);
YamlSec.SectionData.writeAsBinary(W.OS);
}
}
ErrHandler("redundant data was written before relocations");
return false;
}
- if (PaddingSize > 0)
- W.OS.write_zeros(PaddingSize);
+ W.OS.write_zeros(PaddingSize);
for (const XCOFFYAML::Relocation &YamlRel : YamlSec.Relocations) {
- W.write<uint32_t>(YamlRel.VirtualAddress);
+ if (Is64Bit)
+ W.write<uint64_t>(YamlRel.VirtualAddress);
+ else
+ W.write<uint32_t>(YamlRel.VirtualAddress);
W.write<uint32_t>(YamlRel.SymbolIndex);
W.write<uint8_t>(YamlRel.Info);
W.write<uint8_t>(YamlRel.Type);
ErrHandler("redundant data was written before symbols");
return false;
}
- if (PaddingSize > 0)
- W.OS.write_zeros(PaddingSize);
+ W.OS.write_zeros(PaddingSize);
for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols) {
- if (nameShouldBeInStringTable(YamlSym.SymbolName)) {
- // For XCOFF32: A value of 0 indicates that the symbol name is in the
- // string table.
- W.write<int32_t>(0);
+ if (Is64Bit) {
+ W.write<uint64_t>(YamlSym.Value);
W.write<uint32_t>(Strings.getOffset(YamlSym.SymbolName));
} else {
- writeName(YamlSym.SymbolName, W);
+ if (nameShouldBeInStringTable(YamlSym.SymbolName)) {
+ // For XCOFF32: A value of 0 indicates that the symbol name is in the
+ // string table.
+ W.write<int32_t>(0);
+ W.write<uint32_t>(Strings.getOffset(YamlSym.SymbolName));
+ } else {
+ writeName(YamlSym.SymbolName, W);
+ }
+ W.write<uint32_t>(YamlSym.Value);
}
- W.write<uint32_t>(YamlSym.Value);
W.write<int16_t>(
YamlSym.SectionName.size() ? SectionIndexMap[YamlSym.SectionName] : 0);
W.write<uint16_t>(YamlSym.Type);
// length of each auxiliary entry is the same as a symbol table entry (18
// bytes). The format and quantity of auxiliary entries depend on the
// storage class (n_sclass) and type (n_type) of the symbol table entry.
- W.OS.write_zeros(18);
+ W.OS.write_zeros(XCOFF::SymbolTableEntrySize);
}
}
return true;
}
bool XCOFFWriter::writeXCOFF() {
- if (Is64Bit) {
- ErrHandler("only XCOFF32 is currently supported");
- return false;
- }
if (!assignAddressesAndIndices())
return false;
StartOffset = W.OS.tell();
--- /dev/null
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-readobj --headers --symbols %t | \
+# RUN: FileCheck %s --check-prefix=CHECK64
+
+--- !XCOFF
+FileHeader:
+ MagicNumber: 0x01F7
+Sections:
+ - Name: .text
+ Flags: [ STYP_TEXT ]
+ - Name: .data
+ Flags: [ STYP_DATA ]
+ SectionData: "0000000000000FC0"
+ - Name: .bss
+ Flags: [ STYP_BSS ]
+ Relocations:
+ - Type: 0x02
+ - Name: .debug
+ Address: 0x0
+ Size: 0x60
+ Flags: [ STYP_DEBUG, STYP_DATA ]
+ SectionData: 01110103
+Symbols:
+ - Name: .file
+ Section: N_DEBUG
+ - Name: .undef
+ - Name: .abs
+ Section: N_ABS
+ - Name: .text
+ Value: 0x0
+ Section: .text
+ Type: 0x0
+ StorageClass: C_HIDEXT
+
+# CHECK64: AddressSize: 64bit
+# CHECK64-NEXT: FileHeader {
+# CHECK64-NEXT: Magic: 0x1F7
+# CHECK64-NEXT: NumberOfSections: 4
+# CHECK64-NEXT: TimeStamp: None (0x0)
+# CHECK64-NEXT: SymbolTableOffset: 0x152
+# CHECK64-NEXT: SymbolTableEntries: 4
+# CHECK64-NEXT: OptionalHeaderSize: 0x0
+# CHECK64-NEXT: Flags: 0x0
+# CHECK64-NEXT: }
+# CHECK64-NEXT: Sections [
+# CHECK64-NEXT: Section {
+# CHECK64-NEXT: Index: 1
+# CHECK64-NEXT: Name: .text
+# CHECK64-NEXT: PhysicalAddress: 0x0
+# CHECK64-NEXT: VirtualAddress: 0x0
+# CHECK64-NEXT: Size: 0x0
+# CHECK64-NEXT: RawDataOffset: 0x0
+# CHECK64-NEXT: RelocationPointer: 0x0
+# CHECK64-NEXT: LineNumberPointer: 0x0
+# CHECK64-NEXT: NumberOfRelocations: 0
+# CHECK64-NEXT: NumberOfLineNumbers: 0
+# CHECK64-NEXT: Type: STYP_TEXT (0x20)
+# CHECK64-NEXT: }
+# CHECK64-NEXT: Section {
+# CHECK64-NEXT: Index: 2
+# CHECK64-NEXT: Name: .data
+# CHECK64-NEXT: PhysicalAddress: 0x0
+# CHECK64-NEXT: VirtualAddress: 0x0
+# CHECK64-NEXT: Size: 0x8
+# CHECK64-NEXT: RawDataOffset: 0x138
+# CHECK64-NEXT: RelocationPointer: 0x0
+# CHECK64-NEXT: LineNumberPointer: 0x0
+# CHECK64-NEXT: NumberOfRelocations: 0
+# CHECK64-NEXT: NumberOfLineNumbers: 0
+# CHECK64-NEXT: Type: STYP_DATA (0x40)
+# CHECK64-NEXT: }
+# CHECK64-NEXT: Section {
+# CHECK64-NEXT: Index: 3
+# CHECK64-NEXT: Name: .bss
+# CHECK64-NEXT: PhysicalAddress: 0x8
+# CHECK64-NEXT: VirtualAddress: 0x8
+# CHECK64-NEXT: Size: 0x0
+# CHECK64-NEXT: RawDataOffset: 0x0
+# CHECK64-NEXT: RelocationPointer: 0x144
+# CHECK64-NEXT: LineNumberPointer: 0x0
+# CHECK64-NEXT: NumberOfRelocations: 1
+# CHECK64-NEXT: NumberOfLineNumbers: 0
+# CHECK64-NEXT: Type: STYP_BSS (0x80)
+# CHECK64-NEXT: }
+# CHECK64-NEXT: Section {
+# CHECK64-NEXT: Index: 4
+# CHECK64-NEXT: Name: .debug
+# CHECK64-NEXT: PhysicalAddress: 0x0
+# CHECK64-NEXT: VirtualAddress: 0x0
+# CHECK64-NEXT: Size: 0x60
+# CHECK64-NEXT: RawDataOffset: 0x140
+# CHECK64-NEXT: RelocationPointer: 0x0
+# CHECK64-NEXT: LineNumberPointer: 0x0
+# CHECK64-NEXT: NumberOfRelocations: 0
+# CHECK64-NEXT: NumberOfLineNumbers: 0
+# CHECK64-NEXT: Type: 0x2040
+# CHECK64-NEXT: }
+# CHECK64-NEXT: ]
+# CHECK64-NEXT: Symbols [
+# CHECK64-NEXT: Symbol {
+# CHECK64-NEXT: Index: 0
+# CHECK64-NEXT: Name: .file
+# CHECK64-NEXT: Value: 0x0
+# CHECK64-NEXT: Section: N_DEBUG
+# CHECK64-NEXT: Type: 0x0
+# CHECK64-NEXT: StorageClass: C_NULL (0x0)
+# CHECK64-NEXT: NumberOfAuxEntries: 0
+# CHECK64-NEXT: }
+# CHECK64-NEXT: Symbol {
+# CHECK64-NEXT: Index: 1
+# CHECK64-NEXT: Name: .undef
+# CHECK64-NEXT: Value: 0x0
+# CHECK64-NEXT: Section: N_UNDEF
+# CHECK64-NEXT: Type: 0x0
+# CHECK64-NEXT: StorageClass: C_NULL (0x0)
+# CHECK64-NEXT: NumberOfAuxEntries: 0
+# CHECK64-NEXT: }
+# CHECK64-NEXT: Symbol {
+# CHECK64-NEXT: Index: 2
+# CHECK64-NEXT: Name: .abs
+# CHECK64-NEXT: Value: 0x0
+# CHECK64-NEXT: Section: N_ABS
+# CHECK64-NEXT: Type: 0x0
+# CHECK64-NEXT: StorageClass: C_NULL (0x0)
+# CHECK64-NEXT: NumberOfAuxEntries: 0
+# CHECK64-NEXT: }
+# CHECK64-NEXT: Symbol {
+# CHECK64-NEXT: Index: 3
+# CHECK64-NEXT: Name: .text
+# CHECK64-NEXT: Value (RelocatableAddress): 0x0
+# CHECK64-NEXT: Section: .text
+# CHECK64-NEXT: Type: 0x0
+# CHECK64-NEXT: StorageClass: C_HIDEXT (0x6B)
+# CHECK64-NEXT: NumberOfAuxEntries: 0
+# CHECK64-NEXT: }
+# CHECK64-NEXT: ]