1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[ObjectYAML] MachO support for endianness

This patch adds support to the macho<->yaml tools for preserving endianness in MachO structures and DWARF data.

llvm-svn: 290381
This commit is contained in:
Chris Bieneman 2016-12-22 21:58:03 +00:00
parent 6877ce89ac
commit bda2f27975
11 changed files with 1317 additions and 89 deletions

View File

@ -67,6 +67,7 @@ struct PubSection {
};
struct Data {
bool IsLittleEndian;
std::vector<Abbrev> AbbrevDecls;
std::vector<StringRef> DebugStrings;
std::vector<ARange> ARanges;

View File

@ -106,6 +106,7 @@ struct LinkEditData {
};
struct Object {
bool IsLittleEndian;
FileHeader Header;
std::vector<LoadCommand> LoadCommands;
std::vector<Section> Sections;

View File

@ -14,6 +14,7 @@
#include "llvm/ObjectYAML/MachOYAML.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/MachO.h"
#include <string.h> // For memcpy, memset and strnlen.
@ -100,6 +101,10 @@ void MappingTraits<MachOYAML::Object>::mapping(IO &IO,
IO.setContext(&Object);
}
IO.mapTag("!mach-o", true);
IO.mapOptional("IsLittleEndian", Object.IsLittleEndian,
sys::IsLittleEndianHost);
Object.DWARF.IsLittleEndian = Object.IsLittleEndian;
IO.mapRequired("FileHeader", Object.Header);
IO.mapOptional("LoadCommands", Object.LoadCommands);
if(!Object.LinkEdit.isEmpty() || !IO.outputting())

View File

@ -0,0 +1,100 @@
# RUN: yaml2obj %s | obj2yaml | FileCheck %s
--- !mach-o
IsLittleEndian: false
FileHeader:
magic: 0xFEEDFACE
cputype: 0x00000012
cpusubtype: 0x00000000
filetype: 0x00000001
ncmds: 3
sizeofcmds: 368
flags: 0x00002000
LoadCommands:
- cmd: LC_SEGMENT
cmdsize: 328
segname: ''
vmaddr: 0
vmsize: 236
fileoff: 476
filesize: 236
maxprot: 7
initprot: 7
nsects: 4
flags: 0
Sections:
- sectname: __text
segname: __TEXT
addr: 0x0000000000000000
size: 188
offset: 0x000001DC
align: 4
reloff: 0x000002C8
nreloc: 9
flags: 0x80000400
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __textcoal_nt
segname: __TEXT
addr: 0x00000000000000BC
size: 0
offset: 0x00000298
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x8000000B
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __picsymbolstub1
segname: __TEXT
addr: 0x00000000000000BC
size: 0
offset: 0x00000298
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x80000008
reserved1: 0x00000000
reserved2: 0x00000020
reserved3: 0x00000000
- sectname: __cstring
segname: __TEXT
addr: 0x00000000000000BC
size: 48
offset: 0x00000298
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000002
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- cmd: LC_VERSION_MIN_MACOSX
cmdsize: 16
version: 658432
sdk: 0
- cmd: LC_SYMTAB
cmdsize: 24
symoff: 784
nsyms: 0
stroff: 808
strsize: 36
LinkEditData:
StringTable:
- ''
- _compilerrt_abort_impl
- ___absvdi2
- ''
...
#CHECK: IsLittleEndian: false
#CHECK: FileHeader:
#CHECK: magic: 0xFEEDFACE
#CHECK: cputype: 0x00000012
#CHECK: cpusubtype: 0x00000000
#CHECK: filetype: 0x00000001
#CHECK: ncmds: 3
#CHECK: sizeofcmds: 368
#CHECK: flags: 0x00002000

View File

@ -0,0 +1,485 @@
# RUN: yaml2obj %s | obj2yaml | FileCheck %s
--- !mach-o
IsLittleEndian: false
FileHeader:
magic: 0xFEEDFACE
cputype: 0x00000012
cpusubtype: 0x00000000
filetype: 0x00000001
ncmds: 4
sizeofcmds: 1264
flags: 0x00002000
LoadCommands:
- cmd: LC_SEGMENT
cmdsize: 1144
segname: ''
vmaddr: 0
vmsize: 1122
fileoff: 1292
filesize: 1122
maxprot: 7
initprot: 7
nsects: 16
flags: 0
Sections:
- sectname: __text
segname: __TEXT
addr: 0x0000000000000000
size: 188
offset: 0x0000050C
align: 4
reloff: 0x00000970
nreloc: 9
flags: 0x80000400
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __textcoal_nt
segname: __TEXT
addr: 0x00000000000000BC
size: 0
offset: 0x000005C8
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x8000000B
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __picsymbolstub1
segname: __TEXT
addr: 0x00000000000000BC
size: 0
offset: 0x000005C8
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x80000008
reserved1: 0x00000000
reserved2: 0x00000020
reserved3: 0x00000000
- sectname: __cstring
segname: __TEXT
addr: 0x00000000000000BC
size: 48
offset: 0x000005C8
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000002
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_str
segname: __DWARF
addr: 0x00000000000000EC
size: 182
offset: 0x000005F8
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_loc
segname: __DWARF
addr: 0x00000000000001A2
size: 0
offset: 0x000006AE
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_abbrev
segname: __DWARF
addr: 0x00000000000001A2
size: 104
offset: 0x000006AE
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_info
segname: __DWARF
addr: 0x000000000000020A
size: 141
offset: 0x00000716
align: 0
reloff: 0x000009B8
nreloc: 2
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_ranges
segname: __DWARF
addr: 0x0000000000000297
size: 0
offset: 0x000007A3
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_macinfo
segname: __DWARF
addr: 0x0000000000000297
size: 1
offset: 0x000007A3
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __apple_names
segname: __DWARF
addr: 0x0000000000000298
size: 60
offset: 0x000007A4
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __apple_objc
segname: __DWARF
addr: 0x00000000000002D4
size: 36
offset: 0x000007E0
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __apple_namespac
segname: __DWARF
addr: 0x00000000000002F8
size: 36
offset: 0x00000804
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __apple_types
segname: __DWARF
addr: 0x000000000000031C
size: 133
offset: 0x00000828
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_frame
segname: __DWARF
addr: 0x00000000000003A4
size: 48
offset: 0x000008B0
align: 2
reloff: 0x000009C8
nreloc: 1
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_line
segname: __DWARF
addr: 0x00000000000003D4
size: 142
offset: 0x000008E0
align: 0
reloff: 0x000009D0
nreloc: 1
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- cmd: LC_VERSION_MIN_MACOSX
cmdsize: 16
version: 658432
sdk: 0
- cmd: LC_SYMTAB
cmdsize: 24
symoff: 2520
nsyms: 2
stroff: 2544
strsize: 36
- cmd: LC_DYSYMTAB
cmdsize: 80
ilocalsym: 0
nlocalsym: 0
iextdefsym: 0
nextdefsym: 1
iundefsym: 1
nundefsym: 1
tocoff: 0
ntoc: 0
modtaboff: 0
nmodtab: 0
extrefsymoff: 0
nextrefsyms: 0
indirectsymoff: 0
nindirectsyms: 0
extreloff: 0
nextrel: 0
locreloff: 0
nlocrel: 0
LinkEditData:
NameList:
- n_strx: 24
n_type: 0x0F
n_sect: 1
n_desc: 0
n_value: 0
- n_strx: 1
n_type: 0x01
n_sect: 0
n_desc: 0
n_value: 0
StringTable:
- ''
- _compilerrt_abort_impl
- ___absvdi2
- ''
DWARF:
debug_str:
- 'clang version 4.0.0 (trunk 290181) (llvm/trunk 290209)'
- ../compiler-rt/lib/builtins/absvdi2.c
- /Users/cbieneman/dev/open-source/llvm-build-rel
- int
- di_int
- long long int
- __absvdi2
- a
- N
- t
debug_abbrev:
- Code: 0x00000001
Tag: DW_TAG_compile_unit
Children: DW_CHILDREN_yes
Attributes:
- Attribute: DW_AT_producer
Form: DW_FORM_strp
- Attribute: DW_AT_language
Form: DW_FORM_data2
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_stmt_list
Form: DW_FORM_sec_offset
- Attribute: DW_AT_comp_dir
Form: DW_FORM_strp
- Attribute: DW_AT_low_pc
Form: DW_FORM_addr
- Attribute: DW_AT_high_pc
Form: DW_FORM_data4
- Code: 0x00000002
Tag: DW_TAG_base_type
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_encoding
Form: DW_FORM_data1
- Attribute: DW_AT_byte_size
Form: DW_FORM_data1
- Code: 0x00000003
Tag: DW_TAG_typedef
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_type
Form: DW_FORM_ref4
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_decl_file
Form: DW_FORM_data1
- Attribute: DW_AT_decl_line
Form: DW_FORM_data1
- Code: 0x00000004
Tag: DW_TAG_subprogram
Children: DW_CHILDREN_yes
Attributes:
- Attribute: DW_AT_low_pc
Form: DW_FORM_addr
- Attribute: DW_AT_high_pc
Form: DW_FORM_data4
- Attribute: DW_AT_frame_base
Form: DW_FORM_exprloc
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_decl_file
Form: DW_FORM_data1
- Attribute: DW_AT_decl_line
Form: DW_FORM_data1
- Attribute: DW_AT_prototyped
Form: DW_FORM_flag_present
- Attribute: DW_AT_type
Form: DW_FORM_ref4
- Attribute: DW_AT_external
Form: DW_FORM_flag_present
- Code: 0x00000005
Tag: DW_TAG_formal_parameter
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_location
Form: DW_FORM_exprloc
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_decl_file
Form: DW_FORM_data1
- Attribute: DW_AT_decl_line
Form: DW_FORM_data1
- Attribute: DW_AT_type
Form: DW_FORM_ref4
- Code: 0x00000006
Tag: DW_TAG_variable
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_location
Form: DW_FORM_exprloc
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_decl_file
Form: DW_FORM_data1
- Attribute: DW_AT_decl_line
Form: DW_FORM_data1
- Attribute: DW_AT_type
Form: DW_FORM_ref4
- Code: 0x00000007
Tag: DW_TAG_const_type
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_type
Form: DW_FORM_ref4
...
#CHECK: DWARF:
#CHECK: debug_str:
#CHECK: - 'clang version 4.0.0 (trunk 290181) (llvm/trunk 290209)'
#CHECK: - ../compiler-rt/lib/builtins/absvdi2.c
#CHECK: - /Users/cbieneman/dev/open-source/llvm-build-rel
#CHECK: - int
#CHECK: - di_int
#CHECK: - long long int
#CHECK: - __absvdi2
#CHECK: - a
#CHECK: - N
#CHECK: - t
#CHECK: debug_abbrev:
#CHECK: - Code: 0x00000001
#CHECK: Tag: DW_TAG_compile_unit
#CHECK: Children: DW_CHILDREN_yes
#CHECK: Attributes:
#CHECK: - Attribute: DW_AT_producer
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_language
#CHECK: Form: DW_FORM_data2
#CHECK: - Attribute: DW_AT_name
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_stmt_list
#CHECK: Form: DW_FORM_sec_offset
#CHECK: - Attribute: DW_AT_comp_dir
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_low_pc
#CHECK: Form: DW_FORM_addr
#CHECK: - Attribute: DW_AT_high_pc
#CHECK: Form: DW_FORM_data4
#CHECK: - Code: 0x00000002
#CHECK: Tag: DW_TAG_base_type
#CHECK: Children: DW_CHILDREN_no
#CHECK: Attributes:
#CHECK: - Attribute: DW_AT_name
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_encoding
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_byte_size
#CHECK: Form: DW_FORM_data1
#CHECK: - Code: 0x00000003
#CHECK: Tag: DW_TAG_typedef
#CHECK: Children: DW_CHILDREN_no
#CHECK: Attributes:
#CHECK: - Attribute: DW_AT_type
#CHECK: Form: DW_FORM_ref4
#CHECK: - Attribute: DW_AT_name
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_decl_file
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_decl_line
#CHECK: Form: DW_FORM_data1
#CHECK: - Code: 0x00000004
#CHECK: Tag: DW_TAG_subprogram
#CHECK: Children: DW_CHILDREN_yes
#CHECK: Attributes:
#CHECK: - Attribute: DW_AT_low_pc
#CHECK: Form: DW_FORM_addr
#CHECK: - Attribute: DW_AT_high_pc
#CHECK: Form: DW_FORM_data4
#CHECK: - Attribute: DW_AT_frame_base
#CHECK: Form: DW_FORM_exprloc
#CHECK: - Attribute: DW_AT_name
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_decl_file
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_decl_line
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_prototyped
#CHECK: Form: DW_FORM_flag_present
#CHECK: - Attribute: DW_AT_type
#CHECK: Form: DW_FORM_ref4
#CHECK: - Attribute: DW_AT_external
#CHECK: Form: DW_FORM_flag_present
#CHECK: - Code: 0x00000005
#CHECK: Tag: DW_TAG_formal_parameter
#CHECK: Children: DW_CHILDREN_no
#CHECK: Attributes:
#CHECK: - Attribute: DW_AT_location
#CHECK: Form: DW_FORM_exprloc
#CHECK: - Attribute: DW_AT_name
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_decl_file
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_decl_line
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_type
#CHECK: Form: DW_FORM_ref4
#CHECK: - Code: 0x00000006
#CHECK: Tag: DW_TAG_variable
#CHECK: Children: DW_CHILDREN_no
#CHECK: Attributes:
#CHECK: - Attribute: DW_AT_location
#CHECK: Form: DW_FORM_exprloc
#CHECK: - Attribute: DW_AT_name
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_decl_file
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_decl_line
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_type
#CHECK: Form: DW_FORM_ref4
#CHECK: - Code: 0x00000007
#CHECK: Tag: DW_TAG_const_type
#CHECK: Children: DW_CHILDREN_no
#CHECK: Attributes:
#CHECK: - Attribute: DW_AT_type
#CHECK: Form: DW_FORM_ref4

View File

@ -0,0 +1,474 @@
# RUN: yaml2obj %s | obj2yaml | FileCheck %s
--- !mach-o
IsLittleEndian: true
FileHeader:
magic: 0xFEEDFACF
cputype: 0x01000007
cpusubtype: 0x00000003
filetype: 0x00000001
ncmds: 4
sizeofcmds: 1392
flags: 0x00002000
reserved: 0x00000000
LoadCommands:
- cmd: LC_SEGMENT_64
cmdsize: 1272
segname: ''
vmaddr: 0
vmsize: 1086
fileoff: 1424
filesize: 1086
maxprot: 7
initprot: 7
nsects: 15
flags: 0
Sections:
- sectname: __text
segname: __TEXT
addr: 0x0000000000000000
size: 93
offset: 0x00000590
align: 4
reloff: 0x000009D0
nreloc: 3
flags: 0x80000400
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __cstring
segname: __TEXT
addr: 0x000000000000005D
size: 48
offset: 0x000005ED
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000002
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_str
segname: __DWARF
addr: 0x000000000000008D
size: 182
offset: 0x0000061D
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_loc
segname: __DWARF
addr: 0x0000000000000143
size: 0
offset: 0x000006D3
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_abbrev
segname: __DWARF
addr: 0x0000000000000143
size: 104
offset: 0x000006D3
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_info
segname: __DWARF
addr: 0x00000000000001AB
size: 146
offset: 0x0000073B
align: 0
reloff: 0x000009E8
nreloc: 2
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_ranges
segname: __DWARF
addr: 0x000000000000023D
size: 0
offset: 0x000007CD
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_macinfo
segname: __DWARF
addr: 0x000000000000023D
size: 1
offset: 0x000007CD
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __apple_names
segname: __DWARF
addr: 0x000000000000023E
size: 60
offset: 0x000007CE
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __apple_objc
segname: __DWARF
addr: 0x000000000000027A
size: 36
offset: 0x0000080A
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __apple_namespac
segname: __DWARF
addr: 0x000000000000029E
size: 36
offset: 0x0000082E
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __apple_types
segname: __DWARF
addr: 0x00000000000002C2
size: 133
offset: 0x00000852
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __compact_unwind
segname: __LD
addr: 0x0000000000000348
size: 32
offset: 0x000008D8
align: 3
reloff: 0x000009F8
nreloc: 1
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __eh_frame
segname: __TEXT
addr: 0x0000000000000368
size: 64
offset: 0x000008F8
align: 3
reloff: 0x00000000
nreloc: 0
flags: 0x6800000B
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __debug_line
segname: __DWARF
addr: 0x00000000000003A8
size: 150
offset: 0x00000938
align: 0
reloff: 0x00000A00
nreloc: 1
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- cmd: LC_VERSION_MIN_MACOSX
cmdsize: 16
version: 658432
sdk: 0
- cmd: LC_SYMTAB
cmdsize: 24
symoff: 2568
nsyms: 2
stroff: 2600
strsize: 36
- cmd: LC_DYSYMTAB
cmdsize: 80
ilocalsym: 0
nlocalsym: 0
iextdefsym: 0
nextdefsym: 1
iundefsym: 1
nundefsym: 1
tocoff: 0
ntoc: 0
modtaboff: 0
nmodtab: 0
extrefsymoff: 0
nextrefsyms: 0
indirectsymoff: 0
nindirectsyms: 0
extreloff: 0
nextrel: 0
locreloff: 0
nlocrel: 0
LinkEditData:
NameList:
- n_strx: 24
n_type: 0x0F
n_sect: 1
n_desc: 0
n_value: 0
- n_strx: 1
n_type: 0x01
n_sect: 0
n_desc: 0
n_value: 0
StringTable:
- ''
- _compilerrt_abort_impl
- ___absvdi2
- ''
DWARF:
debug_str:
- 'clang version 4.0.0 (trunk 290181) (llvm/trunk 290209)'
- ../compiler-rt/lib/builtins/absvdi2.c
- /Users/cbieneman/dev/open-source/llvm-build-rel
- int
- di_int
- long long int
- __absvdi2
- a
- N
- t
debug_abbrev:
- Code: 0x00000001
Tag: DW_TAG_compile_unit
Children: DW_CHILDREN_yes
Attributes:
- Attribute: DW_AT_producer
Form: DW_FORM_strp
- Attribute: DW_AT_language
Form: DW_FORM_data2
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_stmt_list
Form: DW_FORM_sec_offset
- Attribute: DW_AT_comp_dir
Form: DW_FORM_strp
- Attribute: DW_AT_low_pc
Form: DW_FORM_addr
- Attribute: DW_AT_high_pc
Form: DW_FORM_data4
- Code: 0x00000002
Tag: DW_TAG_base_type
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_encoding
Form: DW_FORM_data1
- Attribute: DW_AT_byte_size
Form: DW_FORM_data1
- Code: 0x00000003
Tag: DW_TAG_typedef
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_type
Form: DW_FORM_ref4
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_decl_file
Form: DW_FORM_data1
- Attribute: DW_AT_decl_line
Form: DW_FORM_data1
- Code: 0x00000004
Tag: DW_TAG_subprogram
Children: DW_CHILDREN_yes
Attributes:
- Attribute: DW_AT_low_pc
Form: DW_FORM_addr
- Attribute: DW_AT_high_pc
Form: DW_FORM_data4
- Attribute: DW_AT_frame_base
Form: DW_FORM_exprloc
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_decl_file
Form: DW_FORM_data1
- Attribute: DW_AT_decl_line
Form: DW_FORM_data1
- Attribute: DW_AT_prototyped
Form: DW_FORM_flag_present
- Attribute: DW_AT_type
Form: DW_FORM_ref4
- Attribute: DW_AT_external
Form: DW_FORM_flag_present
- Code: 0x00000005
Tag: DW_TAG_formal_parameter
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_location
Form: DW_FORM_exprloc
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_decl_file
Form: DW_FORM_data1
- Attribute: DW_AT_decl_line
Form: DW_FORM_data1
- Attribute: DW_AT_type
Form: DW_FORM_ref4
- Code: 0x00000006
Tag: DW_TAG_variable
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_location
Form: DW_FORM_exprloc
- Attribute: DW_AT_name
Form: DW_FORM_strp
- Attribute: DW_AT_decl_file
Form: DW_FORM_data1
- Attribute: DW_AT_decl_line
Form: DW_FORM_data1
- Attribute: DW_AT_type
Form: DW_FORM_ref4
- Code: 0x00000007
Tag: DW_TAG_const_type
Children: DW_CHILDREN_no
Attributes:
- Attribute: DW_AT_type
Form: DW_FORM_ref4
...
#CHECK: DWARF:
#CHECK: debug_str:
#CHECK: - 'clang version 4.0.0 (trunk 290181) (llvm/trunk 290209)'
#CHECK: - ../compiler-rt/lib/builtins/absvdi2.c
#CHECK: - /Users/cbieneman/dev/open-source/llvm-build-rel
#CHECK: - int
#CHECK: - di_int
#CHECK: - long long int
#CHECK: - __absvdi2
#CHECK: - a
#CHECK: - N
#CHECK: - t
#CHECK: debug_abbrev:
#CHECK: - Code: 0x00000001
#CHECK: Tag: DW_TAG_compile_unit
#CHECK: Children: DW_CHILDREN_yes
#CHECK: Attributes:
#CHECK: - Attribute: DW_AT_producer
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_language
#CHECK: Form: DW_FORM_data2
#CHECK: - Attribute: DW_AT_name
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_stmt_list
#CHECK: Form: DW_FORM_sec_offset
#CHECK: - Attribute: DW_AT_comp_dir
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_low_pc
#CHECK: Form: DW_FORM_addr
#CHECK: - Attribute: DW_AT_high_pc
#CHECK: Form: DW_FORM_data4
#CHECK: - Code: 0x00000002
#CHECK: Tag: DW_TAG_base_type
#CHECK: Children: DW_CHILDREN_no
#CHECK: Attributes:
#CHECK: - Attribute: DW_AT_name
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_encoding
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_byte_size
#CHECK: Form: DW_FORM_data1
#CHECK: - Code: 0x00000003
#CHECK: Tag: DW_TAG_typedef
#CHECK: Children: DW_CHILDREN_no
#CHECK: Attributes:
#CHECK: - Attribute: DW_AT_type
#CHECK: Form: DW_FORM_ref4
#CHECK: - Attribute: DW_AT_name
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_decl_file
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_decl_line
#CHECK: Form: DW_FORM_data1
#CHECK: - Code: 0x00000004
#CHECK: Tag: DW_TAG_subprogram
#CHECK: Children: DW_CHILDREN_yes
#CHECK: Attributes:
#CHECK: - Attribute: DW_AT_low_pc
#CHECK: Form: DW_FORM_addr
#CHECK: - Attribute: DW_AT_high_pc
#CHECK: Form: DW_FORM_data4
#CHECK: - Attribute: DW_AT_frame_base
#CHECK: Form: DW_FORM_exprloc
#CHECK: - Attribute: DW_AT_name
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_decl_file
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_decl_line
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_prototyped
#CHECK: Form: DW_FORM_flag_present
#CHECK: - Attribute: DW_AT_type
#CHECK: Form: DW_FORM_ref4
#CHECK: - Attribute: DW_AT_external
#CHECK: Form: DW_FORM_flag_present
#CHECK: - Code: 0x00000005
#CHECK: Tag: DW_TAG_formal_parameter
#CHECK: Children: DW_CHILDREN_no
#CHECK: Attributes:
#CHECK: - Attribute: DW_AT_location
#CHECK: Form: DW_FORM_exprloc
#CHECK: - Attribute: DW_AT_name
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_decl_file
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_decl_line
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_type
#CHECK: Form: DW_FORM_ref4
#CHECK: - Code: 0x00000006
#CHECK: Tag: DW_TAG_variable
#CHECK: Children: DW_CHILDREN_no
#CHECK: Attributes:
#CHECK: - Attribute: DW_AT_location
#CHECK: Form: DW_FORM_exprloc
#CHECK: - Attribute: DW_AT_name
#CHECK: Form: DW_FORM_strp
#CHECK: - Attribute: DW_AT_decl_file
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_decl_line
#CHECK: Form: DW_FORM_data1
#CHECK: - Attribute: DW_AT_type
#CHECK: Form: DW_FORM_ref4
#CHECK: - Code: 0x00000007
#CHECK: Tag: DW_TAG_const_type
#CHECK: Children: DW_CHILDREN_no
#CHECK: Attributes:
#CHECK: - Attribute: DW_AT_type
#CHECK: Form: DW_FORM_ref4
#CHECK: ...

View File

@ -0,0 +1,132 @@
# RUN: yaml2obj %s | obj2yaml | FileCheck %s
--- !mach-o
IsLittleEndian: true
FileHeader:
magic: 0xFEEDFACF
cputype: 0x01000007
cpusubtype: 0x00000003
filetype: 0x00000001
ncmds: 4
sizeofcmds: 512
flags: 0x00002000
reserved: 0x00000000
LoadCommands:
- cmd: LC_SEGMENT_64
cmdsize: 392
segname: ''
vmaddr: 0
vmsize: 240
fileoff: 544
filesize: 240
maxprot: 7
initprot: 7
nsects: 4
flags: 0
Sections:
- sectname: __text
segname: __TEXT
addr: 0x0000000000000000
size: 93
offset: 0x00000220
align: 4
reloff: 0x00000310
nreloc: 3
flags: 0x80000400
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __cstring
segname: __TEXT
addr: 0x000000000000005D
size: 48
offset: 0x0000027D
align: 0
reloff: 0x00000000
nreloc: 0
flags: 0x00000002
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __compact_unwind
segname: __LD
addr: 0x0000000000000090
size: 32
offset: 0x000002B0
align: 3
reloff: 0x00000328
nreloc: 1
flags: 0x02000000
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- sectname: __eh_frame
segname: __TEXT
addr: 0x00000000000000B0
size: 64
offset: 0x000002D0
align: 3
reloff: 0x00000000
nreloc: 0
flags: 0x6800000B
reserved1: 0x00000000
reserved2: 0x00000000
reserved3: 0x00000000
- cmd: LC_VERSION_MIN_MACOSX
cmdsize: 16
version: 658432
sdk: 0
- cmd: LC_SYMTAB
cmdsize: 24
symoff: 816
nsyms: 2
stroff: 848
strsize: 36
- cmd: LC_DYSYMTAB
cmdsize: 80
ilocalsym: 0
nlocalsym: 0
iextdefsym: 0
nextdefsym: 1
iundefsym: 1
nundefsym: 1
tocoff: 0
ntoc: 0
modtaboff: 0
nmodtab: 0
extrefsymoff: 0
nextrefsyms: 0
indirectsymoff: 0
nindirectsyms: 0
extreloff: 0
nextrel: 0
locreloff: 0
nlocrel: 0
LinkEditData:
NameList:
- n_strx: 24
n_type: 0x0F
n_sect: 1
n_desc: 0
n_value: 0
- n_strx: 1
n_type: 0x01
n_sect: 0
n_desc: 0
n_value: 0
StringTable:
- ''
- _compilerrt_abort_impl
- ___absvdi2
- ''
...
#CHECK: FileHeader:
#CHECK: magic: 0xFEEDFACF
#CHECK: cputype: 0x01000007
#CHECK: cpusubtype: 0x00000003
#CHECK: filetype: 0x00000001
#CHECK: ncmds: 4
#CHECK: sizeofcmds: 512
#CHECK: flags: 0x00002000
#CHECK: reserved: 0x00000000

View File

@ -36,7 +36,7 @@ class MachODumper {
void dumpExportTrie(std::unique_ptr<MachOYAML::Object> &Y);
void dumpSymbols(std::unique_ptr<MachOYAML::Object> &Y);
void dumpDebugAbbrev(DWARFContextInMemory &DCtx,
std::unique_ptr<MachOYAML::Object> &Y);
std::unique_ptr<MachOYAML::Object> &Y);
void dumpDebugStrings(DWARFContextInMemory &DCtx,
std::unique_ptr<MachOYAML::Object> &Y);
@ -165,12 +165,13 @@ const char *MachODumper::processLoadCommandData<MachO::rpath_command>(
Expected<std::unique_ptr<MachOYAML::Object>> MachODumper::dump() {
auto Y = make_unique<MachOYAML::Object>();
Y->IsLittleEndian = Obj.isLittleEndian();
dumpHeader(Y);
dumpLoadCommands(Y);
dumpLinkEdit(Y);
DWARFContextInMemory DICtx(Obj);
if(auto Err = dwarf2yaml(DICtx, Y->DWARF))
if (auto Err = dwarf2yaml(DICtx, Y->DWARF))
return errorCodeToError(Err);
return std::move(Y);
}
@ -451,12 +452,11 @@ void MachODumper::dumpSymbols(std::unique_ptr<MachOYAML::Object> &Y) {
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));
Obj.is64Bit()
? constructNameList<MachO::nlist_64>(
Obj.getSymbol64TableEntry(Symbol.getRawDataRefImpl()))
: constructNameList<MachO::nlist>(
Obj.getSymbolTableEntry(Symbol.getRawDataRefImpl()));
LEData.NameList.push_back(NLE);
}
@ -529,6 +529,6 @@ std::error_code macho2yaml(raw_ostream &Out, const object::Binary &Binary) {
}
return obj2yaml_error::success;
}
return obj2yaml_error::unsupported_obj_file_format;
}

