[llvm] [yaml2obj][XOFF] Update yaml2obj for XCOFF to create valid XCOFF files in more cases. (PR #77620)
James Henderson via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 25 00:47:45 PST 2024
================
@@ -134,23 +155,58 @@ bool XCOFFWriter::initSectionHeader(uint64_t &CurrentOffset) {
}
}
- // Calculate the physical/virtual address. This field should contain 0 for
- // all sections except the text, data and bss sections.
- if (InitSections[I].Flags != XCOFF::STYP_TEXT &&
- InitSections[I].Flags != XCOFF::STYP_DATA &&
- InitSections[I].Flags != XCOFF::STYP_BSS)
- InitSections[I].Address = 0;
- else
- InitSections[I].Address = CurrentSecAddr;
+ if (!InitSections[I].Size)
+ InitSections[I].Size = InitSections[I].SectionData.binary_size();
+
+ // Section data addresses (physical/virtual) are related to symbol
+ // addresses and alignments. Furthermore, it is possible to specify the
+ // same starting addresses for the .text, .data, and .tdata sections.
+ // Without examining all the symbols and their addreses and alignments,
+ // it is not possible to compute valid section addresses. The only
+ // condition required by XCOFF is that the .bss section immediately
+ // follows the .data section, and the .tbss section immediately follows
+ // the .tdata section. Therefore, we only assign addresses to the .bss
+ // and .tbss sections if they do not already have non-zero addresses.
+ // (If the YAML file is being used to generate a valid object file, we
+ // expect all section addresses to be specified explicitly.)
+ switch (InitSections[I].Flags) {
+ case XCOFF::STYP_DATA:
+ CurrentEndDataAddr = InitSections[I].Address + InitSections[I].Size;
+ break;
+ case XCOFF::STYP_BSS:
+ if (!InitSections[I].Address)
+ InitSections[I].Address = CurrentEndDataAddr;
+ break;
+ case XCOFF::STYP_TDATA:
+ CurrentEndTDataAddr = InitSections[I].Address + InitSections[I].Size;
+ break;
+ case XCOFF::STYP_TBSS:
+ if (!InitSections[I].Address)
+ InitSections[I].Address = CurrentEndTDataAddr;
+ break;
+ }
- // Calculate the FileOffsetToData and data size for sections.
if (InitSections[I].SectionData.binary_size()) {
- InitSections[I].FileOffsetToData = CurrentOffset;
+ if (InitSections[I].FileOffsetToData) {
+ // Use the providedFileOffsetToData.
+ if (CurrentOffset > InitSections[I].FileOffsetToData) {
+ ErrOverwrite(CurrentOffset, InitSections[I].FileOffsetToData,
+ "FileOffsetToData for the " +
+ InitSections[I].SectionName + " section");
+ return false;
+ }
+ CurrentOffset = InitSections[I].FileOffsetToData;
+ } else {
+ CurrentOffset = alignTo(CurrentOffset, DefaultSectionAlign);
+ InitSections[I].FileOffsetToData = CurrentOffset;
+ }
CurrentOffset += InitSections[I].SectionData.binary_size();
- // Ensure the offset is aligned to DefaultSectionAlign.
- CurrentOffset = alignTo(CurrentOffset, DefaultSectionAlign);
- InitSections[I].Size = CurrentOffset - InitSections[I].FileOffsetToData;
- CurrentSecAddr += InitSections[I].Size;
+ if (CurrentOffset > MaxRawDataSize) {
+ ErrHandler("maximum object size (" + Twine(MaxRawDataSize) +
----------------
jh7370 wrote:
Is this tested?
https://github.com/llvm/llvm-project/pull/77620
More information about the llvm-commits
mailing list