mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[yaml2obj] Initial the support of yaml2obj for 32-bit XCOFF.
Summary: The patch implements the mapping of the Yaml information to XCOFF object file to enable the yaml2obj tool for XCOFF. Currently only 32-bit is supported. Reviewed By: jhenderson, shchenz Differential Revision: https://reviews.llvm.org/D95505
This commit is contained in:
parent
779c968967
commit
4a3c52750c
@ -33,6 +33,8 @@ constexpr uint8_t AllocRegNo = 31;
|
|||||||
|
|
||||||
enum ReservedSectionNum : int16_t { N_DEBUG = -2, N_ABS = -1, N_UNDEF = 0 };
|
enum ReservedSectionNum : int16_t { N_DEBUG = -2, N_ABS = -1, N_UNDEF = 0 };
|
||||||
|
|
||||||
|
enum MagicNumber : uint16_t { XCOFF32 = 0x01DF, XCOFF64 = 0x01F7 };
|
||||||
|
|
||||||
// x_smclas field of x_csect from system header: /usr/include/syms.h
|
// x_smclas field of x_csect from system header: /usr/include/syms.h
|
||||||
/// Storage Mapping Class definitions.
|
/// Storage Mapping Class definitions.
|
||||||
enum StorageMappingClass : uint8_t {
|
enum StorageMappingClass : uint8_t {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "llvm/ObjectYAML/MachOYAML.h"
|
#include "llvm/ObjectYAML/MachOYAML.h"
|
||||||
#include "llvm/ObjectYAML/MinidumpYAML.h"
|
#include "llvm/ObjectYAML/MinidumpYAML.h"
|
||||||
#include "llvm/ObjectYAML/WasmYAML.h"
|
#include "llvm/ObjectYAML/WasmYAML.h"
|
||||||
|
#include "llvm/ObjectYAML/XCOFFYAML.h"
|
||||||
#include "llvm/Support/YAMLTraits.h"
|
#include "llvm/Support/YAMLTraits.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@ -31,6 +32,7 @@ struct YamlObjectFile {
|
|||||||
std::unique_ptr<MachOYAML::UniversalBinary> FatMachO;
|
std::unique_ptr<MachOYAML::UniversalBinary> FatMachO;
|
||||||
std::unique_ptr<MinidumpYAML::Object> Minidump;
|
std::unique_ptr<MinidumpYAML::Object> Minidump;
|
||||||
std::unique_ptr<WasmYAML::Object> Wasm;
|
std::unique_ptr<WasmYAML::Object> Wasm;
|
||||||
|
std::unique_ptr<XCOFFYAML::Object> Xcoff;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct MappingTraits<YamlObjectFile> {
|
template <> struct MappingTraits<YamlObjectFile> {
|
||||||
|
@ -23,32 +23,62 @@ struct FileHeader {
|
|||||||
llvm::yaml::Hex16 Magic;
|
llvm::yaml::Hex16 Magic;
|
||||||
uint16_t NumberOfSections;
|
uint16_t NumberOfSections;
|
||||||
int32_t TimeStamp;
|
int32_t TimeStamp;
|
||||||
llvm::yaml::Hex32 SymbolTableOffset; // File offset to symbol table.
|
llvm::yaml::Hex64 SymbolTableOffset;
|
||||||
int32_t NumberOfSymTableEntries;
|
uint32_t NumberOfSymTableEntries;
|
||||||
uint16_t AuxHeaderSize;
|
uint16_t AuxHeaderSize;
|
||||||
llvm::yaml::Hex16 Flags;
|
llvm::yaml::Hex16 Flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Relocation {
|
||||||
|
llvm::yaml::Hex64 VirtualAddress;
|
||||||
|
llvm::yaml::Hex64 SymbolIndex;
|
||||||
|
llvm::yaml::Hex8 Info;
|
||||||
|
llvm::yaml::Hex8 Type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Section {
|
||||||
|
StringRef SectionName;
|
||||||
|
llvm::yaml::Hex64 Address;
|
||||||
|
llvm::yaml::Hex64 Size;
|
||||||
|
llvm::yaml::Hex64 FileOffsetToData;
|
||||||
|
llvm::yaml::Hex64 FileOffsetToRelocations;
|
||||||
|
llvm::yaml::Hex64 FileOffsetToLineNumbers; // Line number pointer. Not supported yet.
|
||||||
|
llvm::yaml::Hex16 NumberOfRelocations;
|
||||||
|
llvm::yaml::Hex16 NumberOfLineNumbers; // Line number counts. Not supported yet.
|
||||||
|
uint32_t Flags;
|
||||||
|
yaml::BinaryRef SectionData;
|
||||||
|
std::vector<Relocation> Relocations;
|
||||||
|
};
|
||||||
|
|
||||||
struct Symbol {
|
struct Symbol {
|
||||||
StringRef SymbolName;
|
StringRef SymbolName;
|
||||||
llvm::yaml::Hex32 Value; // Symbol value; storage class-dependent.
|
llvm::yaml::Hex64 Value; // Symbol value; storage class-dependent.
|
||||||
StringRef SectionName;
|
StringRef SectionName;
|
||||||
llvm::yaml::Hex16 Type;
|
llvm::yaml::Hex16 Type;
|
||||||
XCOFF::StorageClass StorageClass;
|
XCOFF::StorageClass StorageClass;
|
||||||
uint8_t NumberOfAuxEntries; // Number of auxiliary entries
|
uint8_t NumberOfAuxEntries;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Object {
|
struct Object {
|
||||||
FileHeader Header;
|
FileHeader Header;
|
||||||
|
std::vector<Section> Sections;
|
||||||
std::vector<Symbol> Symbols;
|
std::vector<Symbol> Symbols;
|
||||||
Object();
|
Object();
|
||||||
};
|
};
|
||||||
} // namespace XCOFFYAML
|
} // namespace XCOFFYAML
|
||||||
} // namespace llvm
|
} // namespace llvm
|
||||||
|
|
||||||
LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Symbol)
|
LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Symbol)
|
||||||
|
LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Relocation)
|
||||||
|
LLVM_YAML_IS_SEQUENCE_VECTOR(XCOFFYAML::Section)
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
namespace yaml {
|
namespace yaml {
|
||||||
|
|
||||||
|
template <> struct ScalarBitSetTraits<XCOFF::SectionTypeFlags> {
|
||||||
|
static void bitset(IO &IO, XCOFF::SectionTypeFlags &Value);
|
||||||
|
};
|
||||||
|
|
||||||
template <> struct ScalarEnumerationTraits<XCOFF::StorageClass> {
|
template <> struct ScalarEnumerationTraits<XCOFF::StorageClass> {
|
||||||
static void enumeration(IO &IO, XCOFF::StorageClass &Value);
|
static void enumeration(IO &IO, XCOFF::StorageClass &Value);
|
||||||
};
|
};
|
||||||
@ -57,14 +87,23 @@ template <> struct MappingTraits<XCOFFYAML::FileHeader> {
|
|||||||
static void mapping(IO &IO, XCOFFYAML::FileHeader &H);
|
static void mapping(IO &IO, XCOFFYAML::FileHeader &H);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct MappingTraits<XCOFFYAML::Object> {
|
|
||||||
static void mapping(IO &IO, XCOFFYAML::Object &Obj);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct MappingTraits<XCOFFYAML::Symbol> {
|
template <> struct MappingTraits<XCOFFYAML::Symbol> {
|
||||||
static void mapping(IO &IO, XCOFFYAML::Symbol &S);
|
static void mapping(IO &IO, XCOFFYAML::Symbol &S);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <> struct MappingTraits<XCOFFYAML::Relocation> {
|
||||||
|
static void mapping(IO &IO, XCOFFYAML::Relocation &R);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> struct MappingTraits<XCOFFYAML::Section> {
|
||||||
|
static void mapping(IO &IO, XCOFFYAML::Section &Sec);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> struct MappingTraits<XCOFFYAML::Object> {
|
||||||
|
static void mapping(IO &IO, XCOFFYAML::Object &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace yaml
|
} // namespace yaml
|
||||||
} // namespace llvm
|
} // namespace llvm
|
||||||
|
|
||||||
|
@ -40,6 +40,10 @@ namespace WasmYAML {
|
|||||||
struct Object;
|
struct Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace XCOFFYAML {
|
||||||
|
struct Object;
|
||||||
|
}
|
||||||
|
|
||||||
namespace ArchYAML {
|
namespace ArchYAML {
|
||||||
struct Archive;
|
struct Archive;
|
||||||
}
|
}
|
||||||
@ -58,6 +62,7 @@ bool yaml2macho(YamlObjectFile &Doc, raw_ostream &Out, ErrorHandler EH);
|
|||||||
bool yaml2minidump(MinidumpYAML::Object &Doc, raw_ostream &Out,
|
bool yaml2minidump(MinidumpYAML::Object &Doc, raw_ostream &Out,
|
||||||
ErrorHandler EH);
|
ErrorHandler EH);
|
||||||
bool yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH);
|
bool yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH);
|
||||||
|
bool yaml2xcoff(XCOFFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH);
|
||||||
|
|
||||||
bool convertYAML(Input &YIn, raw_ostream &Out, ErrorHandler ErrHandler,
|
bool convertYAML(Input &YIn, raw_ostream &Out, ErrorHandler ErrHandler,
|
||||||
unsigned DocNum = 1, uint64_t MaxSize = UINT64_MAX);
|
unsigned DocNum = 1, uint64_t MaxSize = UINT64_MAX);
|
||||||
|
@ -18,6 +18,7 @@ add_llvm_component_library(LLVMObjectYAML
|
|||||||
MinidumpYAML.cpp
|
MinidumpYAML.cpp
|
||||||
WasmEmitter.cpp
|
WasmEmitter.cpp
|
||||||
WasmYAML.cpp
|
WasmYAML.cpp
|
||||||
|
XCOFFEmitter.cpp
|
||||||
XCOFFYAML.cpp
|
XCOFFYAML.cpp
|
||||||
YAML.cpp
|
YAML.cpp
|
||||||
yaml2obj.cpp
|
yaml2obj.cpp
|
||||||
|
@ -59,6 +59,9 @@ void MappingTraits<YamlObjectFile>::mapping(IO &IO,
|
|||||||
} else if (IO.mapTag("!WASM")) {
|
} else if (IO.mapTag("!WASM")) {
|
||||||
ObjectFile.Wasm.reset(new WasmYAML::Object());
|
ObjectFile.Wasm.reset(new WasmYAML::Object());
|
||||||
MappingTraits<WasmYAML::Object>::mapping(IO, *ObjectFile.Wasm);
|
MappingTraits<WasmYAML::Object>::mapping(IO, *ObjectFile.Wasm);
|
||||||
|
} else if (IO.mapTag("!XCOFF")) {
|
||||||
|
ObjectFile.Xcoff.reset(new XCOFFYAML::Object());
|
||||||
|
MappingTraits<XCOFFYAML::Object>::mapping(IO, *ObjectFile.Xcoff);
|
||||||
} else if (const Node *N = In.getCurrentNode()) {
|
} else if (const Node *N = In.getCurrentNode()) {
|
||||||
if (N->getRawTag().empty())
|
if (N->getRawTag().empty())
|
||||||
IO.setError("YAML Object File missing document type tag!");
|
IO.setError("YAML Object File missing document type tag!");
|
||||||
|
315
lib/ObjectYAML/XCOFFEmitter.cpp
Normal file
315
lib/ObjectYAML/XCOFFEmitter.cpp
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
//===- yaml2xcoff - Convert YAML to a xcoff object file -------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
///
|
||||||
|
/// \file
|
||||||
|
/// The xcoff component of yaml2obj.
|
||||||
|
///
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
#include "llvm/BinaryFormat/XCOFF.h"
|
||||||
|
#include "llvm/Object/XCOFFObjectFile.h"
|
||||||
|
#include "llvm/ObjectYAML/ObjectYAML.h"
|
||||||
|
#include "llvm/ObjectYAML/yaml2obj.h"
|
||||||
|
#include "llvm/Support/EndianStream.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include "llvm/Support/LEB128.h"
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr unsigned DefaultSectionAlign = 4;
|
||||||
|
constexpr int16_t MaxSectionIndex = INT16_MAX;
|
||||||
|
constexpr uint32_t MaxRawDataSize = UINT32_MAX;
|
||||||
|
|
||||||
|
class XCOFFWriter {
|
||||||
|
public:
|
||||||
|
XCOFFWriter(XCOFFYAML::Object &Obj, raw_ostream &OS, yaml::ErrorHandler EH)
|
||||||
|
: Obj(Obj), W(OS, support::big), ErrHandler(EH) {
|
||||||
|
Is64Bit = Obj.Header.Magic == XCOFF::XCOFF64;
|
||||||
|
}
|
||||||
|
bool writeXCOFF();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool initFileHeader(uint64_t CurrentOffset);
|
||||||
|
bool initSectionHeader(uint64_t &CurrentOffset);
|
||||||
|
bool initRelocations(uint64_t &CurrentOffset);
|
||||||
|
bool assignAddressesAndIndices();
|
||||||
|
void writeFileHeader();
|
||||||
|
void writeSectionHeader();
|
||||||
|
bool writeSectionData();
|
||||||
|
bool writeRelocations();
|
||||||
|
bool writeSymbols();
|
||||||
|
|
||||||
|
XCOFFYAML::Object &Obj;
|
||||||
|
bool Is64Bit = false;
|
||||||
|
support::endian::Writer W;
|
||||||
|
yaml::ErrorHandler ErrHandler;
|
||||||
|
uint64_t StartOffset;
|
||||||
|
// Map the section name to its corrresponding section index.
|
||||||
|
DenseMap<StringRef, int16_t> SectionIndexMap = {
|
||||||
|
{StringRef("N_DEBUG"), XCOFF::N_DEBUG},
|
||||||
|
{StringRef("N_ABS"), XCOFF::N_ABS},
|
||||||
|
{StringRef("N_UNDEF"), XCOFF::N_UNDEF}};
|
||||||
|
XCOFFYAML::FileHeader InitFileHdr = Obj.Header;
|
||||||
|
std::vector<XCOFFYAML::Section> InitSections = Obj.Sections;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void writeName(StringRef StrName, support::endian::Writer W) {
|
||||||
|
char Name[XCOFF::NameSize];
|
||||||
|
memset(Name, 0, XCOFF::NameSize);
|
||||||
|
memcpy(Name, StrName.data(), StrName.size());
|
||||||
|
ArrayRef<char> NameRef(Name, XCOFF::NameSize);
|
||||||
|
W.write(NameRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XCOFFWriter::initRelocations(uint64_t &CurrentOffset) {
|
||||||
|
for (uint16_t I = 0, E = InitSections.size(); I < E; ++I) {
|
||||||
|
if (!InitSections[I].Relocations.empty()) {
|
||||||
|
InitSections[I].NumberOfRelocations = InitSections[I].Relocations.size();
|
||||||
|
InitSections[I].FileOffsetToRelocations = CurrentOffset;
|
||||||
|
CurrentOffset += InitSections[I].NumberOfRelocations *
|
||||||
|
XCOFF::RelocationSerializationSize32;
|
||||||
|
if (CurrentOffset > MaxRawDataSize) {
|
||||||
|
ErrHandler("maximum object size of" + Twine(MaxRawDataSize) +
|
||||||
|
"exceeded when writing relocation data");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XCOFFWriter::initSectionHeader(uint64_t &CurrentOffset) {
|
||||||
|
uint64_t CurrentSecAddr = 0;
|
||||||
|
for (uint16_t I = 0, E = InitSections.size(); I < E; ++I) {
|
||||||
|
if (CurrentOffset > MaxRawDataSize) {
|
||||||
|
ErrHandler("maximum object size of" + Twine(MaxRawDataSize) +
|
||||||
|
"exceeded when writing section data");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign indices for sections.
|
||||||
|
if (InitSections[I].SectionName.size() &&
|
||||||
|
!SectionIndexMap[InitSections[I].SectionName]) {
|
||||||
|
// The section index starts from 1.
|
||||||
|
SectionIndexMap[InitSections[I].SectionName] = I + 1;
|
||||||
|
if ((I + 1) > MaxSectionIndex) {
|
||||||
|
ErrHandler("exceeded the maximum permitted section index of " +
|
||||||
|
Twine(MaxSectionIndex));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// Calculate the FileOffsetToData and data size for sections.
|
||||||
|
if (InitSections[I].SectionData.binary_size()) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return initRelocations(CurrentOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XCOFFWriter::initFileHeader(uint64_t CurrentOffset) {
|
||||||
|
// The default format of the object file is XCOFF32.
|
||||||
|
InitFileHdr.Magic = XCOFF::XCOFF32;
|
||||||
|
InitFileHdr.NumberOfSections = Obj.Sections.size();
|
||||||
|
InitFileHdr.NumberOfSymTableEntries = Obj.Symbols.size();
|
||||||
|
|
||||||
|
for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols) {
|
||||||
|
// Add the number of auxiliary symbols to the total number.
|
||||||
|
InitFileHdr.NumberOfSymTableEntries += YamlSym.NumberOfAuxEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate SymbolTableOffset for the file header.
|
||||||
|
if (InitFileHdr.NumberOfSymTableEntries) {
|
||||||
|
InitFileHdr.SymbolTableOffset = CurrentOffset;
|
||||||
|
CurrentOffset +=
|
||||||
|
InitFileHdr.NumberOfSymTableEntries * XCOFF::SymbolTableEntrySize;
|
||||||
|
if (CurrentOffset > MaxRawDataSize) {
|
||||||
|
ErrHandler("maximum object size of" + Twine(MaxRawDataSize) +
|
||||||
|
"exceeded when writing symbols");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: Calculate FileOffsetToLineNumbers when line number supported.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XCOFFWriter::assignAddressesAndIndices() {
|
||||||
|
uint64_t CurrentOffset =
|
||||||
|
sizeof(XCOFF::FileHeader32) /* TODO: + auxiliaryHeaderSize() */ +
|
||||||
|
InitSections.size() * sizeof(XCOFF::SectionHeader32);
|
||||||
|
|
||||||
|
// Calculate section header info.
|
||||||
|
if (!initSectionHeader(CurrentOffset))
|
||||||
|
return false;
|
||||||
|
// Calculate file header info.
|
||||||
|
return initFileHeader(CurrentOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XCOFFWriter::writeFileHeader() {
|
||||||
|
W.write<uint16_t>(Obj.Header.Magic ? Obj.Header.Magic : InitFileHdr.Magic);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void XCOFFWriter::writeSectionHeader() {
|
||||||
|
for (uint16_t I = 0, E = Obj.Sections.size(); I < E; ++I) {
|
||||||
|
XCOFFYAML::Section YamlSec = Obj.Sections[I];
|
||||||
|
XCOFFYAML::Section DerivedSec = InitSections[I];
|
||||||
|
writeName(YamlSec.SectionName, W);
|
||||||
|
// Virtual address is the same as physical address.
|
||||||
|
uint32_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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XCOFFWriter::writeSectionData() {
|
||||||
|
for (uint16_t I = 0, E = Obj.Sections.size(); I < E; ++I) {
|
||||||
|
XCOFFYAML::Section YamlSec = Obj.Sections[I];
|
||||||
|
if (YamlSec.SectionData.binary_size()) {
|
||||||
|
// Fill the padding size with zeros.
|
||||||
|
int64_t PaddingSize =
|
||||||
|
InitSections[I].FileOffsetToData - (W.OS.tell() - StartOffset);
|
||||||
|
if (PaddingSize < 0) {
|
||||||
|
ErrHandler("redundant data was written before section data");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (PaddingSize > 0)
|
||||||
|
W.OS.write_zeros(PaddingSize);
|
||||||
|
YamlSec.SectionData.writeAsBinary(W.OS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XCOFFWriter::writeRelocations() {
|
||||||
|
for (uint16_t I = 0, E = Obj.Sections.size(); I < E; ++I) {
|
||||||
|
XCOFFYAML::Section YamlSec = Obj.Sections[I];
|
||||||
|
if (!YamlSec.Relocations.empty()) {
|
||||||
|
int64_t PaddingSize =
|
||||||
|
InitSections[I].FileOffsetToRelocations - (W.OS.tell() - StartOffset);
|
||||||
|
if (PaddingSize < 0) {
|
||||||
|
ErrHandler("redundant data was written before relocations");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (PaddingSize > 0)
|
||||||
|
W.OS.write_zeros(PaddingSize);
|
||||||
|
for (const XCOFFYAML::Relocation &YamlRel : YamlSec.Relocations) {
|
||||||
|
W.write<uint32_t>(YamlRel.VirtualAddress);
|
||||||
|
W.write<uint32_t>(YamlRel.SymbolIndex);
|
||||||
|
W.write<uint8_t>(YamlRel.Info);
|
||||||
|
W.write<uint8_t>(YamlRel.Type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XCOFFWriter::writeSymbols() {
|
||||||
|
int64_t PaddingSize =
|
||||||
|
(uint64_t)InitFileHdr.SymbolTableOffset - (W.OS.tell() - StartOffset);
|
||||||
|
if (PaddingSize < 0) {
|
||||||
|
ErrHandler("redundant data was written before symbols");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (PaddingSize > 0)
|
||||||
|
W.OS.write_zeros(PaddingSize);
|
||||||
|
for (const XCOFFYAML::Symbol &YamlSym : Obj.Symbols) {
|
||||||
|
writeName(YamlSym.SymbolName, W);
|
||||||
|
W.write<uint32_t>(YamlSym.Value);
|
||||||
|
W.write<int16_t>(
|
||||||
|
YamlSym.SectionName.size() ? SectionIndexMap[YamlSym.SectionName] : 0);
|
||||||
|
W.write<uint16_t>(YamlSym.Type);
|
||||||
|
W.write<uint8_t>(YamlSym.StorageClass);
|
||||||
|
W.write<uint8_t>(YamlSym.NumberOfAuxEntries);
|
||||||
|
|
||||||
|
// Now output the auxiliary entry.
|
||||||
|
for (uint8_t I = 0, E = YamlSym.NumberOfAuxEntries; I < E; ++I) {
|
||||||
|
// TODO: Auxiliary entry is not supported yet.
|
||||||
|
// The auxiliary entries for a symbol follow its symbol table entry. The
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool XCOFFWriter::writeXCOFF() {
|
||||||
|
if (Is64Bit) {
|
||||||
|
ErrHandler("only XCOFF32 is currently supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!assignAddressesAndIndices())
|
||||||
|
return false;
|
||||||
|
StartOffset = W.OS.tell();
|
||||||
|
writeFileHeader();
|
||||||
|
if (!Obj.Sections.empty()) {
|
||||||
|
writeSectionHeader();
|
||||||
|
if (!writeSectionData())
|
||||||
|
return false;
|
||||||
|
if (!writeRelocations())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!Obj.Symbols.empty())
|
||||||
|
return writeSymbols();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace yaml {
|
||||||
|
|
||||||
|
bool yaml2xcoff(XCOFFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH) {
|
||||||
|
XCOFFWriter Writer(Doc, Out, EH);
|
||||||
|
return Writer.writeXCOFF();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace yaml
|
||||||
|
} // namespace llvm
|
@ -23,6 +23,25 @@ Object::Object() { memset(&Header, 0, sizeof(Header)); }
|
|||||||
|
|
||||||
namespace yaml {
|
namespace yaml {
|
||||||
|
|
||||||
|
void ScalarBitSetTraits<XCOFF::SectionTypeFlags>::bitset(
|
||||||
|
IO &IO, XCOFF::SectionTypeFlags &Value) {
|
||||||
|
#define ECase(X) IO.bitSetCase(Value, #X, XCOFF::X)
|
||||||
|
ECase(STYP_PAD);
|
||||||
|
ECase(STYP_DWARF);
|
||||||
|
ECase(STYP_TEXT);
|
||||||
|
ECase(STYP_DATA);
|
||||||
|
ECase(STYP_BSS);
|
||||||
|
ECase(STYP_EXCEPT);
|
||||||
|
ECase(STYP_INFO);
|
||||||
|
ECase(STYP_TDATA);
|
||||||
|
ECase(STYP_TBSS);
|
||||||
|
ECase(STYP_LOADER);
|
||||||
|
ECase(STYP_DEBUG);
|
||||||
|
ECase(STYP_TYPCHK);
|
||||||
|
ECase(STYP_OVRFLO);
|
||||||
|
#undef ECase
|
||||||
|
}
|
||||||
|
|
||||||
void ScalarEnumerationTraits<XCOFF::StorageClass>::enumeration(
|
void ScalarEnumerationTraits<XCOFF::StorageClass>::enumeration(
|
||||||
IO &IO, XCOFF::StorageClass &Value) {
|
IO &IO, XCOFF::StorageClass &Value) {
|
||||||
#define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
|
#define ECase(X) IO.enumCase(Value, #X, XCOFF::X)
|
||||||
@ -79,30 +98,64 @@ void ScalarEnumerationTraits<XCOFF::StorageClass>::enumeration(
|
|||||||
#undef ECase
|
#undef ECase
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct NSectionFlags {
|
||||||
|
NSectionFlags(IO &) : Flags(XCOFF::SectionTypeFlags(0)) {}
|
||||||
|
NSectionFlags(IO &, uint32_t C) : Flags(XCOFF::SectionTypeFlags(C)) {}
|
||||||
|
|
||||||
|
uint32_t denormalize(IO &) { return Flags; }
|
||||||
|
|
||||||
|
XCOFF::SectionTypeFlags Flags;
|
||||||
|
};
|
||||||
|
|
||||||
void MappingTraits<XCOFFYAML::FileHeader>::mapping(
|
void MappingTraits<XCOFFYAML::FileHeader>::mapping(
|
||||||
IO &IO, XCOFFYAML::FileHeader &FileHdr) {
|
IO &IO, XCOFFYAML::FileHeader &FileHdr) {
|
||||||
IO.mapRequired("MagicNumber", FileHdr.Magic);
|
IO.mapOptional("MagicNumber", FileHdr.Magic);
|
||||||
IO.mapRequired("NumberOfSections", FileHdr.NumberOfSections);
|
IO.mapOptional("NumberOfSections", FileHdr.NumberOfSections);
|
||||||
IO.mapRequired("CreationTime", FileHdr.TimeStamp);
|
IO.mapOptional("CreationTime", FileHdr.TimeStamp);
|
||||||
IO.mapRequired("OffsetToSymbolTable", FileHdr.SymbolTableOffset);
|
IO.mapOptional("OffsetToSymbolTable", FileHdr.SymbolTableOffset);
|
||||||
IO.mapRequired("EntriesInSymbolTable", FileHdr.NumberOfSymTableEntries);
|
IO.mapOptional("EntriesInSymbolTable", FileHdr.NumberOfSymTableEntries);
|
||||||
IO.mapRequired("AuxiliaryHeaderSize", FileHdr.AuxHeaderSize);
|
IO.mapOptional("AuxiliaryHeaderSize", FileHdr.AuxHeaderSize);
|
||||||
IO.mapRequired("Flags", FileHdr.Flags);
|
IO.mapOptional("Flags", FileHdr.Flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MappingTraits<XCOFFYAML::Relocation>::mapping(IO &IO,
|
||||||
|
XCOFFYAML::Relocation &R) {
|
||||||
|
IO.mapOptional("Address", R.VirtualAddress);
|
||||||
|
IO.mapOptional("Symbol", R.SymbolIndex);
|
||||||
|
IO.mapOptional("Info", R.Info);
|
||||||
|
IO.mapOptional("Type", R.Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MappingTraits<XCOFFYAML::Section>::mapping(IO &IO,
|
||||||
|
XCOFFYAML::Section &Sec) {
|
||||||
|
MappingNormalization<NSectionFlags, uint32_t> NC(IO, Sec.Flags);
|
||||||
|
IO.mapOptional("Name", Sec.SectionName);
|
||||||
|
IO.mapOptional("Address", Sec.Address);
|
||||||
|
IO.mapOptional("Size", Sec.Size);
|
||||||
|
IO.mapOptional("FileOffsetToData", Sec.FileOffsetToData);
|
||||||
|
IO.mapOptional("FileOffsetToRelocations", Sec.FileOffsetToRelocations);
|
||||||
|
IO.mapOptional("FileOffsetToLineNumbers", Sec.FileOffsetToLineNumbers);
|
||||||
|
IO.mapOptional("NumberOfRelocations", Sec.NumberOfRelocations);
|
||||||
|
IO.mapOptional("NumberOfLineNumbers", Sec.NumberOfLineNumbers);
|
||||||
|
IO.mapOptional("Flags", NC->Flags);
|
||||||
|
IO.mapOptional("SectionData", Sec.SectionData);
|
||||||
|
IO.mapOptional("Relocations", Sec.Relocations);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MappingTraits<XCOFFYAML::Symbol>::mapping(IO &IO, XCOFFYAML::Symbol &S) {
|
void MappingTraits<XCOFFYAML::Symbol>::mapping(IO &IO, XCOFFYAML::Symbol &S) {
|
||||||
IO.mapRequired("Name", S.SymbolName);
|
IO.mapRequired("Name", S.SymbolName);
|
||||||
IO.mapRequired("Value", S.Value);
|
IO.mapOptional("Value", S.Value);
|
||||||
IO.mapRequired("Section", S.SectionName);
|
IO.mapOptional("Section", S.SectionName);
|
||||||
IO.mapRequired("Type", S.Type);
|
IO.mapOptional("Type", S.Type);
|
||||||
IO.mapRequired("StorageClass", S.StorageClass);
|
IO.mapOptional("StorageClass", S.StorageClass);
|
||||||
IO.mapRequired("NumberOfAuxEntries", S.NumberOfAuxEntries);
|
IO.mapOptional("NumberOfAuxEntries", S.NumberOfAuxEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MappingTraits<XCOFFYAML::Object>::mapping(IO &IO, XCOFFYAML::Object &Obj) {
|
void MappingTraits<XCOFFYAML::Object>::mapping(IO &IO, XCOFFYAML::Object &Obj) {
|
||||||
IO.mapTag("!XCOFF", true);
|
IO.mapTag("!XCOFF", true);
|
||||||
IO.mapRequired("FileHeader", Obj.Header);
|
IO.mapRequired("FileHeader", Obj.Header);
|
||||||
IO.mapRequired("Symbols", Obj.Symbols);
|
IO.mapOptional("Sections", Obj.Sections);
|
||||||
|
IO.mapOptional("Symbols", Obj.Symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace yaml
|
} // namespace yaml
|
||||||
|
@ -44,6 +44,8 @@ bool convertYAML(yaml::Input &YIn, raw_ostream &Out, ErrorHandler ErrHandler,
|
|||||||
return yaml2minidump(*Doc.Minidump, Out, ErrHandler);
|
return yaml2minidump(*Doc.Minidump, Out, ErrHandler);
|
||||||
if (Doc.Wasm)
|
if (Doc.Wasm)
|
||||||
return yaml2wasm(*Doc.Wasm, Out, ErrHandler);
|
return yaml2wasm(*Doc.Wasm, Out, ErrHandler);
|
||||||
|
if (Doc.Xcoff)
|
||||||
|
return yaml2xcoff(*Doc.Xcoff, Out, ErrHandler);
|
||||||
|
|
||||||
ErrHandler("unknown document type");
|
ErrHandler("unknown document type");
|
||||||
return false;
|
return false;
|
||||||
|
164
test/tools/yaml2obj/XCOFF/basic-doc.yaml
Normal file
164
test/tools/yaml2obj/XCOFF/basic-doc.yaml
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
## Check that yaml2obj automatically assigns omited fields with values.
|
||||||
|
# RUN: yaml2obj %s -o %t
|
||||||
|
# RUN: llvm-readobj --headers --symbols %t | FileCheck %s
|
||||||
|
|
||||||
|
--- !XCOFF
|
||||||
|
FileHeader:
|
||||||
|
MagicNumber: 0x1DF
|
||||||
|
Sections:
|
||||||
|
- Name: .text
|
||||||
|
Flags: [ STYP_TEXT ]
|
||||||
|
SectionData: "9061FFF880820000"
|
||||||
|
- Name: .data
|
||||||
|
Flags: [ STYP_DATA ]
|
||||||
|
SectionData: "0000000000000FC0"
|
||||||
|
Relocations:
|
||||||
|
- Address: 0x08
|
||||||
|
- Name: .data
|
||||||
|
Relocations:
|
||||||
|
- Type: 0x02
|
||||||
|
- Name: .debug
|
||||||
|
Address: 0x0
|
||||||
|
Size: 0x60
|
||||||
|
Flags: [ STYP_DEBUG, STYP_DATA ]
|
||||||
|
SectionData: 01110103
|
||||||
|
- Flags: [ STYP_BSS, STYP_DWARF, STYP_EXCEPT, STYP_INFO, STYP_TDATA, STYP_TBSS, STYP_LOADER, STYP_TYPCHK, STYP_OVRFLO ]
|
||||||
|
Symbols:
|
||||||
|
- Name: .file
|
||||||
|
Section: N_DEBUG
|
||||||
|
- Name: .undef
|
||||||
|
- Name: .abs
|
||||||
|
Section: N_ABS
|
||||||
|
- Name: .text
|
||||||
|
Value: 0x0
|
||||||
|
Section: .text
|
||||||
|
Type: 0x0
|
||||||
|
StorageClass: C_HIDEXT
|
||||||
|
NumberOfAuxEntries: 1
|
||||||
|
|
||||||
|
# CHECK: AddressSize: 32bit
|
||||||
|
# CHECK-NEXT: FileHeader {
|
||||||
|
# CHECK-NEXT: Magic: 0x1DF
|
||||||
|
# CHECK-NEXT: NumberOfSections: 5
|
||||||
|
# CHECK-NEXT: TimeStamp: None (0x0)
|
||||||
|
# CHECK-NEXT: SymbolTableOffset: 0x104
|
||||||
|
# CHECK-NEXT: SymbolTableEntries: 5
|
||||||
|
# CHECK-NEXT: OptionalHeaderSize: 0x0
|
||||||
|
# CHECK-NEXT: Flags: 0x0
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: Sections [
|
||||||
|
# CHECK-NEXT: Section {
|
||||||
|
# CHECK-NEXT: Index: 1
|
||||||
|
# CHECK-NEXT: Name: .text
|
||||||
|
# CHECK-NEXT: PhysicalAddress: 0x0
|
||||||
|
# CHECK-NEXT: VirtualAddress: 0x0
|
||||||
|
# CHECK-NEXT: Size: 0x8
|
||||||
|
# CHECK-NEXT: RawDataOffset: 0xDC
|
||||||
|
# CHECK-NEXT: RelocationPointer: 0x0
|
||||||
|
# CHECK-NEXT: LineNumberPointer: 0x0
|
||||||
|
# CHECK-NEXT: NumberOfRelocations: 0
|
||||||
|
# CHECK-NEXT: NumberOfLineNumbers: 0
|
||||||
|
# CHECK-NEXT: Type: STYP_TEXT (0x20)
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: Section {
|
||||||
|
# CHECK-NEXT: Index: 2
|
||||||
|
# CHECK-NEXT: Name: .data
|
||||||
|
# CHECK-NEXT: PhysicalAddress: 0x8
|
||||||
|
# CHECK-NEXT: VirtualAddress: 0x8
|
||||||
|
# CHECK-NEXT: Size: 0x8
|
||||||
|
# CHECK-NEXT: RawDataOffset: 0xE4
|
||||||
|
# CHECK-NEXT: RelocationPointer: 0xF0
|
||||||
|
# CHECK-NEXT: LineNumberPointer: 0x0
|
||||||
|
# CHECK-NEXT: NumberOfRelocations: 1
|
||||||
|
# CHECK-NEXT: NumberOfLineNumbers: 0
|
||||||
|
# CHECK-NEXT: Type: STYP_DATA (0x40)
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: Section {
|
||||||
|
# CHECK-NEXT: Index: 3
|
||||||
|
# CHECK-NEXT: Name: .data
|
||||||
|
# CHECK-NEXT: PhysicalAddress: 0x0
|
||||||
|
# CHECK-NEXT: VirtualAddress: 0x0
|
||||||
|
# CHECK-NEXT: Size: 0x0
|
||||||
|
# CHECK-NEXT: RawDataOffset: 0x0
|
||||||
|
# CHECK-NEXT: RelocationPointer: 0xFA
|
||||||
|
# CHECK-NEXT: LineNumberPointer: 0x0
|
||||||
|
# CHECK-NEXT: NumberOfRelocations: 1
|
||||||
|
# CHECK-NEXT: NumberOfLineNumbers: 0
|
||||||
|
# CHECK-NEXT: Type: 0x0
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: Section {
|
||||||
|
# CHECK-NEXT: Index: 4
|
||||||
|
# CHECK-NEXT: Name: .debug
|
||||||
|
# CHECK-NEXT: PhysicalAddress: 0x0
|
||||||
|
# CHECK-NEXT: VirtualAddress: 0x0
|
||||||
|
# CHECK-NEXT: Size: 0x60
|
||||||
|
# CHECK-NEXT: RawDataOffset: 0xEC
|
||||||
|
# CHECK-NEXT: RelocationPointer: 0x0
|
||||||
|
# CHECK-NEXT: LineNumberPointer: 0x0
|
||||||
|
# CHECK-NEXT: NumberOfRelocations: 0
|
||||||
|
# CHECK-NEXT: NumberOfLineNumbers: 0
|
||||||
|
# CHECK-NEXT: Type: 0x2040
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: Section {
|
||||||
|
# CHECK-NEXT: Index: 5
|
||||||
|
# CHECK-NEXT: Name:
|
||||||
|
# CHECK-NEXT: PhysicalAddress: 0x0
|
||||||
|
# CHECK-NEXT: VirtualAddress: 0x0
|
||||||
|
# CHECK-NEXT: Size: 0x0
|
||||||
|
# CHECK-NEXT: RawDataOffset: 0x0
|
||||||
|
# CHECK-NEXT: RelocationPointer: 0x0
|
||||||
|
# CHECK-NEXT: LineNumberPointer: 0x0
|
||||||
|
# CHECK-NEXT: NumberOfRelocations: 0
|
||||||
|
# CHECK-NEXT: NumberOfLineNumbers: 0
|
||||||
|
# CHECK-NEXT: Type: 0xDF90
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: ]
|
||||||
|
# CHECK-NEXT: Symbols [
|
||||||
|
# CHECK-NEXT: Symbol {
|
||||||
|
# CHECK-NEXT: Index: 0
|
||||||
|
# CHECK-NEXT: Name: .file
|
||||||
|
# CHECK-NEXT: Value: 0x0
|
||||||
|
# CHECK-NEXT: Section: N_DEBUG
|
||||||
|
# CHECK-NEXT: Type: 0x0
|
||||||
|
# CHECK-NEXT: StorageClass: C_NULL (0x0)
|
||||||
|
# CHECK-NEXT: NumberOfAuxEntries: 0
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: Symbol {
|
||||||
|
# CHECK-NEXT: Index: 1
|
||||||
|
# CHECK-NEXT: Name: .undef
|
||||||
|
# CHECK-NEXT: Value: 0x0
|
||||||
|
# CHECK-NEXT: Section: N_UNDEF
|
||||||
|
# CHECK-NEXT: Type: 0x0
|
||||||
|
# CHECK-NEXT: StorageClass: C_NULL (0x0)
|
||||||
|
# CHECK-NEXT: NumberOfAuxEntries: 0
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: Symbol {
|
||||||
|
# CHECK-NEXT: Index: 2
|
||||||
|
# CHECK-NEXT: Name: .abs
|
||||||
|
# CHECK-NEXT: Value: 0x0
|
||||||
|
# CHECK-NEXT: Section: N_ABS
|
||||||
|
# CHECK-NEXT: Type: 0x0
|
||||||
|
# CHECK-NEXT: StorageClass: C_NULL (0x0)
|
||||||
|
# CHECK-NEXT: NumberOfAuxEntries: 0
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: Symbol {
|
||||||
|
# CHECK-NEXT: Index: 3
|
||||||
|
# CHECK-NEXT: Name: .text
|
||||||
|
# CHECK-NEXT: Value (RelocatableAddress): 0x0
|
||||||
|
# CHECK-NEXT: Section: .text
|
||||||
|
# CHECK-NEXT: Type: 0x0
|
||||||
|
# CHECK-NEXT: StorageClass: C_HIDEXT (0x6B)
|
||||||
|
# CHECK-NEXT: NumberOfAuxEntries: 1
|
||||||
|
# CHECK-NEXT: CSECT Auxiliary Entry {
|
||||||
|
# CHECK-NEXT: Index: 4
|
||||||
|
# CHECK-NEXT: SectionLen: 0
|
||||||
|
# CHECK-NEXT: ParameterHashIndex: 0x0
|
||||||
|
# CHECK-NEXT: TypeChkSectNum: 0x0
|
||||||
|
# CHECK-NEXT: SymbolAlignmentLog2: 0
|
||||||
|
# CHECK-NEXT: SymbolType: XTY_ER (0x0)
|
||||||
|
# CHECK-NEXT: StorageMappingClass: XMC_PR (0x0)
|
||||||
|
# CHECK-NEXT: StabInfoIndex: 0x0
|
||||||
|
# CHECK-NEXT: StabSectNum: 0x0
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: ]
|
122
test/tools/yaml2obj/XCOFF/full-contents.yaml
Normal file
122
test/tools/yaml2obj/XCOFF/full-contents.yaml
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
## Test that we can explicitly specify all the fields.
|
||||||
|
# RUN: yaml2obj %s -o %t
|
||||||
|
# RUN: llvm-readobj --headers --symbols %t | FileCheck %s
|
||||||
|
|
||||||
|
--- !XCOFF
|
||||||
|
FileHeader:
|
||||||
|
MagicNumber: 0x1DF
|
||||||
|
NumberOfSections: 2
|
||||||
|
CreationTime: 0
|
||||||
|
OffsetToSymbolTable: 0x7A
|
||||||
|
EntriesInSymbolTable: 4
|
||||||
|
AuxiliaryHeaderSize: 0
|
||||||
|
Flags: 0x0
|
||||||
|
Sections:
|
||||||
|
- Name: .text
|
||||||
|
Address: 0x0
|
||||||
|
Size: 0x8
|
||||||
|
FileOffsetToData: 0x64
|
||||||
|
FileOffsetToRelocations: 0x0
|
||||||
|
FileOffsetToLineNumbers: 0x0
|
||||||
|
NumberOfRelocations: 0x0
|
||||||
|
NumberOfLineNumbers: 0x0
|
||||||
|
Flags: [ STYP_TEXT ]
|
||||||
|
SectionData: "3860000048"
|
||||||
|
- Name: .data
|
||||||
|
Address: 0x8
|
||||||
|
Size: 0x4
|
||||||
|
FileOffsetToData: 0x6C
|
||||||
|
FileOffsetToRelocations: 0x70
|
||||||
|
FileOffsetToLineNumbers: 0x0
|
||||||
|
NumberOfRelocations: 0x1
|
||||||
|
NumberOfLineNumbers: 0x0
|
||||||
|
Flags: [ STYP_DATA ]
|
||||||
|
SectionData: "00000088"
|
||||||
|
Relocations:
|
||||||
|
- Address: 0x80
|
||||||
|
Symbol: 0x21
|
||||||
|
Info: 0x1F
|
||||||
|
Type: 0x0
|
||||||
|
Symbols:
|
||||||
|
- Name: .text
|
||||||
|
Value: 0x0
|
||||||
|
Section: .text
|
||||||
|
Type: 0x0
|
||||||
|
StorageClass: C_STAT
|
||||||
|
NumberOfAuxEntries: 1
|
||||||
|
- Name: .data
|
||||||
|
Value: 0x80
|
||||||
|
Section: .data
|
||||||
|
Type: 0x0
|
||||||
|
StorageClass: C_STAT
|
||||||
|
NumberOfAuxEntries: 1
|
||||||
|
|
||||||
|
# CHECK: FileHeader {
|
||||||
|
# CHECK-NEXT: Magic: 0x1DF
|
||||||
|
# CHECK-NEXT: NumberOfSections: 2
|
||||||
|
# CHECK-NEXT: TimeStamp: None (0x0)
|
||||||
|
# CHECK-NEXT: SymbolTableOffset: 0x7A
|
||||||
|
# CHECK-NEXT: SymbolTableEntries: 4
|
||||||
|
# CHECK-NEXT: OptionalHeaderSize: 0x0
|
||||||
|
# CHECK-NEXT: Flags: 0x0
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: Sections [
|
||||||
|
# CHECK-NEXT: Section {
|
||||||
|
# CHECK-NEXT: Index: 1
|
||||||
|
# CHECK-NEXT: Name: .text
|
||||||
|
# CHECK-NEXT: PhysicalAddress: 0x0
|
||||||
|
# CHECK-NEXT: VirtualAddress: 0x0
|
||||||
|
# CHECK-NEXT: Size: 0x8
|
||||||
|
# CHECK-NEXT: RawDataOffset: 0x64
|
||||||
|
# CHECK-NEXT: RelocationPointer: 0x0
|
||||||
|
# CHECK-NEXT: LineNumberPointer: 0x0
|
||||||
|
# CHECK-NEXT: NumberOfRelocations: 0
|
||||||
|
# CHECK-NEXT: NumberOfLineNumbers: 0
|
||||||
|
# CHECK-NEXT: Type: STYP_TEXT (0x20)
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: Section {
|
||||||
|
# CHECK-NEXT: Index: 2
|
||||||
|
# CHECK-NEXT: Name: .data
|
||||||
|
# CHECK-NEXT: PhysicalAddress: 0x8
|
||||||
|
# CHECK-NEXT: VirtualAddress: 0x8
|
||||||
|
# CHECK-NEXT: Size: 0x4
|
||||||
|
# CHECK-NEXT: RawDataOffset: 0x6C
|
||||||
|
# CHECK-NEXT: RelocationPointer: 0x70
|
||||||
|
# CHECK-NEXT: LineNumberPointer: 0x0
|
||||||
|
# CHECK-NEXT: NumberOfRelocations: 1
|
||||||
|
# CHECK-NEXT: NumberOfLineNumbers: 0
|
||||||
|
# CHECK-NEXT: Type: STYP_DATA (0x40)
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: ]
|
||||||
|
# CHECK-NEXT: Symbols [
|
||||||
|
# CHECK-NEXT: Symbol {
|
||||||
|
# CHECK-NEXT: Index: 0
|
||||||
|
# CHECK-NEXT: Name: .text
|
||||||
|
# CHECK-NEXT: Value (RelocatableAddress): 0x0
|
||||||
|
# CHECK-NEXT: Section: .text
|
||||||
|
# CHECK-NEXT: Type: 0x0
|
||||||
|
# CHECK-NEXT: StorageClass: C_STAT (0x3)
|
||||||
|
# CHECK-NEXT: NumberOfAuxEntries: 1
|
||||||
|
# CHECK-NEXT: Sect Auxiliary Entry For Stat {
|
||||||
|
# CHECK-NEXT: Index: 1
|
||||||
|
# CHECK-NEXT: SectionLength: 0
|
||||||
|
# CHECK-NEXT: NumberOfRelocEnt: 0
|
||||||
|
# CHECK-NEXT: NumberOfLineNum: 0
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: Symbol {
|
||||||
|
# CHECK-NEXT: Index: 2
|
||||||
|
# CHECK-NEXT: Name: .data
|
||||||
|
# CHECK-NEXT: Value (RelocatableAddress): 0x80
|
||||||
|
# CHECK-NEXT: Section: .data
|
||||||
|
# CHECK-NEXT: Type: 0x0
|
||||||
|
# CHECK-NEXT: StorageClass: C_STAT (0x3)
|
||||||
|
# CHECK-NEXT: NumberOfAuxEntries: 1
|
||||||
|
# CHECK-NEXT: Sect Auxiliary Entry For Stat {
|
||||||
|
# CHECK-NEXT: Index: 3
|
||||||
|
# CHECK-NEXT: SectionLength: 0
|
||||||
|
# CHECK-NEXT: NumberOfRelocEnt: 0
|
||||||
|
# CHECK-NEXT: NumberOfLineNum: 0
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: }
|
||||||
|
# CHECK-NEXT: ]
|
@ -26,6 +26,7 @@ static_library("ObjectYAML") {
|
|||||||
"ObjectYAML.cpp",
|
"ObjectYAML.cpp",
|
||||||
"WasmEmitter.cpp",
|
"WasmEmitter.cpp",
|
||||||
"WasmYAML.cpp",
|
"WasmYAML.cpp",
|
||||||
|
"XCOFFEmitter.cpp"
|
||||||
"XCOFFYAML.cpp",
|
"XCOFFYAML.cpp",
|
||||||
"YAML.cpp",
|
"YAML.cpp",
|
||||||
"yaml2obj.cpp",
|
"yaml2obj.cpp",
|
||||||
|
Loading…
Reference in New Issue
Block a user