E_NO_SUCH_BLOG

Programming, philosophy, pedaling.


ruby-macho 2.0.0

Jul 5, 2018

Tags: ruby-macho, ruby, programming, devblog

I released ruby-macho 2.0.0 onto an unsuspecting world a few days ago. Here are some release notes. I haven't done any in a while, so I'll be including some changes from 1.2.0 and 1.3.0 as well.

Ruby 2.5 support

Landed in 1.2.0.

This is a little bit of an exaggeration, since it required no code changes. But we now officially support it!

LC_BUILD_VERSION and LC_NOTE

Landed in 1.2.0.

Apple added two new load commands to the Mach-O spec, so we had to implement them as well. LC_BUILD_VERSION is a beefed up LC_VERSION_MIN_MACOSX that includes optional version information for build tools (think clang, ld, etc.), while LC_NOTE just points to an arbitrary data region within the binary.

Many thanks to Misty for the BuildVersionCommand implementation!

Library-wide #to_h support

Landed in 1.3.0.pre.1.

Virtually all classes in ruby-macho now support #to_h, making it easy to get an interchangeable representation of a Mach-O binary (or slice of a binary):

macho = MachO.open("/bin/bash")
macho.load_commands.first.to_h
# => {"segname"=>"__PAGEZERO", "vmaddr"=>0, "vmsize"=>4096, "fileoff"=>0, "filesize"=>0, "maxprot"=>0, "initprot"=>0, "nsects"=>0, "flags"=>0, "sections"=>[], "view"=>{"endianness"=>:little, "offset"=>28}, "cmd"=>1, "cmdsize"=>56, "type"=>:LC_SEGMENT, "structure"=>{"format"=>"L=2Z16L=4l=2L=2", "bytesize"=>56}}

This should make it easy to build web-friendly APIs with ruby-macho — try macho.to_h.to_json!

Correct merge_machos / new_from_machos behavior

Landed in 2.0.0.

Before 2.0, the code that generated a fat Mach-O from one or more single-arch Mach-Os was totally wrong — it didn't align the Mach-O slices along page boundaries (and didn't even try to calculate the right alignment). This has since been fixed through the addition of SegmentCommand#guess_align, MachOFile#segment_alignment, and Sections::MAX_SECT_ALIGN. Together with the same strategy used by lipo for building universal Mach-Os, this seems to produce the correct results.

Thanks to Aleks for finding this bug and reporting it to me!


Reddit discussion