mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-20 14:29:27 +00:00
Don't allocate temporary string for section data.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183040 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
47afc19625
commit
05bc4a6f20
@ -36,10 +36,34 @@ inline SectionCharacteristics operator|(SectionCharacteristics a,
|
|||||||
// The structure of the yaml files is not an exact 1:1 match to COFF. In order
|
// The structure of the yaml files is not an exact 1:1 match to COFF. In order
|
||||||
// to use yaml::IO, we use these structures which are closer to the source.
|
// to use yaml::IO, we use these structures which are closer to the source.
|
||||||
namespace COFFYAML {
|
namespace COFFYAML {
|
||||||
|
/// In an object file this is just a binary blob. In an yaml file it is an hex
|
||||||
|
/// string. Using this avoid having to allocate temporary strings.
|
||||||
|
/// FIXME: not COFF specific.
|
||||||
|
class BinaryRef {
|
||||||
|
union {
|
||||||
|
ArrayRef<uint8_t> BinaryData;
|
||||||
|
StringRef HexData;
|
||||||
|
};
|
||||||
|
bool isBinary;
|
||||||
|
public:
|
||||||
|
BinaryRef(ArrayRef<uint8_t> BinaryData)
|
||||||
|
: BinaryData(BinaryData), isBinary(true) {}
|
||||||
|
BinaryRef(StringRef HexData) : HexData(HexData), isBinary(false) {}
|
||||||
|
BinaryRef() : isBinary(false) {}
|
||||||
|
StringRef getHex() const {
|
||||||
|
assert(!isBinary);
|
||||||
|
return HexData;
|
||||||
|
}
|
||||||
|
ArrayRef<uint8_t> getBinary() const {
|
||||||
|
assert(isBinary);
|
||||||
|
return BinaryData;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct Section {
|
struct Section {
|
||||||
COFF::section Header;
|
COFF::section Header;
|
||||||
unsigned Alignment;
|
unsigned Alignment;
|
||||||
StringRef SectionData;
|
BinaryRef SectionData;
|
||||||
std::vector<COFF::relocation> Relocations;
|
std::vector<COFF::relocation> Relocations;
|
||||||
StringRef Name;
|
StringRef Name;
|
||||||
Section();
|
Section();
|
||||||
@ -49,7 +73,7 @@ namespace COFFYAML {
|
|||||||
COFF::symbol Header;
|
COFF::symbol Header;
|
||||||
COFF::SymbolBaseType SimpleType;
|
COFF::SymbolBaseType SimpleType;
|
||||||
COFF::SymbolComplexType ComplexType;
|
COFF::SymbolComplexType ComplexType;
|
||||||
StringRef AuxiliaryData;
|
BinaryRef AuxiliaryData;
|
||||||
StringRef Name;
|
StringRef Name;
|
||||||
Symbol();
|
Symbol();
|
||||||
};
|
};
|
||||||
@ -70,6 +94,12 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(COFF::relocation)
|
|||||||
namespace llvm {
|
namespace llvm {
|
||||||
namespace yaml {
|
namespace yaml {
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ScalarTraits<COFFYAML::BinaryRef> {
|
||||||
|
static void output(const COFFYAML::BinaryRef &, void*, llvm::raw_ostream &);
|
||||||
|
static StringRef input(StringRef, void*, COFFYAML::BinaryRef &);
|
||||||
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct ScalarEnumerationTraits<COFF::MachineTypes> {
|
struct ScalarEnumerationTraits<COFF::MachineTypes> {
|
||||||
static void enumeration(IO &IO, COFF::MachineTypes &Value);
|
static void enumeration(IO &IO, COFF::MachineTypes &Value);
|
||||||
|
@ -229,6 +229,23 @@ struct NType {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScalarTraits<COFFYAML::BinaryRef>::output(const COFFYAML::BinaryRef &Val,
|
||||||
|
void *, llvm::raw_ostream &Out) {
|
||||||
|
ArrayRef<uint8_t> Data = Val.getBinary();
|
||||||
|
for (ArrayRef<uint8_t>::iterator I = Data.begin(), E = Data.end(); I != E;
|
||||||
|
++I) {
|
||||||
|
uint8_t Byte = *I;
|
||||||
|
Out << hexdigit(Byte >> 4);
|
||||||
|
Out << hexdigit(Byte & 0xf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StringRef ScalarTraits<COFFYAML::BinaryRef>::input(StringRef Scalar, void *,
|
||||||
|
COFFYAML::BinaryRef &Val) {
|
||||||
|
Val = COFFYAML::BinaryRef(Scalar);
|
||||||
|
return StringRef();
|
||||||
|
}
|
||||||
|
|
||||||
void MappingTraits<COFF::relocation>::mapping(IO &IO, COFF::relocation &Rel) {
|
void MappingTraits<COFF::relocation>::mapping(IO &IO, COFF::relocation &Rel) {
|
||||||
MappingNormalization<NType, uint16_t> NT(IO, Rel.Type);
|
MappingNormalization<NType, uint16_t> NT(IO, Rel.Type);
|
||||||
|
|
||||||
|
@ -13,8 +13,6 @@
|
|||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/YAMLTraits.h"
|
#include "llvm/Support/YAMLTraits.h"
|
||||||
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -25,8 +23,6 @@ class COFFDumper {
|
|||||||
void dumpHeader(const object::coff_file_header *Header);
|
void dumpHeader(const object::coff_file_header *Header);
|
||||||
void dumpSections(unsigned numSections);
|
void dumpSections(unsigned numSections);
|
||||||
void dumpSymbols(unsigned numSymbols);
|
void dumpSymbols(unsigned numSymbols);
|
||||||
StringRef getHexString(ArrayRef<uint8_t> Data);
|
|
||||||
std::list<std::string> Strings;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
COFFDumper(const object::COFFObjectFile &Obj);
|
COFFDumper(const object::COFFObjectFile &Obj);
|
||||||
@ -68,7 +64,7 @@ void COFFDumper::dumpSections(unsigned NumSections) {
|
|||||||
|
|
||||||
ArrayRef<uint8_t> sectionData;
|
ArrayRef<uint8_t> sectionData;
|
||||||
Obj.getSectionContents(Sect, sectionData);
|
Obj.getSectionContents(Sect, sectionData);
|
||||||
Sec.SectionData = getHexString(sectionData);
|
Sec.SectionData = COFFYAML::BinaryRef(sectionData);
|
||||||
|
|
||||||
std::vector<COFF::relocation> Relocations;
|
std::vector<COFF::relocation> Relocations;
|
||||||
for (object::relocation_iterator rIter = iter->begin_relocations();
|
for (object::relocation_iterator rIter = iter->begin_relocations();
|
||||||
@ -100,23 +96,11 @@ void COFFDumper::dumpSymbols(unsigned NumSymbols) {
|
|||||||
Sym.Header.Value = Symbol->Value;
|
Sym.Header.Value = Symbol->Value;
|
||||||
Sym.Header.SectionNumber = Symbol->SectionNumber;
|
Sym.Header.SectionNumber = Symbol->SectionNumber;
|
||||||
Sym.Header.NumberOfAuxSymbols = Symbol->NumberOfAuxSymbols;
|
Sym.Header.NumberOfAuxSymbols = Symbol->NumberOfAuxSymbols;
|
||||||
Sym.AuxiliaryData = getHexString(Obj.getSymbolAuxData(Symbol));
|
Sym.AuxiliaryData = COFFYAML::BinaryRef(Obj.getSymbolAuxData(Symbol));
|
||||||
Symbols.push_back(Sym);
|
Symbols.push_back(Sym);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef COFFDumper::getHexString(ArrayRef<uint8_t> Data) {
|
|
||||||
std::string S;
|
|
||||||
for (ArrayRef<uint8_t>::iterator I = Data.begin(), E = Data.end(); I != E;
|
|
||||||
++I) {
|
|
||||||
uint8_t Byte = *I;
|
|
||||||
S.push_back(hexdigit(Byte >> 4));
|
|
||||||
S.push_back(hexdigit(Byte & 0xf));
|
|
||||||
}
|
|
||||||
Strings.push_back(S);
|
|
||||||
return Strings.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
COFFYAML::Object &COFFDumper::getYAMLObj() {
|
COFFYAML::Object &COFFDumper::getYAMLObj() {
|
||||||
return YAMLObj;
|
return YAMLObj;
|
||||||
}
|
}
|
||||||
|
@ -139,8 +139,9 @@ static bool layoutCOFF(COFFParser &CP) {
|
|||||||
for (std::vector<COFFYAML::Section>::iterator i = CP.Obj.Sections.begin(),
|
for (std::vector<COFFYAML::Section>::iterator i = CP.Obj.Sections.begin(),
|
||||||
e = CP.Obj.Sections.end();
|
e = CP.Obj.Sections.end();
|
||||||
i != e; ++i) {
|
i != e; ++i) {
|
||||||
if (!i->SectionData.empty()) {
|
StringRef SecData = i->SectionData.getHex();
|
||||||
i->Header.SizeOfRawData = i->SectionData.size()/2;
|
if (!SecData.empty()) {
|
||||||
|
i->Header.SizeOfRawData = SecData.size()/2;
|
||||||
i->Header.PointerToRawData = CurrentSectionDataOffset;
|
i->Header.PointerToRawData = CurrentSectionDataOffset;
|
||||||
CurrentSectionDataOffset += i->Header.SizeOfRawData;
|
CurrentSectionDataOffset += i->Header.SizeOfRawData;
|
||||||
if (!i->Relocations.empty()) {
|
if (!i->Relocations.empty()) {
|
||||||
@ -163,7 +164,7 @@ static bool layoutCOFF(COFFParser &CP) {
|
|||||||
for (std::vector<COFFYAML::Symbol>::iterator i = CP.Obj.Symbols.begin(),
|
for (std::vector<COFFYAML::Symbol>::iterator i = CP.Obj.Symbols.begin(),
|
||||||
e = CP.Obj.Symbols.end();
|
e = CP.Obj.Symbols.end();
|
||||||
i != e; ++i) {
|
i != e; ++i) {
|
||||||
unsigned AuxBytes = i->AuxiliaryData.size() / 2;
|
unsigned AuxBytes = i->AuxiliaryData.getHex().size() / 2;
|
||||||
if (AuxBytes % COFF::SymbolSize != 0) {
|
if (AuxBytes % COFF::SymbolSize != 0) {
|
||||||
errs() << "AuxiliaryData size not a multiple of symbol size!\n";
|
errs() << "AuxiliaryData size not a multiple of symbol size!\n";
|
||||||
return false;
|
return false;
|
||||||
@ -248,8 +249,9 @@ bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
|
|||||||
for (std::vector<COFFYAML::Section>::iterator i = CP.Obj.Sections.begin(),
|
for (std::vector<COFFYAML::Section>::iterator i = CP.Obj.Sections.begin(),
|
||||||
e = CP.Obj.Sections.end();
|
e = CP.Obj.Sections.end();
|
||||||
i != e; ++i) {
|
i != e; ++i) {
|
||||||
if (!i->SectionData.empty()) {
|
StringRef SecData = i->SectionData.getHex();
|
||||||
if (!writeHexData(i->SectionData, OS)) {
|
if (!SecData.empty()) {
|
||||||
|
if (!writeHexData(SecData, OS)) {
|
||||||
errs() << "SectionData must be a collection of pairs of hex bytes";
|
errs() << "SectionData must be a collection of pairs of hex bytes";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -273,8 +275,9 @@ bool writeCOFF(COFFParser &CP, raw_ostream &OS) {
|
|||||||
<< binary_le(i->Header.Type)
|
<< binary_le(i->Header.Type)
|
||||||
<< binary_le(i->Header.StorageClass)
|
<< binary_le(i->Header.StorageClass)
|
||||||
<< binary_le(i->Header.NumberOfAuxSymbols);
|
<< binary_le(i->Header.NumberOfAuxSymbols);
|
||||||
if (!i->AuxiliaryData.empty()) {
|
StringRef Data = i->AuxiliaryData.getHex();
|
||||||
if (!writeHexData(i->AuxiliaryData, OS)) {
|
if (!Data.empty()) {
|
||||||
|
if (!writeHexData(Data, OS)) {
|
||||||
errs() << "AuxiliaryData must be a collection of pairs of hex bytes";
|
errs() << "AuxiliaryData must be a collection of pairs of hex bytes";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user