llvm.org GIT mirror llvm / 1074344
[yaml2obj/obj2yaml][MachO] Allow setting custom section data Reviewers: alexshap, jhenderson, rupprecht Reviewed By: alexshap, jhenderson Subscribers: abrachet, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D65799 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@369348 91177308-0d34-0410-b5e6-96231b3b80d8 Seiya Nuta a month ago
9 changed file(s) with 223 addition(s) and 26 deletion(s). Raw diff Collapse all Expand all
580580 uint32_t reserved3;
581581 };
582582
583 inline bool isVirtualSection(uint8_t type) {
584 return (type == MachO::S_ZEROFILL || type == MachO::S_GB_ZEROFILL ||
585 type == MachO::S_THREAD_LOCAL_ZEROFILL);
586 }
587
583588 struct fvmlib {
584589 uint32_t name;
585590 uint32_t minor_version;
296296 uint64_t getSectionAddress(DataRefImpl Sec) const override;
297297 uint64_t getSectionIndex(DataRefImpl Sec) const override;
298298 uint64_t getSectionSize(DataRefImpl Sec) const override;
299 ArrayRef getSectionContents(uint32_t Offset, uint64_t Size) const;
299300 Expected>
300301 getSectionContents(DataRefImpl Sec) const override;
301302 uint64_t getSectionAlignment(DataRefImpl Sec) const override;
1717 #include "llvm/ADT/StringRef.h"
1818 #include "llvm/BinaryFormat/MachO.h"
1919 #include "llvm/ObjectYAML/DWARFYAML.h"
20 #include "llvm/ObjectYAML/YAML.h"
2021 #include "llvm/Support/YAMLTraits.h"
2122 #include
2223 #include
3839 llvm::yaml::Hex32 reserved1;
3940 llvm::yaml::Hex32 reserved2;
4041 llvm::yaml::Hex32 reserved3;
42 Optional content;
4143 };
4244
4345 struct FileHeader {
197199
198200 template <> struct MappingTraits {
199201 static void mapping(IO &IO, MachOYAML::Section &Section);
202 static StringRef validate(IO &io, MachOYAML::Section &Section);
200203 };
201204
202205 template <> struct MappingTraits {
19441944 return SectSize;
19451945 }
19461946
1947 ArrayRef MachOObjectFile::getSectionContents(uint32_t Offset,
1948 uint64_t Size) const {
1949 return arrayRefFromStringRef(getData().substr(Offset, Size));
1950 }
1951
19471952 Expected>
19481953 MachOObjectFile::getSectionContents(DataRefImpl Sec) const {
19491954 uint32_t Offset;
19591964 Size = Sect.size;
19601965 }
19611966
1962 return arrayRefFromStringRef(getData().substr(Offset, Size));
1967 return getSectionContents(Offset, Size);
19631968 }
19641969
19651970 uint64_t MachOObjectFile::getSectionAlignment(DataRefImpl Sec) const {
259259 }
260260 }
261261 return Error::success();
262 }
263
264 static bool isVirtualSection(uint8_t type) {
265 return (type == MachO::S_ZEROFILL || type == MachO::S_GB_ZEROFILL ||
266 type == MachO::S_THREAD_LOCAL_ZEROFILL);
267262 }
268263
269264 Error MachOWriter::writeSectionData(raw_ostream &OS) {
310305 }
311306
312307 // Skip if it's a virtual section.
313 if (isVirtualSection(Sec.flags & MachO::SECTION_TYPE))
308 if (MachO::isVirtualSection(Sec.flags & MachO::SECTION_TYPE))
314309 continue;
315310
316 // Fill section data with 0xDEADBEEF
317 Fill(OS, Sec.size, 0xDEADBEEFu);
311 if (Sec.content) {
312 yaml::BinaryRef Content = *Sec.content;
313 Content.writeAsBinary(OS);
314 ZeroFillBytes(OS, Sec.size - Content.binary_size());
315 } else {
316 // Fill section data with 0xDEADBEEF.
317 Fill(OS, Sec.size, 0xDEADBEEFu);
318 }
318319 }
319320 uint64_t segSize = is64Bit ? LC.Data.segment_command_64_data.filesize
320321 : LC.Data.segment_command_data.filesize;
286286 IO.mapRequired("reserved1", Section.reserved1);
287287 IO.mapRequired("reserved2", Section.reserved2);
288288 IO.mapOptional("reserved3", Section.reserved3);
289 IO.mapOptional("content", Section.content);
290 }
291
292 StringRef
293 MappingTraits::validate(IO &IO,
294 MachOYAML::Section &Section) {
295 if (Section.content && Section.size < Section.content->binary_size())
296 return "Section size must be greater than or equal to the content size";
297 return {};
289298 }
290299
291300 void MappingTraits::mapping(
0 ## Show that yaml2obj supports custom section data for Mach-O YAML inputs.
1
2 ## Case 1: The size of content is greater than the section size.
3 # RUN: not yaml2obj --docnum=1 %s -o %t1 2>&1 | FileCheck %s --check-prefix=CASE1
4 # CASE1: error: Section size must be greater than or equal to the content size
5
6 --- !mach-o
7 FileHeader:
8 magic: 0xFEEDFACF
9 cputype: 0x01000007
10 cpusubtype: 0x00000003
11 filetype: 0x00000001
12 ncmds: 1
13 sizeofcmds: 232
14 flags: 0x00002000
15 reserved: 0x00000000
16 LoadCommands:
17 - cmd: LC_SEGMENT_64
18 cmdsize: 232
19 segname: ''
20 vmaddr: 0
21 vmsize: 4
22 fileoff: 392
23 filesize: 4
24 maxprot: 7
25 initprot: 7
26 nsects: 1
27 flags: 0
28 Sections:
29 - sectname: __data
30 segname: __DATA
31 addr: 0x0000000000000000
32 size: 0
33 offset: 0x00000188
34 align: 2
35 reloff: 0x00000000
36 nreloc: 0
37 flags: 0x00000000
38 reserved1: 0x00000000
39 reserved2: 0x00000000
40 reserved3: 0x00000000
41 content: CDAB3412
42
43 ## Case 2: The content size equals the section size.
44 # RUN: yaml2obj --docnum=2 %s > %t2
45 # RUN: llvm-readobj --sections --section-data %t2 | FileCheck %s --check-prefix=CASE2
46 # CASE2: Index: 0
47 # CASE2-NEXT: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
48 # CASE2-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
49 # CASE2-NEXT: Address: 0x0
50 # CASE2-NEXT: Size: 0x4
51 # CASE2-NEXT: Offset: 392
52 # CASE2-NEXT: Alignment: 2
53 # CASE2-NEXT: RelocationOffset: 0x0
54 # CASE2-NEXT: RelocationCount: 0
55 # CASE2-NEXT: Type: Regular (0x0)
56 # CASE2-NEXT: Attributes [ (0x0)
57 # CASE2-NEXT: ]
58 # CASE2-NEXT: Reserved1: 0x0
59 # CASE2-NEXT: Reserved2: 0x0
60 # CASE2-NEXT: Reserved3: 0x0
61 # CASE2-NEXT: SectionData (
62 # CASE2-NEXT: 0000: CDAB3412 |..4.|
63 # CASE2-NEXT: )
64
65 --- !mach-o
66 FileHeader:
67 magic: 0xFEEDFACF
68 cputype: 0x01000007
69 cpusubtype: 0x00000003
70 filetype: 0x00000001
71 ncmds: 1
72 sizeofcmds: 232
73 flags: 0x00002000
74 reserved: 0x00000000
75 LoadCommands:
76 - cmd: LC_SEGMENT_64
77 cmdsize: 232
78 segname: ''
79 vmaddr: 0
80 vmsize: 4
81 fileoff: 392
82 filesize: 4
83 maxprot: 7
84 initprot: 7
85 nsects: 1
86 flags: 0
87 Sections:
88 - sectname: __data
89 segname: __DATA
90 addr: 0x0000000000000000
91 size: 4
92 offset: 0x00000188
93 align: 2
94 reloff: 0x00000000
95 nreloc: 0
96 flags: 0x00000000
97 reserved1: 0x00000000
98 reserved2: 0x00000000
99 reserved3: 0x00000000
100 content: CDAB3412
101
102 ## Case 3: The content size is less than the section size. In this case, the area
103 ## after the custom content is filled with zeroes.
104 # RUN: yaml2obj --docnum=3 %s > %t3
105 # RUN: llvm-readobj --sections --section-data %t3 | FileCheck %s --check-prefix=CASE3
106 # CASE3: Index: 0
107 # CASE3-NEXT: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
108 # CASE3-NEXT: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
109 # CASE3-NEXT: Address: 0x0
110 # CASE3-NEXT: Size: 0x4
111 # CASE3-NEXT: Offset: 392
112 # CASE3-NEXT: Alignment: 2
113 # CASE3-NEXT: RelocationOffset: 0x0
114 # CASE3-NEXT: RelocationCount: 0
115 # CASE3-NEXT: Type: Regular (0x0)
116 # CASE3-NEXT: Attributes [ (0x0)
117 # CASE3-NEXT: ]
118 # CASE3-NEXT: Reserved1: 0x0
119 # CASE3-NEXT: Reserved2: 0x0
120 # CASE3-NEXT: Reserved3: 0x0
121 # CASE3-NEXT: SectionData (
122 # CASE3-NEXT: 0000: AA000000 |....|
123 # CASE3-NEXT: )
124
125 --- !mach-o
126 FileHeader:
127 magic: 0xFEEDFACF
128 cputype: 0x01000007
129 cpusubtype: 0x00000003
130 filetype: 0x00000001
131 ncmds: 1
132 sizeofcmds: 232
133 flags: 0x00002000
134 reserved: 0x00000000
135 LoadCommands:
136 - cmd: LC_SEGMENT_64
137 cmdsize: 232
138 segname: ''
139 vmaddr: 0
140 vmsize: 4
141 fileoff: 392
142 filesize: 4
143 maxprot: 7
144 initprot: 7
145 nsects: 1
146 flags: 0
147 Sections:
148 - sectname: __data
149 segname: __DATA
150 addr: 0x0000000000000000
151 size: 4
152 offset: 0x00000188
153 align: 2
154 reloff: 0x00000000
155 nreloc: 0
156 flags: 0x00000000
157 reserved1: 0x00000000
158 reserved2: 0x00000000
159 reserved3: 0x00000000
160 content: AA
162162 - ''
163163 ...
164164
165 # CHECK: Sections:
166 # CHECK-NEXT: - sectname: __text
165 # CHECK: - sectname: __text
167166 # CHECK-NEXT: segname: __TEXT
168167 # CHECK-NEXT: addr: 0x0000000000000000
169168 # CHECK-NEXT: size: 72
175174 # CHECK-NEXT: reserved1: 0x00000000
176175 # CHECK-NEXT: reserved2: 0x00000000
177176 # CHECK-NEXT: reserved3: 0x00000000
177 # CHECK-NEXT: content: {{(EFBEADDE){18}$}}
178178 # CHECK-NEXT: - sectname: __data
179179 # CHECK-NEXT: segname: __DATA
180180 # CHECK-NEXT: addr: 0x0000000000000048
187187 # CHECK-NEXT: reserved1: 0x00000000
188188 # CHECK-NEXT: reserved2: 0x00000000
189189 # CHECK-NEXT: reserved3: 0x00000000
190 # CHECK-NEXT: content: EFBEADDE{{$}}
190191 # CHECK-NEXT: - sectname: __bss
191192 # CHECK-NEXT: segname: __DATA
192193 # CHECK-NEXT: addr: 0x00000000000000A0
223224 # CHECK-NEXT: reserved1: 0x00000000
224225 # CHECK-NEXT: reserved2: 0x00000000
225226 # CHECK-NEXT: reserved3: 0x00000000
227 # CHECK-NEXT: content: {{.*}}
3838 void dumpDebugStrings(DWARFContext &DCtx,
3939 std::unique_ptr &Y);
4040
41 template
42 MachOYAML::Section constructSectionCommon(SectionType Sec);
43 template
44 MachOYAML::Section constructSection(SectionType Sec);
45 template
46 const char *
47 extractSections(const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd,
48 std::vector &Sections);
49
4150 public:
4251 MachODumper(const object::MachOObjectFile &O) : Obj(O) {}
4352 Expected> dump();
4554
4655 #define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \
4756 case MachO::LCName: \
48 memcpy((void *) & (LC.Data.LCStruct##_data), LoadCmd.Ptr, \
57 memcpy((void *)&(LC.Data.LCStruct##_data), LoadCmd.Ptr, \
4958 sizeof(MachO::LCStruct)); \
5059 if (Obj.isLittleEndian() != sys::IsLittleEndianHost) \
5160 MachO::swapStruct(LC.Data.LCStruct##_data); \
5362 break;
5463
5564 template
56 MachOYAML::Section constructSectionCommon(SectionType Sec) {
65 MachOYAML::Section MachODumper::constructSectionCommon(SectionType Sec) {
5766 MachOYAML::Section TempSec;
5867 memcpy(reinterpret_cast(&TempSec.sectname[0]), &Sec.sectname[0], 16);
5968 memcpy(reinterpret_cast(&TempSec.segname[0]), &Sec.segname[0], 16);
6776 TempSec.reserved1 = Sec.reserved1;
6877 TempSec.reserved2 = Sec.reserved2;
6978 TempSec.reserved3 = 0;
79 if (!MachO::isVirtualSection(Sec.flags & MachO::SECTION_TYPE))
80 TempSec.content =
81 yaml::BinaryRef(Obj.getSectionContents(Sec.offset, Sec.size));
7082 return TempSec;
7183 }
7284
73 template
74 MachOYAML::Section constructSection(SectionType Sec);
75
76 template <> MachOYAML::Section constructSection(MachO::section Sec) {
85 template <>
86 MachOYAML::Section MachODumper::constructSection(MachO::section Sec) {
7787 MachOYAML::Section TempSec = constructSectionCommon(Sec);
7888 TempSec.reserved3 = 0;
7989 return TempSec;
8090 }
8191
82 template <> MachOYAML::Section constructSection(MachO::section_64 Sec) {
92 template <>
93 MachOYAML::Section MachODumper::constructSection(MachO::section_64 Sec) {
8394 MachOYAML::Section TempSec = constructSectionCommon(Sec);
8495 TempSec.reserved3 = Sec.reserved3;
8596 return TempSec;
8697 }
8798
8899 template
89 const char *
90 extractSections(const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd,
91 std::vector &Sections,
92 bool IsLittleEndian) {
100 const char *MachODumper::extractSections(
101 const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd,
102 std::vector &Sections) {
93103 auto End = LoadCmd.Ptr + LoadCmd.C.cmdsize;
94104 const SectionType *Curr =
95105 reinterpret_cast(LoadCmd.Ptr + sizeof(SegmentType));
96106 for (; reinterpret_cast(Curr) < End; Curr++) {
97 if (IsLittleEndian != sys::IsLittleEndianHost) {
107 if (Obj.isLittleEndian() != sys::IsLittleEndianHost) {
98108 SectionType Sec;
99109 memcpy((void *)&Sec, Curr, sizeof(SectionType));
100110 MachO::swapStruct(Sec);
117127 const char *MachODumper::processLoadCommandData(
118128 MachOYAML::LoadCommand &LC,
119129 const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd) {
120 return extractSections(
121 LoadCmd, LC.Sections, Obj.isLittleEndian());
130 return extractSections(LoadCmd,
131 LC.Sections);
122132 }
123133
124134 template <>
126136 MachOYAML::LoadCommand &LC,
127137 const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd) {
128138 return extractSections(
129 LoadCmd, LC.Sections, Obj.isLittleEndian());
139 LoadCmd, LC.Sections);
130140 }
131141
132142 template