void MachObjectWriter::WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCSectionData &SD, uint64_t FileOffset, uint64_t RelocationsStart, unsigned NumRelocations) { uint64_t SectionSize = Layout.getSectionAddressSize(&SD); // The offset is unused for virtual sections. if (SD.getSection().isVirtualSection()) { assert(Layout.getSectionFileSize(&SD) == 0 && "Invalid file size!"); FileOffset = 0; } // struct section (68 bytes) or // struct section_64 (80 bytes) uint64_t Start = OS.tell(); (void) Start; const MCSectionMachO &Section = cast<MCSectionMachO>(SD.getSection()); WriteBytes(Section.getSectionName(), 16); WriteBytes(Section.getSegmentName(), 16); if (is64Bit()) { Write64(getSectionAddress(&SD)); // address Write64(SectionSize); // size } else { Write32(getSectionAddress(&SD)); // address Write32(SectionSize); // size } Write32(FileOffset); unsigned Flags = Section.getTypeAndAttributes(); if (SD.hasInstructions()) Flags |= MCSectionMachO::S_ATTR_SOME_INSTRUCTIONS; assert(isPowerOf2_32(SD.getAlignment()) && "Invalid alignment!"); Write32(Log2_32(SD.getAlignment())); Write32(NumRelocations ? RelocationsStart : 0); Write32(NumRelocations); Write32(Flags); Write32(IndirectSymBase.lookup(&SD)); // reserved1 Write32(Section.getStubSize()); // reserved2 if (is64Bit()) Write32(0); // reserved3 assert(OS.tell() - Start == (is64Bit() ? macho::Section64Size : macho::Section32Size)); }
/// This function takes a section data object from the assembler /// and creates the associated COFF section staging object. void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) { assert(SectionData.getSection().getVariant() == MCSection::SV_COFF && "Got non COFF section in the COFF backend!"); // FIXME: Not sure how to verify this (at least in a debug build). MCSectionCOFF const &Sec = static_cast<MCSectionCOFF const &>(SectionData.getSection()); COFFSection *coff_section = createSection(Sec.getSectionName()); COFFSymbol *coff_symbol = createSymbol(Sec.getSectionName()); coff_section->Symbol = coff_symbol; coff_symbol->Section = coff_section; coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_STATIC; // In this case the auxiliary symbol is a Section Definition. coff_symbol->Aux.resize(1); memset(&coff_symbol->Aux[0], 0, sizeof(coff_symbol->Aux[0])); coff_symbol->Aux[0].AuxType = ATSectionDefinition; coff_symbol->Aux[0].Aux.SectionDefinition.Selection = Sec.getSelection(); coff_section->Header.Characteristics = Sec.getCharacteristics(); uint32_t &Characteristics = coff_section->Header.Characteristics; switch (SectionData.getAlignment()) { case 1: Characteristics |= COFF::IMAGE_SCN_ALIGN_1BYTES; break; case 2: Characteristics |= COFF::IMAGE_SCN_ALIGN_2BYTES; break; case 4: Characteristics |= COFF::IMAGE_SCN_ALIGN_4BYTES; break; case 8: Characteristics |= COFF::IMAGE_SCN_ALIGN_8BYTES; break; case 16: Characteristics |= COFF::IMAGE_SCN_ALIGN_16BYTES; break; case 32: Characteristics |= COFF::IMAGE_SCN_ALIGN_32BYTES; break; case 64: Characteristics |= COFF::IMAGE_SCN_ALIGN_64BYTES; break; case 128: Characteristics |= COFF::IMAGE_SCN_ALIGN_128BYTES; break; case 256: Characteristics |= COFF::IMAGE_SCN_ALIGN_256BYTES; break; case 512: Characteristics |= COFF::IMAGE_SCN_ALIGN_512BYTES; break; case 1024: Characteristics |= COFF::IMAGE_SCN_ALIGN_1024BYTES; break; case 2048: Characteristics |= COFF::IMAGE_SCN_ALIGN_2048BYTES; break; case 4096: Characteristics |= COFF::IMAGE_SCN_ALIGN_4096BYTES; break; case 8192: Characteristics |= COFF::IMAGE_SCN_ALIGN_8192BYTES; break; default: llvm_unreachable("unsupported section alignment"); } // Bind internal COFF section to MC section. coff_section->MCData = &SectionData; SectionMap[&SectionData.getSection()] = coff_section; }
void MCObjectStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { MCStreamer::EmitInstruction(Inst, STI); MCSectionData *SD = getCurrentSectionData(); SD->getSection().setHasInstructions(true); // Now that a machine instruction has been assembled into this section, make // a line entry for any .loc directive that has been seen. MCLineEntry::Make(this, getCurrentSection().first); // If this instruction doesn't need relaxation, just emit it as data. MCAssembler &Assembler = getAssembler(); if (!Assembler.getBackend().mayNeedRelaxation(Inst)) { EmitInstToData(Inst, STI); return; } // Otherwise, relax and emit it as data if either: // - The RelaxAll flag was passed // - Bundling is enabled and this instruction is inside a bundle-locked // group. We want to emit all such instructions into the same data // fragment. if (Assembler.getRelaxAll() || (Assembler.isBundlingEnabled() && SD->getSection().isBundleLocked())) { MCInst Relaxed; getAssembler().getBackend().relaxInstruction(Inst, Relaxed); while (getAssembler().getBackend().mayNeedRelaxation(Relaxed)) getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed); EmitInstToData(Relaxed, STI); return; } // Otherwise emit to a separate fragment. EmitInstToFragment(Inst, STI); }