Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:19

0001 //===- GOFF.h - GOFF object file implementation -----------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file declares the GOFFObjectFile class.
0010 // Record classes and derivatives are also declared and implemented.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_OBJECT_GOFF_H
0015 #define LLVM_OBJECT_GOFF_H
0016 
0017 #include "llvm/ADT/SmallString.h"
0018 #include "llvm/ADT/SmallVector.h"
0019 #include "llvm/BinaryFormat/GOFF.h"
0020 #include "llvm/Support/Debug.h"
0021 #include "llvm/Support/Endian.h"
0022 #include "llvm/Support/raw_ostream.h"
0023 
0024 namespace llvm {
0025 namespace object {
0026 
0027 /// \brief Represents a GOFF physical record.
0028 ///
0029 /// Specifies protected member functions to manipulate the record. These should
0030 /// be called from deriving classes to change values as that record specifies.
0031 class Record {
0032 public:
0033   static Error getContinuousData(const uint8_t *Record, uint16_t DataLength,
0034                                  int DataIndex, SmallString<256> &CompleteData);
0035 
0036   static bool isContinued(const uint8_t *Record) {
0037     uint8_t IsContinued;
0038     getBits(Record, 1, 7, 1, IsContinued);
0039     return IsContinued;
0040   }
0041 
0042   static bool isContinuation(const uint8_t *Record) {
0043     uint8_t IsContinuation;
0044     getBits(Record, 1, 6, 1, IsContinuation);
0045     return IsContinuation;
0046   }
0047 
0048 protected:
0049   /// \brief Get bit field of specified byte.
0050   ///
0051   /// Used to pack bit fields into one byte. Fields are packed left to right.
0052   /// Bit index zero is the most significant bit of the byte.
0053   ///
0054   /// \param ByteIndex index of byte the field is in.
0055   /// \param BitIndex index of first bit of field.
0056   /// \param Length length of bit field.
0057   /// \param Value value of bit field.
0058   static void getBits(const uint8_t *Bytes, uint8_t ByteIndex, uint8_t BitIndex,
0059                       uint8_t Length, uint8_t &Value) {
0060     assert(ByteIndex < GOFF::RecordLength && "Byte index out of bounds!");
0061     assert(BitIndex < 8 && "Bit index out of bounds!");
0062     assert(Length + BitIndex <= 8 && "Bit length too long!");
0063 
0064     get<uint8_t>(Bytes, ByteIndex, Value);
0065     Value = (Value >> (8 - BitIndex - Length)) & ((1 << Length) - 1);
0066   }
0067 
0068   template <class T>
0069   static void get(const uint8_t *Bytes, uint8_t ByteIndex, T &Value) {
0070     assert(ByteIndex + sizeof(T) <= GOFF::RecordLength &&
0071            "Byte index out of bounds!");
0072     Value = support::endian::read<T, llvm::endianness::big>(&Bytes[ByteIndex]);
0073   }
0074 };
0075 
0076 class TXTRecord : public Record {
0077 public:
0078   /// \brief Maximum length of data; any more must go in continuation.
0079   static const uint8_t TXTMaxDataLength = 56;
0080 
0081   static Error getData(const uint8_t *Record, SmallString<256> &CompleteData);
0082 
0083   static void getElementEsdId(const uint8_t *Record, uint32_t &EsdId) {
0084     get<uint32_t>(Record, 4, EsdId);
0085   }
0086 
0087   static void getOffset(const uint8_t *Record, uint32_t &Offset) {
0088     get<uint32_t>(Record, 12, Offset);
0089   }
0090 
0091   static void getDataLength(const uint8_t *Record, uint16_t &Length) {
0092     get<uint16_t>(Record, 22, Length);
0093   }
0094 };
0095 
0096 class HDRRecord : public Record {
0097 public:
0098   static Error getData(const uint8_t *Record, SmallString<256> &CompleteData);
0099 
0100   static uint16_t getPropertyModuleLength(const uint8_t *Record) {
0101     uint16_t Length;
0102     get<uint16_t>(Record, 52, Length);
0103     return Length;
0104   }
0105 };
0106 
0107 class ESDRecord : public Record {
0108 public:
0109   /// \brief Number of bytes for name; any more must go in continuation.
0110   /// This is the number of bytes that can fit into the data field of an ESD
0111   /// record.
0112   static const uint8_t ESDMaxUncontinuedNameLength = 8;
0113 
0114   /// \brief Maximum name length for ESD records and continuations.
0115   /// This is the number of bytes that can fit into the data field of an ESD
0116   /// record AND following continuations. This is limited fundamentally by the
0117   /// 16 bit SIGNED length field.
0118   static const uint16_t MaxNameLength = 32 * 1024;
0119 
0120 public:
0121   static Error getData(const uint8_t *Record, SmallString<256> &CompleteData);
0122 
0123   // ESD Get routines.
0124   static void getSymbolType(const uint8_t *Record,
0125                             GOFF::ESDSymbolType &SymbolType) {
0126     uint8_t Value;
0127     get<uint8_t>(Record, 3, Value);
0128     SymbolType = (GOFF::ESDSymbolType)Value;
0129   }
0130 
0131   static void getEsdId(const uint8_t *Record, uint32_t &EsdId) {
0132     get<uint32_t>(Record, 4, EsdId);
0133   }
0134 
0135   static void getParentEsdId(const uint8_t *Record, uint32_t &EsdId) {
0136     get<uint32_t>(Record, 8, EsdId);
0137   }
0138 
0139   static void getOffset(const uint8_t *Record, uint32_t &Offset) {
0140     get<uint32_t>(Record, 16, Offset);
0141   }
0142 
0143   static void getLength(const uint8_t *Record, uint32_t &Length) {
0144     get<uint32_t>(Record, 24, Length);
0145   }
0146 
0147   static void getNameSpaceId(const uint8_t *Record, GOFF::ESDNameSpaceId &Id) {
0148     uint8_t Value;
0149     get<uint8_t>(Record, 40, Value);
0150     Id = (GOFF::ESDNameSpaceId)Value;
0151   }
0152 
0153   static void getFillBytePresent(const uint8_t *Record, bool &Present) {
0154     uint8_t Value;
0155     getBits(Record, 41, 0, 1, Value);
0156     Present = (bool)Value;
0157   }
0158 
0159   static void getNameMangled(const uint8_t *Record, bool &Mangled) {
0160     uint8_t Value;
0161     getBits(Record, 41, 1, 1, Value);
0162     Mangled = (bool)Value;
0163   }
0164 
0165   static void getRenamable(const uint8_t *Record, bool &Renamable) {
0166     uint8_t Value;
0167     getBits(Record, 41, 2, 1, Value);
0168     Renamable = (bool)Value;
0169   }
0170 
0171   static void getRemovable(const uint8_t *Record, bool &Removable) {
0172     uint8_t Value;
0173     getBits(Record, 41, 3, 1, Value);
0174     Removable = (bool)Value;
0175   }
0176 
0177   static void getFillByteValue(const uint8_t *Record, uint8_t &Fill) {
0178     get<uint8_t>(Record, 42, Fill);
0179   }
0180 
0181   static void getAdaEsdId(const uint8_t *Record, uint32_t &EsdId) {
0182     get<uint32_t>(Record, 44, EsdId);
0183   }
0184 
0185   static void getSortPriority(const uint8_t *Record, uint32_t &Priority) {
0186     get<uint32_t>(Record, 48, Priority);
0187   }
0188 
0189   static void getAmode(const uint8_t *Record, GOFF::ESDAmode &Amode) {
0190     uint8_t Value;
0191     get<uint8_t>(Record, 60, Value);
0192     Amode = (GOFF::ESDAmode)Value;
0193   }
0194 
0195   static void getRmode(const uint8_t *Record, GOFF::ESDRmode &Rmode) {
0196     uint8_t Value;
0197     get<uint8_t>(Record, 61, Value);
0198     Rmode = (GOFF::ESDRmode)Value;
0199   }
0200 
0201   static void getTextStyle(const uint8_t *Record, GOFF::ESDTextStyle &Style) {
0202     uint8_t Value;
0203     getBits(Record, 62, 0, 4, Value);
0204     Style = (GOFF::ESDTextStyle)Value;
0205   }
0206 
0207   static void getBindingAlgorithm(const uint8_t *Record,
0208                                   GOFF::ESDBindingAlgorithm &Algorithm) {
0209     uint8_t Value;
0210     getBits(Record, 62, 4, 4, Value);
0211     Algorithm = (GOFF::ESDBindingAlgorithm)Value;
0212   }
0213 
0214   static void getTaskingBehavior(const uint8_t *Record,
0215                                  GOFF::ESDTaskingBehavior &TaskingBehavior) {
0216     uint8_t Value;
0217     getBits(Record, 63, 0, 3, Value);
0218     TaskingBehavior = (GOFF::ESDTaskingBehavior)Value;
0219   }
0220 
0221   static void getReadOnly(const uint8_t *Record, bool &ReadOnly) {
0222     uint8_t Value;
0223     getBits(Record, 63, 4, 1, Value);
0224     ReadOnly = (bool)Value;
0225   }
0226 
0227   static void getExecutable(const uint8_t *Record,
0228                             GOFF::ESDExecutable &Executable) {
0229     uint8_t Value;
0230     getBits(Record, 63, 5, 3, Value);
0231     Executable = (GOFF::ESDExecutable)Value;
0232   }
0233 
0234   static void getDuplicateSeverity(const uint8_t *Record,
0235                                    GOFF::ESDDuplicateSymbolSeverity &DSS) {
0236     uint8_t Value;
0237     getBits(Record, 64, 2, 2, Value);
0238     DSS = (GOFF::ESDDuplicateSymbolSeverity)Value;
0239   }
0240 
0241   static void getBindingStrength(const uint8_t *Record,
0242                                  GOFF::ESDBindingStrength &Strength) {
0243     uint8_t Value;
0244     getBits(Record, 64, 4, 4, Value);
0245     Strength = (GOFF::ESDBindingStrength)Value;
0246   }
0247 
0248   static void getLoadingBehavior(const uint8_t *Record,
0249                                  GOFF::ESDLoadingBehavior &Behavior) {
0250     uint8_t Value;
0251     getBits(Record, 65, 0, 2, Value);
0252     Behavior = (GOFF::ESDLoadingBehavior)Value;
0253   }
0254 
0255   static void getIndirectReference(const uint8_t *Record, bool &Indirect) {
0256     uint8_t Value;
0257     getBits(Record, 65, 3, 1, Value);
0258     Indirect = (bool)Value;
0259   }
0260 
0261   static void getBindingScope(const uint8_t *Record,
0262                               GOFF::ESDBindingScope &Scope) {
0263     uint8_t Value;
0264     getBits(Record, 65, 4, 4, Value);
0265     Scope = (GOFF::ESDBindingScope)Value;
0266   }
0267 
0268   static void getLinkageType(const uint8_t *Record,
0269                              GOFF::ESDLinkageType &Type) {
0270     uint8_t Value;
0271     getBits(Record, 66, 2, 1, Value);
0272     Type = (GOFF::ESDLinkageType)Value;
0273   }
0274 
0275   static void getAlignment(const uint8_t *Record,
0276                            GOFF::ESDAlignment &Alignment) {
0277     uint8_t Value;
0278     getBits(Record, 66, 3, 5, Value);
0279     Alignment = (GOFF::ESDAlignment)Value;
0280   }
0281 
0282   static uint16_t getNameLength(const uint8_t *Record) {
0283     uint16_t Length;
0284     get<uint16_t>(Record, 70, Length);
0285     return Length;
0286   }
0287 };
0288 
0289 class ENDRecord : public Record {
0290 public:
0291   static Error getData(const uint8_t *Record, SmallString<256> &CompleteData);
0292 
0293   static uint16_t getNameLength(const uint8_t *Record) {
0294     uint16_t Length;
0295     get<uint16_t>(Record, 24, Length);
0296     return Length;
0297   }
0298 };
0299 
0300 } // end namespace object
0301 } // end namespace llvm
0302 
0303 #endif