@@ -86,95 +86,68 @@ func (r loadCmdReader) WriteAt(offset int64, data interface{}) error {
86
86
}
87
87
88
88
// machoCombineDwarf merges dwarf info generated by dsymutil into a macho executable.
89
- // machoCombineDwarf returns true and skips merging if the input executable is for iOS.
90
89
//
91
90
// With internal linking, DWARF is embedded into the executable, this lets us do the
92
91
// same for external linking.
93
- // inexe is the path to the executable with no DWARF. It must have enough room in the macho
92
+ // exef is the file of the executable with no DWARF. It must have enough room in the macho
94
93
// header to add the DWARF sections. (Use ld's -headerpad option)
94
+ // exem is the macho representation of exef.
95
95
// dsym is the path to the macho file containing DWARF from dsymutil.
96
96
// outexe is the path where the combined executable should be saved.
97
- func machoCombineDwarf (ctxt * Link , inexe , dsym , outexe string ) (bool , error ) {
98
- exef , err := os .Open (inexe )
99
- if err != nil {
100
- return false , err
101
- }
102
- exem , err := macho .NewFile (exef )
103
- if err != nil {
104
- return false , err
105
- }
106
- cmdOffset := unsafe .Sizeof (exem .FileHeader )
107
- is64bit := exem .Magic == macho .Magic64
108
- if is64bit {
109
- // mach_header_64 has one extra uint32.
110
- cmdOffset += unsafe .Sizeof (exem .Magic )
111
- }
112
- // Check for LC_VERSION_MIN_IPHONEOS.
113
- reader := loadCmdReader {next : int64 (cmdOffset ), f : exef , order : exem .ByteOrder }
114
- for i := uint32 (0 ); i < exem .Ncmd ; i ++ {
115
- cmd , err := reader .Next ()
116
- if err != nil {
117
- return false , err
118
- }
119
- if cmd .Cmd == LC_VERSION_MIN_IPHONEOS {
120
- // The executable is for iOS, which doesn't support unmapped
121
- // segments such as our __DWARF segment. Skip combining.
122
- return true , nil
123
- }
124
- }
97
+ func machoCombineDwarf (ctxt * Link , exef * os.File , exem * macho.File , dsym , outexe string ) error {
125
98
dwarff , err := os .Open (dsym )
126
99
if err != nil {
127
- return false , err
100
+ return err
128
101
}
129
102
outf , err := os .Create (outexe )
130
103
if err != nil {
131
- return false , err
104
+ return err
132
105
}
133
106
outf .Chmod (0755 )
134
107
135
108
dwarfm , err := macho .NewFile (dwarff )
136
109
if err != nil {
137
- return false , err
110
+ return err
138
111
}
139
112
140
113
// The string table needs to be the last thing in the file
141
114
// for code signing to work. So we'll need to move the
142
115
// linkedit section, but all the others can be copied directly.
143
116
linkseg = exem .Segment ("__LINKEDIT" )
144
117
if linkseg == nil {
145
- return false , fmt .Errorf ("missing __LINKEDIT segment" )
118
+ return fmt .Errorf ("missing __LINKEDIT segment" )
146
119
}
147
120
148
121
if _ , err = exef .Seek (0 , 0 ); err != nil {
149
- return false , err
122
+ return err
150
123
}
151
124
if _ , err := io .CopyN (outf , exef , int64 (linkseg .Offset )); err != nil {
152
- return false , err
125
+ return err
153
126
}
154
127
155
128
realdwarf = dwarfm .Segment ("__DWARF" )
156
129
if realdwarf == nil {
157
- return false , fmt .Errorf ("missing __DWARF segment" )
130
+ return fmt .Errorf ("missing __DWARF segment" )
158
131
}
159
132
160
133
// Try to compress the DWARF sections. This includes some Apple
161
134
// proprietary sections like __apple_types.
162
135
compressedSects , compressedBytes , err := machoCompressSections (ctxt , dwarfm )
163
136
if err != nil {
164
- return false , err
137
+ return err
165
138
}
166
139
167
140
// Now copy the dwarf data into the output.
168
141
// Kernel requires all loaded segments to be page-aligned in the file,
169
142
// even though we mark this one as being 0 bytes of virtual address space.
170
143
dwarfstart = machoCalcStart (realdwarf .Offset , linkseg .Offset , pageAlign )
171
144
if _ , err = outf .Seek (dwarfstart , 0 ); err != nil {
172
- return false , err
145
+ return err
173
146
}
174
147
dwarfaddr = int64 ((linkseg .Addr + linkseg .Memsz + 1 << pageAlign - 1 ) &^ (1 << pageAlign - 1 ))
175
148
176
149
if _ , err = dwarff .Seek (int64 (realdwarf .Offset ), 0 ); err != nil {
177
- return false , err
150
+ return err
178
151
}
179
152
180
153
// Write out the compressed sections, or the originals if we gave up
@@ -183,62 +156,68 @@ func machoCombineDwarf(ctxt *Link, inexe, dsym, outexe string) (bool, error) {
183
156
if compressedBytes != nil {
184
157
dwarfsize = uint64 (len (compressedBytes ))
185
158
if _ , err := outf .Write (compressedBytes ); err != nil {
186
- return false , err
159
+ return err
187
160
}
188
161
} else {
189
162
if _ , err := io .CopyN (outf , dwarff , int64 (realdwarf .Filesz )); err != nil {
190
- return false , err
163
+ return err
191
164
}
192
165
dwarfsize = realdwarf .Filesz
193
166
}
194
167
195
168
// And finally the linkedit section.
196
169
if _ , err = exef .Seek (int64 (linkseg .Offset ), 0 ); err != nil {
197
- return false , err
170
+ return err
198
171
}
199
172
linkstart = machoCalcStart (linkseg .Offset , uint64 (dwarfstart )+ dwarfsize , pageAlign )
200
173
linkoffset = uint32 (linkstart - int64 (linkseg .Offset ))
201
174
if _ , err = outf .Seek (linkstart , 0 ); err != nil {
202
- return false , err
175
+ return err
203
176
}
204
177
if _ , err := io .Copy (outf , exef ); err != nil {
205
- return false , err
178
+ return err
206
179
}
207
180
208
181
// Now we need to update the headers.
209
182
textsect := exem .Section ("__text" )
210
183
if linkseg == nil {
211
- return false , fmt .Errorf ("missing __text section" )
184
+ return fmt .Errorf ("missing __text section" )
212
185
}
213
186
187
+ cmdOffset := unsafe .Sizeof (exem .FileHeader )
188
+ is64bit := exem .Magic == macho .Magic64
189
+ if is64bit {
190
+ // mach_header_64 has one extra uint32.
191
+ cmdOffset += unsafe .Sizeof (exem .Magic )
192
+ }
214
193
dwarfCmdOffset := int64 (cmdOffset ) + int64 (exem .FileHeader .Cmdsz )
215
194
availablePadding := int64 (textsect .Offset ) - dwarfCmdOffset
216
195
if availablePadding < int64 (realdwarf .Len ) {
217
- return false , fmt .Errorf ("No room to add dwarf info. Need at least %d padding bytes, found %d" , realdwarf .Len , availablePadding )
196
+ return fmt .Errorf ("No room to add dwarf info. Need at least %d padding bytes, found %d" , realdwarf .Len , availablePadding )
218
197
}
219
198
// First, copy the dwarf load command into the header. It will be
220
199
// updated later with new offsets and lengths as necessary.
221
200
if _ , err = outf .Seek (dwarfCmdOffset , 0 ); err != nil {
222
- return false , err
201
+ return err
223
202
}
224
203
if _ , err := io .CopyN (outf , bytes .NewReader (realdwarf .Raw ()), int64 (realdwarf .Len )); err != nil {
225
- return false , err
204
+ return err
226
205
}
227
206
if _ , err = outf .Seek (int64 (unsafe .Offsetof (exem .FileHeader .Ncmd )), 0 ); err != nil {
228
- return false , err
207
+ return err
229
208
}
230
209
if err = binary .Write (outf , exem .ByteOrder , exem .Ncmd + 1 ); err != nil {
231
- return false , err
210
+ return err
232
211
}
233
212
if err = binary .Write (outf , exem .ByteOrder , exem .Cmdsz + realdwarf .Len ); err != nil {
234
- return false , err
213
+ return err
235
214
}
236
215
237
- reader = loadCmdReader {next : int64 (cmdOffset ), f : outf , order : exem .ByteOrder }
216
+ reader : = loadCmdReader {next : int64 (cmdOffset ), f : outf , order : exem .ByteOrder }
238
217
for i := uint32 (0 ); i < exem .Ncmd ; i ++ {
239
218
cmd , err := reader .Next ()
240
219
if err != nil {
241
- return false , err
220
+ return err
242
221
}
243
222
switch cmd .Cmd {
244
223
case macho .LoadCmdSegment64 :
@@ -261,11 +240,11 @@ func machoCombineDwarf(ctxt *Link, inexe, dsym, outexe string) (bool, error) {
261
240
err = fmt .Errorf ("Unknown load command 0x%x (%s)\n " , int (cmd .Cmd ), cmd .Cmd )
262
241
}
263
242
if err != nil {
264
- return false , err
243
+ return err
265
244
}
266
245
}
267
246
// Do the final update of the DWARF segment's load command.
268
- return false , machoUpdateDwarfHeader (& reader , ctxt .BuildMode , compressedSects )
247
+ return machoUpdateDwarfHeader (& reader , ctxt .BuildMode , compressedSects )
269
248
}
270
249
271
250
// machoCompressSections tries to compress the DWARF segments in dwarfm,
0 commit comments