{"id":15684593,"url":"https://github.com/tenderlove/worf","last_synced_at":"2025-08-02T01:36:50.488Z","repository":{"id":43470000,"uuid":"383620230","full_name":"tenderlove/WORF","owner":"tenderlove","description":"WORF, the DWARF parser","archived":false,"fork":false,"pushed_at":"2022-03-05T19:11:24.000Z","size":152,"stargazers_count":10,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-07T17:29:29.401Z","etag":null,"topics":["dwarf","dwarf-parser","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tenderlove.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-06T23:20:40.000Z","updated_at":"2024-08-19T04:19:20.000Z","dependencies_parsed_at":"2022-08-03T03:15:20.644Z","dependency_job_id":null,"html_url":"https://github.com/tenderlove/WORF","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tenderlove%2FWORF","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tenderlove%2FWORF/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tenderlove%2FWORF/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tenderlove%2FWORF/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tenderlove","download_url":"https://codeload.github.com/tenderlove/WORF/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tenderlove%2FWORF/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":258903365,"owners_count":22775780,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dwarf","dwarf-parser","ruby"],"created_at":"2024-10-03T17:19:38.357Z","updated_at":"2025-06-10T15:32:38.405Z","avatar_url":"https://github.com/tenderlove.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WORF, the DWARF parser\n\nWORF is a DWARF parser that is written in Ruby.  You can use this library to\nparse DWARF files.  I usually use this with Mach-O files or ELF files, but\nas long as you have an IO object that contains DWARF data, WORF will parse it.\n\nWith DWARF data, you can write some debugging utilities, but as an example\nI'll write a very simple version of [pahole](https://linux.die.net/man/1/pahole),\na utility that finds holes in structs.\n\n## Example pahole\n\nThis example only works on macOS.  We're going to find structs in Ruby that have\nholes in them (or wasted space).\n\nFirst we'll use [OdinFlex](https://github.com/tenderlove/odinflex) to find Ruby's archive file:\n\n```ruby\narchive = nil\n\nFile.open(RbConfig.ruby) do |f|\n  my_macho = OdinFlex::MachO.new f\n  my_macho.each do |section|\n    if section.symtab?\n      archive = section.nlist.find_all(\u0026:archive?).map(\u0026:archive).uniq.first\n      break\n    end\n  end\nend\n```\n\nNow that we have the archive file, we're going to use OdinFlex again to process\nthe AR file which will give us access to all of the Mach-O files stored inside.\nThose Mach-O files also have debugging sections that contain DWARF data, and\nwe'll use WORF to parse that data:\n\n```ruby\nFile.open(archive) do |f|\n  ar = OdinFlex::AR.new f\n  ar.each do |object_file|\n    next unless object_file.identifier =~ /\\.o$/\n    p object_file.identifier\n\n    mach_o = OdinFlex::MachO.new(f)\n    debug_abbrev = debug_strs = debug_info = nil\n\n    mach_o.each do |part|\n      if part.section?\n        case part.sectname\n        when \"__debug_abbrev\"\n          debug_abbrev = WORF::DebugAbbrev.new f, part, mach_o.start_pos\n        when \"__debug_str\"\n          debug_strs = WORF::DebugStrings.new f, part, mach_o.start_pos\n        when \"__debug_info\"\n          debug_info = WORF::DebugInfo.new f, part, mach_o.start_pos\n        end\n      end\n    end\n\n    if debug_abbrev \u0026\u0026 debug_strs \u0026\u0026 debug_info\n      puts \"great\"\n      process_debug_info(debug_abbrev, debug_strs, debug_info)\n      ## Now process the DWARF info\n    end\n    exit\n  end\nend\n```\n\nNow we can process the DWARF information and find holes in structs!\n\nOk, I am feeling lazy and don't want to write the rest of this program.\nCheck in the examples folder for a full listing.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftenderlove%2Fworf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftenderlove%2Fworf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftenderlove%2Fworf/lists"}