View File

@ -16,9 +16,31 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SwapByteOrder.h"
using namespace llvm;
template <typename T>
void writeInteger(T Integer, raw_ostream &OS, bool IsLittleEndian) {
if (IsLittleEndian != sys::IsLittleEndianHost)
sys::swapByteOrder(Integer);
OS.write(reinterpret_cast<char *>(&Integer), sizeof(T));
}
void writeVariableSizedInteger(uint64_t Integer, size_t Size, raw_ostream &OS,
bool IsLittleEndian) {
if (8 == Size)
writeInteger((uint64_t)Integer, OS, IsLittleEndian);
else if (4 == Size)
writeInteger((uint32_t)Integer, OS, IsLittleEndian);
else if (2 == Size)
writeInteger((uint16_t)Integer, OS, IsLittleEndian);
else if (1 == Size)
writeInteger((uint8_t)Integer, OS, IsLittleEndian);
else
assert(false && "Invalid integer write size.");
}
void ZeroFillBytes(raw_ostream &OS, size_t Size) {
std::vector<uint8_t> FillData;
FillData.insert(FillData.begin(), Size, 0);
@ -49,34 +71,37 @@ void yaml2debug_abbrev(raw_ostream &OS, const DWARFYAML::Data &DI) {
void yaml2debug_aranges(raw_ostream &OS, const DWARFYAML::Data &DI) {
for (auto Range : DI.ARanges) {
auto HeaderStart = OS.tell();
OS.write(reinterpret_cast<char *>(&Range.Length), 4);
OS.write(reinterpret_cast<char *>(&Range.Version), 2);
OS.write(reinterpret_cast<char *>(&Range.CuOffset), 4);
OS.write(reinterpret_cast<char *>(&Range.AddrSize), 1);
OS.write(reinterpret_cast<char *>(&Range.SegSize), 1);
writeInteger((uint32_t)Range.Length, OS, DI.IsLittleEndian);
writeInteger((uint16_t)Range.Version, OS, DI.IsLittleEndian);
writeInteger((uint32_t)Range.CuOffset, OS, DI.IsLittleEndian);
writeInteger((uint8_t)Range.AddrSize, OS, DI.IsLittleEndian);
writeInteger((uint8_t)Range.SegSize, OS, DI.IsLittleEndian);
auto HeaderSize = OS.tell() - HeaderStart;
auto FirstDescriptor = alignTo(HeaderSize, Range.AddrSize * 2);
ZeroFillBytes(OS, FirstDescriptor - HeaderSize);
for (auto Descriptor : Range.Descriptors) {
OS.write(reinterpret_cast<char *>(&Descriptor.Address), Range.AddrSize);
OS.write(reinterpret_cast<char *>(&Descriptor.Length), Range.AddrSize);
writeVariableSizedInteger(Descriptor.Address, Range.AddrSize, OS,
DI.IsLittleEndian);
writeVariableSizedInteger(Descriptor.Length, Range.AddrSize, OS,
DI.IsLittleEndian);
}
ZeroFillBytes(OS, Range.AddrSize * 2);
}
}
void yaml2pubsection(raw_ostream &OS, const DWARFYAML::PubSection &Sect) {
OS.write(reinterpret_cast<const char *>(&Sect.Length), 4);
OS.write(reinterpret_cast<const char *>(&Sect.Version), 2);
OS.write(reinterpret_cast<const char *>(&Sect.UnitOffset), 4);
OS.write(reinterpret_cast<const char *>(&Sect.UnitSize), 4);
void yaml2pubsection(raw_ostream &OS, const DWARFYAML::PubSection &Sect,
bool IsLittleEndian) {
writeInteger((uint32_t)Sect.Length, OS, IsLittleEndian);
writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian);
writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian);
writeInteger((uint32_t)Sect.UnitSize, OS, IsLittleEndian);
for (auto Entry : Sect.Entries) {
OS.write(reinterpret_cast<const char *>(&Entry.DieOffset), 4);
writeInteger((uint32_t)Entry.DieOffset, OS, IsLittleEndian);
if (Sect.IsGNUStyle)
OS.write(reinterpret_cast<const char *>(&Entry.Descriptor), 4);
writeInteger((uint32_t)Entry.Descriptor, OS, IsLittleEndian);
OS.write(Entry.Name.data(), Entry.Name.size());
OS.write('\0');
}
}
}

