1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[obj2yaml] [yaml2obj] Support for MachO nlist and string table

This commit adds round tripping for MachO symbol data. Symbols are entries in the name list, that contain offsets into the string table which is at the end of the __LINKEDIT segment.

llvm-svn: 271604
This commit is contained in:
Chris Bieneman 2016-06-02 22:54:06 +00:00
parent 009edf13a8
commit 45ad72aa8e
5 changed files with 610 additions and 7 deletions

View File

@ -57,6 +57,13 @@ struct LoadCommand {
uint64_t ZeroPadBytes; uint64_t ZeroPadBytes;
}; };
struct NListEntry {
uint32_t n_strx;
uint8_t n_type;
uint8_t n_sect;
uint16_t n_desc;
uint64_t n_value;
};
struct RebaseOpcode { struct RebaseOpcode {
MachO::RebaseOpcode Opcode; MachO::RebaseOpcode Opcode;
uint8_t Imm; uint8_t Imm;
@ -91,6 +98,8 @@ struct LinkEditData {
std::vector<MachOYAML::BindOpcode> WeakBindOpcodes; std::vector<MachOYAML::BindOpcode> WeakBindOpcodes;
std::vector<MachOYAML::BindOpcode> LazyBindOpcodes; std::vector<MachOYAML::BindOpcode> LazyBindOpcodes;
MachOYAML::ExportEntry ExportTrie; MachOYAML::ExportEntry ExportTrie;
std::vector<NListEntry> NameList;
std::vector<StringRef> StringTable;
}; };
struct Object { struct Object {
@ -111,6 +120,8 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::ExportEntry) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::ExportEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::NListEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef)
namespace llvm { namespace llvm {
namespace yaml { namespace yaml {
@ -147,6 +158,10 @@ template <> struct MappingTraits<MachOYAML::Section> {
static void mapping(IO &IO, MachOYAML::Section &Section); static void mapping(IO &IO, MachOYAML::Section &Section);
}; };
template <> struct MappingTraits<MachOYAML::NListEntry> {
static void mapping(IO &IO, MachOYAML::NListEntry &NListEntry);
};
#define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \ #define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \
io.enumCase(value, #LCName, MachO::LCName); io.enumCase(value, #LCName, MachO::LCName);

View File

@ -104,6 +104,8 @@ void MappingTraits<MachOYAML::LinkEditData>::mapping(
IO.mapOptional("WeakBindOpcodes", LinkEditData.WeakBindOpcodes); IO.mapOptional("WeakBindOpcodes", LinkEditData.WeakBindOpcodes);
IO.mapOptional("LazyBindOpcodes", LinkEditData.LazyBindOpcodes); IO.mapOptional("LazyBindOpcodes", LinkEditData.LazyBindOpcodes);
IO.mapOptional("ExportTrie", LinkEditData.ExportTrie); IO.mapOptional("ExportTrie", LinkEditData.ExportTrie);
IO.mapOptional("NameList", LinkEditData.NameList);
IO.mapOptional("StringTable", LinkEditData.StringTable);
} }
void MappingTraits<MachOYAML::RebaseOpcode>::mapping( void MappingTraits<MachOYAML::RebaseOpcode>::mapping(
@ -134,6 +136,15 @@ void MappingTraits<MachOYAML::ExportEntry>::mapping(
IO.mapOptional("Children", ExportEntry.Children); IO.mapOptional("Children", ExportEntry.Children);
} }
void MappingTraits<MachOYAML::NListEntry>::mapping(
IO &IO, MachOYAML::NListEntry &NListEntry) {
IO.mapRequired("n_strx", NListEntry.n_strx);
IO.mapRequired("n_type", NListEntry.n_type);
IO.mapRequired("n_sect", NListEntry.n_sect);
IO.mapRequired("n_desc", NListEntry.n_desc);
IO.mapRequired("n_value", NListEntry.n_value);
}
template <typename StructType> template <typename StructType>
void mapLoadCommandData(IO &IO, MachOYAML::LoadCommand &LoadCommand) {} void mapLoadCommandData(IO &IO, MachOYAML::LoadCommand &LoadCommand) {}

View File

@ -0,0 +1,511 @@
# RUN: yaml2obj -format=macho %s | obj2yaml | FileCheck %s
--- !mach-o
FileHeader:
magic: 0xFEEDFACF
cputype: 0x01000007
cpusubtype: 0x80000003
filetype: 0x00000002
ncmds: 16
sizeofcmds: 1408
flags: 0x00218085
reserved: 0x00000000
LoadCommands:
- cmd: LC_SEGMENT_64
cmdsize: 72
segname: __PAGEZERO
vmaddr: 0
vmsize: 4294967296
fileoff: 0
filesize: 0
maxprot: 0
initprot: 0
nsects: 0
flags: 0
- cmd: LC_SEGMENT_64
cmdsize: 552
segname: __TEXT
vmaddr: 4294967296
vmsize: 8192
fileoff: 0
filesize: 8192
maxprot: 7
initprot: 5
nsects: 6
flags: 0
Sections:
- cmd: LC_SEGMENT_64
cmdsize: 312
segname: __DATA
vmaddr: 4294975488
vmsize: 4096
fileoff: 8192
filesize: 4096
maxprot: 7
initprot: 3
nsects: 3
flags: 0
Sections:
- cmd: LC_SEGMENT_64
cmdsize: 72
segname: __LINKEDIT
vmaddr: 4294979584
vmsize: 4096
fileoff: 12288
filesize: 2508
maxprot: 7
initprot: 1
nsects: 0
flags: 0
- cmd: LC_DYLD_INFO_ONLY
cmdsize: 48
rebase_off: 12288
rebase_size: 8
bind_off: 12296
bind_size: 96
weak_bind_off: 0
weak_bind_size: 0
lazy_bind_off: 12392
lazy_bind_size: 624
export_off: 13016
export_size: 48
- cmd: LC_SYMTAB
cmdsize: 24
symoff: 13080
nsyms: 30
stroff: 13700
strsize: 1096
- cmd: LC_DYSYMTAB
cmdsize: 80
ilocalsym: 0
nlocalsym: 9
iextdefsym: 9
nextdefsym: 2
iundefsym: 11
nundefsym: 19
tocoff: 0
ntoc: 0
modtaboff: 0
nmodtab: 0
extrefsymoff: 0
nextrefsyms: 0
indirectsymoff: 13560
nindirectsyms: 35
extreloff: 0
nextrel: 0
locreloff: 0
nlocrel: 0
- cmd: LC_LOAD_DYLINKER
cmdsize: 32
name: 12
PayloadString: /usr/lib/dyld
ZeroPadBytes: 7
- cmd: LC_UUID
cmdsize: 24
uuid: 461A1B28-822F-3F38-B670-645419E636F5
- cmd: LC_VERSION_MIN_MACOSX
cmdsize: 16
version: 658176
sdk: 658176
- cmd: LC_SOURCE_VERSION
cmdsize: 16
version: 0
- cmd: LC_MAIN
cmdsize: 24
entryoff: 4448
stacksize: 0
- cmd: LC_LOAD_DYLIB
cmdsize: 48
dylib:
name: 24
timestamp: 2
current_version: 7864576
compatibility_version: 65536
PayloadString: '/usr/lib/libc++.1.dylib'
ZeroPadBytes: 1
- cmd: LC_LOAD_DYLIB
cmdsize: 56
dylib:
name: 24
timestamp: 2
current_version: 80349697
compatibility_version: 65536
PayloadString: /usr/lib/libSystem.B.dylib
ZeroPadBytes: 6
- cmd: LC_FUNCTION_STARTS
cmdsize: 16
dataoff: 13064
datasize: 16
- cmd: LC_DATA_IN_CODE
cmdsize: 16
dataoff: 13080
datasize: 0
LinkEditData:
NameList:
- n_strx: 2
n_type: 30
n_sect: 1
n_desc: 128
n_value: 4294971808
- n_strx: 69
n_type: 30
n_sect: 1
n_desc: 128
n_value: 4294971888
- n_strx: 166
n_type: 30
n_sect: 1
n_desc: 128
n_value: 4294973024
- n_strx: 204
n_type: 30
n_sect: 1
n_desc: 128
n_value: 4294973056
- n_strx: 320
n_type: 30
n_sect: 1
n_desc: 128
n_value: 4294974784
- n_strx: 344
n_type: 30
n_sect: 1
n_desc: 128
n_value: 4294974800
- n_strx: 387
n_type: 30
n_sect: 1
n_desc: 128
n_value: 4294974832
- n_strx: 420
n_type: 14
n_sect: 4
n_desc: 0
n_value: 4294975104
- n_strx: 438
n_type: 14
n_sect: 4
n_desc: 0
n_value: 4294975280
- n_strx: 456
n_type: 15
n_sect: 1
n_desc: 16
n_value: 4294967296
- n_strx: 476
n_type: 15
n_sect: 1
n_desc: 0
n_value: 4294971744
- n_strx: 482
n_type: 1
n_sect: 0
n_desc: 512
n_value: 0
- n_strx: 498
n_type: 1
n_sect: 0
n_desc: 256
n_value: 0
- n_strx: 537
n_type: 1
n_sect: 0
n_desc: 256
n_value: 0
- n_strx: 567
n_type: 1
n_sect: 0
n_desc: 256
n_value: 0
- n_strx: 642
n_type: 1
n_sect: 0
n_desc: 256
n_value: 0
- n_strx: 711
n_type: 1
n_sect: 0
n_desc: 256
n_value: 0
- n_strx: 774
n_type: 1
n_sect: 0
n_desc: 256
n_value: 0
- n_strx: 834
n_type: 1
n_sect: 0
n_desc: 256
n_value: 0
- n_strx: 851
n_type: 1
n_sect: 0
n_desc: 256
n_value: 0
- n_strx: 875
n_type: 1
n_sect: 0
n_desc: 256
n_value: 0
- n_strx: 897
n_type: 1
n_sect: 0
n_desc: 256
n_value: 0
- n_strx: 954
n_type: 1
n_sect: 0
n_desc: 256
n_value: 0
- n_strx: 982
n_type: 1
n_sect: 0
n_desc: 256
n_value: 0
- n_strx: 999
n_type: 1
n_sect: 0
n_desc: 256
n_value: 0
- n_strx: 1018
n_type: 1
n_sect: 0
n_desc: 256
n_value: 0
- n_strx: 1035
n_type: 1
n_sect: 0
n_desc: 256
n_value: 0
- n_strx: 1057
n_type: 1
n_sect: 0
n_desc: 512
n_value: 0
- n_strx: 1065
n_type: 1
n_sect: 0
n_desc: 512
n_value: 0
- n_strx: 1073
n_type: 1
n_sect: 0
n_desc: 512
n_value: 0
StringTable:
- ' '
- __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc
- __ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m
- __ZNSt3__111char_traitsIcE6lengthEPKc
- __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_
- ___clang_call_terminate
- __ZNSt3__111char_traitsIcE11eq_int_typeEii
- __ZNSt3__111char_traitsIcE3eofEv
- GCC_except_table2
- GCC_except_table4
- __mh_execute_header
- _main
- __Unwind_Resume
- __ZNKSt3__16locale9use_facetERNS0_2idE
- __ZNKSt3__18ios_base6getlocEv
- __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEmc
- __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev
- __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryC1ERS3_
- __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryD1Ev
- __ZNSt3__14coutE
- __ZNSt3__15ctypeIcE2idE
- __ZNSt3__16localeD1Ev
- __ZNSt3__18ios_base33__set_badbit_and_consider_rethrowEv
- __ZNSt3__18ios_base5clearEj
- __ZSt9terminatev
- ___cxa_begin_catch
- ___cxa_end_catch
- ___gxx_personality_v0
- _memset
- _strlen
- dyld_stub_binder
...
#CHECK: NameList:
#CHECK: - n_strx: 2
#CHECK: n_type: 30
#CHECK: n_sect: 1
#CHECK: n_desc: 128
#CHECK: n_value: 4294971808
#CHECK: - n_strx: 69
#CHECK: n_type: 30
#CHECK: n_sect: 1
#CHECK: n_desc: 128
#CHECK: n_value: 4294971888
#CHECK: - n_strx: 166
#CHECK: n_type: 30
#CHECK: n_sect: 1
#CHECK: n_desc: 128
#CHECK: n_value: 4294973024
#CHECK: - n_strx: 204
#CHECK: n_type: 30
#CHECK: n_sect: 1
#CHECK: n_desc: 128
#CHECK: n_value: 4294973056
#CHECK: - n_strx: 320
#CHECK: n_type: 30
#CHECK: n_sect: 1
#CHECK: n_desc: 128
#CHECK: n_value: 4294974784
#CHECK: - n_strx: 344
#CHECK: n_type: 30
#CHECK: n_sect: 1
#CHECK: n_desc: 128
#CHECK: n_value: 4294974800
#CHECK: - n_strx: 387
#CHECK: n_type: 30
#CHECK: n_sect: 1
#CHECK: n_desc: 128
#CHECK: n_value: 4294974832
#CHECK: - n_strx: 420
#CHECK: n_type: 14
#CHECK: n_sect: 4
#CHECK: n_desc: 0
#CHECK: n_value: 4294975104
#CHECK: - n_strx: 438
#CHECK: n_type: 14
#CHECK: n_sect: 4
#CHECK: n_desc: 0
#CHECK: n_value: 4294975280
#CHECK: - n_strx: 456
#CHECK: n_type: 15
#CHECK: n_sect: 1
#CHECK: n_desc: 16
#CHECK: n_value: 4294967296
#CHECK: - n_strx: 476
#CHECK: n_type: 15
#CHECK: n_sect: 1
#CHECK: n_desc: 0
#CHECK: n_value: 4294971744
#CHECK: - n_strx: 482
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 512
#CHECK: n_value: 0
#CHECK: - n_strx: 498
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 256
#CHECK: n_value: 0
#CHECK: - n_strx: 537
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 256
#CHECK: n_value: 0
#CHECK: - n_strx: 567
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 256
#CHECK: n_value: 0
#CHECK: - n_strx: 642
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 256
#CHECK: n_value: 0
#CHECK: - n_strx: 711
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 256
#CHECK: n_value: 0
#CHECK: - n_strx: 774
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 256
#CHECK: n_value: 0
#CHECK: - n_strx: 834
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 256
#CHECK: n_value: 0
#CHECK: - n_strx: 851
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 256
#CHECK: n_value: 0
#CHECK: - n_strx: 875
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 256
#CHECK: n_value: 0
#CHECK: - n_strx: 897
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 256
#CHECK: n_value: 0
#CHECK: - n_strx: 954
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 256
#CHECK: n_value: 0
#CHECK: - n_strx: 982
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 256
#CHECK: n_value: 0
#CHECK: - n_strx: 999
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 256
#CHECK: n_value: 0
#CHECK: - n_strx: 1018
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 256
#CHECK: n_value: 0
#CHECK: - n_strx: 1035
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 256
#CHECK: n_value: 0
#CHECK: - n_strx: 1057
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 512
#CHECK: n_value: 0
#CHECK: - n_strx: 1065
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 512
#CHECK: n_value: 0
#CHECK: - n_strx: 1073
#CHECK: n_type: 1
#CHECK: n_sect: 0
#CHECK: n_desc: 512
#CHECK: n_value: 0
#CHECK: StringTable:
#CHECK: - ' '
#CHECK: - __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc
#CHECK: - __ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m
#CHECK: - __ZNSt3__111char_traitsIcE6lengthEPKc
#CHECK: - __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_
#CHECK: - ___clang_call_terminate
#CHECK: - __ZNSt3__111char_traitsIcE11eq_int_typeEii
#CHECK: - __ZNSt3__111char_traitsIcE3eofEv
#CHECK: - GCC_except_table2
#CHECK: - GCC_except_table4
#CHECK: - __mh_execute_header
#CHECK: - _main
#CHECK: - __Unwind_Resume
#CHECK: - __ZNKSt3__16locale9use_facetERNS0_2idE
#CHECK: - __ZNKSt3__18ios_base6getlocEv
#CHECK: - __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEmc
#CHECK: - __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev
#CHECK: - __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryC1ERS3_
#CHECK: - __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryD1Ev
#CHECK: - __ZNSt3__14coutE
#CHECK: - __ZNSt3__15ctypeIcE2idE
#CHECK: - __ZNSt3__16localeD1Ev
#CHECK: - __ZNSt3__18ios_base33__set_badbit_and_consider_rethrowEv
#CHECK: - __ZNSt3__18ios_base5clearEj
#CHECK: - __ZSt9terminatev
#CHECK: - ___cxa_begin_catch
#CHECK: - ___cxa_end_catch
#CHECK: - ___gxx_personality_v0
#CHECK: - _memset
#CHECK: - _strlen
#CHECK: - dyld_stub_binder

View File

@ -33,6 +33,7 @@ class MachODumper {
void dumpBindOpcodes(std::vector<MachOYAML::BindOpcode> &BindOpcodes, void dumpBindOpcodes(std::vector<MachOYAML::BindOpcode> &BindOpcodes,
ArrayRef<uint8_t> OpcodeBuffer, bool Lazy = false); ArrayRef<uint8_t> OpcodeBuffer, bool Lazy = false);
void dumpExportTrie(std::unique_ptr<MachOYAML::Object> &Y); void dumpExportTrie(std::unique_ptr<MachOYAML::Object> &Y);
void dumpSymbols(std::unique_ptr<MachOYAML::Object> &Y);
public: public:
MachODumper(const object::MachOObjectFile &O) : Obj(O) {} MachODumper(const object::MachOObjectFile &O) : Obj(O) {}
@ -210,6 +211,7 @@ void MachODumper::dumpLinkEdit(std::unique_ptr<MachOYAML::Object> &Y) {
dumpBindOpcodes(Y->LinkEdit.LazyBindOpcodes, Obj.getDyldInfoLazyBindOpcodes(), dumpBindOpcodes(Y->LinkEdit.LazyBindOpcodes, Obj.getDyldInfoLazyBindOpcodes(),
true); true);
dumpExportTrie(Y); dumpExportTrie(Y);
dumpSymbols(Y);
} }
void MachODumper::dumpRebaseOpcodes(std::unique_ptr<MachOYAML::Object> &Y) { void MachODumper::dumpRebaseOpcodes(std::unique_ptr<MachOYAML::Object> &Y) {
@ -424,6 +426,41 @@ void MachODumper::dumpExportTrie(std::unique_ptr<MachOYAML::Object> &Y) {
processExportNode(ExportsTrie.begin(), ExportsTrie.end(), LEData.ExportTrie); processExportNode(ExportsTrie.begin(), ExportsTrie.end(), LEData.ExportTrie);
} }
template <typename nlist_t>
MachOYAML::NListEntry constructNameList(const nlist_t &nlist) {
MachOYAML::NListEntry NL;
NL.n_strx = nlist.n_strx;
NL.n_type = nlist.n_type;
NL.n_sect = nlist.n_sect;
NL.n_desc = nlist.n_desc;
NL.n_value = nlist.n_value;
return NL;
}
void MachODumper::dumpSymbols(std::unique_ptr<MachOYAML::Object> &Y) {
MachOYAML::LinkEditData &LEData = Y->LinkEdit;
for (auto Symbol : Obj.symbols()) {
MachOYAML::NListEntry NLE =
Obj.is64Bit() ? constructNameList<MachO::nlist_64>(
*reinterpret_cast<const MachO::nlist_64 *>(
Symbol.getRawDataRefImpl().p))
: constructNameList<MachO::nlist>(
*reinterpret_cast<const MachO::nlist *>(
Symbol.getRawDataRefImpl().p));
LEData.NameList.push_back(NLE);
}
StringRef RemainingTable = Obj.getStringTableData();
while (RemainingTable.size() > 0) {
auto SymbolPair = RemainingTable.split('\0');
RemainingTable = SymbolPair.second;
if (SymbolPair.first.empty())
break;
LEData.StringTable.push_back(SymbolPair.first);
}
}
Error macho2yaml(raw_ostream &Out, const object::MachOObjectFile &Obj) { Error macho2yaml(raw_ostream &Out, const object::MachOObjectFile &Obj) {
MachODumper Dumper(Obj); MachODumper Dumper(Obj);
Expected<std::unique_ptr<MachOYAML::Object>> YAML = Dumper.dump(); Expected<std::unique_ptr<MachOYAML::Object>> YAML = Dumper.dump();

View File

@ -165,7 +165,7 @@ size_t writeLoadCommandData<MachO::dylinker_command>(MachOYAML::LoadCommand &LC,
template <> template <>
size_t writeLoadCommandData<MachO::rpath_command>(MachOYAML::LoadCommand &LC, size_t writeLoadCommandData<MachO::rpath_command>(MachOYAML::LoadCommand &LC,
raw_ostream &OS) { raw_ostream &OS) {
return writePayloadString(LC, OS); return writePayloadString(LC, OS);
} }
@ -295,23 +295,23 @@ void MachOWriter::writeBindOpcodes(
} }
} }
void MachOWriter::dumpExportEntry(raw_ostream &OS, MachOYAML::ExportEntry &Entry) { void MachOWriter::dumpExportEntry(raw_ostream &OS,
MachOYAML::ExportEntry &Entry) {
encodeSLEB128(Entry.TerminalSize, OS); encodeSLEB128(Entry.TerminalSize, OS);
if (Entry.TerminalSize > 0) { if (Entry.TerminalSize > 0) {
encodeSLEB128(Entry.Flags, OS); encodeSLEB128(Entry.Flags, OS);
if ( Entry.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT ) { if (Entry.Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT) {
encodeSLEB128(Entry.Other, OS); encodeSLEB128(Entry.Other, OS);
OS << Entry.ImportName; OS << Entry.ImportName;
OS.write('\0'); OS.write('\0');
} } else {
else {
encodeSLEB128(Entry.Address, OS); encodeSLEB128(Entry.Address, OS);
if (Entry.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) if (Entry.Flags & MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
encodeSLEB128(Entry.Other, OS); encodeSLEB128(Entry.Other, OS);
} }
} }
OS.write(static_cast<uint8_t>(Entry.Children.size())); OS.write(static_cast<uint8_t>(Entry.Children.size()));
for (auto EE : Entry.Children){ for (auto EE : Entry.Children) {
OS << EE.Name; OS << EE.Name;
OS.write('\0'); OS.write('\0');
encodeSLEB128(EE.NodeOffset, OS); encodeSLEB128(EE.NodeOffset, OS);
@ -325,6 +325,17 @@ Error MachOWriter::writeExportTrie(raw_ostream &OS) {
return Error::success(); return Error::success();
} }
template <typename NListType>
void writeNListEntry(MachOYAML::NListEntry &NLE, raw_ostream &OS) {
NListType ListEntry;
ListEntry.n_strx = NLE.n_strx;
ListEntry.n_type = NLE.n_type;
ListEntry.n_sect = NLE.n_sect;
ListEntry.n_desc = NLE.n_desc;
ListEntry.n_value = NLE.n_value;
OS.write(reinterpret_cast<const char *>(&ListEntry), sizeof(NListType));
}
Error MachOWriter::writeLinkEditData(raw_ostream &OS) { Error MachOWriter::writeLinkEditData(raw_ostream &OS) {
MachOYAML::LinkEditData &LinkEdit = Obj.LinkEdit; MachOYAML::LinkEditData &LinkEdit = Obj.LinkEdit;
MachO::dyld_info_command *DyldInfoOnlyCmd = 0; MachO::dyld_info_command *DyldInfoOnlyCmd = 0;
@ -357,9 +368,27 @@ Error MachOWriter::writeLinkEditData(raw_ostream &OS) {
LinkEdit.LazyBindOpcodes); LinkEdit.LazyBindOpcodes);
ZeroToOffset(OS, DyldInfoOnlyCmd->export_off); ZeroToOffset(OS, DyldInfoOnlyCmd->export_off);
if(auto Err = writeExportTrie(OS)) if (auto Err = writeExportTrie(OS))
return Err; return Err;
ZeroToOffset(OS, SymtabCmd->symoff);
for (auto NLE : LinkEdit.NameList) {
if (is64Bit)
writeNListEntry<MachO::nlist_64>(NLE, OS);
else
writeNListEntry<MachO::nlist>(NLE, OS);
}
auto currOffset = OS.tell() - fileStart;
if (currOffset < SymtabCmd->stroff)
Fill(OS, SymtabCmd->stroff - currOffset, 0xDEADBEEFu);
for (auto Str : LinkEdit.StringTable) {
OS.write(Str.data(), Str.size());
OS.write('\0');
}
// Fill to the end of the string table // Fill to the end of the string table
ZeroToOffset(OS, SymtabCmd->stroff + SymtabCmd->strsize); ZeroToOffset(OS, SymtabCmd->stroff + SymtabCmd->strsize);