27#define DEBUG_TYPE "goff-writer" 
   63  char *BufferPtr = Buffer;
 
   66  char Buffer[BufferSize];
 
   78  uint32_t getNumLogicalRecords() { 
return LogicalRecords; }
 
   84  void write_zeros(
unsigned NumZeros);
 
   87  template <
typename value_type> 
void writebe(value_type 
Value) {
 
   90    write((
const char *)&
Value, 
sizeof(value_type));
 
   97  void finalizeRecord();
 
  102  void updateFlagsAndWritePrefix(
bool IsContinued);
 
  105  size_t getRemainingSize();
 
  111GOFFOstream::~GOFFOstream() { finalizeRecord(); }
 
  113void GOFFOstream::updateFlagsAndWritePrefix(
bool IsContinued) {
 
  115  if (TypeAndFlags & RecContinued)
 
  116    TypeAndFlags |= RecContinuation;
 
  118    TypeAndFlags |= RecContinued;
 
  120    TypeAndFlags &= ~RecContinued;
 
  123     << 
static_cast<unsigned char>(TypeAndFlags)    
 
  124     << 
static_cast<unsigned char>(0);              
 
  129size_t GOFFOstream::getRemainingSize() {
 
  130  return size_t(&Buffer[BufferSize] - BufferPtr);
 
  133void GOFFOstream::write(
const char *
Ptr, 
size_t Size) {
 
  134  size_t RemainingSize = getRemainingSize();
 
  145  updateFlagsAndWritePrefix(
true);
 
  146  OS.
write(Buffer, 
size_t(BufferPtr - Buffer));
 
  147  if (RemainingSize > 0) {
 
  149    Ptr += RemainingSize;
 
  150    Size -= RemainingSize;
 
  153  while (
Size > BufferSize) {
 
  154    updateFlagsAndWritePrefix(
true);
 
  162  BufferPtr = &Buffer[
Size];
 
  165void GOFFOstream::write_zeros(
unsigned NumZeros) {
 
  166  assert(NumZeros <= 16 && 
"Range for zeros too large");
 
  169  size_t RemainingSize = getRemainingSize();
 
  171    memset(BufferPtr, 0, NumZeros);
 
  172    BufferPtr += NumZeros;
 
  177  static char Zeros[16] = {
 
  180  write(Zeros, NumZeros);
 
  185  TypeAndFlags = 
Type << 4;
 
  189void GOFFOstream::finalizeRecord() {
 
  190  if (Buffer == BufferPtr)
 
  192  updateFlagsAndWritePrefix(
false);
 
  193  OS.
write(Buffer, 
size_t(BufferPtr - Buffer));
 
  204  uint32_t ParentEsdId;
 
  211  GOFF::BehavioralAttributes BehavAttrs;
 
  212  GOFF::SymbolFlags SymbolFlags;
 
  213  uint32_t SortKey = 0;
 
  214  uint32_t SectionLength = 0;
 
  215  uint32_t ADAEsdId = 0;
 
  216  uint32_t EASectionEDEsdId = 0;
 
  217  uint32_t EASectionOffset = 0;
 
  218  uint8_t FillByteValue = 0;
 
  220  GOFFSymbol() : EsdId(0), ParentEsdId(0) {}
 
  222  GOFFSymbol(StringRef Name, uint32_t EsdID, 
const GOFF::SDAttr &Attr)
 
  229  GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
 
  230             const GOFF::EDAttr &Attr)
 
  240    BehavAttrs.setRmode(Attr.
Rmode);
 
  247  GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
 
  254    BehavAttrs.setLinkageType(Attr.
Linkage);
 
  255    BehavAttrs.setAmode(Attr.
Amode);
 
  259  GOFFSymbol(StringRef Name, uint32_t EsdID, uint32_t ParentEsdID,
 
  260             const GOFF::EDAttr &EDAttr, 
const GOFF::PRAttr &Attr)
 
  265    BehavAttrs.setLinkageType(Attr.
Linkage);
 
  267    BehavAttrs.setAlignment(EDAttr.
Alignment);
 
  276  void writeSymbol(
const GOFFSymbol &Symbol);
 
  277  void writeText(
const MCSectionGOFF *MC);
 
  280  void defineSectionSymbols(
const MCSectionGOFF &Section);
 
  281  void defineLabel(
const MCSymbolGOFF &Symbol);
 
  282  void defineSymbols();
 
  285  GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm);
 
  286  uint64_t writeObject();
 
  290GOFFWriter::GOFFWriter(raw_pwrite_stream &OS, MCAssembler &Asm)
 
  293void GOFFWriter::defineSectionSymbols(
const MCSectionGOFF &Section) {
 
  308    MCSectionGOFF *Parent = 
Section.getParent();
 
  312    if (
Section.requiresNonZeroLength()) {
 
  318      if (!PR.SectionLength)
 
  319        PR.SectionLength = 2;
 
  325void GOFFWriter::defineLabel(
const MCSymbolGOFF &Symbol) {
 
  326  MCSectionGOFF &
Section = 
static_cast<MCSectionGOFF &
>(
Symbol.getSection());
 
  328                Section.getEDAttributes().NameSpace, 
Symbol.getLDAttributes());
 
  330    LD.ADAEsdId = 
Symbol.getADA()->getOrdinal();
 
  334void GOFFWriter::defineSymbols() {
 
  335  unsigned Ordinal = 0;
 
  337  for (MCSection &S : Asm) {
 
  338    auto &
Section = 
static_cast<MCSectionGOFF &
>(S);
 
  340    defineSectionSymbols(Section);
 
  344  for (
const MCSymbol &Sym : 
Asm.symbols()) {
 
  345    if (Sym.isTemporary())
 
  347    auto &
Symbol = 
static_cast<const MCSymbolGOFF &
>(Sym);
 
  348    if (
Symbol.hasLDAttributes()) {
 
  349      Symbol.setIndex(++Ordinal);
 
  355void GOFFWriter::writeHeader() {
 
  358  OS.writebe<uint32_t>(0); 
 
  359  OS.writebe<uint32_t>(0); 
 
  361  OS.writebe<uint16_t>(0); 
 
  364  OS.writebe<uint32_t>(1); 
 
  365  OS.writebe<uint16_t>(0); 
 
  369void GOFFWriter::writeSymbol(
const GOFFSymbol &Symbol) {
 
  370  if (
Symbol.Offset >= (((uint64_t)1) << 31))
 
  374  SmallString<256> 
Name;
 
  381  uint16_t NameLength = 
Name.size();
 
  384  OS.writebe<uint8_t>(
Symbol.SymbolType);   
 
  385  OS.writebe<uint32_t>(
Symbol.EsdId);       
 
  386  OS.writebe<uint32_t>(
Symbol.ParentEsdId); 
 
  387  OS.writebe<uint32_t>(0);                  
 
  388  OS.writebe<uint32_t>(
 
  389      static_cast<uint32_t
>(
Symbol.Offset));     
 
  390  OS.writebe<uint32_t>(0);                       
 
  391  OS.writebe<uint32_t>(
Symbol.SectionLength);    
 
  392  OS.writebe<uint32_t>(
Symbol.EASectionEDEsdId); 
 
  393  OS.writebe<uint32_t>(
Symbol.EASectionOffset);  
 
  394  OS.writebe<uint32_t>(0);                       
 
  395  OS.writebe<uint8_t>(
Symbol.NameSpace);         
 
  396  OS.writebe<uint8_t>(
Symbol.SymbolFlags);       
 
  397  OS.writebe<uint8_t>(
Symbol.FillByteValue);     
 
  398  OS.writebe<uint8_t>(0);                        
 
  399  OS.writebe<uint32_t>(
Symbol.ADAEsdId);         
 
  400  OS.writebe<uint32_t>(
Symbol.SortKey);          
 
  401  OS.writebe<uint64_t>(0);                       
 
  402  for (
auto F : 
Symbol.BehavAttrs.Attr)
 
  403    OS.writebe<uint8_t>(
F);          
 
  404  OS.writebe<uint16_t>(NameLength);  
 
  405  OS.write(
Name.data(), NameLength); 
 
  410class TextStream : 
public raw_ostream {
 
  419  char Buffer[BufferSize];
 
  426  const uint32_t EsdId;
 
  432  void write_impl(
const char *
Ptr, 
size_t Size) 
override;
 
  434  uint64_t current_pos()
 const override { 
return Offset; }
 
  437  explicit TextStream(GOFFOstream &OS, uint32_t EsdId,
 
  439      : OS(OS), 
Offset(0), EsdId(EsdId), RecordStyle(RecordStyle) {
 
  440    SetBuffer(Buffer, 
sizeof(Buffer));
 
  443  ~TextStream()
 override { flush(); }
 
  447void TextStream::write_impl(
const char *
Ptr, 
size_t Size) {
 
  448  size_t WrittenLength = 0;
 
  451  if (
Offset + 
Size > std::numeric_limits<int32_t>::max())
 
  454  while (WrittenLength < 
Size) {
 
  455    size_t ToWriteLength =
 
  459    OS.writebe<uint8_t>(GOFF::Flags(4, 4, RecordStyle)); 
 
  460    OS.writebe<uint32_t>(EsdId);                         
 
  461    OS.writebe<uint32_t>(0);                             
 
  462    OS.writebe<uint32_t>(
static_cast<uint32_t
>(
Offset)); 
 
  463    OS.writebe<uint32_t>(0);                      
 
  464    OS.writebe<uint16_t>(0);                      
 
  465    OS.writebe<uint16_t>(ToWriteLength);          
 
  466    OS.write(
Ptr + WrittenLength, ToWriteLength); 
 
  468    WrittenLength += ToWriteLength;
 
  473void GOFFWriter::writeText(
const MCSectionGOFF *Section) {
 
  479  Asm.writeSectionData(S, Section);
 
  482void GOFFWriter::writeEnd() {
 
  490  OS.writebe<uint8_t>(GOFF::Flags(6, 2, 
F)); 
 
  491  OS.writebe<uint8_t>(AMODE);                
 
  496  OS.writebe<uint32_t>(0);     
 
  497  OS.writebe<uint32_t>(ESDID); 
 
  500uint64_t GOFFWriter::writeObject() {
 
  505  for (
const MCSection &Section : Asm)
 
  506    writeText(
static_cast<const MCSectionGOFF *
>(&Section));
 
  514                    << 
" logical records.");
 
  516  return OS.getWrittenSize();
 
  521    : TargetObjectWriter(
std::
move(MOTW)), OS(OS) {}
 
 
  530std::unique_ptr<MCObjectWriter>
 
  533  return std::make_unique<GOFFObjectWriter>(std::move(MOTW), OS);
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
#define LLVM_LIKELY(EXPR)
 
This file provides utility functions for converting between EBCDIC-1047 and UTF-8.
 
This file declares the MCSectionGOFF class, which contains all of the necessary machine code sections...
 
This file contains the MCSymbolGOFF class.
 
GOFFObjectWriter(std::unique_ptr< MCGOFFObjectTargetWriter > MOTW, raw_pwrite_stream &OS)
 
uint64_t writeObject() override
Write the object file and returns the number of bytes written.
 
~GOFFObjectWriter() override
 
LLVM_ABI uint64_t getSectionAddressSize(const MCSection &Sec) const
 
GOFF::EDAttr getEDAttributes() const
 
unsigned getOrdinal() const
 
The instances of the Type class are immutable: once they are created, they are never changed.
 
LLVM Value Representation.
 
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
 
raw_ostream & write(unsigned char C)
 
An abstract base class for streams implementations that also support a pwrite operation.
 
LLVM_ABI std::error_code convertToEBCDIC(StringRef Source, SmallVectorImpl< char > &Result)
 
constexpr uint8_t PayloadLength
 
constexpr uint16_t MaxDataLength
Maximum data length before starting a new card for RLD and TXT data.
 
constexpr uint8_t PTVPrefix
Prefix byte on every record. This indicates GOFF format.
 
constexpr uint8_t RecordLength
Length of the parts of a physical GOFF record.
 
@ ESD_NS_ProgramManagementBinder
 
@ ESD_ST_ElementDefinition
 
@ ESD_ST_SectionDefinition
 
value_type byte_swap(value_type value, endianness endian)
 
This is an optimization pass for GlobalISel generic memory operations.
 
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
 
std::unique_ptr< MCObjectWriter > createGOFFObjectWriter(std::unique_ptr< MCGOFFObjectTargetWriter > MOTW, raw_pwrite_stream &OS)
Construct a new GOFF writer instance.
 
LLVM_ABI Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
 
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
 
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
 
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
 
Implement std::hash so that hash_code can be used in STL containers.
 
GOFF::ESDReserveQwords ReservedQwords
 
GOFF::ESDAlignment Alignment
 
GOFF::ESDTextStyle TextStyle
 
GOFF::ESDLoadingBehavior LoadBehavior
 
GOFF::ESDNameSpaceId NameSpace
 
GOFF::ESDBindingAlgorithm BindAlgorithm
 
GOFF::ESDBindingStrength BindingStrength
 
GOFF::ESDExecutable Executable
 
GOFF::ESDBindingScope BindingScope
 
GOFF::ESDLinkageType Linkage
 
GOFF::ESDLinkageType Linkage
 
GOFF::ESDBindingScope BindingScope
 
GOFF::ESDExecutable Executable
 
GOFF::ESDTaskingBehavior TaskingBehavior
 
GOFF::ESDBindingScope BindingScope