View File

@ -41,8 +41,7 @@ private:
Error writeLoadCommands(raw_ostream &OS);
Error writeSectionData(raw_ostream &OS);
Error writeLinkEditData(raw_ostream &OS);
Error writeDWARFData(raw_ostream &OS,
std::vector<MachOYAML::Section> &Sections);
void writeBindOpcodes(raw_ostream &OS,
std::vector<MachOYAML::BindOpcode> &BindOpcodes);
// LinkEdit writers
@ -85,6 +84,9 @@ Error MachOWriter::writeHeader(raw_ostream &OS) {
Header.flags = Obj.Header.flags;
Header.reserved = Obj.Header.reserved;
if (Obj.IsLittleEndian != sys::IsLittleEndianHost)
MachO::swapStruct(Header);
auto header_size =
is64Bit ? sizeof(MachO::mach_header_64) : sizeof(MachO::mach_header);
OS.write((const char *)&Header, header_size);
@ -110,16 +112,20 @@ SectionType constructSection(MachOYAML::Section Sec) {
}
template <typename StructType>
size_t writeLoadCommandData(MachOYAML::LoadCommand &LC, raw_ostream &OS) {
size_t writeLoadCommandData(MachOYAML::LoadCommand &LC, raw_ostream &OS,
bool IsLittleEndian) {
return 0;
}
template <>
size_t writeLoadCommandData<MachO::segment_command>(MachOYAML::LoadCommand &LC,
raw_ostream &OS) {
raw_ostream &OS,
bool IsLittleEndian) {
size_t BytesWritten = 0;
for (const auto &Sec : LC.Sections) {
auto TempSec = constructSection<MachO::section>(Sec);
if (IsLittleEndian != sys::IsLittleEndianHost)
MachO::swapStruct(TempSec);
OS.write(reinterpret_cast<const char *>(&(TempSec)),
sizeof(MachO::section));
BytesWritten += sizeof(MachO::section);
@ -128,13 +134,14 @@ size_t writeLoadCommandData<MachO::segment_command>(MachOYAML::LoadCommand &LC,
}
template <>
size_t
writeLoadCommandData<MachO::segment_command_64>(MachOYAML::LoadCommand &LC,
raw_ostream &OS) {
size_t writeLoadCommandData<MachO::segment_command_64>(
MachOYAML::LoadCommand &LC, raw_ostream &OS, bool IsLittleEndian) {
size_t BytesWritten = 0;
for (const auto &Sec : LC.Sections) {
auto TempSec = constructSection<MachO::section_64>(Sec);
TempSec.reserved3 = Sec.reserved3;
if (IsLittleEndian != sys::IsLittleEndianHost)
MachO::swapStruct(TempSec);
OS.write(reinterpret_cast<const char *>(&(TempSec)),
sizeof(MachO::section_64));
BytesWritten += sizeof(MachO::section_64);
@ -153,19 +160,22 @@ size_t writePayloadString(MachOYAML::LoadCommand &LC, raw_ostream &OS) {
template <>
size_t writeLoadCommandData<MachO::dylib_command>(MachOYAML::LoadCommand &LC,
raw_ostream &OS) {
raw_ostream &OS,
bool IsLittleEndian) {
return writePayloadString(LC, OS);
}
template <>
size_t writeLoadCommandData<MachO::dylinker_command>(MachOYAML::LoadCommand &LC,
raw_ostream &OS) {
raw_ostream &OS,
bool IsLittleEndian) {
return writePayloadString(LC, OS);
}
template <>
size_t writeLoadCommandData<MachO::rpath_command>(MachOYAML::LoadCommand &LC,
raw_ostream &OS) {
raw_ostream &OS,
bool IsLittleEndian) {
return writePayloadString(LC, OS);
}
@ -190,20 +200,28 @@ void MachOWriter::ZeroToOffset(raw_ostream &OS, size_t Offset) {
Error MachOWriter::writeLoadCommands(raw_ostream &OS) {
for (auto &LC : Obj.LoadCommands) {
size_t BytesWritten = 0;
llvm::MachO::macho_load_command Data = LC.Data;
#define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \
case MachO::LCName: \
OS.write(reinterpret_cast<const char *>(&(LC.Data.LCStruct##_data)), \
if (Obj.IsLittleEndian != sys::IsLittleEndianHost) \
MachO::swapStruct(Data.LCStruct##_data); \
OS.write(reinterpret_cast<const char *>(&(Data.LCStruct##_data)), \
sizeof(MachO::LCStruct)); \
BytesWritten = sizeof(MachO::LCStruct); \
BytesWritten += writeLoadCommandData<MachO::LCStruct>(LC, OS); \
BytesWritten += \
writeLoadCommandData<MachO::LCStruct>(LC, OS, Obj.IsLittleEndian); \
break;
switch (LC.Data.load_command_data.cmd) {
default:
OS.write(reinterpret_cast<const char *>(&(LC.Data.load_command_data)),
if (Obj.IsLittleEndian != sys::IsLittleEndianHost)
MachO::swapStruct(Data.load_command_data);
OS.write(reinterpret_cast<const char *>(&(Data.load_command_data)),
sizeof(MachO::load_command));
BytesWritten = sizeof(MachO::load_command);
BytesWritten += writeLoadCommandData<MachO::load_command>(LC, OS);
BytesWritten +=
writeLoadCommandData<MachO::load_command>(LC, OS, Obj.IsLittleEndian);
break;
#include "llvm/Support/MachO.def"
}
@ -230,41 +248,38 @@ Error MachOWriter::writeLoadCommands(raw_ostream &OS) {
}
Error MachOWriter::writeSectionData(raw_ostream &OS) {
bool FoundLinkEditSeg = false;
for (auto &LC : Obj.LoadCommands) {
switch (LC.Data.load_command_data.cmd) {
case MachO::LC_SEGMENT:
case MachO::LC_SEGMENT_64:
auto currOffset = OS.tell() - fileStart;
auto segname = LC.Data.segment_command_data.segname;
uint64_t segOff = is64Bit ? LC.Data.segment_command_64_data.fileoff
: LC.Data.segment_command_data.fileoff;
if (0 == strncmp(&segname[0], "__LINKEDIT", 16)) {
if (0 == strncmp(&LC.Data.segment_command_data.segname[0], "__LINKEDIT", 16)) {
FoundLinkEditSeg = true;
if (auto Err = writeLinkEditData(OS))
return Err;
} else if (0 == strncmp(&segname[0], "__DWARF", 16)) {
if (auto Err = writeDWARFData(OS, LC.Sections))
return Err;
} else {
}
for (auto &Sec : LC.Sections) {
ZeroToOffset(OS, Sec.offset);
// Zero Fill any data between the end of the last thing we wrote and the
// start of this section.
if (currOffset < segOff) {
ZeroFillBytes(OS, segOff - currOffset);
}
for (auto &Sec : LC.Sections) {
// Zero Fill any data between the end of the last thing we wrote and
// the
// start of this section.
assert(
(OS.tell() - fileStart <= Sec.offset ||
Sec.offset == (uint32_t)0) &&
"Wrote too much data somewhere, section offsets don't line up.");
currOffset = OS.tell() - fileStart;
if (currOffset < Sec.offset) {
ZeroFillBytes(OS, Sec.offset - currOffset);
assert((OS.tell() - fileStart <= Sec.offset ||
Sec.offset == (uint32_t)0) &&
"Wrote too much data somewhere, section offsets don't line up.");
if (0 == strncmp(&Sec.segname[0], "__DWARF", 16)) {
if (0 == strncmp(&Sec.sectname[0], "__debug_str", 16)) {
yaml2debug_str(OS, Obj.DWARF);
} else if (0 == strncmp(&Sec.sectname[0], "__debug_abbrev", 16)) {
yaml2debug_abbrev(OS, Obj.DWARF);
} else if (0 == strncmp(&Sec.sectname[0], "__debug_aranges", 16)) {
yaml2debug_aranges(OS, Obj.DWARF);
} else if (0 == strncmp(&Sec.sectname[0], "__debug_pubnames", 16)) {
yaml2pubsection(OS, Obj.DWARF.PubNames, Obj.IsLittleEndian);
} else if (0 == strncmp(&Sec.sectname[0], "__debug_pubtypes", 16)) {
yaml2pubsection(OS, Obj.DWARF.PubTypes, Obj.IsLittleEndian);
}
} else {
// Fills section data with 0xDEADBEEF
Fill(OS, Sec.size, 0xDEADBEEFu);
}
@ -275,6 +290,12 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) {
break;
}
}
// Old PPC Object Files didn't have __LINKEDIT segments, the data was just
// stuck at the end of the file.
if (!FoundLinkEditSeg) {
if (auto Err = writeLinkEditData(OS))
return Err;
}
return Error::success();
}
@ -328,13 +349,17 @@ Error MachOWriter::writeExportTrie(raw_ostream &OS) {
}
template <typename NListType>
void writeNListEntry(MachOYAML::NListEntry &NLE, raw_ostream &OS) {
void writeNListEntry(MachOYAML::NListEntry &NLE, raw_ostream &OS,
bool IsLittleEndian) {
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;
if (sys::IsBigEndianHost)
MachO::swapStruct(ListEntry);
OS.write(reinterpret_cast<const char *>(&ListEntry), sizeof(NListType));
}
@ -384,25 +409,6 @@ Error MachOWriter::writeLinkEditData(raw_ostream &OS) {
return Error::success();
}
Error MachOWriter::writeDWARFData(raw_ostream &OS,
std::vector<MachOYAML::Section> &Sections) {
for (auto Section : Sections) {
ZeroToOffset(OS, Section.offset);
if (0 == strncmp(&Section.sectname[0], "__debug_str", 16)) {
yaml2debug_str(OS, Obj.DWARF);
} else if (0 == strncmp(&Section.sectname[0], "__debug_abbrev", 16)) {
yaml2debug_abbrev(OS, Obj.DWARF);
} else if (0 == strncmp(&Section.sectname[0], "__debug_aranges", 16)) {
yaml2debug_aranges(OS, Obj.DWARF);
} else if (0 == strncmp(&Section.sectname[0], "__debug_pubnames", 16)) {
yaml2pubsection(OS, Obj.DWARF.PubNames);
} else if (0 == strncmp(&Section.sectname[0], "__debug_pubtypes", 16)) {
yaml2pubsection(OS, Obj.DWARF.PubTypes);
}
}
return Error::success();
}
Error MachOWriter::writeRebaseOpcodes(raw_ostream &OS) {
MachOYAML::LinkEditData &LinkEdit = Obj.LinkEdit;
@ -434,9 +440,9 @@ Error MachOWriter::writeLazyBindOpcodes(raw_ostream &OS) {
Error MachOWriter::writeNameList(raw_ostream &OS) {
for (auto NLE : Obj.LinkEdit.NameList) {
if (is64Bit)
writeNListEntry<MachO::nlist_64>(NLE, OS);
writeNListEntry<MachO::nlist_64>(NLE, OS, Obj.IsLittleEndian);
else
writeNListEntry<MachO::nlist>(NLE, OS);
writeNListEntry<MachO::nlist>(NLE, OS, Obj.IsLittleEndian);
}
return Error::success();
}

View File

@ -38,13 +38,12 @@ int yaml2coff(llvm::COFFYAML::Object &Doc, llvm::raw_ostream &Out);
int yaml2elf(llvm::ELFYAML::Object &Doc, llvm::raw_ostream &Out);
int yaml2macho(llvm::yaml::YamlObjectFile &Doc, llvm::raw_ostream &Out);
void yaml2debug_abbrev(llvm::raw_ostream &OS,
const llvm::DWARFYAML::Data &DI);
void yaml2debug_str(llvm::raw_ostream &OS,
const llvm::DWARFYAML::Data &DI);
void yaml2debug_abbrev(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI);
void yaml2debug_str(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI);
void yaml2debug_aranges(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI);
void yaml2pubsection(llvm::raw_ostream &OS,
const llvm::DWARFYAML::PubSection &Sect);
const llvm::DWARFYAML::PubSection &Sect,
bool IsLittleEndian);
#endif