From d587f4ac1e345dbe4855cd96fd2cd803eee64a91 Mon Sep 17 00:00:00 2001 From: Eden Federman Date: Mon, 27 Feb 2023 13:16:44 -0800 Subject: [PATCH] Instrumentation as resource (#78) This PR changes the way Odigos performs instrumentation to **Instrumentation as resource**. Instead of adding instrumentation via initContainer and a shared mount, odigos now adds a resource that can be allocated via the `.spec.resources.limits` field. In addition, this PR upgrades the .NET instrumentation version to v0.5.0 and improves the uninstall process. --- agents/dotnet/.gitignore | 1 - agents/dotnet/Dockerfile | 5 - agents/dotnet/init.sh | 6 - agents/golang/Dockerfile | 11 - agents/java/Dockerfile | 4 - agents/nodejs/Dockerfile | 12 - agents/python/Dockerfile | 23 - .../controllers/datacollection/configmap.go | 9 +- .../controllers/datacollection/daemonset.go | 34 +- autoscaler/controllers/gateway/deployment.go | 2 +- cli/cmd/uninstall.go | 90 +- instrumentor/patch/dotnet.go | 104 +- instrumentor/patch/java.go | 82 +- instrumentor/patch/nodejs.go | 79 +- instrumentor/patch/python.go | 81 +- odiglet/Dockerfile | 41 +- .../agents}/nodejs/.dockerignore | 0 .../agents}/nodejs/package.json | 0 .../agents}/nodejs/src/autoinstrumentation.ts | 0 .../agents}/nodejs/tsconfig.json | 0 .../agents}/python/requirements.txt | 0 odiglet/cmd/main.go | 114 +- odiglet/go.mod | 10 +- odiglet/go.sum | 173 +- odiglet/pkg/allocator/allocate.go | 46 - odiglet/pkg/allocator/bj/binjector.go | 61 - odiglet/pkg/allocator/bj/inject_elf.go | 127 - odiglet/pkg/allocator/bj/inject_test.go | 91 - odiglet/pkg/allocator/bj/utils.go | 129 - odiglet/pkg/allocator/debug/LICENSE | 27 - .../pkg/allocator/debug/dwarf/attr_string.go | 89 - odiglet/pkg/allocator/debug/dwarf/buf.go | 192 -- .../pkg/allocator/debug/dwarf/class_string.go | 16 - odiglet/pkg/allocator/debug/dwarf/const.go | 319 -- odiglet/pkg/allocator/debug/dwarf/entry.go | 769 ----- .../pkg/allocator/debug/dwarf/entry_test.go | 197 -- .../pkg/allocator/debug/dwarf/export_test.go | 7 - odiglet/pkg/allocator/debug/dwarf/line.go | 656 ---- .../pkg/allocator/debug/dwarf/line_test.go | 314 -- odiglet/pkg/allocator/debug/dwarf/open.go | 96 - .../pkg/allocator/debug/dwarf/tag_string.go | 44 - .../allocator/debug/dwarf/testdata/cycle.c | 7 - .../allocator/debug/dwarf/testdata/cycle.elf | Bin 2624 -> 0 bytes .../debug/dwarf/testdata/line-clang.elf | Bin 10271 -> 0 bytes .../debug/dwarf/testdata/line-gcc-win.bin | Bin 133202 -> 0 bytes .../debug/dwarf/testdata/line-gcc.elf | Bin 10113 -> 0 bytes .../allocator/debug/dwarf/testdata/line1.c | 9 - .../allocator/debug/dwarf/testdata/line1.h | 7 - .../allocator/debug/dwarf/testdata/line2.c | 6 - .../allocator/debug/dwarf/testdata/ranges.c | 25 - .../allocator/debug/dwarf/testdata/ranges.elf | Bin 10348 -> 0 bytes .../allocator/debug/dwarf/testdata/split.c | 5 - .../allocator/debug/dwarf/testdata/split.elf | Bin 9509 -> 0 bytes .../allocator/debug/dwarf/testdata/typedef.c | 85 - .../debug/dwarf/testdata/typedef.elf | Bin 12448 -> 0 bytes .../debug/dwarf/testdata/typedef.elf4 | Bin 9496 -> 0 bytes .../debug/dwarf/testdata/typedef.macho | Bin 5024 -> 0 bytes odiglet/pkg/allocator/debug/dwarf/type.go | 727 ---- .../pkg/allocator/debug/dwarf/type_test.go | 170 - odiglet/pkg/allocator/debug/dwarf/typeunit.go | 160 - odiglet/pkg/allocator/debug/dwarf/unit.go | 110 - odiglet/pkg/allocator/debug/elf/elf.go | 3000 ----------------- odiglet/pkg/allocator/debug/elf/elf_test.go | 49 - odiglet/pkg/allocator/debug/elf/exports.go | 32 - odiglet/pkg/allocator/debug/elf/file.go | 964 ------ odiglet/pkg/allocator/debug/elf/file_test.go | 812 ----- odiglet/pkg/allocator/debug/elf/reader.go | 108 - .../pkg/allocator/debug/elf/relocations.go | 529 --- .../pkg/allocator/debug/elf/symbols_test.go | 834 ----- .../debug/elf/testdata/compressed-32.obj | Bin 2208 -> 0 bytes .../debug/elf/testdata/compressed-64.obj | Bin 3280 -> 0 bytes .../debug/elf/testdata/gcc-386-freebsd-exec | Bin 5742 -> 0 bytes .../debug/elf/testdata/gcc-amd64-linux-exec | Bin 8844 -> 0 bytes .../gcc-amd64-openbsd-debug-with-rela.obj | Bin 6544 -> 0 bytes .../testdata/go-relocation-test-clang-arm.obj | Bin 3092 -> 0 bytes .../testdata/go-relocation-test-clang-x86.obj | Bin 1900 -> 0 bytes .../go-relocation-test-gcc424-x86-64.obj | Bin 3088 -> 0 bytes .../go-relocation-test-gcc441-x86-64.obj | Bin 2936 -> 0 bytes .../go-relocation-test-gcc441-x86.obj | Bin 1884 -> 0 bytes .../go-relocation-test-gcc482-aarch64.obj | Bin 3392 -> 0 bytes .../go-relocation-test-gcc482-ppc64le.obj | Bin 3016 -> 0 bytes .../go-relocation-test-gcc492-arm.obj | Bin 2648 -> 0 bytes .../go-relocation-test-gcc492-mips64.obj | Bin 4120 -> 0 bytes .../go-relocation-test-gcc492-mipsle.obj | Bin 2864 -> 0 bytes .../go-relocation-test-gcc493-mips64le.obj | Bin 4160 -> 0 bytes .../testdata/go-relocation-test-gcc5-ppc.obj | Bin 2356 -> 0 bytes .../go-relocation-test-gcc531-s390x.obj | Bin 3864 -> 0 bytes .../go-relocation-test-gcc540-mips.obj | Bin 3064 -> 0 bytes .../go-relocation-test-gcc620-sparc64.obj | Bin 5952 -> 0 bytes .../go-relocation-test-gcc720-riscv64.obj | Bin 9576 -> 0 bytes .../debug/elf/testdata/hello-world-core.gz | Bin 12678 -> 0 bytes .../pkg/allocator/debug/elf/testdata/hello.c | 7 - .../testdata/zdebug-test-gcc484-x86-64.obj | Bin 3216 -> 0 bytes odiglet/pkg/allocator/debug/elf/write.go | 282 -- odiglet/pkg/allocator/debug/goobj2/file.go | 929 ----- .../pkg/allocator/debug/goobj2/file_test.go | 92 - .../debug/goobj2/internal/bio/buf.go | 143 - .../debug/goobj2/internal/bio/buf_mmap.go | 63 - .../debug/goobj2/internal/bio/buf_nommap.go | 12 - .../debug/goobj2/internal/bio/must.go | 43 - .../debug/goobj2/internal/goobj2/extras.go | 5 - .../debug/goobj2/internal/goobj2/goobj2.go | 1220 ------- .../debug/goobj2/internal/objabi/objabi.go | 1249 ------- .../internal/unsafeheader/unsafeheader.go | 38 - .../debug/goobj2/testdata/aes_encrypt.go | 39 - .../allocator/debug/goobj2/testdata/format.go | 33 - .../debug/goobj2/testdata/hello_world.go | 7 - .../goobj2/testdata/http_not_found_handler.go | 25 - .../debug/goobj2/testdata/loop_de_loop.go | 12 - .../debug/goobj2/testdata/reflect.go | 43 - .../debug/goobj2/testdata/trim_string.go | 16 - odiglet/pkg/allocator/debug/goobj2/write.go | 412 --- odiglet/pkg/allocator/debug/gosym/pclntab.go | 454 --- .../pkg/allocator/debug/gosym/pclntab_test.go | 263 -- odiglet/pkg/allocator/debug/gosym/symtab.go | 715 ---- .../pkg/allocator/debug/gosym/symtab_test.go | 43 - .../allocator/debug/gosym/testdata/main.go | 10 - .../debug/gosym/testdata/pclinetest.h | 9 - .../debug/gosym/testdata/pclinetest.s | 48 - odiglet/pkg/allocator/debug/macho/README.md | 3 - odiglet/pkg/allocator/debug/macho/exports.go | 27 - odiglet/pkg/allocator/debug/macho/fat.go | 146 - odiglet/pkg/allocator/debug/macho/file.go | 952 ------ .../pkg/allocator/debug/macho/file_test.go | 379 --- odiglet/pkg/allocator/debug/macho/macho.go | 414 --- .../pkg/allocator/debug/macho/reloctype.go | 72 - .../allocator/debug/macho/reloctype_string.go | 49 - .../testdata/clang-386-darwin-exec-with-rpath | Bin 8416 -> 0 bytes .../debug/macho/testdata/clang-386-darwin.obj | Bin 464 -> 0 bytes .../clang-amd64-darwin-exec-with-rpath | Bin 8432 -> 0 bytes .../macho/testdata/clang-amd64-darwin.obj | Bin 768 -> 0 bytes .../testdata/fat-gcc-386-amd64-darwin-exec | Bin 28992 -> 0 bytes .../debug/macho/testdata/gcc-386-darwin-exec | Bin 12588 -> 0 bytes .../macho/testdata/gcc-amd64-darwin-exec | Bin 8512 -> 0 bytes .../testdata/gcc-amd64-darwin-exec-debug | Bin 4540 -> 0 bytes .../allocator/debug/macho/testdata/hello.c | 8 - odiglet/pkg/allocator/debug/macho/write.go | 343 -- odiglet/pkg/allocator/debug/pe/cert.go | 50 - odiglet/pkg/allocator/debug/pe/exports.go | 141 - odiglet/pkg/allocator/debug/pe/file.go | 469 --- .../pkg/allocator/debug/pe/file_cgo_test.go | 32 - odiglet/pkg/allocator/debug/pe/file_test.go | 627 ---- odiglet/pkg/allocator/debug/pe/imports.go | 182 - odiglet/pkg/allocator/debug/pe/net.go | 69 - odiglet/pkg/allocator/debug/pe/pe.go | 153 - odiglet/pkg/allocator/debug/pe/reloc.go | 171 - odiglet/pkg/allocator/debug/pe/section.go | 109 - odiglet/pkg/allocator/debug/pe/string.go | 70 - odiglet/pkg/allocator/debug/pe/symbol.go | 98 - .../debug/pe/testdata/gcc-386-mingw-exec | Bin 29941 -> 0 bytes .../pe/testdata/gcc-386-mingw-no-symbols-exec | Bin 8704 -> 0 bytes .../debug/pe/testdata/gcc-386-mingw-obj | Bin 2372 -> 0 bytes .../debug/pe/testdata/gcc-amd64-mingw-exec | Bin 273083 -> 0 bytes .../debug/pe/testdata/gcc-amd64-mingw-obj | Bin 736 -> 0 bytes .../pkg/allocator/debug/pe/testdata/hello.c | 8 - odiglet/pkg/allocator/debug/pe/write.go | 195 -- odiglet/pkg/allocator/debug/plan9obj/file.go | 328 -- .../pkg/allocator/debug/plan9obj/file_test.go | 81 - .../pkg/allocator/debug/plan9obj/plan9obj.go | 36 - .../debug/plan9obj/testdata/386-plan9-exec | Bin 37232 -> 0 bytes .../debug/plan9obj/testdata/amd64-plan9-exec | Bin 34279 -> 0 bytes .../allocator/debug/plan9obj/testdata/hello.c | 8 - odiglet/pkg/allocator/fix.go | 22 - odiglet/pkg/allocator/payload/mmap.asm | 9 - odiglet/pkg/containers/container.go | 89 - odiglet/pkg/containers/runtimes/containerd.go | 41 - odiglet/pkg/containers/runtimes/crio.go | 71 - odiglet/pkg/containers/runtimes/docker.go | 40 - odiglet/pkg/containers/runtimes/root.go | 40 - odiglet/pkg/env/current.go | 8 + odiglet/pkg/instrumentation/consts/consts.go | 6 + .../instrumentation/devices/ids_manager.go | 54 + .../pkg/instrumentation/devices/kubelet.go | 91 + odiglet/pkg/instrumentation/fs/agents.go | 14 + .../instrumentation/instrumentlang/dotnet.go | 54 + .../instrumentation/instrumentlang/java.go | 35 + .../instrumentation/instrumentlang/nodejs.go | 39 + .../instrumentation/instrumentlang/python.go | 40 + odiglet/pkg/instrumentation/lister.go | 75 + odiglet/pkg/instrumentation/plugin.go | 83 + odiglet/pkg/log/logger.go | 5 + odiglet/pkg/request.go | 7 - 182 files changed, 838 insertions(+), 23117 deletions(-) delete mode 100644 agents/dotnet/.gitignore delete mode 100644 agents/dotnet/Dockerfile delete mode 100644 agents/dotnet/init.sh delete mode 100644 agents/golang/Dockerfile delete mode 100644 agents/java/Dockerfile delete mode 100644 agents/nodejs/Dockerfile delete mode 100644 agents/python/Dockerfile rename {agents => odiglet/agents}/nodejs/.dockerignore (100%) rename {agents => odiglet/agents}/nodejs/package.json (100%) rename {agents => odiglet/agents}/nodejs/src/autoinstrumentation.ts (100%) rename {agents => odiglet/agents}/nodejs/tsconfig.json (100%) rename {agents => odiglet/agents}/python/requirements.txt (100%) delete mode 100644 odiglet/pkg/allocator/allocate.go delete mode 100644 odiglet/pkg/allocator/bj/binjector.go delete mode 100644 odiglet/pkg/allocator/bj/inject_elf.go delete mode 100644 odiglet/pkg/allocator/bj/inject_test.go delete mode 100644 odiglet/pkg/allocator/bj/utils.go delete mode 100644 odiglet/pkg/allocator/debug/LICENSE delete mode 100644 odiglet/pkg/allocator/debug/dwarf/attr_string.go delete mode 100644 odiglet/pkg/allocator/debug/dwarf/buf.go delete mode 100644 odiglet/pkg/allocator/debug/dwarf/class_string.go delete mode 100644 odiglet/pkg/allocator/debug/dwarf/const.go delete mode 100644 odiglet/pkg/allocator/debug/dwarf/entry.go delete mode 100644 odiglet/pkg/allocator/debug/dwarf/entry_test.go delete mode 100644 odiglet/pkg/allocator/debug/dwarf/export_test.go delete mode 100644 odiglet/pkg/allocator/debug/dwarf/line.go delete mode 100644 odiglet/pkg/allocator/debug/dwarf/line_test.go delete mode 100644 odiglet/pkg/allocator/debug/dwarf/open.go delete mode 100644 odiglet/pkg/allocator/debug/dwarf/tag_string.go delete mode 100644 odiglet/pkg/allocator/debug/dwarf/testdata/cycle.c delete mode 100644 odiglet/pkg/allocator/debug/dwarf/testdata/cycle.elf delete mode 100644 odiglet/pkg/allocator/debug/dwarf/testdata/line-clang.elf delete mode 100644 odiglet/pkg/allocator/debug/dwarf/testdata/line-gcc-win.bin delete mode 100644 odiglet/pkg/allocator/debug/dwarf/testdata/line-gcc.elf delete mode 100644 odiglet/pkg/allocator/debug/dwarf/testdata/line1.c delete mode 100644 odiglet/pkg/allocator/debug/dwarf/testdata/line1.h delete mode 100644 odiglet/pkg/allocator/debug/dwarf/testdata/line2.c delete mode 100644 odiglet/pkg/allocator/debug/dwarf/testdata/ranges.c delete mode 100755 odiglet/pkg/allocator/debug/dwarf/testdata/ranges.elf delete mode 100644 odiglet/pkg/allocator/debug/dwarf/testdata/split.c delete mode 100644 odiglet/pkg/allocator/debug/dwarf/testdata/split.elf delete mode 100644 odiglet/pkg/allocator/debug/dwarf/testdata/typedef.c delete mode 100755 odiglet/pkg/allocator/debug/dwarf/testdata/typedef.elf delete mode 100644 odiglet/pkg/allocator/debug/dwarf/testdata/typedef.elf4 delete mode 100644 odiglet/pkg/allocator/debug/dwarf/testdata/typedef.macho delete mode 100644 odiglet/pkg/allocator/debug/dwarf/type.go delete mode 100644 odiglet/pkg/allocator/debug/dwarf/type_test.go delete mode 100644 odiglet/pkg/allocator/debug/dwarf/typeunit.go delete mode 100644 odiglet/pkg/allocator/debug/dwarf/unit.go delete mode 100644 odiglet/pkg/allocator/debug/elf/elf.go delete mode 100644 odiglet/pkg/allocator/debug/elf/elf_test.go delete mode 100644 odiglet/pkg/allocator/debug/elf/exports.go delete mode 100644 odiglet/pkg/allocator/debug/elf/file.go delete mode 100644 odiglet/pkg/allocator/debug/elf/file_test.go delete mode 100644 odiglet/pkg/allocator/debug/elf/reader.go delete mode 100644 odiglet/pkg/allocator/debug/elf/relocations.go delete mode 100644 odiglet/pkg/allocator/debug/elf/symbols_test.go delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/compressed-32.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/compressed-64.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/gcc-386-freebsd-exec delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/gcc-amd64-linux-exec delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/gcc-amd64-openbsd-debug-with-rela.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-clang-arm.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-clang-x86.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc424-x86-64.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc441-x86-64.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc441-x86.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc482-aarch64.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc482-ppc64le.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc492-arm.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc492-mips64.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc492-mipsle.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc493-mips64le.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc5-ppc.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc531-s390x.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc540-mips.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc620-sparc64.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc720-riscv64.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/hello-world-core.gz delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/hello.c delete mode 100644 odiglet/pkg/allocator/debug/elf/testdata/zdebug-test-gcc484-x86-64.obj delete mode 100644 odiglet/pkg/allocator/debug/elf/write.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/file.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/file_test.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/internal/bio/buf.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/internal/bio/buf_mmap.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/internal/bio/buf_nommap.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/internal/bio/must.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/internal/goobj2/extras.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/internal/goobj2/goobj2.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/internal/objabi/objabi.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/internal/unsafeheader/unsafeheader.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/testdata/aes_encrypt.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/testdata/format.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/testdata/hello_world.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/testdata/http_not_found_handler.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/testdata/loop_de_loop.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/testdata/reflect.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/testdata/trim_string.go delete mode 100644 odiglet/pkg/allocator/debug/goobj2/write.go delete mode 100644 odiglet/pkg/allocator/debug/gosym/pclntab.go delete mode 100644 odiglet/pkg/allocator/debug/gosym/pclntab_test.go delete mode 100644 odiglet/pkg/allocator/debug/gosym/symtab.go delete mode 100644 odiglet/pkg/allocator/debug/gosym/symtab_test.go delete mode 100644 odiglet/pkg/allocator/debug/gosym/testdata/main.go delete mode 100644 odiglet/pkg/allocator/debug/gosym/testdata/pclinetest.h delete mode 100644 odiglet/pkg/allocator/debug/gosym/testdata/pclinetest.s delete mode 100644 odiglet/pkg/allocator/debug/macho/README.md delete mode 100644 odiglet/pkg/allocator/debug/macho/exports.go delete mode 100644 odiglet/pkg/allocator/debug/macho/fat.go delete mode 100644 odiglet/pkg/allocator/debug/macho/file.go delete mode 100644 odiglet/pkg/allocator/debug/macho/file_test.go delete mode 100644 odiglet/pkg/allocator/debug/macho/macho.go delete mode 100644 odiglet/pkg/allocator/debug/macho/reloctype.go delete mode 100644 odiglet/pkg/allocator/debug/macho/reloctype_string.go delete mode 100644 odiglet/pkg/allocator/debug/macho/testdata/clang-386-darwin-exec-with-rpath delete mode 100644 odiglet/pkg/allocator/debug/macho/testdata/clang-386-darwin.obj delete mode 100644 odiglet/pkg/allocator/debug/macho/testdata/clang-amd64-darwin-exec-with-rpath delete mode 100644 odiglet/pkg/allocator/debug/macho/testdata/clang-amd64-darwin.obj delete mode 100644 odiglet/pkg/allocator/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec delete mode 100644 odiglet/pkg/allocator/debug/macho/testdata/gcc-386-darwin-exec delete mode 100644 odiglet/pkg/allocator/debug/macho/testdata/gcc-amd64-darwin-exec delete mode 100644 odiglet/pkg/allocator/debug/macho/testdata/gcc-amd64-darwin-exec-debug delete mode 100644 odiglet/pkg/allocator/debug/macho/testdata/hello.c delete mode 100644 odiglet/pkg/allocator/debug/macho/write.go delete mode 100644 odiglet/pkg/allocator/debug/pe/cert.go delete mode 100644 odiglet/pkg/allocator/debug/pe/exports.go delete mode 100644 odiglet/pkg/allocator/debug/pe/file.go delete mode 100644 odiglet/pkg/allocator/debug/pe/file_cgo_test.go delete mode 100644 odiglet/pkg/allocator/debug/pe/file_test.go delete mode 100644 odiglet/pkg/allocator/debug/pe/imports.go delete mode 100644 odiglet/pkg/allocator/debug/pe/net.go delete mode 100644 odiglet/pkg/allocator/debug/pe/pe.go delete mode 100644 odiglet/pkg/allocator/debug/pe/reloc.go delete mode 100644 odiglet/pkg/allocator/debug/pe/section.go delete mode 100644 odiglet/pkg/allocator/debug/pe/string.go delete mode 100644 odiglet/pkg/allocator/debug/pe/symbol.go delete mode 100644 odiglet/pkg/allocator/debug/pe/testdata/gcc-386-mingw-exec delete mode 100644 odiglet/pkg/allocator/debug/pe/testdata/gcc-386-mingw-no-symbols-exec delete mode 100644 odiglet/pkg/allocator/debug/pe/testdata/gcc-386-mingw-obj delete mode 100644 odiglet/pkg/allocator/debug/pe/testdata/gcc-amd64-mingw-exec delete mode 100644 odiglet/pkg/allocator/debug/pe/testdata/gcc-amd64-mingw-obj delete mode 100644 odiglet/pkg/allocator/debug/pe/testdata/hello.c delete mode 100644 odiglet/pkg/allocator/debug/pe/write.go delete mode 100644 odiglet/pkg/allocator/debug/plan9obj/file.go delete mode 100644 odiglet/pkg/allocator/debug/plan9obj/file_test.go delete mode 100644 odiglet/pkg/allocator/debug/plan9obj/plan9obj.go delete mode 100644 odiglet/pkg/allocator/debug/plan9obj/testdata/386-plan9-exec delete mode 100644 odiglet/pkg/allocator/debug/plan9obj/testdata/amd64-plan9-exec delete mode 100644 odiglet/pkg/allocator/debug/plan9obj/testdata/hello.c delete mode 100644 odiglet/pkg/allocator/fix.go delete mode 100644 odiglet/pkg/allocator/payload/mmap.asm delete mode 100644 odiglet/pkg/containers/container.go delete mode 100644 odiglet/pkg/containers/runtimes/containerd.go delete mode 100644 odiglet/pkg/containers/runtimes/crio.go delete mode 100644 odiglet/pkg/containers/runtimes/docker.go delete mode 100644 odiglet/pkg/containers/runtimes/root.go create mode 100644 odiglet/pkg/instrumentation/consts/consts.go create mode 100644 odiglet/pkg/instrumentation/devices/ids_manager.go create mode 100644 odiglet/pkg/instrumentation/devices/kubelet.go create mode 100644 odiglet/pkg/instrumentation/fs/agents.go create mode 100644 odiglet/pkg/instrumentation/instrumentlang/dotnet.go create mode 100644 odiglet/pkg/instrumentation/instrumentlang/java.go create mode 100644 odiglet/pkg/instrumentation/instrumentlang/nodejs.go create mode 100644 odiglet/pkg/instrumentation/instrumentlang/python.go create mode 100644 odiglet/pkg/instrumentation/lister.go create mode 100644 odiglet/pkg/instrumentation/plugin.go delete mode 100644 odiglet/pkg/request.go diff --git a/agents/dotnet/.gitignore b/agents/dotnet/.gitignore deleted file mode 100644 index 87160f4826..0000000000 --- a/agents/dotnet/.gitignore +++ /dev/null @@ -1 +0,0 @@ -from-source/ diff --git a/agents/dotnet/Dockerfile b/agents/dotnet/Dockerfile deleted file mode 100644 index e3ef8b31bc..0000000000 --- a/agents/dotnet/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM alpine:3 -ADD https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/download/v0.0.1/otel-dotnet-autoinstrumentation-0.0.1-musl.tar.gz /tmp/ -ADD init.sh /tmp -RUN chmod +x /tmp/init.sh -ENTRYPOINT [ "/tmp/init.sh"] \ No newline at end of file diff --git a/agents/dotnet/init.sh b/agents/dotnet/init.sh deleted file mode 100644 index d35b9e7407..0000000000 --- a/agents/dotnet/init.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -mkdir /tmp/otel -cd /tmp/otel -tar xvf /tmp/otel-dotnet-autoinstrumentation-0.0.1-musl.tar.gz -mv /tmp/otel/* /agent -chmod -R 777 /agent \ No newline at end of file diff --git a/agents/golang/Dockerfile b/agents/golang/Dockerfile deleted file mode 100644 index 534c07ac5d..0000000000 --- a/agents/golang/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM fedora:35 as builder -RUN dnf install clang llvm make libbpf-devel git -y -RUN curl -LO https://go.dev/dl/go1.18.linux-amd64.tar.gz && tar -C /usr/local -xzf go*.linux-amd64.tar.gz -ENV PATH="/usr/local/go/bin:${PATH}" -RUN git clone https://github.com/keyval-dev/opentelemetry-go-instrumentation /app -WORKDIR /app -RUN make build - -FROM gcr.io/distroless/base-debian11 -COPY --from=builder /app/kv-go-instrumentation / -CMD ["/kv-go-instrumentation"] \ No newline at end of file diff --git a/agents/java/Dockerfile b/agents/java/Dockerfile deleted file mode 100644 index c55d7be829..0000000000 --- a/agents/java/Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM busybox -ARG OTEL_VERSIN=1.22.1 -ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v$OTEL_VERSIN/opentelemetry-javaagent.jar /javaagent.jar -RUN chmod -R go+r /javaagent.jar \ No newline at end of file diff --git a/agents/nodejs/Dockerfile b/agents/nodejs/Dockerfile deleted file mode 100644 index cd648ccea2..0000000000 --- a/agents/nodejs/Dockerfile +++ /dev/null @@ -1,12 +0,0 @@ -FROM node:16 AS build - -WORKDIR /operator-build -COPY . . - -RUN npm install - -FROM busybox - -COPY --from=build /operator-build/build/workspace /autoinstrumentation - -RUN chmod -R go+r /autoinstrumentation diff --git a/agents/python/Dockerfile b/agents/python/Dockerfile deleted file mode 100644 index 884381261f..0000000000 --- a/agents/python/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# To build one auto-instrumentation image for Python, please: -# - Ensure the packages are installed in the `/autoinstrumentation` directory. This is required as when instrumenting the pod, -# one init container will be created to copy all the content in `/autoinstrumentation` directory to your app's container. Then -# update the `PYTHONPATH` environment variable accordingly. To achieve this, you can mimic the one in `autoinstrumentation/python/Dockerfile` -# by using multi-stage builds. In the first stage, install all the required packages in one custom directory with `pip install --target`. -# Then in the second stage, copy the directory to `/autoinstrumentation`. -# - Ensure you have `opentelemetry-distro` and `opentelemetry-instrumentation` or your customized alternatives installed. -# Those two packages are essential to Python auto-instrumentation. -# - Grant the necessary access to `/autoinstrumentation` directory. `chmod -R go+r /autoinstrumentation` - -FROM python:3.10-alpine AS build - -WORKDIR /operator-build - -ADD requirements.txt . - -RUN mkdir workspace && pip install --target workspace -r requirements.txt - -FROM busybox - -COPY --from=build /operator-build/workspace /autoinstrumentation - -RUN chmod -R go+r /autoinstrumentation \ No newline at end of file diff --git a/autoscaler/controllers/datacollection/configmap.go b/autoscaler/controllers/datacollection/configmap.go index e7281fbb6a..4c8655d31a 100644 --- a/autoscaler/controllers/datacollection/configmap.go +++ b/autoscaler/controllers/datacollection/configmap.go @@ -129,7 +129,8 @@ func getConfigMapData(apps *odigosv1.InstrumentedApplicationList, dests *odigosv }, }, Processors: commonconf.GenericMap{ - "batch": empty, + "batch": empty, + "odigosresourcename": empty, }, Extensions: commonconf.GenericMap{ "health_check": empty, @@ -260,7 +261,7 @@ func getConfigMapData(apps *odigosv1.InstrumentedApplicationList, dests *odigosv cfg.Service.Pipelines["logs"] = commonconf.Pipeline{ Receivers: []string{"filelog"}, - Processors: []string{"batch"}, + Processors: []string{"batch", "odigosresourcename"}, Exporters: []string{"otlp/gateway"}, } } @@ -268,7 +269,7 @@ func getConfigMapData(apps *odigosv1.InstrumentedApplicationList, dests *odigosv if collectTraces { cfg.Service.Pipelines["traces"] = commonconf.Pipeline{ Receivers: []string{"otlp", "zipkin"}, - Processors: []string{"batch"}, + Processors: []string{"batch", "odigosresourcename"}, Exporters: []string{"otlp/gateway"}, } } @@ -281,7 +282,7 @@ func getConfigMapData(apps *odigosv1.InstrumentedApplicationList, dests *odigosv cfg.Service.Pipelines["metrics"] = commonconf.Pipeline{ Receivers: []string{"otlp", "kubeletstats"}, - Processors: []string{"batch"}, + Processors: []string{"batch", "odigosresourcename"}, Exporters: []string{"otlp/gateway"}, } } diff --git a/autoscaler/controllers/datacollection/daemonset.go b/autoscaler/controllers/datacollection/daemonset.go index f6ddcf5e0d..a81e501bc4 100644 --- a/autoscaler/controllers/datacollection/daemonset.go +++ b/autoscaler/controllers/datacollection/daemonset.go @@ -21,8 +21,8 @@ import ( const ( collectorLabel = "odigos.io/data-collection" containerName = "data-collection" - containerImage = "otel/opentelemetry-collector-contrib:0.55.0" - containerCommand = "/otelcol-contrib" + containerImage = "keyval/otel-collector-contrib:v0.2" + containerCommand = "/otelcontribcol" confDir = "/conf" configHashAnnotation = "odigos.io/config-hash" dataCollectionSA = "odigos-data-collection" @@ -126,6 +126,14 @@ func getDesiredDaemonSet(datacollection *odigosv1.CollectorsGroup, configData st }, }, }, + { + Name: "kubeletpodresources", + VolumeSource: corev1.VolumeSource{ + HostPath: &corev1.HostPathVolumeSource{ + Path: "/var/lib/kubelet/pod-resources", + }, + }, + }, }, Containers: []corev1.Container{ { @@ -147,6 +155,21 @@ func getDesiredDaemonSet(datacollection *odigosv1.CollectorsGroup, configData st MountPath: "/var/log", ReadOnly: true, }, + { + Name: "kubeletpodresources", + MountPath: "/var/lib/kubelet/pod-resources", + ReadOnly: true, + }, + }, + Env: []corev1.EnvVar{ + { + Name: "NODE_NAME", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + FieldPath: "spec.nodeName", + }, + }, + }, }, LivenessProbe: &corev1.Probe{ ProbeHandler: corev1.ProbeHandler{ @@ -164,6 +187,9 @@ func getDesiredDaemonSet(datacollection *odigosv1.CollectorsGroup, configData st }, }, }, + SecurityContext: &corev1.SecurityContext{ + Privileged: boolPtr(true), + }, }, }, HostNetwork: true, @@ -206,3 +232,7 @@ func patchDaemonSet(existing *appsv1.DaemonSet, desired *appsv1.DaemonSet, ctx c return updated, nil } + +func boolPtr(b bool) *bool { + return &b +} diff --git a/autoscaler/controllers/gateway/deployment.go b/autoscaler/controllers/gateway/deployment.go index caff072b6c..fe10220187 100644 --- a/autoscaler/controllers/gateway/deployment.go +++ b/autoscaler/controllers/gateway/deployment.go @@ -18,7 +18,7 @@ import ( const ( containerName = "gateway" - containerImage = "keyval/otel-collector-contrib:v0.1" + containerImage = "keyval/otel-collector-contrib:v0.2" containerCommand = "/otelcontribcol" confDir = "/conf" configHashAnnotation = "odigos.io/config-hash" diff --git a/cli/cmd/uninstall.go b/cli/cmd/uninstall.go index db02092503..33f05f7186 100644 --- a/cli/cmd/uninstall.go +++ b/cli/cmd/uninstall.go @@ -1,6 +1,3 @@ -/* -Copyright © 2022 NAME HERE -*/ package cmd import ( @@ -13,11 +10,19 @@ import ( "github.com/keyval-dev/odigos/cli/pkg/log" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" "strings" + "time" "github.com/spf13/cobra" ) +const ( + odigosDeviceName = "instrumentation.odigos.io" + goAgentImage = "keyval/otel-go-agent" + golangKernelDebugVolumeName = "kernel-debug" +) + // uninstallCmd represents the uninstall command var uninstallCmd = &cobra.Command{ Use: "uninstall", @@ -57,6 +62,9 @@ to quickly create a Cobra application.`, createKubeResourceWithLogging(ctx, fmt.Sprintf("Uninstalling Namespace %s", ns), client, cmd, ns, uninstallNamespace) + // Wait for namespace to be deleted + waitForNamespaceDeletion(ctx, client, ns) + l := log.Print("Rolling back odigos changes to pods") err = rollbackPodChanges(ctx, client) if err != nil { @@ -69,6 +77,18 @@ to quickly create a Cobra application.`, }, } +func waitForNamespaceDeletion(ctx context.Context, client *kube.Client, ns string) { + l := log.Print("Waiting for namespace to be deleted") + wait.PollImmediate(1*time.Second, 5*time.Minute, func() (bool, error) { + _, err := client.CoreV1().Namespaces().Get(ctx, ns, metav1.GetOptions{}) + if err != nil { + l.Success() + return true, nil + } + return false, nil + }) +} + func rollbackPodChanges(ctx context.Context, client *kube.Client) error { deps, err := client.AppsV1().Deployments("").List(ctx, metav1.ListOptions{}) if err != nil { @@ -80,10 +100,7 @@ func rollbackPodChanges(ctx context.Context, client *kube.Client) error { continue } - if err := rollbackPodTemplateSpec(ctx, client, &dep.Spec.Template); err != nil { - return err - } - + rollbackPodTemplateSpec(ctx, client, &dep.Spec.Template) if _, err := client.AppsV1().Deployments(dep.Namespace).Update(ctx, &dep, metav1.UpdateOptions{}); err != nil { return err } @@ -99,10 +116,7 @@ func rollbackPodChanges(ctx context.Context, client *kube.Client) error { continue } - if err := rollbackPodTemplateSpec(ctx, client, &s.Spec.Template); err != nil { - return err - } - + rollbackPodTemplateSpec(ctx, client, &s.Spec.Template) if _, err := client.AppsV1().StatefulSets(s.Namespace).Update(ctx, &s, metav1.UpdateOptions{}); err != nil { return err } @@ -111,45 +125,43 @@ func rollbackPodChanges(ctx context.Context, client *kube.Client) error { return nil } -func rollbackPodTemplateSpec(ctx context.Context, client *kube.Client, pts *v1.PodTemplateSpec) error { - // Remove odigos volumes - for i, v := range pts.Spec.Volumes { - if strings.Contains(v.Name, "odigos") || strings.Contains(v.Name, "agentdir") { - pts.Spec.Volumes = append(pts.Spec.Volumes[:i], pts.Spec.Volumes[i+1:]...) - } - } - - // Remove containers with keyval image +func rollbackPodTemplateSpec(ctx context.Context, client *kube.Client, pts *v1.PodTemplateSpec) { + // Odigos instruments pods in two ways: + // A. For Java/.NET/Python/NodeJS apps, it adds a resource limit to the container + instrumentedViaResourceLimit := false for i, c := range pts.Spec.Containers { - if strings.Contains(c.Image, "keyval") || strings.Contains(c.Image, "odigos") { - pts.Spec.Containers = append(pts.Spec.Containers[:i], pts.Spec.Containers[i+1:]...) + if c.Resources.Limits != nil { + for val, _ := range c.Resources.Limits { + if strings.Contains(val.String(), odigosDeviceName) { + instrumentedViaResourceLimit = true + delete(pts.Spec.Containers[i].Resources.Limits, val) + } + } } + } - if len(c.Command) > 0 && c.Command[0] == "/odigos/init" { - // set container command to be container args - pts.Spec.Containers[i].Command = pts.Spec.Containers[i].Args - pts.Spec.Containers[i].Args = nil - } + if instrumentedViaResourceLimit { + return } - // Remove volume mounts + // B. For Go apps, it adds a sidecar container + + // Remove containers with go agent image for i, c := range pts.Spec.Containers { - for j, vm := range c.VolumeMounts { - if strings.Contains(vm.Name, "odigos") || strings.Contains(vm.Name, "agentdir") { - pts.Spec.Containers[i].VolumeMounts = append(c.VolumeMounts[:j], c.VolumeMounts[j+1:]...) - } + if strings.Contains(c.Image, goAgentImage) { + pts.Spec.Containers = append(pts.Spec.Containers[:i], pts.Spec.Containers[i+1:]...) } } - // Remove odigos init containers - for i, c := range pts.Spec.InitContainers { - if strings.Contains(c.Image, "keyval") || strings.Contains(c.Image, "odigos") || - strings.Contains(c.Image, "otel") { - pts.Spec.InitContainers = append(pts.Spec.InitContainers[:i], pts.Spec.InitContainers[i+1:]...) + // Roll back shared process namespace + pts.Spec.ShareProcessNamespace = nil + + // Remove odigos volumes + for i, v := range pts.Spec.Volumes { + if v.Name == golangKernelDebugVolumeName { + pts.Spec.Volumes = append(pts.Spec.Volumes[:i], pts.Spec.Volumes[i+1:]...) } } - - return nil } func uninstallDeployments(ctx context.Context, cmd *cobra.Command, client *kube.Client, ns string) error { diff --git a/instrumentor/patch/dotnet.go b/instrumentor/patch/dotnet.go index f1769db23c..082f95b8e6 100644 --- a/instrumentor/patch/dotnet.go +++ b/instrumentor/patch/dotnet.go @@ -1,29 +1,10 @@ package patch import ( - "fmt" odigosv1 "github.com/keyval-dev/odigos/api/odigos/v1alpha1" "github.com/keyval-dev/odigos/common" v1 "k8s.io/api/core/v1" -) - -const ( - dotnetAgentName = "edenfed/otel-dotnet-agent:v0.1" - enableProfilingEnvVar = "CORECLR_ENABLE_PROFILING" - profilerEndVar = "CORECLR_PROFILER" - profilerId = "{918728DD-259F-4A6A-AC2B-B85E1B658318}" - profilerPathEnv = "CORECLR_PROFILER_PATH" - profilerPath = "/agent/OpenTelemetry.AutoInstrumentation.ClrProfiler.Native.so" - intergationEnv = "OTEL_INTEGRATIONS" - intergations = "/agent/integrations.json" - conventionsEnv = "OTEL_CONVENTION" - serviceNameEnv = "OTEL_SERVICE" - convetions = "OpenTelemetry" - collectorUrlEnv = "OTEL_TRACE_AGENT_URL" - tracerHomeEnv = "OTEL_DOTNET_TRACER_HOME" - exportTypeEnv = "OTEL_EXPORTER" - tracerHome = "/agent" - dotnetVolumeName = "agentdir-dotnet" + "k8s.io/apimachinery/pkg/api/resource" ) var dotNet = &dotNetPatcher{} @@ -31,86 +12,10 @@ var dotNet = &dotNetPatcher{} type dotNetPatcher struct{} func (d *dotNetPatcher) Patch(podSpec *v1.PodTemplateSpec, instrumentation *odigosv1.InstrumentedApplication) { - podSpec.Spec.Volumes = append(podSpec.Spec.Volumes, v1.Volume{ - Name: dotnetVolumeName, - VolumeSource: v1.VolumeSource{ - EmptyDir: &v1.EmptyDirVolumeSource{}, - }, - }) - - podSpec.Spec.InitContainers = append(podSpec.Spec.InitContainers, v1.Container{ - Name: "copy-dotnet-agent", - Image: dotnetAgentName, - VolumeMounts: []v1.VolumeMount{ - { - Name: dotnetVolumeName, - MountPath: tracerHome, - }, - }, - }) - var modifiedContainers []v1.Container for _, container := range podSpec.Spec.Containers { if shouldPatch(instrumentation, common.DotNetProgrammingLanguage, container.Name) { - container.Env = append([]v1.EnvVar{{ - Name: NodeIPEnvName, - ValueFrom: &v1.EnvVarSource{ - FieldRef: &v1.ObjectFieldSelector{ - FieldPath: "status.hostIP", - }, - }, - }}, container.Env...) - - container.Env = append(container.Env, v1.EnvVar{ - Name: enableProfilingEnvVar, - Value: "1", - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: profilerEndVar, - Value: profilerId, - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: profilerPathEnv, - Value: profilerPath, - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: intergationEnv, - Value: intergations, - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: tracerHomeEnv, - Value: tracerHome, - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: conventionsEnv, - Value: convetions, - }) - - // Currently .NET instrumentation only support zipkin format, we should move to OTLP when support is added - container.Env = append(container.Env, v1.EnvVar{ - Name: collectorUrlEnv, - Value: fmt.Sprintf("http://%s:9411/api/v2/spans", HostIPEnvValue), - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: serviceNameEnv, - Value: calculateAppName(podSpec, &container, instrumentation), - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: exportTypeEnv, - Value: "Zipkin", - }) - - container.VolumeMounts = append(container.VolumeMounts, v1.VolumeMount{ - MountPath: tracerHome, - Name: dotnetVolumeName, - }) + container.Resources.Limits["instrumentation.odigos.io/dotnet"] = resource.MustParse("1") } modifiedContainers = append(modifiedContainers, container) @@ -120,9 +25,8 @@ func (d *dotNetPatcher) Patch(podSpec *v1.PodTemplateSpec, instrumentation *odig } func (d *dotNetPatcher) IsInstrumented(podSpec *v1.PodTemplateSpec, instrumentation *odigosv1.InstrumentedApplication) bool { - // TODO: Deep comparison - for _, c := range podSpec.Spec.InitContainers { - if c.Name == "copy-dotnet-agent" { + for _, c := range podSpec.Spec.Containers { + if _, exists := c.Resources.Limits["instrumentation.odigos.io/dotnet"]; exists { return true } } diff --git a/instrumentor/patch/java.go b/instrumentor/patch/java.go index be89bc3a88..74ed331384 100644 --- a/instrumentor/patch/java.go +++ b/instrumentor/patch/java.go @@ -1,23 +1,10 @@ package patch import ( - "fmt" odigosv1 "github.com/keyval-dev/odigos/api/odigos/v1alpha1" "github.com/keyval-dev/odigos/common" - "github.com/keyval-dev/odigos/common/consts" v1 "k8s.io/api/core/v1" -) - -const ( - javaAgentImage = "keyval/otel-java-agent:v0.5" - javaVolumeName = "agentdir-java" - javaMountPath = "/agent" - otelResourceAttributesEnvVar = "OTEL_RESOURCE_ATTRIBUTES" - otelResourceAttrPatteern = "service.name=%s,k8s.pod.name=%s" - javaOptsEnvVar = "JAVA_OPTS" - javaToolOptionsEnvVar = "JAVA_TOOL_OPTIONS" - javaToolOptionsPattern = "-javaagent:/agent/opentelemetry-javaagent-all.jar " + - "-Dotel.traces.sampler=always_on -Dotel.exporter.otlp.endpoint=http://%s:%d" + "k8s.io/apimachinery/pkg/api/resource" ) var java = &javaPatcher{} @@ -25,70 +12,10 @@ var java = &javaPatcher{} type javaPatcher struct{} func (j *javaPatcher) Patch(podSpec *v1.PodTemplateSpec, instrumentation *odigosv1.InstrumentedApplication) { - podSpec.Spec.Volumes = append(podSpec.Spec.Volumes, v1.Volume{ - Name: javaVolumeName, - VolumeSource: v1.VolumeSource{ - EmptyDir: &v1.EmptyDirVolumeSource{}, - }, - }) - - podSpec.Spec.InitContainers = append(podSpec.Spec.InitContainers, v1.Container{ - Name: "copy-java-agent", - Image: javaAgentImage, - Command: []string{"cp", "/javaagent.jar", "/agent/opentelemetry-javaagent-all.jar"}, - VolumeMounts: []v1.VolumeMount{ - { - Name: javaVolumeName, - MountPath: javaMountPath, - }, - }, - }) - var modifiedContainers []v1.Container for _, container := range podSpec.Spec.Containers { if shouldPatch(instrumentation, common.JavaProgrammingLanguage, container.Name) { - container.Env = append([]v1.EnvVar{{ - Name: NodeIPEnvName, - ValueFrom: &v1.EnvVarSource{ - FieldRef: &v1.ObjectFieldSelector{ - FieldPath: "status.hostIP", - }, - }, - }, - { - Name: PodNameEnvVName, - ValueFrom: &v1.EnvVarSource{ - FieldRef: &v1.ObjectFieldSelector{ - FieldPath: "metadata.name", - }, - }, - }, - }, container.Env...) - - idx := getIndexOfEnv(container.Env, javaToolOptionsEnvVar) - if idx == -1 { - container.Env = append(container.Env, v1.EnvVar{ - Name: javaToolOptionsEnvVar, - Value: fmt.Sprintf(javaToolOptionsPattern, HostIPEnvValue, consts.OTLPPort), - }) - } else { - container.Env[idx].Value = container.Env[idx].Value + " " + fmt.Sprintf(javaToolOptionsPattern, HostIPEnvValue, consts.OTLPPort) - } - - container.Env = append(container.Env, v1.EnvVar{ - Name: javaOptsEnvVar, - Value: fmt.Sprintf(javaToolOptionsPattern, HostIPEnvValue, consts.OTLPPort), - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: otelResourceAttributesEnvVar, - Value: fmt.Sprintf(otelResourceAttrPatteern, calculateAppName(podSpec, &container, instrumentation), PodNameEnvValue), - }) - - container.VolumeMounts = append(container.VolumeMounts, v1.VolumeMount{ - MountPath: javaMountPath, - Name: javaVolumeName, - }) + container.Resources.Limits["instrumentation.odigos.io/java"] = resource.MustParse("1") } modifiedContainers = append(modifiedContainers, container) @@ -98,9 +25,8 @@ func (j *javaPatcher) Patch(podSpec *v1.PodTemplateSpec, instrumentation *odigos } func (j *javaPatcher) IsInstrumented(podSpec *v1.PodTemplateSpec, instrumentation *odigosv1.InstrumentedApplication) bool { - // TODO: Deep comparison - for _, c := range podSpec.Spec.InitContainers { - if c.Name == "copy-java-agent" { + for _, c := range podSpec.Spec.Containers { + if _, exists := c.Resources.Limits["instrumentation.odigos.io/java"]; exists { return true } } diff --git a/instrumentor/patch/nodejs.go b/instrumentor/patch/nodejs.go index 7d618ea240..1b74cd71ab 100644 --- a/instrumentor/patch/nodejs.go +++ b/instrumentor/patch/nodejs.go @@ -1,22 +1,10 @@ package patch import ( - "fmt" odigosv1 "github.com/keyval-dev/odigos/api/odigos/v1alpha1" "github.com/keyval-dev/odigos/common" - "github.com/keyval-dev/odigos/common/consts" v1 "k8s.io/api/core/v1" -) - -const ( - nodeAgentImage = "keyval/otel-nodejs-agent:v0.3" - nodeVolumeName = "agentdir-nodejs" - nodeMountPath = "/agent-nodejs" - nodeEnvNodeDebug = "OTEL_NODEJS_DEBUG" - nodeEnvTraceExporter = "OTEL_TRACES_EXPORTER" - nodeEnvEndpoint = "OTEL_EXPORTER_OTLP_ENDPOINT" - nodeEnvServiceName = "OTEL_SERVICE_NAME" - nodeEnvNodeOptions = "NODE_OPTIONS" + "k8s.io/apimachinery/pkg/api/resource" ) var nodeJs = &nodeJsPatcher{} @@ -24,76 +12,21 @@ var nodeJs = &nodeJsPatcher{} type nodeJsPatcher struct{} func (n *nodeJsPatcher) Patch(podSpec *v1.PodTemplateSpec, instrumentation *odigosv1.InstrumentedApplication) { - podSpec.Spec.Volumes = append(podSpec.Spec.Volumes, v1.Volume{ - Name: nodeVolumeName, - VolumeSource: v1.VolumeSource{ - EmptyDir: &v1.EmptyDirVolumeSource{}, - }, - }) - - podSpec.Spec.InitContainers = append(podSpec.Spec.InitContainers, v1.Container{ - Name: "copy-nodejs-agent", - Image: nodeAgentImage, - Command: []string{"cp", "-a", "/autoinstrumentation/.", fmt.Sprintf("/%s/", nodeMountPath)}, - VolumeMounts: []v1.VolumeMount{ - { - Name: nodeVolumeName, - MountPath: nodeMountPath, - }, - }, - }) - var modifiedContainers []v1.Container for _, container := range podSpec.Spec.Containers { if shouldPatch(instrumentation, common.JavascriptProgrammingLanguage, container.Name) { - container.Env = append([]v1.EnvVar{{ - Name: NodeIPEnvName, - ValueFrom: &v1.EnvVarSource{ - FieldRef: &v1.ObjectFieldSelector{ - FieldPath: "status.hostIP", - }, - }, - }}, container.Env...) - - container.Env = append(container.Env, v1.EnvVar{ - Name: nodeEnvNodeDebug, - Value: "true", - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: nodeEnvTraceExporter, - Value: "otlp", - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: nodeEnvEndpoint, - Value: fmt.Sprintf("http://%s:%d", HostIPEnvValue, consts.OTLPPort), - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: nodeEnvServiceName, - Value: calculateAppName(podSpec, &container, instrumentation), - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: nodeEnvNodeOptions, - Value: fmt.Sprintf("--require /%s/autoinstrumentation.js", nodeMountPath), - }) - - container.VolumeMounts = append(container.VolumeMounts, v1.VolumeMount{ - MountPath: nodeMountPath, - Name: nodeVolumeName, - }) + container.Resources.Limits["instrumentation.odigos.io/nodejs"] = resource.MustParse("1") } + modifiedContainers = append(modifiedContainers, container) } + podSpec.Spec.Containers = modifiedContainers } func (n *nodeJsPatcher) IsInstrumented(podSpec *v1.PodTemplateSpec, instrumentation *odigosv1.InstrumentedApplication) bool { - // TODO: Deep comparison - for _, c := range podSpec.Spec.InitContainers { - if c.Name == "copy-nodejs-agent" { + for _, c := range podSpec.Spec.Containers { + if _, exists := c.Resources.Limits["instrumentation.odigos.io/nodejs"]; exists { return true } } diff --git a/instrumentor/patch/python.go b/instrumentor/patch/python.go index abc31c9a4b..fb89c7836e 100644 --- a/instrumentor/patch/python.go +++ b/instrumentor/patch/python.go @@ -1,11 +1,10 @@ package patch import ( - "fmt" odigosv1 "github.com/keyval-dev/odigos/api/odigos/v1alpha1" "github.com/keyval-dev/odigos/common" - "github.com/keyval-dev/odigos/common/consts" v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" ) const ( @@ -24,81 +23,12 @@ var python = &pythonPatcher{} type pythonPatcher struct{} func (p *pythonPatcher) Patch(podSpec *v1.PodTemplateSpec, instrumentation *odigosv1.InstrumentedApplication) { - podSpec.Spec.Volumes = append(podSpec.Spec.Volumes, v1.Volume{ - Name: pythonVolumeName, - VolumeSource: v1.VolumeSource{ - EmptyDir: &v1.EmptyDirVolumeSource{}, - }, - }) - - podSpec.Spec.InitContainers = append(podSpec.Spec.InitContainers, v1.Container{ - Name: pythonInitContainerName, - Image: pythonAgentName, - Command: []string{"cp", "-a", "/autoinstrumentation/.", "/otel-auto-instrumentation/"}, - VolumeMounts: []v1.VolumeMount{ - { - Name: pythonVolumeName, - MountPath: pythonMountPath, - }, - }, - }) - var modifiedContainers []v1.Container for _, container := range podSpec.Spec.Containers { if shouldPatch(instrumentation, common.PythonProgrammingLanguage, container.Name) { - container.Env = append([]v1.EnvVar{{ - Name: NodeIPEnvName, - ValueFrom: &v1.EnvVarSource{ - FieldRef: &v1.ObjectFieldSelector{ - FieldPath: "status.hostIP", - }, - }, - }, - { - Name: PodNameEnvVName, - ValueFrom: &v1.EnvVarSource{ - FieldRef: &v1.ObjectFieldSelector{ - FieldPath: "metadata.name", - }, - }, - }, - }, container.Env...) - - container.Env = append(container.Env, v1.EnvVar{ - Name: envLogCorrelation, - Value: "true", - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: "PYTHONPATH", - Value: "/otel-auto-instrumentation/opentelemetry/instrumentation/auto_instrumentation:/otel-auto-instrumentation", - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: "OTEL_EXPORTER_OTLP_ENDPOINT", - Value: fmt.Sprintf("http://%s:%d", HostIPEnvValue, consts.OTLPHttpPort), - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: "OTEL_RESOURCE_ATTRIBUTES", - Value: fmt.Sprintf("service.name=%s,k8s.pod.name=%s", calculateAppName(podSpec, &container, instrumentation), PodNameEnvValue), - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: envOtelTracesExporter, - Value: envValOtelHttpExporter, - }) - - container.Env = append(container.Env, v1.EnvVar{ - Name: envOtelMetricsExporter, - Value: "", - }) - - container.VolumeMounts = append(container.VolumeMounts, v1.VolumeMount{ - MountPath: pythonMountPath, - Name: pythonVolumeName, - }) + container.Resources.Limits["instrumentation.odigos.io/python"] = resource.MustParse("1") } + modifiedContainers = append(modifiedContainers, container) } @@ -106,9 +36,8 @@ func (p *pythonPatcher) Patch(podSpec *v1.PodTemplateSpec, instrumentation *odig } func (p *pythonPatcher) IsInstrumented(podSpec *v1.PodTemplateSpec, instrumentation *odigosv1.InstrumentedApplication) bool { - // TODO: Deep comparison - for _, c := range podSpec.Spec.InitContainers { - if c.Name == pythonInitContainerName { + for _, c := range podSpec.Spec.Containers { + if _, exists := c.Resources.Limits["instrumentation.odigos.io/python"]; exists { return true } } diff --git a/odiglet/Dockerfile b/odiglet/Dockerfile index dc46dd00b4..ea76ec448b 100644 --- a/odiglet/Dockerfile +++ b/odiglet/Dockerfile @@ -1,12 +1,43 @@ +FROM python:3.10-alpine AS python-builder +WORKDIR /python-instrumentation +ADD agents/python/requirements.txt . +RUN mkdir workspace && pip install --target workspace -r requirements.txt + +FROM node:16 AS nodejs-builder +WORKDIR /nodejs-instrumentation +COPY agents/nodejs . +RUN npm install + +FROM busybox AS dotnet-builder +WORKDIR /dotnet-instrumentation +ARG DOTNET_OTEL_VERSIN=0.5.0 +ADD https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/download/v$DOTNET_OTEL_VERSIN/opentelemetry-dotnet-instrumentation-linux-musl.zip . +RUN unzip opentelemetry-dotnet-instrumentation-linux-musl.zip && rm opentelemetry-dotnet-instrumentation-linux-musl.zip + FROM golang:1.19 AS builder WORKDIR /go/src/github.com/keyval-dev/odigos/odiglet COPY . . -RUN apt-get update && apt-get install -y nasm -RUN nasm pkg/allocator/payload/mmap.asm RUN go mod download -RUN CGO_ENABLED=0 GOOS=linux go build -o app cmd/main.go +RUN CGO_ENABLED=0 GOOS=linux go build -o odiglet cmd/main.go + +WORKDIR /instrumentations + +# Java +ARG JAVA_OTEL_VERSIN=1.22.1 +ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v$JAVA_OTEL_VERSIN/opentelemetry-javaagent.jar /instrumentations/java/javaagent.jar + +# Python +COPY --from=python-builder /python-instrumentation/workspace /instrumentations/python + +# NodeJS +COPY --from=nodejs-builder /nodejs-instrumentation/build/workspace /instrumentations/nodejs + +# .NET +COPY --from=dotnet-builder /dotnet-instrumentation /instrumentations/dotnet FROM gcr.io/distroless/static-debian10 WORKDIR /root/ -COPY --from=builder /go/src/github.com/keyval-dev/odigos/odiglet/app . -CMD ["/root/app"] +COPY --from=builder /go/src/github.com/keyval-dev/odigos/odiglet/odiglet . +WORKDIR /instrumentations/ +COPY --from=builder /instrumentations/ . +CMD ["/root/odiglet"] diff --git a/agents/nodejs/.dockerignore b/odiglet/agents/nodejs/.dockerignore similarity index 100% rename from agents/nodejs/.dockerignore rename to odiglet/agents/nodejs/.dockerignore diff --git a/agents/nodejs/package.json b/odiglet/agents/nodejs/package.json similarity index 100% rename from agents/nodejs/package.json rename to odiglet/agents/nodejs/package.json diff --git a/agents/nodejs/src/autoinstrumentation.ts b/odiglet/agents/nodejs/src/autoinstrumentation.ts similarity index 100% rename from agents/nodejs/src/autoinstrumentation.ts rename to odiglet/agents/nodejs/src/autoinstrumentation.ts diff --git a/agents/nodejs/tsconfig.json b/odiglet/agents/nodejs/tsconfig.json similarity index 100% rename from agents/nodejs/tsconfig.json rename to odiglet/agents/nodejs/tsconfig.json diff --git a/agents/python/requirements.txt b/odiglet/agents/python/requirements.txt similarity index 100% rename from agents/python/requirements.txt rename to odiglet/agents/python/requirements.txt diff --git a/odiglet/cmd/main.go b/odiglet/cmd/main.go index c3b7e7683f..d3ecf70d4c 100644 --- a/odiglet/cmd/main.go +++ b/odiglet/cmd/main.go @@ -1,19 +1,14 @@ package main import ( - "encoding/json" - "github.com/keyval-dev/odigos/odiglet/pkg" - "github.com/keyval-dev/odigos/odiglet/pkg/allocator" - "github.com/keyval-dev/odigos/odiglet/pkg/containers" - "github.com/keyval-dev/odigos/odiglet/pkg/containers/runtimes" + "context" "github.com/keyval-dev/odigos/odiglet/pkg/env" + "github.com/keyval-dev/odigos/odiglet/pkg/instrumentation" "github.com/keyval-dev/odigos/odiglet/pkg/log" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/kubevirt/device-plugin-manager/pkg/dpm" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" - "net/http" "os" - "path" ) func main() { @@ -40,103 +35,20 @@ func main() { os.Exit(-1) } - server := newHTTPServer(clientset) - http.Handle("/launch", server) - - log.Logger.V(0).Info("Listening on port 8080") - log.Logger.V(0).Error(http.ListenAndServe(":8080", nil), "Failed to start http server") + startDeviceManager(clientset) } -type httpServer struct { - kubeClient kubernetes.Interface -} +func startDeviceManager(clientset *kubernetes.Clientset) { + log.Logger.V(0).Info("Starting device manager") + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() -func newHTTPServer(kubeClient kubernetes.Interface) *httpServer { - return &httpServer{ - kubeClient: kubeClient, - } -} - -func (s *httpServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { - log.Logger.V(0).Info("Got a new launch request") - - // verify request is POST - if r.Method != http.MethodPost { - w.WriteHeader(http.StatusMethodNotAllowed) - return - } - - // verify request type is application/json - if r.Header.Get("Content-Type") != "application/json" { - w.WriteHeader(http.StatusUnsupportedMediaType) - return - } - - // verify request body is not empty - if r.Body == nil { - w.WriteHeader(http.StatusBadRequest) - return - } - - // verify request body is valid json - decoder := json.NewDecoder(r.Body) - var req pkg.LaunchRequest - err := decoder.Decode(&req) + lister, err := instrumentation.NewLister(ctx, clientset) if err != nil { - w.WriteHeader(http.StatusBadRequest) - return - } - - // verify request body has exe_path and pod_name and pod_namespace - if req.ExePath == "" || req.PodName == "" || req.PodNamespace == "" { - w.WriteHeader(http.StatusBadRequest) - return - } - - // Verify pod belongs to current node - log.Logger.V(0).Info("Getting pod", "pod", req.PodName, "namespace", req.PodNamespace) - pod, err := s.kubeClient.CoreV1().Pods(req.PodNamespace).Get(r.Context(), req.PodName, metav1.GetOptions{}) - if err != nil { - log.Logger.Error(err, "Failed to get pod", "pod", req.PodName, "namespace", req.PodNamespace) - w.WriteHeader(http.StatusInternalServerError) - return - } - if pod.Spec.NodeName != env.Current.NodeName { - log.Logger.Error(err, "Pod does not belong to current node", "pod", req.PodName, "namespace", req.PodNamespace) - w.WriteHeader(http.StatusBadRequest) - return - } - - // Find container ids - containerIds, err := containers.FindIDs(r.Context(), req.PodName, req.PodNamespace, s.kubeClient) - if err != nil { - log.Logger.Error(err, "Failed to find target containers") - w.WriteHeader(http.StatusInternalServerError) - return + log.Logger.Error(err, "Failed to create new lister") + os.Exit(-1) } - for _, containerId := range containerIds { - cri, err := runtimes.ByName(containerId.Runtime) - if err != nil { - log.Logger.Error(err, "Failed to find runtime", "runtime", containerId.Runtime) - w.WriteHeader(http.StatusInternalServerError) - return - } - - fs, err := cri.GetFileSystemPath(containerId.ID) - if err != nil { - log.Logger.Error(err, "Failed to get filesystem path", "container", containerId.ID) - w.WriteHeader(http.StatusInternalServerError) - return - } - - log.Logger.V(0).Info("Got filesystem path", "path", fs) - exePath := path.Join(fs, req.ExePath) - err = allocator.Apply(exePath) - if err != nil { - log.Logger.Error(err, "Failed to apply allocator", "exe", exePath) - w.WriteHeader(http.StatusInternalServerError) - return - } - } + manager := dpm.NewManager(lister) + manager.Run() } diff --git a/odiglet/go.mod b/odiglet/go.mod index ab1b83680d..ae960e3fe3 100644 --- a/odiglet/go.mod +++ b/odiglet/go.mod @@ -8,13 +8,17 @@ require ( github.com/fatih/color v1.13.0 github.com/go-logr/logr v1.2.3 github.com/go-logr/zapr v1.2.3 + github.com/google/uuid v1.1.2 + github.com/kubevirt/device-plugin-manager v1.19.4 github.com/moby/sys/mountinfo v0.6.2 + github.com/otiai10/copy v1.9.0 go.uber.org/zap v1.24.0 google.golang.org/grpc v1.49.0 - k8s.io/api v0.26.0 - k8s.io/apimachinery v0.26.0 + k8s.io/api v0.26.1 + k8s.io/apimachinery v0.26.1 k8s.io/client-go v0.26.0 k8s.io/cri-api v0.26.0 + k8s.io/kubelet v0.26.1 ) require ( @@ -24,10 +28,12 @@ require ( github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect + github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/swag v0.19.14 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/go-cmp v0.5.9 // indirect diff --git a/odiglet/go.sum b/odiglet/go.sum index 8c9f2b16ab..bcc394e1fe 100644 --- a/odiglet/go.sum +++ b/odiglet/go.sum @@ -6,6 +6,7 @@ cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxK cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= @@ -31,16 +32,39 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/Binject/shellcode v0.0.0-20191101084904-a8a90e7d4563 h1:T8z8Wz/fqaPPANF8Unv4LjWLoa0TAvsjYAsRpvSkOqs= github.com/Binject/shellcode v0.0.0-20191101084904-a8a90e7d4563/go.mod h1:HMbzsKPz1sF7H4Hmeovh+d2PH2iKPYpAB4XMOVz8wmM= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -57,6 +81,7 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v20.10.22+incompatible h1:6jX4yB+NtcbldT90k7vBSaWJDB3i+zkVJT9BEK8kQkk= @@ -65,7 +90,10 @@ github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKoh github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -74,28 +102,47 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -152,27 +199,43 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kubevirt/device-plugin-manager v1.19.4 h1:kqKOzbFceNr1Gfs3eTEj/U96NBl7HSRdZe9RDcpBx+E= +github.com/kubevirt/device-plugin-manager v1.19.4/go.mod h1:gPIAptDNdxXBVbq4I2eNPlLy8ZHbd24KpjNLWmpfQuU= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= @@ -182,40 +245,90 @@ github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= +github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4= +github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/otiai10/copy v1.9.0 h1:7KFNiCgZ91Ru4qW4CWPf/7jqtxLagGRmIxWldPP9VY4= +github.com/otiai10/copy v1.9.0/go.mod h1:hsfX19wcn0UWIHUQ3/4fHuehhk2UyArQ9dVFAn3FczI= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= +github.com/otiai10/mint v1.4.0 h1:umwcf7gbpEwf7WFzqmWwSv0CzbeMsae2u9ZvpP8j2q4= +github.com/otiai10/mint v1.4.0/go.mod h1:gifjb2MYOoULtKLqUAEILUG/9KONW6f7YsJ6vQLTlFI= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -232,19 +345,24 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -280,6 +398,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVD golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -287,6 +407,7 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -300,10 +421,12 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -326,17 +449,25 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -349,8 +480,12 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -382,6 +517,8 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -392,6 +529,7 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -485,6 +623,7 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200916143405-f6a2fa72f0c4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I= google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= @@ -500,6 +639,7 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= @@ -521,17 +661,25 @@ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -539,6 +687,8 @@ gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o= gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -548,18 +698,30 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.26.0 h1:IpPlZnxBpV1xl7TGk/X6lFtpgjgntCg8PJ+qrPHAC7I= -k8s.io/api v0.26.0/go.mod h1:k6HDTaIFC8yn1i6pSClSqIwLABIcLV9l5Q4EcngKnQg= -k8s.io/apimachinery v0.26.0 h1:1feANjElT7MvPqp0JT6F3Ss6TWDwmcjLypwoPpEf7zg= -k8s.io/apimachinery v0.26.0/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= +k8s.io/api v0.19.2/go.mod h1:IQpK0zFQ1xc5iNIQPqzgoOwuFugaYHK4iCknlAQP9nI= +k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ= +k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg= +k8s.io/apimachinery v0.19.2/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= +k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ= +k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= +k8s.io/client-go v0.19.2/go.mod h1:S5wPhCqyDNAlzM9CnEdgTGV4OqhsW3jGO1UM1epwfJA= k8s.io/client-go v0.26.0 h1:lT1D3OfO+wIi9UFolCrifbjUUgu7CpLca0AD8ghRLI8= k8s.io/client-go v0.26.0/go.mod h1:I2Sh57A79EQsDmn7F7ASpmru1cceh3ocVT9KlX2jEZg= +k8s.io/component-base v0.19.2/go.mod h1:g5LrsiTiabMLZ40AR6Hl45f088DevyGY+cCE2agEIVo= k8s.io/cri-api v0.26.0 h1:/Cfs9BUtGwYWjRCscd/4q+uJ0UqCzwcIZDI+Eyvle78= k8s.io/cri-api v0.26.0/go.mod h1:I5TGOn/ziMzqIcUvsYZzVE8xDAB1JBkvcwvR0yDreuw= +k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4= k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= +k8s.io/kubelet v0.19.2/go.mod h1:FHHoByVWzh6kNaarXaDPAa751Oz6REcOVRyFT84L1Is= +k8s.io/kubelet v0.26.1 h1:wQyCQYmLW6GN3v7gVTxnc3jAE4zMYDlzdF3FZV4rKas= +k8s.io/kubelet v0.26.1/go.mod h1:gFVZ1Ab4XdjtnYdVRATwGwku7FhTxo6LVEZwYoQaDT8= +k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20221107191617-1a15be271d1d h1:0Smp/HP1OH4Rvhe+4B8nWGERtlqAGSftbSbbmm45oFs= k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= @@ -567,7 +729,10 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/odiglet/pkg/allocator/allocate.go b/odiglet/pkg/allocator/allocate.go deleted file mode 100644 index 7e5060f10d..0000000000 --- a/odiglet/pkg/allocator/allocate.go +++ /dev/null @@ -1,46 +0,0 @@ -package allocator - -import ( - _ "embed" - "github.com/keyval-dev/odigos/odiglet/pkg/allocator/bj" - "github.com/keyval-dev/odigos/odiglet/pkg/allocator/debug/elf" - "github.com/keyval-dev/odigos/odiglet/pkg/log" - "os" -) - -//go:embed payload/mmap -var payloadBytes []byte - -func Apply(exePath string) error { - log.Logger.V(0).Info("Applying allocation", "exePath", exePath) - - inputStat, err := os.Stat(exePath) - if err != nil { - log.Logger.Error(err, "Failed to stat exePath", "exePath", exePath) - return err - } - - // Parse elf file - f, err := elf.Open(exePath) - if err != nil { - log.Logger.Error(err, "Failed to open elf file", "exePath", exePath) - return err - } - - output, shoff, err := bj.StaticSilvioMethod(f, payloadBytes) - if err != nil { - log.Logger.Error(err, "Failed to apply allocation", "exePath", exePath) - return err - } - - output = applyFixForGoBinaries(f, shoff, output) - - // Write output to exePath - err = os.WriteFile(exePath, output, inputStat.Mode()) - if err != nil { - log.Logger.Error(err, "Failed to write output to exePath", "exePath", exePath) - return err - } - - return nil -} diff --git a/odiglet/pkg/allocator/bj/binjector.go b/odiglet/pkg/allocator/bj/binjector.go deleted file mode 100644 index e21af92b2d..0000000000 --- a/odiglet/pkg/allocator/bj/binjector.go +++ /dev/null @@ -1,61 +0,0 @@ -package bj - -import ( - "io/ioutil" - "os" - - "github.com/Binject/shellcode" -) - -// Injection Methods -const ( - PtNoteInject int = iota - SilvioInject = iota -) - -// BinjectConfig - Configuration Settings for the Binject modules -type BinjectConfig struct { - CodeCaveMode bool - InjectionMethod int - - Repo *shellcode.Repo -} - -// BinjectFile - Inject shellcode into a binary file -func BinjectFile(sourceFile string, destFile string, shellcodeFile string, config *BinjectConfig) error { - - shellcodeBytes, err := ioutil.ReadFile(shellcodeFile) - if err != nil { - return err - } - - sourceBytes, err := ioutil.ReadFile(sourceFile) - if err != nil { - return err - } - - destBytes, err := Binject(sourceBytes, shellcodeBytes, config) - if err != nil { - return err - } - - f, err := os.Create(destFile) - if err != nil { - return err - } - defer f.Close() - _, err = f.Write(destBytes) - return err -} - -// Binject - Inject shellcode into a byte array -func Binject(sourceBytes []byte, shellcodeBytes []byte, config *BinjectConfig) ([]byte, error) { - - binType, err := BinaryMagic(sourceBytes) - var binject func([]byte, []byte, *BinjectConfig) ([]byte, error) - switch binType { - case ERROR: - return nil, err - } - return binject(sourceBytes, shellcodeBytes, config) -} diff --git a/odiglet/pkg/allocator/bj/inject_elf.go b/odiglet/pkg/allocator/bj/inject_elf.go deleted file mode 100644 index 8614b65a58..0000000000 --- a/odiglet/pkg/allocator/bj/inject_elf.go +++ /dev/null @@ -1,127 +0,0 @@ -package bj - -import ( - "bytes" - "github.com/Binject/shellcode/api" - "github.com/keyval-dev/odigos/odiglet/pkg/allocator/debug/elf" - "log" -) - -// ElfBinject - Inject shellcode into an ELF binary -func ElfBinject(sourceBytes []byte, shellcodeBytes []byte, config *BinjectConfig) ([]byte, uint64, error) { - - elfFile, err := elf.NewFile(bytes.NewReader(sourceBytes)) - if err != nil { - return nil, 0, err - } - - // - // BEGIN CODE CAVE DETECTION SECTION - // - - if config.CodeCaveMode == true { - log.Printf("Using Code Cave Method") - caves, err := FindCaves(sourceBytes) - if err != nil { - return nil, 0, err - } - for _, cave := range caves { - for _, section := range elfFile.Sections { - if cave.Start >= section.Offset && cave.End <= (section.Size+section.Offset) && - cave.End-cave.Start >= uint64(MIN_CAVE_SIZE) { - log.Printf("Cave found (start/end/size): %d / %d / %d \n", cave.Start, cave.End, cave.End-cave.Start) - } - } - } - } - // - // END CODE CAVE DETECTION SECTION - // - - return StaticSilvioMethod(elfFile, shellcodeBytes) -} - -func StaticSilvioMethod(elfFile *elf.File, userShellCode []byte) ([]byte, uint64, error) { - /* - Circa 1998: http://vxheavens.com/lib/vsc01.html <--Thanks to elfmaster - 6. Increase p_shoff by PAGE_SIZE in the ELF header - 7. Patch the insertion code (parasite) to jump to the entry point (original) - 1. Locate the text segment program header - -Modify the entry point of the ELF header to point to the new code (p_vaddr + p_filesz) - -Increase p_filesz to account for the new code (parasite) - -Increase p_memsz to account for the new code (parasite) - 2. For each phdr which is after the insertion (text segment) - -increase p_offset by PAGE_SIZE - 3. For the last shdr in the text segment - -increase sh_len by the parasite length - 4. For each shdr which is after the insertion - -Increase sh_offset by PAGE_SIZE - 5. Physically insert the new code (parasite) and pad to PAGE_SIZE, - into the file - text segment p_offset + p_filesz (original) - */ - - //PAGE_SIZE := uint64(4096) - - scAddr := uint64(0) - sclen := uint64(0) - shellcode := []byte{} - - // 6. Increase p_shoff by PAGE_SIZE in the ELF header - //elfFile.FileHeader.SHTOffset += int64(PAGE_SIZE) - - afterTextSegment := false - for _, p := range elfFile.Progs { - - if afterTextSegment { - //2. For each phdr which is after the insertion (text segment) - //-increase p_offset by PAGE_SIZE - - // todo: this doesn't match the diff - //p.Off += PAGE_SIZE - //p.Vaddr += PAGE_SIZE - //p.Paddr += PAGE_SIZE - - } else if p.Type == elf.PT_LOAD && p.Flags == (elf.PF_R|elf.PF_X) { - // 1. Locate the text segment program header - // -Modify the entry point of the ELF header to point to the new code (p_vaddr + p_filesz) - originalEntry := elfFile.FileHeader.Entry - elfFile.FileHeader.Entry = p.Vaddr + p.Filesz - - // 7. Patch the insertion code (parasite) to jump to the entry point (original) - scAddr = p.Vaddr + p.Filesz - shellcode = api.ApplySuffixJmpIntel64(userShellCode, uint32(scAddr), uint32(originalEntry), elfFile.ByteOrder) - - sclen = uint64(len(shellcode)) - log.Println("Shellcode Length: ", sclen) - - // -Increase p_filesz to account for the new code (parasite) - p.Filesz += sclen - // -Increase p_memsz to account for the new code (parasite) - p.Memsz += sclen - - afterTextSegment = true - } - } - - // 3. For the last shdr in the text segment - //sortedSections := elfFile.Sections[:] - //sort.Slice(sortedSections, func(a, b int) bool { return elfFile.Sections[a].Offset < elfFile.Sections[b].Offset }) - for _, s := range elfFile.Sections { - - if s.Addr > scAddr { - // 4. For each shdr which is after the insertion - // -Increase sh_offset by PAGE_SIZE - //s.Offset += PAGE_SIZE - //s.Addr += PAGE_SIZE - - } else if s.Size+s.Addr == scAddr { // assuming entry was set to (p_vaddr + p_filesz) above - // -increase sh_len by the parasite length - s.Size += sclen - } - } - - // 5. Physically insert the new code (parasite) and pad to PAGE_SIZE, - // into the file - text segment p_offset + p_filesz (original) - elfFile.Insertion = shellcode - return elfFile.Bytes() -} diff --git a/odiglet/pkg/allocator/bj/inject_test.go b/odiglet/pkg/allocator/bj/inject_test.go deleted file mode 100644 index 25cf310ad5..0000000000 --- a/odiglet/pkg/allocator/bj/inject_test.go +++ /dev/null @@ -1,91 +0,0 @@ -package bj - -import ( - "bytes" - "io" - "log" - "os" - "testing" -) - -func CompareFiles(file1, file2 string) bool { - const chunkSize = 64 * 1024 - f1, err := os.Open(file1) - if err != nil { - log.Fatal(err) - } - f2, err := os.Open(file2) - if err != nil { - log.Fatal(err) - } - - for { - b1 := make([]byte, chunkSize) - _, err1 := f1.Read(b1) - - b2 := make([]byte, chunkSize) - _, err2 := f2.Read(b2) - - if err1 != nil || err2 != nil { - if err1 == io.EOF && err2 == io.EOF { - return true - } else if err1 == io.EOF || err2 == io.EOF { - return false - } else { - log.Fatal(err1, err2) - } - } - - if !bytes.Equal(b1, b2) { - return false - } - } -} - -func Test_Elf_Inject_Static_Nop_1(t *testing.T) { - - os.Mkdir("tmp", 0755) - err := BinjectFile("test/static_ls", "tmp/static_ls_injected", "test/nop.bin", &BinjectConfig{CodeCaveMode: false, InjectionMethod: SilvioInject}) - if err != nil { - t.Error(err) - } - - if !CompareFiles("test/static_ls_nop_injected", "tmp/static_ls_injected") { - t.Error("Generated File Did Not Match!") - } else { - t.Log("Shellcode Injected Successfully!") - } - os.RemoveAll("tmp") -} - -func Test_Elf_Inject_Exec_Hello_1(t *testing.T) { - - os.Mkdir("tmp", 0755) - err := BinjectFile("test/static_ls", "tmp/static_ls_injected", "test/hello.bin", &BinjectConfig{CodeCaveMode: false, InjectionMethod: SilvioInject}) - if err != nil { - t.Error(err) - } - - if !CompareFiles("test/static_ls_hello_injected", "tmp/static_ls_injected") { - t.Error("Generated File Did Not Match!") - } else { - t.Log("Shellcode Injected Successfully!") - } - os.RemoveAll("tmp") -} - -func Test_Elf_Inject_Exec_PTNOTE_Hello_1(t *testing.T) { - - os.Mkdir("tmp", 0755) - err := BinjectFile("test/static_ls", "tmp/ls_ptnote_hallo.injected", "test/hallo.bin", &BinjectConfig{CodeCaveMode: false, InjectionMethod: PtNoteInject}) - if err != nil { - t.Error(err) - } - - if !CompareFiles("test/ls_ptnote_hallo", "tmp/ls_ptnote_hallo.injected") { - t.Error("Generated File Did Not Match!") - } else { - t.Log("Shellcode Injected Successfully!") - } - os.RemoveAll("tmp") -} diff --git a/odiglet/pkg/allocator/bj/utils.go b/odiglet/pkg/allocator/bj/utils.go deleted file mode 100644 index adfb42f601..0000000000 --- a/odiglet/pkg/allocator/bj/utils.go +++ /dev/null @@ -1,129 +0,0 @@ -package bj - -import ( - "bytes" - "errors" - "io/ioutil" - "log" - - "github.com/fatih/color" -) - -const ( - // ERROR - constant for an error - ERROR = iota - // ELF - constant for ELF binary format - ELF = iota - // MACHO - constant for Mach-O binary format - MACHO = iota - // FAT - constant for FAT/Mach-O binary format - FAT = iota - // PE - constant for PE binary format - PE = iota - // MIN_CAVE_SIZE - the smallest a code cave can be - MIN_CAVE_SIZE = 94 -) - -var ( - // Set up colors - cyan = color.New(color.FgCyan) - blue = color.New(color.FgBlue) - red = color.New(color.FgRed) -) - -// Cave - structure describing a code cave -type Cave struct { - Start, End uint64 -} - -// BinaryMagicFile - Identifies the Binary Format of a file by looking at its magic number -func BinaryMagicFile(filename string) (int, error) { - - buf, err := ioutil.ReadFile(filename) - if err != nil { - return ERROR, err - } - return BinaryMagic(buf) -} - -// BinaryMagic - Identifies the Binary Format of a file by looking at its magic number -func BinaryMagic(buf []byte) (int, error) { - - //log.Printf("%x\n", buf[:4]) - - if bytes.Equal(buf[:4], []byte{0x7F, 'E', 'L', 'F'}) { - log.Printf("ELF\n") - return ELF, nil - } - - if bytes.Equal(buf[:3], []byte{0xfe, 0xed, 0xfa}) { - if buf[3] == 0xce || buf[3] == 0xcf { - // FE ED FA CE - Mach-O binary (32-bit) - // FE ED FA CF - Mach-O binary (64-bit) - log.Printf("MACHO\n") - return MACHO, nil - } - } - - if bytes.Equal(buf[1:4], []byte{0xfa, 0xed, 0xfe}) { - if buf[0] == 0xce || buf[0] == 0xcf { - // CE FA ED FE - Mach-O binary (reverse byte ordering scheme, 32-bit) - // CF FA ED FE - Mach-O binary (reverse byte ordering scheme, 64-bit) - log.Printf("MACHO\n") - return MACHO, nil - } - } - - if bytes.Equal(buf[:2], []byte{0x4d, 0x5a}) { - log.Printf("PE\n") - return PE, nil - } - - if bytes.Equal(buf[:3], []byte{0xca, 0xfe, 0xba}) { - if buf[3] == 0xbe || buf[3] == 0xbf { - log.Println(red.Sprintf("FAT\n")) - return FAT, nil - } - } - - if bytes.Equal(buf[1:4], []byte{0xba, 0xfe, 0xca}) { - if buf[0] == 0xbe || buf[0] == 0xbf { - log.Println(red.Sprintf("FAT\n")) - return FAT, nil - } - } - - return ERROR, errors.New("Unknown Binary Format") -} - -// FindCavesFile - finds code caves in a file -func FindCavesFile(sourceFile string) ([]Cave, error) { - buf, err := ioutil.ReadFile(sourceFile) - if err != nil { - return nil, err - } - return FindCaves(buf) -} - -// FindCaves - finds code caves in a byte array -func FindCaves(sourceBytes []byte) ([]Cave, error) { - var caves []Cave - - count := 1 - caveStart := uint64(0) - for i := uint64(0); i < uint64(len(sourceBytes)); i++ { - switch sourceBytes[i] { - case 0: - if count == 1 { - caveStart = i - } - count++ - default: - if count >= MIN_CAVE_SIZE { - caves = append(caves, Cave{Start: caveStart, End: i}) - } - count = 1 - } - } - return caves, nil -} diff --git a/odiglet/pkg/allocator/debug/LICENSE b/odiglet/pkg/allocator/debug/LICENSE deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/odiglet/pkg/allocator/debug/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/odiglet/pkg/allocator/debug/dwarf/attr_string.go b/odiglet/pkg/allocator/debug/dwarf/attr_string.go deleted file mode 100644 index 34e3659a64..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/attr_string.go +++ /dev/null @@ -1,89 +0,0 @@ -// Code generated by "stringer -type Attr -trimprefix=Attr"; DO NOT EDIT. - -package dwarf - -import "strconv" - -const _Attr_name = "SiblingLocationNameOrderingByteSizeBitOffsetBitSizeStmtListLowpcHighpcLanguageDiscrDiscrValueVisibilityImportStringLengthCommonRefCompDirConstValueContainingTypeDefaultValueInlineIsOptionalLowerBoundProducerPrototypedReturnAddrStartScopeStrideSizeUpperBoundAbstractOriginAccessibilityAddrClassArtificialBaseTypesCallingCountDataMemberLocDeclColumnDeclFileDeclLineDeclarationDiscrListEncodingExternalFrameBaseFriendIdentifierCaseMacroInfoNamelistItemPrioritySegmentSpecificationStaticLinkTypeUseLocationVarParamVirtualityVtableElemLocAllocatedAssociatedDataLocationStrideEntrypcUseUTF8ExtensionRangesTrampolineCallColumnCallFileCallLineDescription" - -var _Attr_map = map[Attr]string{ - 1: _Attr_name[0:7], - 2: _Attr_name[7:15], - 3: _Attr_name[15:19], - 9: _Attr_name[19:27], - 11: _Attr_name[27:35], - 12: _Attr_name[35:44], - 13: _Attr_name[44:51], - 16: _Attr_name[51:59], - 17: _Attr_name[59:64], - 18: _Attr_name[64:70], - 19: _Attr_name[70:78], - 21: _Attr_name[78:83], - 22: _Attr_name[83:93], - 23: _Attr_name[93:103], - 24: _Attr_name[103:109], - 25: _Attr_name[109:121], - 26: _Attr_name[121:130], - 27: _Attr_name[130:137], - 28: _Attr_name[137:147], - 29: _Attr_name[147:161], - 30: _Attr_name[161:173], - 32: _Attr_name[173:179], - 33: _Attr_name[179:189], - 34: _Attr_name[189:199], - 37: _Attr_name[199:207], - 39: _Attr_name[207:217], - 42: _Attr_name[217:227], - 44: _Attr_name[227:237], - 46: _Attr_name[237:247], - 47: _Attr_name[247:257], - 49: _Attr_name[257:271], - 50: _Attr_name[271:284], - 51: _Attr_name[284:293], - 52: _Attr_name[293:303], - 53: _Attr_name[303:312], - 54: _Attr_name[312:319], - 55: _Attr_name[319:324], - 56: _Attr_name[324:337], - 57: _Attr_name[337:347], - 58: _Attr_name[347:355], - 59: _Attr_name[355:363], - 60: _Attr_name[363:374], - 61: _Attr_name[374:383], - 62: _Attr_name[383:391], - 63: _Attr_name[391:399], - 64: _Attr_name[399:408], - 65: _Attr_name[408:414], - 66: _Attr_name[414:428], - 67: _Attr_name[428:437], - 68: _Attr_name[437:449], - 69: _Attr_name[449:457], - 70: _Attr_name[457:464], - 71: _Attr_name[464:477], - 72: _Attr_name[477:487], - 73: _Attr_name[487:491], - 74: _Attr_name[491:502], - 75: _Attr_name[502:510], - 76: _Attr_name[510:520], - 77: _Attr_name[520:533], - 78: _Attr_name[533:542], - 79: _Attr_name[542:552], - 80: _Attr_name[552:564], - 81: _Attr_name[564:570], - 82: _Attr_name[570:577], - 83: _Attr_name[577:584], - 84: _Attr_name[584:593], - 85: _Attr_name[593:599], - 86: _Attr_name[599:609], - 87: _Attr_name[609:619], - 88: _Attr_name[619:627], - 89: _Attr_name[627:635], - 90: _Attr_name[635:646], -} - -func (i Attr) String() string { - if str, ok := _Attr_map[i]; ok { - return str - } - return "Attr(" + strconv.FormatInt(int64(i), 10) + ")" -} diff --git a/odiglet/pkg/allocator/debug/dwarf/buf.go b/odiglet/pkg/allocator/debug/dwarf/buf.go deleted file mode 100644 index 24d266db10..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/buf.go +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Buffered reading and decoding of DWARF data streams. - -package dwarf - -import ( - "encoding/binary" - "strconv" -) - -// Data buffer being decoded. -type buf struct { - dwarf *Data - order binary.ByteOrder - format dataFormat - name string - off Offset - data []byte - err error -} - -// Data format, other than byte order. This affects the handling of -// certain field formats. -type dataFormat interface { - // DWARF version number. Zero means unknown. - version() int - - // 64-bit DWARF format? - dwarf64() (dwarf64 bool, isKnown bool) - - // Size of an address, in bytes. Zero means unknown. - addrsize() int -} - -// Some parts of DWARF have no data format, e.g., abbrevs. -type unknownFormat struct{} - -func (u unknownFormat) version() int { - return 0 -} - -func (u unknownFormat) dwarf64() (bool, bool) { - return false, false -} - -func (u unknownFormat) addrsize() int { - return 0 -} - -func makeBuf(d *Data, format dataFormat, name string, off Offset, data []byte) buf { - return buf{d, d.order, format, name, off, data, nil} -} - -func (b *buf) uint8() uint8 { - if len(b.data) < 1 { - b.error("underflow") - return 0 - } - val := b.data[0] - b.data = b.data[1:] - b.off++ - return val -} - -func (b *buf) bytes(n int) []byte { - if len(b.data) < n { - b.error("underflow") - return nil - } - data := b.data[0:n] - b.data = b.data[n:] - b.off += Offset(n) - return data -} - -func (b *buf) skip(n int) { b.bytes(n) } - -func (b *buf) string() string { - for i := 0; i < len(b.data); i++ { - if b.data[i] == 0 { - s := string(b.data[0:i]) - b.data = b.data[i+1:] - b.off += Offset(i + 1) - return s - } - } - b.error("underflow") - return "" -} - -func (b *buf) uint16() uint16 { - a := b.bytes(2) - if a == nil { - return 0 - } - return b.order.Uint16(a) -} - -func (b *buf) uint32() uint32 { - a := b.bytes(4) - if a == nil { - return 0 - } - return b.order.Uint32(a) -} - -func (b *buf) uint64() uint64 { - a := b.bytes(8) - if a == nil { - return 0 - } - return b.order.Uint64(a) -} - -// Read a varint, which is 7 bits per byte, little endian. -// the 0x80 bit means read another byte. -func (b *buf) varint() (c uint64, bits uint) { - for i := 0; i < len(b.data); i++ { - byte := b.data[i] - c |= uint64(byte&0x7F) << bits - bits += 7 - if byte&0x80 == 0 { - b.off += Offset(i + 1) - b.data = b.data[i+1:] - return c, bits - } - } - return 0, 0 -} - -// Unsigned int is just a varint. -func (b *buf) uint() uint64 { - x, _ := b.varint() - return x -} - -// Signed int is a sign-extended varint. -func (b *buf) int() int64 { - ux, bits := b.varint() - x := int64(ux) - if x&(1<<(bits-1)) != 0 { - x |= -1 << bits - } - return x -} - -// Address-sized uint. -func (b *buf) addr() uint64 { - switch b.format.addrsize() { - case 1: - return uint64(b.uint8()) - case 2: - return uint64(b.uint16()) - case 4: - return uint64(b.uint32()) - case 8: - return b.uint64() - } - b.error("unknown address size") - return 0 -} - -func (b *buf) unitLength() (length Offset, dwarf64 bool) { - length = Offset(b.uint32()) - if length == 0xffffffff { - dwarf64 = true - length = Offset(b.uint64()) - } else if length >= 0xfffffff0 { - b.error("unit length has reserved value") - } - return -} - -func (b *buf) error(s string) { - if b.err == nil { - b.data = nil - b.err = DecodeError{b.name, b.off, s} - } -} - -type DecodeError struct { - Name string - Offset Offset - Err string -} - -func (e DecodeError) Error() string { - return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err -} diff --git a/odiglet/pkg/allocator/debug/dwarf/class_string.go b/odiglet/pkg/allocator/debug/dwarf/class_string.go deleted file mode 100644 index a6aabff524..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/class_string.go +++ /dev/null @@ -1,16 +0,0 @@ -// Code generated by "stringer -type=Class"; DO NOT EDIT. - -package dwarf - -import "strconv" - -const _Class_name = "ClassUnknownClassAddressClassBlockClassConstantClassExprLocClassFlagClassLinePtrClassLocListPtrClassMacPtrClassRangeListPtrClassReferenceClassReferenceSigClassStringClassReferenceAltClassStringAlt" - -var _Class_index = [...]uint8{0, 12, 24, 34, 47, 59, 68, 80, 95, 106, 123, 137, 154, 165, 182, 196} - -func (i Class) String() string { - if i < 0 || i >= Class(len(_Class_index)-1) { - return "Class(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _Class_name[_Class_index[i]:_Class_index[i+1]] -} diff --git a/odiglet/pkg/allocator/debug/dwarf/const.go b/odiglet/pkg/allocator/debug/dwarf/const.go deleted file mode 100644 index 4dda83e692..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/const.go +++ /dev/null @@ -1,319 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Constants - -package dwarf - -//go:generate stringer -type Attr -trimprefix=Attr - -// An Attr identifies the attribute type in a DWARF Entry's Field. -type Attr uint32 - -const ( - AttrSibling Attr = 0x01 - AttrLocation Attr = 0x02 - AttrName Attr = 0x03 - AttrOrdering Attr = 0x09 - AttrByteSize Attr = 0x0B - AttrBitOffset Attr = 0x0C - AttrBitSize Attr = 0x0D - AttrStmtList Attr = 0x10 - AttrLowpc Attr = 0x11 - AttrHighpc Attr = 0x12 - AttrLanguage Attr = 0x13 - AttrDiscr Attr = 0x15 - AttrDiscrValue Attr = 0x16 - AttrVisibility Attr = 0x17 - AttrImport Attr = 0x18 - AttrStringLength Attr = 0x19 - AttrCommonRef Attr = 0x1A - AttrCompDir Attr = 0x1B - AttrConstValue Attr = 0x1C - AttrContainingType Attr = 0x1D - AttrDefaultValue Attr = 0x1E - AttrInline Attr = 0x20 - AttrIsOptional Attr = 0x21 - AttrLowerBound Attr = 0x22 - AttrProducer Attr = 0x25 - AttrPrototyped Attr = 0x27 - AttrReturnAddr Attr = 0x2A - AttrStartScope Attr = 0x2C - AttrStrideSize Attr = 0x2E - AttrUpperBound Attr = 0x2F - AttrAbstractOrigin Attr = 0x31 - AttrAccessibility Attr = 0x32 - AttrAddrClass Attr = 0x33 - AttrArtificial Attr = 0x34 - AttrBaseTypes Attr = 0x35 - AttrCalling Attr = 0x36 - AttrCount Attr = 0x37 - AttrDataMemberLoc Attr = 0x38 - AttrDeclColumn Attr = 0x39 - AttrDeclFile Attr = 0x3A - AttrDeclLine Attr = 0x3B - AttrDeclaration Attr = 0x3C - AttrDiscrList Attr = 0x3D - AttrEncoding Attr = 0x3E - AttrExternal Attr = 0x3F - AttrFrameBase Attr = 0x40 - AttrFriend Attr = 0x41 - AttrIdentifierCase Attr = 0x42 - AttrMacroInfo Attr = 0x43 - AttrNamelistItem Attr = 0x44 - AttrPriority Attr = 0x45 - AttrSegment Attr = 0x46 - AttrSpecification Attr = 0x47 - AttrStaticLink Attr = 0x48 - AttrType Attr = 0x49 - AttrUseLocation Attr = 0x4A - AttrVarParam Attr = 0x4B - AttrVirtuality Attr = 0x4C - AttrVtableElemLoc Attr = 0x4D - AttrAllocated Attr = 0x4E - AttrAssociated Attr = 0x4F - AttrDataLocation Attr = 0x50 - AttrStride Attr = 0x51 - AttrEntrypc Attr = 0x52 - AttrUseUTF8 Attr = 0x53 - AttrExtension Attr = 0x54 - AttrRanges Attr = 0x55 - AttrTrampoline Attr = 0x56 - AttrCallColumn Attr = 0x57 - AttrCallFile Attr = 0x58 - AttrCallLine Attr = 0x59 - AttrDescription Attr = 0x5A -) - -func (a Attr) GoString() string { - if str, ok := _Attr_map[a]; ok { - return "dwarf.Attr" + str - } - return "dwarf." + a.String() -} - -// A format is a DWARF data encoding format. -type format uint32 - -const ( - // value formats - formAddr format = 0x01 - formDwarfBlock2 format = 0x03 - formDwarfBlock4 format = 0x04 - formData2 format = 0x05 - formData4 format = 0x06 - formData8 format = 0x07 - formString format = 0x08 - formDwarfBlock format = 0x09 - formDwarfBlock1 format = 0x0A - formData1 format = 0x0B - formFlag format = 0x0C - formSdata format = 0x0D - formStrp format = 0x0E - formUdata format = 0x0F - formRefAddr format = 0x10 - formRef1 format = 0x11 - formRef2 format = 0x12 - formRef4 format = 0x13 - formRef8 format = 0x14 - formRefUdata format = 0x15 - formIndirect format = 0x16 - // The following are new in DWARF 4. - formSecOffset format = 0x17 - formExprloc format = 0x18 - formFlagPresent format = 0x19 - formRefSig8 format = 0x20 - // Extensions for multi-file compression (.dwz) - // http://www.dwarfstd.org/ShowIssue.php?issue=120604.1 - formGnuRefAlt format = 0x1f20 - formGnuStrpAlt format = 0x1f21 -) - -//go:generate stringer -type Tag -trimprefix=Tag - -// A Tag is the classification (the type) of an Entry. -type Tag uint32 - -const ( - TagArrayType Tag = 0x01 - TagClassType Tag = 0x02 - TagEntryPoint Tag = 0x03 - TagEnumerationType Tag = 0x04 - TagFormalParameter Tag = 0x05 - TagImportedDeclaration Tag = 0x08 - TagLabel Tag = 0x0A - TagLexDwarfBlock Tag = 0x0B - TagMember Tag = 0x0D - TagPointerType Tag = 0x0F - TagReferenceType Tag = 0x10 - TagCompileUnit Tag = 0x11 - TagStringType Tag = 0x12 - TagStructType Tag = 0x13 - TagSubroutineType Tag = 0x15 - TagTypedef Tag = 0x16 - TagUnionType Tag = 0x17 - TagUnspecifiedParameters Tag = 0x18 - TagVariant Tag = 0x19 - TagCommonDwarfBlock Tag = 0x1A - TagCommonInclusion Tag = 0x1B - TagInheritance Tag = 0x1C - TagInlinedSubroutine Tag = 0x1D - TagModule Tag = 0x1E - TagPtrToMemberType Tag = 0x1F - TagSetType Tag = 0x20 - TagSubrangeType Tag = 0x21 - TagWithStmt Tag = 0x22 - TagAccessDeclaration Tag = 0x23 - TagBaseType Tag = 0x24 - TagCatchDwarfBlock Tag = 0x25 - TagConstType Tag = 0x26 - TagConstant Tag = 0x27 - TagEnumerator Tag = 0x28 - TagFileType Tag = 0x29 - TagFriend Tag = 0x2A - TagNamelist Tag = 0x2B - TagNamelistItem Tag = 0x2C - TagPackedType Tag = 0x2D - TagSubprogram Tag = 0x2E - TagTemplateTypeParameter Tag = 0x2F - TagTemplateValueParameter Tag = 0x30 - TagThrownType Tag = 0x31 - TagTryDwarfBlock Tag = 0x32 - TagVariantPart Tag = 0x33 - TagVariable Tag = 0x34 - TagVolatileType Tag = 0x35 - // The following are new in DWARF 3. - TagDwarfProcedure Tag = 0x36 - TagRestrictType Tag = 0x37 - TagInterfaceType Tag = 0x38 - TagNamespace Tag = 0x39 - TagImportedModule Tag = 0x3A - TagUnspecifiedType Tag = 0x3B - TagPartialUnit Tag = 0x3C - TagImportedUnit Tag = 0x3D - TagMutableType Tag = 0x3E // Later removed from DWARF. - TagCondition Tag = 0x3F - TagSharedType Tag = 0x40 - // The following are new in DWARF 4. - TagTypeUnit Tag = 0x41 - TagRvalueReferenceType Tag = 0x42 - TagTemplateAlias Tag = 0x43 -) - -func (t Tag) GoString() string { - if t <= TagTemplateAlias { - return "dwarf.Tag" + t.String() - } - return "dwarf." + t.String() -} - -// Location expression operators. -// The debug info encodes value locations like 8(R3) -// as a sequence of these op codes. -// This package does not implement full expressions; -// the opPlusUconst operator is expected by the type parser. -const ( - opAddr = 0x03 /* 1 op, const addr */ - opDeref = 0x06 - opConst1u = 0x08 /* 1 op, 1 byte const */ - opConst1s = 0x09 /* " signed */ - opConst2u = 0x0A /* 1 op, 2 byte const */ - opConst2s = 0x0B /* " signed */ - opConst4u = 0x0C /* 1 op, 4 byte const */ - opConst4s = 0x0D /* " signed */ - opConst8u = 0x0E /* 1 op, 8 byte const */ - opConst8s = 0x0F /* " signed */ - opConstu = 0x10 /* 1 op, LEB128 const */ - opConsts = 0x11 /* " signed */ - opDup = 0x12 - opDrop = 0x13 - opOver = 0x14 - opPick = 0x15 /* 1 op, 1 byte stack index */ - opSwap = 0x16 - opRot = 0x17 - opXderef = 0x18 - opAbs = 0x19 - opAnd = 0x1A - opDiv = 0x1B - opMinus = 0x1C - opMod = 0x1D - opMul = 0x1E - opNeg = 0x1F - opNot = 0x20 - opOr = 0x21 - opPlus = 0x22 - opPlusUconst = 0x23 /* 1 op, ULEB128 addend */ - opShl = 0x24 - opShr = 0x25 - opShra = 0x26 - opXor = 0x27 - opSkip = 0x2F /* 1 op, signed 2-byte constant */ - opBra = 0x28 /* 1 op, signed 2-byte constant */ - opEq = 0x29 - opGe = 0x2A - opGt = 0x2B - opLe = 0x2C - opLt = 0x2D - opNe = 0x2E - opLit0 = 0x30 - /* OpLitN = OpLit0 + N for N = 0..31 */ - opReg0 = 0x50 - /* OpRegN = OpReg0 + N for N = 0..31 */ - opBreg0 = 0x70 /* 1 op, signed LEB128 constant */ - /* OpBregN = OpBreg0 + N for N = 0..31 */ - opRegx = 0x90 /* 1 op, ULEB128 register */ - opFbreg = 0x91 /* 1 op, SLEB128 offset */ - opBregx = 0x92 /* 2 op, ULEB128 reg; SLEB128 off */ - opPiece = 0x93 /* 1 op, ULEB128 size of piece */ - opDerefSize = 0x94 /* 1-byte size of data retrieved */ - opXderefSize = 0x95 /* 1-byte size of data retrieved */ - opNop = 0x96 - /* next four new in Dwarf v3 */ - opPushObjAddr = 0x97 - opCall2 = 0x98 /* 2-byte offset of DIE */ - opCall4 = 0x99 /* 4-byte offset of DIE */ - opCallRef = 0x9A /* 4- or 8- byte offset of DIE */ - /* 0xE0-0xFF reserved for user-specific */ -) - -// Basic type encodings -- the value for AttrEncoding in a TagBaseType Entry. -const ( - encAddress = 0x01 - encBoolean = 0x02 - encComplexFloat = 0x03 - encFloat = 0x04 - encSigned = 0x05 - encSignedChar = 0x06 - encUnsigned = 0x07 - encUnsignedChar = 0x08 - encImaginaryFloat = 0x09 -) - -// Statement program standard opcode encodings. -const ( - lnsCopy = 1 - lnsAdvancePC = 2 - lnsAdvanceLine = 3 - lnsSetFile = 4 - lnsSetColumn = 5 - lnsNegateStmt = 6 - lnsSetBasicBlock = 7 - lnsConstAddPC = 8 - lnsFixedAdvancePC = 9 - - // DWARF 3 - lnsSetPrologueEnd = 10 - lnsSetEpilogueBegin = 11 - lnsSetISA = 12 -) - -// Statement program extended opcode encodings. -const ( - lneEndSequence = 1 - lneSetAddress = 2 - lneDefineFile = 3 - - // DWARF 4 - lneSetDiscriminator = 4 -) diff --git a/odiglet/pkg/allocator/debug/dwarf/entry.go b/odiglet/pkg/allocator/debug/dwarf/entry.go deleted file mode 100644 index 07b0a56b4d..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/entry.go +++ /dev/null @@ -1,769 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// DWARF debug information entry parser. -// An entry is a sequence of data items of a given format. -// The first word in the entry is an index into what DWARF -// calls the ``abbreviation table.'' An abbreviation is really -// just a type descriptor: it's an array of attribute tag/value format pairs. - -package dwarf - -import ( - "errors" - "strconv" -) - -// a single entry's description: a sequence of attributes -type abbrev struct { - tag Tag - children bool - field []afield -} - -type afield struct { - attr Attr - fmt format - class Class -} - -// a map from entry format ids to their descriptions -type abbrevTable map[uint32]abbrev - -// ParseAbbrev returns the abbreviation table that starts at byte off -// in the .debug_abbrev section. -func (d *Data) parseAbbrev(off uint64, vers int) (abbrevTable, error) { - if m, ok := d.abbrevCache[off]; ok { - return m, nil - } - - data := d.abbrev - if off > uint64(len(data)) { - data = nil - } else { - data = data[off:] - } - b := makeBuf(d, unknownFormat{}, "abbrev", 0, data) - - // Error handling is simplified by the buf getters - // returning an endless stream of 0s after an error. - m := make(abbrevTable) - for { - // Table ends with id == 0. - id := uint32(b.uint()) - if id == 0 { - break - } - - // Walk over attributes, counting. - n := 0 - b1 := b // Read from copy of b. - b1.uint() - b1.uint8() - for { - tag := b1.uint() - fmt := b1.uint() - if tag == 0 && fmt == 0 { - break - } - n++ - } - if b1.err != nil { - return nil, b1.err - } - - // Walk over attributes again, this time writing them down. - var a abbrev - a.tag = Tag(b.uint()) - a.children = b.uint8() != 0 - a.field = make([]afield, n) - for i := range a.field { - a.field[i].attr = Attr(b.uint()) - a.field[i].fmt = format(b.uint()) - a.field[i].class = formToClass(a.field[i].fmt, a.field[i].attr, vers, &b) - } - b.uint() - b.uint() - - m[id] = a - } - if b.err != nil { - return nil, b.err - } - d.abbrevCache[off] = m - return m, nil -} - -// attrIsExprloc indicates attributes that allow exprloc values that -// are encoded as block values in DWARF 2 and 3. See DWARF 4, Figure -// 20. -var attrIsExprloc = map[Attr]bool{ - AttrLocation: true, - AttrByteSize: true, - AttrBitOffset: true, - AttrBitSize: true, - AttrStringLength: true, - AttrLowerBound: true, - AttrReturnAddr: true, - AttrStrideSize: true, - AttrUpperBound: true, - AttrCount: true, - AttrDataMemberLoc: true, - AttrFrameBase: true, - AttrSegment: true, - AttrStaticLink: true, - AttrUseLocation: true, - AttrVtableElemLoc: true, - AttrAllocated: true, - AttrAssociated: true, - AttrDataLocation: true, - AttrStride: true, -} - -// attrPtrClass indicates the *ptr class of attributes that have -// encoding formSecOffset in DWARF 4 or formData* in DWARF 2 and 3. -var attrPtrClass = map[Attr]Class{ - AttrLocation: ClassLocListPtr, - AttrStmtList: ClassLinePtr, - AttrStringLength: ClassLocListPtr, - AttrReturnAddr: ClassLocListPtr, - AttrStartScope: ClassRangeListPtr, - AttrDataMemberLoc: ClassLocListPtr, - AttrFrameBase: ClassLocListPtr, - AttrMacroInfo: ClassMacPtr, - AttrSegment: ClassLocListPtr, - AttrStaticLink: ClassLocListPtr, - AttrUseLocation: ClassLocListPtr, - AttrVtableElemLoc: ClassLocListPtr, - AttrRanges: ClassRangeListPtr, -} - -// formToClass returns the DWARF 4 Class for the given form. If the -// DWARF version is less then 4, it will disambiguate some forms -// depending on the attribute. -func formToClass(form format, attr Attr, vers int, b *buf) Class { - switch form { - default: - b.error("cannot determine class of unknown attribute form") - return 0 - - case formAddr: - return ClassAddress - - case formDwarfBlock1, formDwarfBlock2, formDwarfBlock4, formDwarfBlock: - // In DWARF 2 and 3, ClassExprLoc was encoded as a - // block. DWARF 4 distinguishes ClassBlock and - // ClassExprLoc, but there are no attributes that can - // be both, so we also promote ClassBlock values in - // DWARF 4 that should be ClassExprLoc in case - // producers get this wrong. - if attrIsExprloc[attr] { - return ClassExprLoc - } - return ClassBlock - - case formData1, formData2, formData4, formData8, formSdata, formUdata: - // In DWARF 2 and 3, ClassPtr was encoded as a - // constant. Unlike ClassExprLoc/ClassBlock, some - // DWARF 4 attributes need to distinguish Class*Ptr - // from ClassConstant, so we only do this promotion - // for versions 2 and 3. - if class, ok := attrPtrClass[attr]; vers < 4 && ok { - return class - } - return ClassConstant - - case formFlag, formFlagPresent: - return ClassFlag - - case formRefAddr, formRef1, formRef2, formRef4, formRef8, formRefUdata: - return ClassReference - - case formRefSig8: - return ClassReferenceSig - - case formString, formStrp: - return ClassString - - case formSecOffset: - // DWARF 4 defines four *ptr classes, but doesn't - // distinguish them in the encoding. Disambiguate - // these classes using the attribute. - if class, ok := attrPtrClass[attr]; ok { - return class - } - return ClassUnknown - - case formExprloc: - return ClassExprLoc - - case formGnuRefAlt: - return ClassReferenceAlt - - case formGnuStrpAlt: - return ClassStringAlt - } -} - -// An entry is a sequence of attribute/value pairs. -type Entry struct { - Offset Offset // offset of Entry in DWARF info - Tag Tag // tag (kind of Entry) - Children bool // whether Entry is followed by children - Field []Field -} - -// A Field is a single attribute/value pair in an Entry. -// -// A value can be one of several "attribute classes" defined by DWARF. -// The Go types corresponding to each class are: -// -// DWARF class Go type Class -// ----------- ------- ----- -// address uint64 ClassAddress -// block []byte ClassBlock -// constant int64 ClassConstant -// flag bool ClassFlag -// reference -// to info dwarf.Offset ClassReference -// to type unit uint64 ClassReferenceSig -// string string ClassString -// exprloc []byte ClassExprLoc -// lineptr int64 ClassLinePtr -// loclistptr int64 ClassLocListPtr -// macptr int64 ClassMacPtr -// rangelistptr int64 ClassRangeListPtr -// -// For unrecognized or vendor-defined attributes, Class may be -// ClassUnknown. -type Field struct { - Attr Attr - Val interface{} - Class Class -} - -// A Class is the DWARF 4 class of an attribute value. -// -// In general, a given attribute's value may take on one of several -// possible classes defined by DWARF, each of which leads to a -// slightly different interpretation of the attribute. -// -// DWARF version 4 distinguishes attribute value classes more finely -// than previous versions of DWARF. The reader will disambiguate -// coarser classes from earlier versions of DWARF into the appropriate -// DWARF 4 class. For example, DWARF 2 uses "constant" for constants -// as well as all types of section offsets, but the reader will -// canonicalize attributes in DWARF 2 files that refer to section -// offsets to one of the Class*Ptr classes, even though these classes -// were only defined in DWARF 3. -type Class int - -const ( - // ClassUnknown represents values of unknown DWARF class. - ClassUnknown Class = iota - - // ClassAddress represents values of type uint64 that are - // addresses on the target machine. - ClassAddress - - // ClassBlock represents values of type []byte whose - // interpretation depends on the attribute. - ClassBlock - - // ClassConstant represents values of type int64 that are - // constants. The interpretation of this constant depends on - // the attribute. - ClassConstant - - // ClassExprLoc represents values of type []byte that contain - // an encoded DWARF expression or location description. - ClassExprLoc - - // ClassFlag represents values of type bool. - ClassFlag - - // ClassLinePtr represents values that are an int64 offset - // into the "line" section. - ClassLinePtr - - // ClassLocListPtr represents values that are an int64 offset - // into the "loclist" section. - ClassLocListPtr - - // ClassMacPtr represents values that are an int64 offset into - // the "mac" section. - ClassMacPtr - - // ClassMacPtr represents values that are an int64 offset into - // the "rangelist" section. - ClassRangeListPtr - - // ClassReference represents values that are an Offset offset - // of an Entry in the info section (for use with Reader.Seek). - // The DWARF specification combines ClassReference and - // ClassReferenceSig into class "reference". - ClassReference - - // ClassReferenceSig represents values that are a uint64 type - // signature referencing a type Entry. - ClassReferenceSig - - // ClassString represents values that are strings. If the - // compilation unit specifies the AttrUseUTF8 flag (strongly - // recommended), the string value will be encoded in UTF-8. - // Otherwise, the encoding is unspecified. - ClassString - - // ClassReferenceAlt represents values of type int64 that are - // an offset into the DWARF "info" section of an alternate - // object file. - ClassReferenceAlt - - // ClassStringAlt represents values of type int64 that are an - // offset into the DWARF string section of an alternate object - // file. - ClassStringAlt -) - -//go:generate stringer -type=Class - -func (i Class) GoString() string { - return "dwarf." + i.String() -} - -// Val returns the value associated with attribute Attr in Entry, -// or nil if there is no such attribute. -// -// A common idiom is to merge the check for nil return with -// the check that the value has the expected dynamic type, as in: -// -// v, ok := e.Val(AttrSibling).(int64) -func (e *Entry) Val(a Attr) interface{} { - if f := e.AttrField(a); f != nil { - return f.Val - } - return nil -} - -// AttrField returns the Field associated with attribute Attr in -// Entry, or nil if there is no such attribute. -func (e *Entry) AttrField(a Attr) *Field { - for i, f := range e.Field { - if f.Attr == a { - return &e.Field[i] - } - } - return nil -} - -// An Offset represents the location of an Entry within the DWARF info. -// (See Reader.Seek.) -type Offset uint32 - -// Entry reads a single entry from buf, decoding -// according to the given abbreviation table. -func (b *buf) entry(atab abbrevTable, ubase Offset) *Entry { - off := b.off - id := uint32(b.uint()) - if id == 0 { - return &Entry{} - } - a, ok := atab[id] - if !ok { - b.error("unknown abbreviation table index") - return nil - } - e := &Entry{ - Offset: off, - Tag: a.tag, - Children: a.children, - Field: make([]Field, len(a.field)), - } - for i := range e.Field { - e.Field[i].Attr = a.field[i].attr - e.Field[i].Class = a.field[i].class - fmt := a.field[i].fmt - if fmt == formIndirect { - fmt = format(b.uint()) - } - var val interface{} - switch fmt { - default: - b.error("unknown entry attr format 0x" + strconv.FormatInt(int64(fmt), 16)) - - // address - case formAddr: - val = b.addr() - - // block - case formDwarfBlock1: - val = b.bytes(int(b.uint8())) - case formDwarfBlock2: - val = b.bytes(int(b.uint16())) - case formDwarfBlock4: - val = b.bytes(int(b.uint32())) - case formDwarfBlock: - val = b.bytes(int(b.uint())) - - // constant - case formData1: - val = int64(b.uint8()) - case formData2: - val = int64(b.uint16()) - case formData4: - val = int64(b.uint32()) - case formData8: - val = int64(b.uint64()) - case formSdata: - val = int64(b.int()) - case formUdata: - val = int64(b.uint()) - - // flag - case formFlag: - val = b.uint8() == 1 - // New in DWARF 4. - case formFlagPresent: - // The attribute is implicitly indicated as present, and no value is - // encoded in the debugging information entry itself. - val = true - - // reference to other entry - case formRefAddr: - vers := b.format.version() - if vers == 0 { - b.error("unknown version for DW_FORM_ref_addr") - } else if vers == 2 { - val = Offset(b.addr()) - } else { - is64, known := b.format.dwarf64() - if !known { - b.error("unknown size for DW_FORM_ref_addr") - } else if is64 { - val = Offset(b.uint64()) - } else { - val = Offset(b.uint32()) - } - } - case formRef1: - val = Offset(b.uint8()) + ubase - case formRef2: - val = Offset(b.uint16()) + ubase - case formRef4: - val = Offset(b.uint32()) + ubase - case formRef8: - val = Offset(b.uint64()) + ubase - case formRefUdata: - val = Offset(b.uint()) + ubase - - // string - case formString: - val = b.string() - case formStrp: - var off uint64 // offset into .debug_str - is64, known := b.format.dwarf64() - if !known { - b.error("unknown size for DW_FORM_strp") - } else if is64 { - off = b.uint64() - } else { - off = uint64(b.uint32()) - } - if uint64(int(off)) != off { - b.error("DW_FORM_strp offset out of range") - } - if b.err != nil { - return nil - } - b1 := makeBuf(b.dwarf, unknownFormat{}, "str", 0, b.dwarf.str) - b1.skip(int(off)) - val = b1.string() - if b1.err != nil { - b.err = b1.err - return nil - } - - // lineptr, loclistptr, macptr, rangelistptr - // New in DWARF 4, but clang can generate them with -gdwarf-2. - // Section reference, replacing use of formData4 and formData8. - case formSecOffset, formGnuRefAlt, formGnuStrpAlt: - is64, known := b.format.dwarf64() - if !known { - b.error("unknown size for form 0x" + strconv.FormatInt(int64(fmt), 16)) - } else if is64 { - val = int64(b.uint64()) - } else { - val = int64(b.uint32()) - } - - // exprloc - // New in DWARF 4. - case formExprloc: - val = b.bytes(int(b.uint())) - - // reference - // New in DWARF 4. - case formRefSig8: - // 64-bit type signature. - val = b.uint64() - } - e.Field[i].Val = val - } - if b.err != nil { - return nil - } - return e -} - -// A Reader allows reading Entry structures from a DWARF “info” section. -// The Entry structures are arranged in a tree. The Reader's Next function -// return successive entries from a pre-order traversal of the tree. -// If an entry has children, its Children field will be true, and the children -// follow, terminated by an Entry with Tag 0. -type Reader struct { - b buf - d *Data - err error - unit int - lastChildren bool // .Children of last entry returned by Next - lastSibling Offset // .Val(AttrSibling) of last entry returned by Next -} - -// Reader returns a new Reader for Data. -// The reader is positioned at byte offset 0 in the DWARF “info” section. -func (d *Data) Reader() *Reader { - r := &Reader{d: d} - r.Seek(0) - return r -} - -// AddressSize returns the size in bytes of addresses in the current compilation -// unit. -func (r *Reader) AddressSize() int { - return r.d.unit[r.unit].asize -} - -// Seek positions the Reader at offset off in the encoded entry stream. -// Offset 0 can be used to denote the first entry. -func (r *Reader) Seek(off Offset) { - d := r.d - r.err = nil - r.lastChildren = false - if off == 0 { - if len(d.unit) == 0 { - return - } - u := &d.unit[0] - r.unit = 0 - r.b = makeBuf(r.d, u, "info", u.off, u.data) - return - } - - i := d.offsetToUnit(off) - if i == -1 { - r.err = errors.New("offset out of range") - return - } - u := &d.unit[i] - r.unit = i - r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:]) -} - -// maybeNextUnit advances to the next unit if this one is finished. -func (r *Reader) maybeNextUnit() { - for len(r.b.data) == 0 && r.unit+1 < len(r.d.unit) { - r.unit++ - u := &r.d.unit[r.unit] - r.b = makeBuf(r.d, u, "info", u.off, u.data) - } -} - -// Next reads the next entry from the encoded entry stream. -// It returns nil, nil when it reaches the end of the section. -// It returns an error if the current offset is invalid or the data at the -// offset cannot be decoded as a valid Entry. -func (r *Reader) Next() (*Entry, error) { - if r.err != nil { - return nil, r.err - } - r.maybeNextUnit() - if len(r.b.data) == 0 { - return nil, nil - } - u := &r.d.unit[r.unit] - e := r.b.entry(u.atable, u.base) - if r.b.err != nil { - r.err = r.b.err - return nil, r.err - } - if e != nil { - r.lastChildren = e.Children - if r.lastChildren { - r.lastSibling, _ = e.Val(AttrSibling).(Offset) - } - } else { - r.lastChildren = false - } - return e, nil -} - -// SkipChildren skips over the child entries associated with -// the last Entry returned by Next. If that Entry did not have -// children or Next has not been called, SkipChildren is a no-op. -func (r *Reader) SkipChildren() { - if r.err != nil || !r.lastChildren { - return - } - - // If the last entry had a sibling attribute, - // that attribute gives the offset of the next - // sibling, so we can avoid decoding the - // child subtrees. - if r.lastSibling >= r.b.off { - r.Seek(r.lastSibling) - return - } - - for { - e, err := r.Next() - if err != nil || e == nil || e.Tag == 0 { - break - } - if e.Children { - r.SkipChildren() - } - } -} - -// clone returns a copy of the reader. This is used by the typeReader -// interface. -func (r *Reader) clone() typeReader { - return r.d.Reader() -} - -// offset returns the current buffer offset. This is used by the -// typeReader interface. -func (r *Reader) offset() Offset { - return r.b.off -} - -// SeekPC returns the Entry for the compilation unit that includes pc, -// and positions the reader to read the children of that unit. If pc -// is not covered by any unit, SeekPC returns ErrUnknownPC and the -// position of the reader is undefined. -// -// Because compilation units can describe multiple regions of the -// executable, in the worst case SeekPC must search through all the -// ranges in all the compilation units. Each call to SeekPC starts the -// search at the compilation unit of the last call, so in general -// looking up a series of PCs will be faster if they are sorted. If -// the caller wishes to do repeated fast PC lookups, it should build -// an appropriate index using the Ranges method. -func (r *Reader) SeekPC(pc uint64) (*Entry, error) { - unit := r.unit - for i := 0; i < len(r.d.unit); i++ { - if unit >= len(r.d.unit) { - unit = 0 - } - r.err = nil - r.lastChildren = false - r.unit = unit - u := &r.d.unit[unit] - r.b = makeBuf(r.d, u, "info", u.off, u.data) - e, err := r.Next() - if err != nil { - return nil, err - } - ranges, err := r.d.Ranges(e) - if err != nil { - return nil, err - } - for _, pcs := range ranges { - if pcs[0] <= pc && pc < pcs[1] { - return e, nil - } - } - unit++ - } - return nil, ErrUnknownPC -} - -// Ranges returns the PC ranges covered by e, a slice of [low,high) pairs. -// Only some entry types, such as TagCompileUnit or TagSubprogram, have PC -// ranges; for others, this will return nil with no error. -func (d *Data) Ranges(e *Entry) ([][2]uint64, error) { - var ret [][2]uint64 - - low, lowOK := e.Val(AttrLowpc).(uint64) - - var high uint64 - var highOK bool - highField := e.AttrField(AttrHighpc) - if highField != nil { - switch highField.Class { - case ClassAddress: - high, highOK = highField.Val.(uint64) - case ClassConstant: - off, ok := highField.Val.(int64) - if ok { - high = low + uint64(off) - highOK = true - } - } - } - - if lowOK && highOK { - ret = append(ret, [2]uint64{low, high}) - } - - ranges, rangesOK := e.Val(AttrRanges).(int64) - if rangesOK && d.ranges != nil { - // The initial base address is the lowpc attribute - // of the enclosing compilation unit. - // Although DWARF specifies the lowpc attribute, - // comments in gdb/dwarf2read.c say that some versions - // of GCC use the entrypc attribute, so we check that too. - var cu *Entry - if e.Tag == TagCompileUnit { - cu = e - } else { - i := d.offsetToUnit(e.Offset) - if i == -1 { - return nil, errors.New("no unit for entry") - } - u := &d.unit[i] - b := makeBuf(d, u, "info", u.off, u.data) - cu = b.entry(u.atable, u.base) - if b.err != nil { - return nil, b.err - } - } - - var base uint64 - if cuEntry, cuEntryOK := cu.Val(AttrEntrypc).(uint64); cuEntryOK { - base = cuEntry - } else if cuLow, cuLowOK := cu.Val(AttrLowpc).(uint64); cuLowOK { - base = cuLow - } - - u := &d.unit[d.offsetToUnit(e.Offset)] - buf := makeBuf(d, u, "ranges", Offset(ranges), d.ranges[ranges:]) - for len(buf.data) > 0 { - low = buf.addr() - high = buf.addr() - - if low == 0 && high == 0 { - break - } - - if low == ^uint64(0)>>uint((8-u.addrsize())*8) { - base = high - } else { - ret = append(ret, [2]uint64{base + low, base + high}) - } - } - } - - return ret, nil -} diff --git a/odiglet/pkg/allocator/debug/dwarf/entry_test.go b/odiglet/pkg/allocator/debug/dwarf/entry_test.go deleted file mode 100644 index 58f3023d29..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/entry_test.go +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package dwarf_test - -import ( - . "debug/dwarf" - "reflect" - "testing" -) - -func TestSplit(t *testing.T) { - // debug/dwarf doesn't (currently) support split DWARF, but - // the attributes that pointed to the split DWARF used to - // cause loading the DWARF data to fail entirely (issue - // #12592). Test that we can at least read the DWARF data. - d := elfData(t, "testdata/split.elf") - r := d.Reader() - e, err := r.Next() - if err != nil { - t.Fatal(err) - } - if e.Tag != TagCompileUnit { - t.Fatalf("bad tag: have %s, want %s", e.Tag, TagCompileUnit) - } - // Check that we were able to parse the unknown section offset - // field, even if we can't figure out its DWARF class. - const AttrGNUAddrBase Attr = 0x2133 - f := e.AttrField(AttrGNUAddrBase) - if _, ok := f.Val.(int64); !ok { - t.Fatalf("bad attribute value type: have %T, want int64", f.Val) - } - if f.Class != ClassUnknown { - t.Fatalf("bad class: have %s, want %s", f.Class, ClassUnknown) - } -} - -// wantRange maps from a PC to the ranges of the compilation unit -// containing that PC. -type wantRange struct { - pc uint64 - ranges [][2]uint64 -} - -func TestReaderSeek(t *testing.T) { - want := []wantRange{ - {0x40059d, [][2]uint64{{0x40059d, 0x400601}}}, - {0x400600, [][2]uint64{{0x40059d, 0x400601}}}, - {0x400601, [][2]uint64{{0x400601, 0x400611}}}, - {0x4005f0, [][2]uint64{{0x40059d, 0x400601}}}, // loop test - {0x10, nil}, - {0x400611, nil}, - } - testRanges(t, "testdata/line-gcc.elf", want) -} - -func TestRangesSection(t *testing.T) { - want := []wantRange{ - {0x400500, [][2]uint64{{0x400500, 0x400549}, {0x400400, 0x400408}}}, - {0x400400, [][2]uint64{{0x400500, 0x400549}, {0x400400, 0x400408}}}, - {0x400548, [][2]uint64{{0x400500, 0x400549}, {0x400400, 0x400408}}}, - {0x400407, [][2]uint64{{0x400500, 0x400549}, {0x400400, 0x400408}}}, - {0x400408, nil}, - {0x400449, nil}, - {0x4003ff, nil}, - } - testRanges(t, "testdata/ranges.elf", want) -} - -func testRanges(t *testing.T, name string, want []wantRange) { - d := elfData(t, name) - r := d.Reader() - for _, w := range want { - entry, err := r.SeekPC(w.pc) - if err != nil { - if w.ranges != nil { - t.Errorf("%s: missing Entry for %#x", name, w.pc) - } - if err != ErrUnknownPC { - t.Errorf("%s: expected ErrUnknownPC for %#x, got %v", name, w.pc, err) - } - continue - } - - ranges, err := d.Ranges(entry) - if err != nil { - t.Errorf("%s: %v", name, err) - continue - } - if !reflect.DeepEqual(ranges, w.ranges) { - t.Errorf("%s: for %#x got %x, expected %x", name, w.pc, ranges, w.ranges) - } - } -} - -func TestReaderRanges(t *testing.T) { - d := elfData(t, "testdata/line-gcc.elf") - - subprograms := []struct { - name string - ranges [][2]uint64 - }{ - {"f1", [][2]uint64{{0x40059d, 0x4005e7}}}, - {"main", [][2]uint64{{0x4005e7, 0x400601}}}, - {"f2", [][2]uint64{{0x400601, 0x400611}}}, - } - - r := d.Reader() - i := 0 - for entry, err := r.Next(); entry != nil && err == nil; entry, err = r.Next() { - if entry.Tag != TagSubprogram { - continue - } - - if i > len(subprograms) { - t.Fatalf("too many subprograms (expected at most %d)", i) - } - - if got := entry.Val(AttrName).(string); got != subprograms[i].name { - t.Errorf("subprogram %d name is %s, expected %s", i, got, subprograms[i].name) - } - ranges, err := d.Ranges(entry) - if err != nil { - t.Errorf("subprogram %d: %v", i, err) - continue - } - if !reflect.DeepEqual(ranges, subprograms[i].ranges) { - t.Errorf("subprogram %d ranges are %x, expected %x", i, ranges, subprograms[i].ranges) - } - i++ - } - - if i < len(subprograms) { - t.Errorf("saw only %d subprograms, expected %d", i, len(subprograms)) - } -} - -func Test64Bit(t *testing.T) { - // I don't know how to generate a 64-bit DWARF debug - // compilation unit except by using XCOFF, so this is - // hand-written. - tests := []struct { - name string - info []byte - }{ - { - "32-bit little", - []byte{0x30, 0, 0, 0, // comp unit length - 4, 0, // DWARF version 4 - 0, 0, 0, 0, // abbrev offset - 8, // address size - 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - }, - { - "64-bit little", - []byte{0xff, 0xff, 0xff, 0xff, // 64-bit DWARF - 0x30, 0, 0, 0, 0, 0, 0, 0, // comp unit length - 4, 0, // DWARF version 4 - 0, 0, 0, 0, 0, 0, 0, 0, // abbrev offset - 8, // address size - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - }, - { - "64-bit big", - []byte{0xff, 0xff, 0xff, 0xff, // 64-bit DWARF - 0, 0, 0, 0, 0, 0, 0, 0x30, // comp unit length - 0, 4, // DWARF version 4 - 0, 0, 0, 0, 0, 0, 0, 0, // abbrev offset - 8, // address size - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }, - }, - } - - for _, test := range tests { - _, err := New(nil, nil, nil, test.info, nil, nil, nil, nil) - if err != nil { - t.Errorf("%s: %v", test.name, err) - } - } -} diff --git a/odiglet/pkg/allocator/debug/dwarf/export_test.go b/odiglet/pkg/allocator/debug/dwarf/export_test.go deleted file mode 100644 index b8a25ff531..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/export_test.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package dwarf - -var PathJoin = pathJoin diff --git a/odiglet/pkg/allocator/debug/dwarf/line.go b/odiglet/pkg/allocator/debug/dwarf/line.go deleted file mode 100644 index b862b49d62..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/line.go +++ /dev/null @@ -1,656 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package dwarf - -import ( - "errors" - "fmt" - "io" - "path" - "strings" -) - -// A LineReader reads a sequence of LineEntry structures from a DWARF -// "line" section for a single compilation unit. LineEntries occur in -// order of increasing PC and each LineEntry gives metadata for the -// instructions from that LineEntry's PC to just before the next -// LineEntry's PC. The last entry will have its EndSequence field set. -type LineReader struct { - buf buf - - // Original .debug_line section data. Used by Seek. - section []byte - - // Header information - version uint16 - minInstructionLength int - maxOpsPerInstruction int - defaultIsStmt bool - lineBase int - lineRange int - opcodeBase int - opcodeLengths []int - directories []string - fileEntries []*LineFile - - programOffset Offset // section offset of line number program - endOffset Offset // section offset of byte following program - - initialFileEntries int // initial length of fileEntries - - // Current line number program state machine registers - state LineEntry // public state - fileIndex int // private state -} - -// A LineEntry is a row in a DWARF line table. -type LineEntry struct { - // Address is the program-counter value of a machine - // instruction generated by the compiler. This LineEntry - // applies to each instruction from Address to just before the - // Address of the next LineEntry. - Address uint64 - - // OpIndex is the index of an operation within a VLIW - // instruction. The index of the first operation is 0. For - // non-VLIW architectures, it will always be 0. Address and - // OpIndex together form an operation pointer that can - // reference any individual operation within the instruction - // stream. - OpIndex int - - // File is the source file corresponding to these - // instructions. - File *LineFile - - // Line is the source code line number corresponding to these - // instructions. Lines are numbered beginning at 1. It may be - // 0 if these instructions cannot be attributed to any source - // line. - Line int - - // Column is the column number within the source line of these - // instructions. Columns are numbered beginning at 1. It may - // be 0 to indicate the "left edge" of the line. - Column int - - // IsStmt indicates that Address is a recommended breakpoint - // location, such as the beginning of a line, statement, or a - // distinct subpart of a statement. - IsStmt bool - - // BasicBlock indicates that Address is the beginning of a - // basic block. - BasicBlock bool - - // PrologueEnd indicates that Address is one (of possibly - // many) PCs where execution should be suspended for a - // breakpoint on entry to the containing function. - // - // Added in DWARF 3. - PrologueEnd bool - - // EpilogueBegin indicates that Address is one (of possibly - // many) PCs where execution should be suspended for a - // breakpoint on exit from this function. - // - // Added in DWARF 3. - EpilogueBegin bool - - // ISA is the instruction set architecture for these - // instructions. Possible ISA values should be defined by the - // applicable ABI specification. - // - // Added in DWARF 3. - ISA int - - // Discriminator is an arbitrary integer indicating the block - // to which these instructions belong. It serves to - // distinguish among multiple blocks that may all have with - // the same source file, line, and column. Where only one - // block exists for a given source position, it should be 0. - // - // Added in DWARF 3. - Discriminator int - - // EndSequence indicates that Address is the first byte after - // the end of a sequence of target machine instructions. If it - // is set, only this and the Address field are meaningful. A - // line number table may contain information for multiple - // potentially disjoint instruction sequences. The last entry - // in a line table should always have EndSequence set. - EndSequence bool -} - -// A LineFile is a source file referenced by a DWARF line table entry. -type LineFile struct { - Name string - Mtime uint64 // Implementation defined modification time, or 0 if unknown - Length int // File length, or 0 if unknown -} - -// LineReader returns a new reader for the line table of compilation -// unit cu, which must be an Entry with tag TagCompileUnit. -// -// If this compilation unit has no line table, it returns nil, nil. -func (d *Data) LineReader(cu *Entry) (*LineReader, error) { - if d.line == nil { - // No line tables available. - return nil, nil - } - - // Get line table information from cu. - off, ok := cu.Val(AttrStmtList).(int64) - if !ok { - // cu has no line table. - return nil, nil - } - if off > int64(len(d.line)) { - return nil, errors.New("AttrStmtList value out of range") - } - // AttrCompDir is optional if all file names are absolute. Use - // the empty string if it's not present. - compDir, _ := cu.Val(AttrCompDir).(string) - - // Create the LineReader. - u := &d.unit[d.offsetToUnit(cu.Offset)] - buf := makeBuf(d, u, "line", Offset(off), d.line[off:]) - // The compilation directory is implicitly directories[0]. - r := LineReader{buf: buf, section: d.line, directories: []string{compDir}} - - // Read the header. - if err := r.readHeader(); err != nil { - return nil, err - } - - // Initialize line reader state. - r.Reset() - - return &r, nil -} - -// readHeader reads the line number program header from r.buf and sets -// all of the header fields in r. -func (r *LineReader) readHeader() error { - buf := &r.buf - - // Read basic header fields [DWARF2 6.2.4]. - hdrOffset := buf.off - unitLength, dwarf64 := buf.unitLength() - r.endOffset = buf.off + unitLength - if r.endOffset > buf.off+Offset(len(buf.data)) { - return DecodeError{"line", hdrOffset, fmt.Sprintf("line table end %d exceeds section size %d", r.endOffset, buf.off+Offset(len(buf.data)))} - } - r.version = buf.uint16() - if buf.err == nil && (r.version < 2 || r.version > 4) { - // DWARF goes to all this effort to make new opcodes - // backward-compatible, and then adds fields right in - // the middle of the header in new versions, so we're - // picky about only supporting known line table - // versions. - return DecodeError{"line", hdrOffset, fmt.Sprintf("unknown line table version %d", r.version)} - } - var headerLength Offset - if dwarf64 { - headerLength = Offset(buf.uint64()) - } else { - headerLength = Offset(buf.uint32()) - } - r.programOffset = buf.off + headerLength - r.minInstructionLength = int(buf.uint8()) - if r.version >= 4 { - // [DWARF4 6.2.4] - r.maxOpsPerInstruction = int(buf.uint8()) - } else { - r.maxOpsPerInstruction = 1 - } - r.defaultIsStmt = buf.uint8() != 0 - r.lineBase = int(int8(buf.uint8())) - r.lineRange = int(buf.uint8()) - - // Validate header. - if buf.err != nil { - return buf.err - } - if r.maxOpsPerInstruction == 0 { - return DecodeError{"line", hdrOffset, "invalid maximum operations per instruction: 0"} - } - if r.lineRange == 0 { - return DecodeError{"line", hdrOffset, "invalid line range: 0"} - } - - // Read standard opcode length table. This table starts with opcode 1. - r.opcodeBase = int(buf.uint8()) - r.opcodeLengths = make([]int, r.opcodeBase) - for i := 1; i < r.opcodeBase; i++ { - r.opcodeLengths[i] = int(buf.uint8()) - } - - // Validate opcode lengths. - if buf.err != nil { - return buf.err - } - for i, length := range r.opcodeLengths { - if known, ok := knownOpcodeLengths[i]; ok && known != length { - return DecodeError{"line", hdrOffset, fmt.Sprintf("opcode %d expected to have length %d, but has length %d", i, known, length)} - } - } - - // Read include directories table. The caller already set - // directories[0] to the compilation directory. - for { - directory := buf.string() - if buf.err != nil { - return buf.err - } - if len(directory) == 0 { - break - } - if !pathIsAbs(directory) { - // Relative paths are implicitly relative to - // the compilation directory. - directory = pathJoin(r.directories[0], directory) - } - r.directories = append(r.directories, directory) - } - - // Read file name list. File numbering starts with 1, so leave - // the first entry nil. - r.fileEntries = make([]*LineFile, 1) - for { - if done, err := r.readFileEntry(); err != nil { - return err - } else if done { - break - } - } - r.initialFileEntries = len(r.fileEntries) - - return buf.err -} - -// readFileEntry reads a file entry from either the header or a -// DW_LNE_define_file extended opcode and adds it to r.fileEntries. A -// true return value indicates that there are no more entries to read. -func (r *LineReader) readFileEntry() (bool, error) { - name := r.buf.string() - if r.buf.err != nil { - return false, r.buf.err - } - if len(name) == 0 { - return true, nil - } - off := r.buf.off - dirIndex := int(r.buf.uint()) - if !pathIsAbs(name) { - if dirIndex >= len(r.directories) { - return false, DecodeError{"line", off, "directory index too large"} - } - name = pathJoin(r.directories[dirIndex], name) - } - mtime := r.buf.uint() - length := int(r.buf.uint()) - - r.fileEntries = append(r.fileEntries, &LineFile{name, mtime, length}) - return false, nil -} - -// updateFile updates r.state.File after r.fileIndex has -// changed or r.fileEntries has changed. -func (r *LineReader) updateFile() { - if r.fileIndex < len(r.fileEntries) { - r.state.File = r.fileEntries[r.fileIndex] - } else { - r.state.File = nil - } -} - -// Next sets *entry to the next row in this line table and moves to -// the next row. If there are no more entries and the line table is -// properly terminated, it returns io.EOF. -// -// Rows are always in order of increasing entry.Address, but -// entry.Line may go forward or backward. -func (r *LineReader) Next(entry *LineEntry) error { - if r.buf.err != nil { - return r.buf.err - } - - // Execute opcodes until we reach an opcode that emits a line - // table entry. - for { - if len(r.buf.data) == 0 { - return io.EOF - } - emit := r.step(entry) - if r.buf.err != nil { - return r.buf.err - } - if emit { - return nil - } - } -} - -// knownOpcodeLengths gives the opcode lengths (in varint arguments) -// of known standard opcodes. -var knownOpcodeLengths = map[int]int{ - lnsCopy: 0, - lnsAdvancePC: 1, - lnsAdvanceLine: 1, - lnsSetFile: 1, - lnsNegateStmt: 0, - lnsSetBasicBlock: 0, - lnsConstAddPC: 0, - lnsSetPrologueEnd: 0, - lnsSetEpilogueBegin: 0, - lnsSetISA: 1, - // lnsFixedAdvancePC takes a uint8 rather than a varint; it's - // unclear what length the header is supposed to claim, so - // ignore it. -} - -// step processes the next opcode and updates r.state. If the opcode -// emits a row in the line table, this updates *entry and returns -// true. -func (r *LineReader) step(entry *LineEntry) bool { - opcode := int(r.buf.uint8()) - - if opcode >= r.opcodeBase { - // Special opcode [DWARF2 6.2.5.1, DWARF4 6.2.5.1] - adjustedOpcode := opcode - r.opcodeBase - r.advancePC(adjustedOpcode / r.lineRange) - lineDelta := r.lineBase + adjustedOpcode%r.lineRange - r.state.Line += lineDelta - goto emit - } - - switch opcode { - case 0: - // Extended opcode [DWARF2 6.2.5.3] - length := Offset(r.buf.uint()) - startOff := r.buf.off - opcode := r.buf.uint8() - - switch opcode { - case lneEndSequence: - r.state.EndSequence = true - *entry = r.state - r.resetState() - - case lneSetAddress: - r.state.Address = r.buf.addr() - - case lneDefineFile: - if done, err := r.readFileEntry(); err != nil { - r.buf.err = err - return false - } else if done { - r.buf.err = DecodeError{"line", startOff, "malformed DW_LNE_define_file operation"} - return false - } - r.updateFile() - - case lneSetDiscriminator: - // [DWARF4 6.2.5.3] - r.state.Discriminator = int(r.buf.uint()) - } - - r.buf.skip(int(startOff + length - r.buf.off)) - - if opcode == lneEndSequence { - return true - } - - // Standard opcodes [DWARF2 6.2.5.2] - case lnsCopy: - goto emit - - case lnsAdvancePC: - r.advancePC(int(r.buf.uint())) - - case lnsAdvanceLine: - r.state.Line += int(r.buf.int()) - - case lnsSetFile: - r.fileIndex = int(r.buf.uint()) - r.updateFile() - - case lnsSetColumn: - r.state.Column = int(r.buf.uint()) - - case lnsNegateStmt: - r.state.IsStmt = !r.state.IsStmt - - case lnsSetBasicBlock: - r.state.BasicBlock = true - - case lnsConstAddPC: - r.advancePC((255 - r.opcodeBase) / r.lineRange) - - case lnsFixedAdvancePC: - r.state.Address += uint64(r.buf.uint16()) - - // DWARF3 standard opcodes [DWARF3 6.2.5.2] - case lnsSetPrologueEnd: - r.state.PrologueEnd = true - - case lnsSetEpilogueBegin: - r.state.EpilogueBegin = true - - case lnsSetISA: - r.state.ISA = int(r.buf.uint()) - - default: - // Unhandled standard opcode. Skip the number of - // arguments that the prologue says this opcode has. - for i := 0; i < r.opcodeLengths[opcode]; i++ { - r.buf.uint() - } - } - return false - -emit: - *entry = r.state - r.state.BasicBlock = false - r.state.PrologueEnd = false - r.state.EpilogueBegin = false - r.state.Discriminator = 0 - return true -} - -// advancePC advances "operation pointer" (the combination of Address -// and OpIndex) in r.state by opAdvance steps. -func (r *LineReader) advancePC(opAdvance int) { - opIndex := r.state.OpIndex + opAdvance - r.state.Address += uint64(r.minInstructionLength * (opIndex / r.maxOpsPerInstruction)) - r.state.OpIndex = opIndex % r.maxOpsPerInstruction -} - -// A LineReaderPos represents a position in a line table. -type LineReaderPos struct { - // off is the current offset in the DWARF line section. - off Offset - // numFileEntries is the length of fileEntries. - numFileEntries int - // state and fileIndex are the statement machine state at - // offset off. - state LineEntry - fileIndex int -} - -// Tell returns the current position in the line table. -func (r *LineReader) Tell() LineReaderPos { - return LineReaderPos{r.buf.off, len(r.fileEntries), r.state, r.fileIndex} -} - -// Seek restores the line table reader to a position returned by Tell. -// -// The argument pos must have been returned by a call to Tell on this -// line table. -func (r *LineReader) Seek(pos LineReaderPos) { - r.buf.off = pos.off - r.buf.data = r.section[r.buf.off:r.endOffset] - r.fileEntries = r.fileEntries[:pos.numFileEntries] - r.state = pos.state - r.fileIndex = pos.fileIndex -} - -// Reset repositions the line table reader at the beginning of the -// line table. -func (r *LineReader) Reset() { - // Reset buffer to the line number program offset. - r.buf.off = r.programOffset - r.buf.data = r.section[r.buf.off:r.endOffset] - - // Reset file entries list. - r.fileEntries = r.fileEntries[:r.initialFileEntries] - - // Reset line number program state. - r.resetState() -} - -// resetState resets r.state to its default values -func (r *LineReader) resetState() { - // Reset the state machine registers to the defaults given in - // [DWARF4 6.2.2]. - r.state = LineEntry{ - Address: 0, - OpIndex: 0, - File: nil, - Line: 1, - Column: 0, - IsStmt: r.defaultIsStmt, - BasicBlock: false, - PrologueEnd: false, - EpilogueBegin: false, - ISA: 0, - Discriminator: 0, - } - r.fileIndex = 1 - r.updateFile() -} - -// ErrUnknownPC is the error returned by LineReader.ScanPC when the -// seek PC is not covered by any entry in the line table. -var ErrUnknownPC = errors.New("ErrUnknownPC") - -// SeekPC sets *entry to the LineEntry that includes pc and positions -// the reader on the next entry in the line table. If necessary, this -// will seek backwards to find pc. -// -// If pc is not covered by any entry in this line table, SeekPC -// returns ErrUnknownPC. In this case, *entry and the final seek -// position are unspecified. -// -// Note that DWARF line tables only permit sequential, forward scans. -// Hence, in the worst case, this takes time linear in the size of the -// line table. If the caller wishes to do repeated fast PC lookups, it -// should build an appropriate index of the line table. -func (r *LineReader) SeekPC(pc uint64, entry *LineEntry) error { - if err := r.Next(entry); err != nil { - return err - } - if entry.Address > pc { - // We're too far. Start at the beginning of the table. - r.Reset() - if err := r.Next(entry); err != nil { - return err - } - if entry.Address > pc { - // The whole table starts after pc. - r.Reset() - return ErrUnknownPC - } - } - - // Scan until we pass pc, then back up one. - for { - var next LineEntry - pos := r.Tell() - if err := r.Next(&next); err != nil { - if err == io.EOF { - return ErrUnknownPC - } - return err - } - if next.Address > pc { - if entry.EndSequence { - // pc is in a hole in the table. - return ErrUnknownPC - } - // entry is the desired entry. Back up the - // cursor to "next" and return success. - r.Seek(pos) - return nil - } - *entry = next - } -} - -// pathIsAbs reports whether path is an absolute path (or "full path -// name" in DWARF parlance). This is in "whatever form makes sense for -// the host system", so this accepts both UNIX-style and DOS-style -// absolute paths. We avoid the filepath package because we want this -// to behave the same regardless of our host system and because we -// don't know what system the paths came from. -func pathIsAbs(path string) bool { - _, path = splitDrive(path) - return len(path) > 0 && (path[0] == '/' || path[0] == '\\') -} - -// pathJoin joins dirname and filename. filename must be relative. -// DWARF paths can be UNIX-style or DOS-style, so this handles both. -func pathJoin(dirname, filename string) string { - if len(dirname) == 0 { - return filename - } - // dirname should be absolute, which means we can determine - // whether it's a DOS path reasonably reliably by looking for - // a drive letter or UNC path. - drive, dirname := splitDrive(dirname) - if drive == "" { - // UNIX-style path. - return path.Join(dirname, filename) - } - // DOS-style path. - drive2, filename := splitDrive(filename) - if drive2 != "" { - if strings.ToLower(drive) != strings.ToLower(drive2) { - // Different drives. There's not much we can - // do here, so just ignore the directory. - return drive2 + filename - } - // Drives are the same. Ignore drive on filename. - } - if !(strings.HasSuffix(dirname, "/") || strings.HasSuffix(dirname, `\`)) && dirname != "" { - dirname += `\` - } - return drive + dirname + filename -} - -// splitDrive splits the DOS drive letter or UNC share point from -// path, if any. path == drive + rest -func splitDrive(path string) (drive, rest string) { - if len(path) >= 2 && path[1] == ':' { - if c := path[0]; 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' { - return path[:2], path[2:] - } - } - if len(path) > 3 && (path[0] == '\\' || path[0] == '/') && (path[1] == '\\' || path[1] == '/') { - // Normalize the path so we can search for just \ below. - npath := strings.Replace(path, "/", `\`, -1) - // Get the host part, which must be non-empty. - slash1 := strings.IndexByte(npath[2:], '\\') + 2 - if slash1 > 2 { - // Get the mount-point part, which must be non-empty. - slash2 := strings.IndexByte(npath[slash1+1:], '\\') + slash1 + 1 - if slash2 > slash1 { - return path[:slash2], path[slash2:] - } - } - } - return "", path -} diff --git a/odiglet/pkg/allocator/debug/dwarf/line_test.go b/odiglet/pkg/allocator/debug/dwarf/line_test.go deleted file mode 100644 index 11a254464a..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/line_test.go +++ /dev/null @@ -1,314 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package dwarf_test - -import ( - . "debug/dwarf" - "io" - "strings" - "testing" -) - -var ( - file1C = &LineFile{Name: "/home/austin/go.dev/src/debug/dwarf/testdata/line1.c"} - file1H = &LineFile{Name: "/home/austin/go.dev/src/debug/dwarf/testdata/line1.h"} - file2C = &LineFile{Name: "/home/austin/go.dev/src/debug/dwarf/testdata/line2.c"} -) - -func TestLineELFGCC(t *testing.T) { - // Generated by: - // # gcc --version | head -n1 - // gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2 - // # gcc -g -o line-gcc.elf line*.c - - // Line table based on readelf --debug-dump=rawline,decodedline - want := []LineEntry{ - {Address: 0x40059d, File: file1H, Line: 2, IsStmt: true}, - {Address: 0x4005a5, File: file1H, Line: 2, IsStmt: true}, - {Address: 0x4005b4, File: file1H, Line: 5, IsStmt: true}, - {Address: 0x4005bd, File: file1H, Line: 6, IsStmt: true, Discriminator: 2}, - {Address: 0x4005c7, File: file1H, Line: 5, IsStmt: true, Discriminator: 2}, - {Address: 0x4005cb, File: file1H, Line: 5, IsStmt: false, Discriminator: 1}, - {Address: 0x4005d1, File: file1H, Line: 7, IsStmt: true}, - {Address: 0x4005e7, File: file1C, Line: 6, IsStmt: true}, - {Address: 0x4005eb, File: file1C, Line: 7, IsStmt: true}, - {Address: 0x4005f5, File: file1C, Line: 8, IsStmt: true}, - {Address: 0x4005ff, File: file1C, Line: 9, IsStmt: true}, - {Address: 0x400601, EndSequence: true}, - - {Address: 0x400601, File: file2C, Line: 4, IsStmt: true}, - {Address: 0x400605, File: file2C, Line: 5, IsStmt: true}, - {Address: 0x40060f, File: file2C, Line: 6, IsStmt: true}, - {Address: 0x400611, EndSequence: true}, - } - - testLineTable(t, want, elfData(t, "testdata/line-gcc.elf")) -} - -func TestLineGCCWindows(t *testing.T) { - // Generated by: - // > gcc --version - // gcc (tdm64-1) 4.9.2 - // > gcc -g -o line-gcc-win.bin line1.c C:\workdir\go\src\debug\dwarf\testdata\line2.c - - toWindows := func(lf *LineFile) *LineFile { - lf2 := *lf - lf2.Name = strings.Replace(lf2.Name, "/home/austin/go.dev/", "C:\\workdir\\go\\", -1) - lf2.Name = strings.Replace(lf2.Name, "/", "\\", -1) - return &lf2 - } - file1C := toWindows(file1C) - file1H := toWindows(file1H) - file2C := toWindows(file2C) - - // Line table based on objdump --dwarf=rawline,decodedline - want := []LineEntry{ - {Address: 0x401530, File: file1H, Line: 2, IsStmt: true}, - {Address: 0x401538, File: file1H, Line: 5, IsStmt: true}, - {Address: 0x401541, File: file1H, Line: 6, IsStmt: true, Discriminator: 3}, - {Address: 0x40154b, File: file1H, Line: 5, IsStmt: true, Discriminator: 3}, - {Address: 0x40154f, File: file1H, Line: 5, IsStmt: false, Discriminator: 1}, - {Address: 0x401555, File: file1H, Line: 7, IsStmt: true}, - {Address: 0x40155b, File: file1C, Line: 6, IsStmt: true}, - {Address: 0x401563, File: file1C, Line: 6, IsStmt: true}, - {Address: 0x401568, File: file1C, Line: 7, IsStmt: true}, - {Address: 0x40156d, File: file1C, Line: 8, IsStmt: true}, - {Address: 0x401572, File: file1C, Line: 9, IsStmt: true}, - {Address: 0x401578, EndSequence: true}, - - {Address: 0x401580, File: file2C, Line: 4, IsStmt: true}, - {Address: 0x401588, File: file2C, Line: 5, IsStmt: true}, - {Address: 0x401595, File: file2C, Line: 6, IsStmt: true}, - {Address: 0x40159b, EndSequence: true}, - } - - testLineTable(t, want, peData(t, "testdata/line-gcc-win.bin")) -} - -func TestLineELFClang(t *testing.T) { - // Generated by: - // # clang --version | head -n1 - // Ubuntu clang version 3.4-1ubuntu3 (tags/RELEASE_34/final) (based on LLVM 3.4) - // # clang -g -o line-clang.elf line*. - - want := []LineEntry{ - {Address: 0x400530, File: file1C, Line: 6, IsStmt: true}, - {Address: 0x400534, File: file1C, Line: 7, IsStmt: true, PrologueEnd: true}, - {Address: 0x400539, File: file1C, Line: 8, IsStmt: true}, - {Address: 0x400545, File: file1C, Line: 9, IsStmt: true}, - {Address: 0x400550, File: file1H, Line: 2, IsStmt: true}, - {Address: 0x400554, File: file1H, Line: 5, IsStmt: true, PrologueEnd: true}, - {Address: 0x400568, File: file1H, Line: 6, IsStmt: true}, - {Address: 0x400571, File: file1H, Line: 5, IsStmt: true}, - {Address: 0x400581, File: file1H, Line: 7, IsStmt: true}, - {Address: 0x400583, EndSequence: true}, - - {Address: 0x400590, File: file2C, Line: 4, IsStmt: true}, - {Address: 0x4005a0, File: file2C, Line: 5, IsStmt: true, PrologueEnd: true}, - {Address: 0x4005a7, File: file2C, Line: 6, IsStmt: true}, - {Address: 0x4005b0, EndSequence: true}, - } - - testLineTable(t, want, elfData(t, "testdata/line-clang.elf")) -} - -func TestLineSeek(t *testing.T) { - d := elfData(t, "testdata/line-gcc.elf") - - // Get the line table for the first CU. - cu, err := d.Reader().Next() - if err != nil { - t.Fatal("d.Reader().Next:", err) - } - lr, err := d.LineReader(cu) - if err != nil { - t.Fatal("d.LineReader:", err) - } - - // Read entries forward. - var line LineEntry - var posTable []LineReaderPos - var table []LineEntry - for { - posTable = append(posTable, lr.Tell()) - - err := lr.Next(&line) - if err != nil { - if err == io.EOF { - break - } - t.Fatal("lr.Next:", err) - } - table = append(table, line) - } - - // Test that Reset returns to the first line. - lr.Reset() - if err := lr.Next(&line); err != nil { - t.Fatal("lr.Next after Reset failed:", err) - } else if line != table[0] { - t.Fatal("lr.Next after Reset returned", line, "instead of", table[0]) - } - - // Check that entries match when seeking backward. - for i := len(posTable) - 1; i >= 0; i-- { - lr.Seek(posTable[i]) - err := lr.Next(&line) - if i == len(posTable)-1 { - if err != io.EOF { - t.Fatal("expected io.EOF after seek to end, got", err) - } - } else if err != nil { - t.Fatal("lr.Next after seek to", posTable[i], "failed:", err) - } else if line != table[i] { - t.Fatal("lr.Next after seek to", posTable[i], "returned", line, "instead of", table[i]) - } - } - - // Check that seeking to a PC returns the right line. - if err := lr.SeekPC(table[0].Address-1, &line); err != ErrUnknownPC { - t.Fatalf("lr.SeekPC to %#x returned %v instead of ErrUnknownPC", table[0].Address-1, err) - } - for i, testLine := range table { - if testLine.EndSequence { - if err := lr.SeekPC(testLine.Address, &line); err != ErrUnknownPC { - t.Fatalf("lr.SeekPC to %#x returned %v instead of ErrUnknownPC", testLine.Address, err) - } - continue - } - - nextPC := table[i+1].Address - for pc := testLine.Address; pc < nextPC; pc++ { - if err := lr.SeekPC(pc, &line); err != nil { - t.Fatalf("lr.SeekPC to %#x failed: %v", pc, err) - } else if line != testLine { - t.Fatalf("lr.SeekPC to %#x returned %v instead of %v", pc, line, testLine) - } - } - } -} - -func testLineTable(t *testing.T, want []LineEntry, d *Data) { - // Get line table from d. - var got []LineEntry - dr := d.Reader() - for { - ent, err := dr.Next() - if err != nil { - t.Fatal("dr.Next:", err) - } else if ent == nil { - break - } - - if ent.Tag != TagCompileUnit { - dr.SkipChildren() - continue - } - - // Decode CU's line table. - lr, err := d.LineReader(ent) - if err != nil { - t.Fatal("d.LineReader:", err) - } else if lr == nil { - continue - } - - for { - var line LineEntry - err := lr.Next(&line) - if err != nil { - if err == io.EOF { - break - } - t.Fatal("lr.Next:", err) - } - // Ignore sources from the Windows build environment. - if strings.HasPrefix(line.File.Name, "C:\\crossdev\\") || - strings.HasPrefix(line.File.Name, "C:/crossdev/") { - continue - } - got = append(got, line) - } - } - - // Compare line tables. - if !compareLines(got, want) { - t.Log("Line tables do not match. Got:") - dumpLines(t, got) - t.Log("Want:") - dumpLines(t, want) - t.FailNow() - } -} - -func compareLines(a, b []LineEntry) bool { - if len(a) != len(b) { - return false - } - - for i := range a { - al, bl := a[i], b[i] - // If both are EndSequence, then the only other valid - // field is Address. Otherwise, test equality of all - // fields. - if al.EndSequence && bl.EndSequence && al.Address == bl.Address { - continue - } - if al.File.Name != bl.File.Name { - return false - } - al.File = nil - bl.File = nil - if al != bl { - return false - } - } - return true -} - -func dumpLines(t *testing.T, lines []LineEntry) { - for _, l := range lines { - t.Logf(" %+v File:%+v", l, l.File) - } -} - -type joinTest struct { - dirname, filename string - path string -} - -var joinTests = []joinTest{ - {"a", "b", "a/b"}, - {"a", "", "a"}, - {"", "b", "b"}, - {"/a", "b", "/a/b"}, - {"/a/", "b", "/a/b"}, - - {`C:\Windows\`, `System32`, `C:\Windows\System32`}, - {`C:\Windows\`, ``, `C:\Windows\`}, - {`C:\`, `Windows`, `C:\Windows`}, - {`C:\Windows\`, `C:System32`, `C:\Windows\System32`}, - {`C:\Windows`, `a/b`, `C:\Windows\a/b`}, - {`\\host\share\`, `foo`, `\\host\share\foo`}, - {`\\host\share\`, `foo\bar`, `\\host\share\foo\bar`}, - {`//host/share/`, `foo/bar`, `//host/share/foo/bar`}, - - // The following are "best effort". We shouldn't see relative - // base directories in DWARF, but these test that pathJoin - // doesn't fail miserably if it sees one. - {`C:`, `a`, `C:a`}, - {`C:`, `a\b`, `C:a\b`}, - {`C:.`, `a`, `C:.\a`}, - {`C:a`, `b`, `C:a\b`}, -} - -func TestPathJoin(t *testing.T) { - for _, test := range joinTests { - got := PathJoin(test.dirname, test.filename) - if test.path != got { - t.Errorf("pathJoin(%q, %q) = %q, want %q", test.dirname, test.filename, got, test.path) - } - } -} diff --git a/odiglet/pkg/allocator/debug/dwarf/open.go b/odiglet/pkg/allocator/debug/dwarf/open.go deleted file mode 100644 index 57344d82b4..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/open.go +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package dwarf provides access to DWARF debugging information loaded from -// executable files, as defined in the DWARF 2.0 Standard at -// http://dwarfstd.org/doc/dwarf-2.0.0.pdf -package dwarf - -import "encoding/binary" - -// Data represents the DWARF debugging information -// loaded from an executable file (for example, an ELF or Mach-O executable). -type Data struct { - // raw data - abbrev []byte - aranges []byte - frame []byte - info []byte - line []byte - pubnames []byte - ranges []byte - str []byte - - // parsed data - abbrevCache map[uint64]abbrevTable - order binary.ByteOrder - typeCache map[Offset]Type - typeSigs map[uint64]*typeUnit - unit []unit -} - -// New returns a new Data object initialized from the given parameters. -// Rather than calling this function directly, clients should typically use -// the DWARF method of the File type of the appropriate package debug/elf, -// debug/macho, or debug/pe. -// -// The []byte arguments are the data from the corresponding debug section -// in the object file; for example, for an ELF object, abbrev is the contents of -// the ".debug_abbrev" section. -func New(abbrev, aranges, frame, info, line, pubnames, ranges, str []byte) (*Data, error) { - d := &Data{ - abbrev: abbrev, - aranges: aranges, - frame: frame, - info: info, - line: line, - pubnames: pubnames, - ranges: ranges, - str: str, - abbrevCache: make(map[uint64]abbrevTable), - typeCache: make(map[Offset]Type), - typeSigs: make(map[uint64]*typeUnit), - } - - // Sniff .debug_info to figure out byte order. - // 32-bit DWARF: 4 byte length, 2 byte version. - // 64-bit DWARf: 4 bytes of 0xff, 8 byte length, 2 byte version. - if len(d.info) < 6 { - return nil, DecodeError{"info", Offset(len(d.info)), "too short"} - } - offset := 4 - if d.info[0] == 0xff && d.info[1] == 0xff && d.info[2] == 0xff && d.info[3] == 0xff { - if len(d.info) < 14 { - return nil, DecodeError{"info", Offset(len(d.info)), "too short"} - } - offset = 12 - } - // Fetch the version, a tiny 16-bit number (1, 2, 3, 4, 5). - x, y := d.info[offset], d.info[offset+1] - switch { - case x == 0 && y == 0: - return nil, DecodeError{"info", 4, "unsupported version 0"} - case x == 0: - d.order = binary.BigEndian - case y == 0: - d.order = binary.LittleEndian - default: - return nil, DecodeError{"info", 4, "cannot determine byte order"} - } - - u, err := d.parseUnits() - if err != nil { - return nil, err - } - d.unit = u - return d, nil -} - -// AddTypes will add one .debug_types section to the DWARF data. A -// typical object with DWARF version 4 debug info will have multiple -// .debug_types sections. The name is used for error reporting only, -// and serves to distinguish one .debug_types section from another. -func (d *Data) AddTypes(name string, types []byte) error { - return d.parseTypes(name, types) -} diff --git a/odiglet/pkg/allocator/debug/dwarf/tag_string.go b/odiglet/pkg/allocator/debug/dwarf/tag_string.go deleted file mode 100644 index ac396af050..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/tag_string.go +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated by "stringer -type Tag -trimprefix=Tag"; DO NOT EDIT. - -package dwarf - -import "strconv" - -const ( - _Tag_name_0 = "ArrayTypeClassTypeEntryPointEnumerationTypeFormalParameter" - _Tag_name_1 = "ImportedDeclaration" - _Tag_name_2 = "LabelLexDwarfBlock" - _Tag_name_3 = "Member" - _Tag_name_4 = "PointerTypeReferenceTypeCompileUnitStringTypeStructType" - _Tag_name_5 = "SubroutineTypeTypedefUnionTypeUnspecifiedParametersVariantCommonDwarfBlockCommonInclusionInheritanceInlinedSubroutineModulePtrToMemberTypeSetTypeSubrangeTypeWithStmtAccessDeclarationBaseTypeCatchDwarfBlockConstTypeConstantEnumeratorFileTypeFriendNamelistNamelistItemPackedTypeSubprogramTemplateTypeParameterTemplateValueParameterThrownTypeTryDwarfBlockVariantPartVariableVolatileTypeDwarfProcedureRestrictTypeInterfaceTypeNamespaceImportedModuleUnspecifiedTypePartialUnitImportedUnitMutableTypeConditionSharedTypeTypeUnitRvalueReferenceTypeTemplateAlias" -) - -var ( - _Tag_index_0 = [...]uint8{0, 9, 18, 28, 43, 58} - _Tag_index_2 = [...]uint8{0, 5, 18} - _Tag_index_4 = [...]uint8{0, 11, 24, 35, 45, 55} - _Tag_index_5 = [...]uint16{0, 14, 21, 30, 51, 58, 74, 89, 100, 117, 123, 138, 145, 157, 165, 182, 190, 205, 214, 222, 232, 240, 246, 254, 266, 276, 286, 307, 329, 339, 352, 363, 371, 383, 397, 409, 422, 431, 445, 460, 471, 483, 494, 503, 513, 521, 540, 553} -) - -func (i Tag) String() string { - switch { - case 1 <= i && i <= 5: - i -= 1 - return _Tag_name_0[_Tag_index_0[i]:_Tag_index_0[i+1]] - case i == 8: - return _Tag_name_1 - case 10 <= i && i <= 11: - i -= 10 - return _Tag_name_2[_Tag_index_2[i]:_Tag_index_2[i+1]] - case i == 13: - return _Tag_name_3 - case 15 <= i && i <= 19: - i -= 15 - return _Tag_name_4[_Tag_index_4[i]:_Tag_index_4[i+1]] - case 21 <= i && i <= 67: - i -= 21 - return _Tag_name_5[_Tag_index_5[i]:_Tag_index_5[i+1]] - default: - return "Tag(" + strconv.FormatInt(int64(i), 10) + ")" - } -} diff --git a/odiglet/pkg/allocator/debug/dwarf/testdata/cycle.c b/odiglet/pkg/allocator/debug/dwarf/testdata/cycle.c deleted file mode 100644 index a0b53dfe74..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/testdata/cycle.c +++ /dev/null @@ -1,7 +0,0 @@ -typedef struct aaa *AAA; -typedef AAA BBB; -struct aaa { BBB val; }; - -AAA x(void) { - return (AAA)0; -} diff --git a/odiglet/pkg/allocator/debug/dwarf/testdata/cycle.elf b/odiglet/pkg/allocator/debug/dwarf/testdata/cycle.elf deleted file mode 100644 index e0b66caa638c61c954d32c60c76d4bc261ccc3b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2624 zcmbtW&1(}u6o0eZkJQ+hHh#2JBp#%#HJete2Bq2${6Y~Ciik+rY^G^xvniWRjS6}Z z!J7wB1aDsa6TEx!Kk(?qKftpGeQ#!7-A+~neX#r9`@PS3J2T1COE)e%LI9J13-DWG z6kx>tEzc`)9tx0$<*P5geI)()u zfK~QERtY@?;byW~!Uf{JgF8+YOxNeZ#ZetKK6Q zXG&+#STB}VTd^N(l(wQ~EQ7ci0bE&HI#--nuC~Ltt+SL)wv{&XWMmv zARgTY(aDRkz5SV&xU|EF(?g^NvyjU_ca{eGE~5j1Uh82a_N&O_Nb@z8V%dqoQ)}_6 ztrmEZ-1KqHxYm{RaJ7jxCHvKCB)4~&{m2jNa(Bq)dMG&rOMn+N8x0v^i4Yg<;kZg_ z2quwSTUm|#hNLF{pT;l+9e_S7)x6Q|O=BOHqv%Ii;@GLk>n7f2cKkRx(7gXOeg9es{4QFQi-a>u(`O zIk`_16}>ivS_~M@^_f3LJT0E@s^fo&e`ew>H#oI(*X_1&T}I!Uc-y^V0Q%ub60e`J zS16>-Zz5%WIrQcDyzx(ipGpze-bwX@T3d-a@$CfQ9c z&=>9|7xs36G~VIF9Cj-4PjW|x@JeVqu}l`uNI2y>O&}7TQzFK-25`U#jPpLAKO98% mKAP09%EP_{Z5Z74=iVrPukj(4H?r+N^#{CYaM}sU-S7+1^`W5v diff --git a/odiglet/pkg/allocator/debug/dwarf/testdata/line-clang.elf b/odiglet/pkg/allocator/debug/dwarf/testdata/line-clang.elf deleted file mode 100644 index b63cc781c410a53840c001af944e6292935ce3ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10271 zcmeHNZ)_Y#6`$R`vz<6OpPjUE8fdP?Zk>Y9PV5G^Nt-=8m)xaxnkG(~in{Bw?`$8O z@2vZiCPjde(}LBee*lR9AE+vj_<%%&Du{~ICb()o6r>b^R9cX%s6k2Ef}tUb3a$CQ z*?D(+duOE|%C|gg=gs@`d-G;?ZgzIo-w5~b&^1jk>Ed2NlIby}$}WX?_68{`U5{8M zOwlTC6*bU!ahcLW+^#XdszNibQ+@`x2Um}7D|&QOR+xXrRtx5wA#rN2M5e0R{KZ;Z zWG+NNDhNlp`h8LaAC?v7oy9zCJL5=AxHg4rQ#j^lRbtG!f7Ca+236ca-GoH4Nla{) zWr>q7(Vp}9IMugOqmr9td@0-mz$u9IzgFQ_4trI5OO4Bd>K}6@ijGurWOH{%D&C$- zrVEGL5BF?t-`pL{WrCYzzbQWX?%cg!w#4Ju42k-;8W+t0vLAl=g>U`+cy2uU<8uwa zKXEwv@_VU0gyjp>PfYdjY^vf-x@!6s=mS;!1^PEi-PtUrvdMIQOjs7FtXw{p&0CYP zWEz_B$xK>lEU~jc+S_Ms3T_JCNda~IQ6K0J^Nv)Y!cEC#Wb3j;akXJs*67~RcrZ2l zhh>$fGvS#64!xRM($wbAJL5!V-m8l|>0P-ZAR>>S%6l(tfqP`;)w(%5;^Lh;OpC1^ zlnv`m)JUEn!(R~k|g#&ebs<}WcIg_)0ehIw6l>nt`-1(i5w%3{{i60>}xjuoWf7v^APeCg~t6r zUidl^8G6mT11jxAhFOF5 zPKXP8z$9vD4xKv+Ng&nP^Jl^fRQ=}H7M6oG99xSrG8$fZZM*l1_GEa$OQSg(Uby%c zr874cWH8zxJnor4a%^jBH%1c8BtKqUoDKgMH_bmZ7kV%>yBInUoxKv;AD#VEXt4iS zYosm!+_84z`}#MW-}rXq^hXBW`3oO?w73{~{QdmR+(iHErT*C~+Yw`N^^hn5>8!M&s0p^LELu$%sn7b2+R4Rk6Y3qzFCb~j%^i?$U6u1Y; zJ`8>t{6+B9=;9y22f;6c=fPK_|L=f53{L9+k@nbLp&j;X>sHj(J*(CFNl$D4^N4!~ zIVh^`FGLIM?%RsvC|@==PnW3|NZe| zhUDYANv!zJ*R0y(=k-b5B(tEM7ST4F33?A8YPOkhyuM0JagU7cB@sVkBT_2uOK5LH zB=-v7$5s2RpH?#G&Fx{6FNtM5#$|tol|QyWQr48;f|3s^yHfw(8NbK68@f^5|JxMb z?3xekzq7CJ?m*lAkwQ9O2y_Q~f}7em-c^v|#tpVYDC=k{mL3lrN@R1%OghjN>~7y^ zJ9Y)y^0Dz;$KG&%IJ7Tpb#-@)CDXCghCtg$ESHD};NIVVV1O_i#23)CeYffaMsbne zFo^cava+!Ke*}Z=|E%&4RJuyd%_!~ogt-lueA(ND%GgE}Le3>!kk!OR9%GwO2=RSf z9$BlC_jQHXEu~U%09Abkh34%;$+_=TIcW!sZ$s_%c%C9hZI9B=6z$$;$Y4xU`P?Dz zapE2dr9U?%Y6w;PT@=fNL99lrqj(;#*h)-HqU6+mh&mI!qs!D@Kt(fnh)xun6RaVCe2toa%{m;0=s{ul?ylcbA6>O=ZKKwtnfM7BEl}QDUyom(C#czWwt2gY03EJ1 znigG!Y;O_KRUPoJBWQj7z4XIfy0KDI;sH47;`8LL{l~Wwr98&Mz-vK)*Y|W{V{jB! zRh_Vxu4Oup`I_bTJ@gxoZXEgf@`1X0p1G{+2+<>h(iEr&D&uUjLt=n+9;6$Ve^Ahu z!T-~p=G=jfiOgi8BUZ@elj)A}Ofa4})RD`McEl4Sh4GH~qp|E*M?R6u$7A`JJyUU7 zK{IuvFeXMPVp)+aW{zpPUUm?LoWC@2$erem^d$qGbd{zzX+$u0WHKKc0ncY`KEXA> z6WJ*dOlR_mV5m3Rj-RrU#?yu1NFj+cqGVhINt%e|CPXlPB#n4B&u49mS{BL#3$|<` z6(fMEO{MZ8m`o>8<`aieVxdUFmXX~LCMK-0Y-}=NO~ip^$wpYQY&LepMsWShqi{p? z*kp1PO=l1gMNqb4M;yuJL~t}SIhnvPVem2N0AnFbKyQmvg%JcO$;tFshHbHtk!<1+ zOLR}Uj`8Cv0_2ZOA;70V^qi%&$6mqceAR?hI%nnQtW=_q>l6#%pTkv)i}8cH38{3B z8IV$`u$Q}%Oe>@lpVv)k%&UMcQYsa0{C1eG;91D+AJ?~HF&dRheyT#V=aMl&fvyuYxe%JF*y270zLo}cFj6`tGU z{MnEBSAeIz0?WK#7*_azYPbg6nZHtt$55d$W&E^ZO4GE$b3eI#&WH6!U3lK_99Q^= zjArl0R-o?2KMft_MfnlUtM=y=p7(vW)y|dc#Ak6i@xo)0y69+1p;Yj>D)aBbouQj*Jds9INQ5=*07WwncS__jT;A!m=oyS9l)(&KgtNIu)Mgrjy+GpTS7&Gk&YW z^Y?)5PB7|j{I6X2X@#Fw?RUHS&-ahRoWW(o>& z`@7{g;X^5M`*adZ6!?VrzrvTg%6Q)2^7kA5PNRmSm=Di`zX9uPpU>y7Ql~)fd|77x zE_|GL;U6Yg@dH4oEfq_~F~1Cp6W^)uohm`jlLIi0xj3m zwk7!`$YF5fN#?c7;U><~o*Gm~n*&e_uFbf3KJxR2*4Jw7zu5`{Xs0Wv` z^5VIK6J%f~G+)&pPi{}O_$!Ow{mbL{1V0DM^$mibZ{>PFzF$|1-zfNbRPNtYe9n~X zR|$T8l2T%jaGs2`8ZYRI=amlC2O0+mXszokO2LE{nsq-DR1Xm6+C zE0lYj>0D12E5(#+{sfi&d6zz<^z$zLgED?;JSh*NFD2*GZ3^ zDX&+&?|BP)8lMwtJ|tAkOVInpS`l%@`G@j1UGw>h@^_B|PL*W*P8A<_NK!5I0abUh zb=PCXrzY7W z!akFU7bYi<0OF7=I?5??XhX$g3 z@N!t>zw8KWXaD`Zp?>TB9Xs}g2d%+SZ-1D=$^YsZ%@t(YbdqaD2M4UuFbxj$(I5@R zMp6kuheGy0{0J){Pl#-o{Xasc>HHs{ihme#o1MYR|CI>in#))dv2+}5TG9K_WIUO+ z3OEdRW=wrV9%(35A1$0$sk;3yO1lnOd)58!OT}_I+-%E2mv}U(uYC8*dMXD{{10>u B2^9bU diff --git a/odiglet/pkg/allocator/debug/dwarf/testdata/line-gcc-win.bin b/odiglet/pkg/allocator/debug/dwarf/testdata/line-gcc-win.bin deleted file mode 100644 index 583ad44dd07dabb77cadb01043a45e50295ae7d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 133202 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 YLhg02QYYTpdgiR$Vd@!cpv5`=FMF}4$N&HU diff --git a/odiglet/pkg/allocator/debug/dwarf/testdata/line-gcc.elf b/odiglet/pkg/allocator/debug/dwarf/testdata/line-gcc.elf deleted file mode 100644 index 50500a8eecd95ee18ac78e130e12eef10c4aaf55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10113 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 - -void f2() -{ - printf("hello\n"); -} diff --git a/odiglet/pkg/allocator/debug/dwarf/testdata/ranges.c b/odiglet/pkg/allocator/debug/dwarf/testdata/ranges.c deleted file mode 100644 index 2f208e591c..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/testdata/ranges.c +++ /dev/null @@ -1,25 +0,0 @@ -// gcc -g -O2 -freorder-blocks-and-partition - -const char *arr[10000]; -const char *hot = "hot"; -const char *cold = "cold"; - -__attribute__((noinline)) -void fn(int path) { - int i; - - if (path) { - for (i = 0; i < sizeof arr / sizeof arr[0]; i++) { - arr[i] = hot; - } - } else { - for (i = 0; i < sizeof arr / sizeof arr[0]; i++) { - arr[i] = cold; - } - } -} - -int main(int argc, char *argv[]) { - fn(argc); - return 0; -} diff --git a/odiglet/pkg/allocator/debug/dwarf/testdata/ranges.elf b/odiglet/pkg/allocator/debug/dwarf/testdata/ranges.elf deleted file mode 100755 index 7f54138cffb3bc61a8e537a5becdfc913a41da3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10348 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 NlkaiGDCNwF{{TVI*H!=k diff --git a/odiglet/pkg/allocator/debug/dwarf/testdata/split.c b/odiglet/pkg/allocator/debug/dwarf/testdata/split.c deleted file mode 100644 index 0ef3427d2e..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/testdata/split.c +++ /dev/null @@ -1,5 +0,0 @@ -// gcc -gsplit-dwarf split.c -o split.elf - -int main() -{ -} diff --git a/odiglet/pkg/allocator/debug/dwarf/testdata/split.elf b/odiglet/pkg/allocator/debug/dwarf/testdata/split.elf deleted file mode 100644 index 99ee2c2f0bb739307cf13bc85abd3421166c0167..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9509 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 diff --git a/odiglet/pkg/allocator/debug/dwarf/testdata/typedef.c b/odiglet/pkg/allocator/debug/dwarf/testdata/typedef.c deleted file mode 100644 index 4780a0b2ba..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/testdata/typedef.c +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Linux ELF: -gcc -gdwarf-2 -m64 -c typedef.c && gcc -gdwarf-2 -m64 -o typedef.elf typedef.o - -OS X Mach-O: -gcc -gdwarf-2 -m64 -c typedef.c -o typedef.macho -*/ -#include - -typedef volatile int* t_ptr_volatile_int; -typedef const char *t_ptr_const_char; -typedef long t_long; -typedef unsigned short t_ushort; -typedef int t_func_int_of_float_double(float, double); -typedef int (*t_ptr_func_int_of_float_double)(float, double); -typedef int (*t_ptr_func_int_of_float_complex)(float complex); -typedef int (*t_ptr_func_int_of_double_complex)(double complex); -typedef int (*t_ptr_func_int_of_long_double_complex)(long double complex); -typedef int *t_func_ptr_int_of_char_schar_uchar(char, signed char, unsigned char); -typedef void t_func_void_of_char(char); -typedef void t_func_void_of_void(void); -typedef void t_func_void_of_ptr_char_dots(char*, ...); -typedef struct my_struct { - volatile int vi; - char x : 1; - int y : 4; - int z[0]; - long long array[40]; - int zz[0]; -} t_my_struct; -typedef struct my_struct1 { - int zz [1]; -} t_my_struct1; -typedef union my_union { - volatile int vi; - char x : 1; - int y : 4; - long long array[40]; -} t_my_union; -typedef enum my_enum { - e1 = 1, - e2 = 2, - e3 = -5, - e4 = 1000000000000000LL, -} t_my_enum; - -typedef struct list t_my_list; -struct list { - short val; - t_my_list *next; -}; - -typedef struct tree { - struct tree *left, *right; - unsigned long long val; -} t_my_tree; - -t_ptr_volatile_int *a2; -t_ptr_const_char **a3a; -t_long *a4; -t_ushort *a5; -t_func_int_of_float_double *a6; -t_ptr_func_int_of_float_double *a7; -t_func_ptr_int_of_char_schar_uchar *a8; -t_func_void_of_char *a9; -t_func_void_of_void *a10; -t_func_void_of_ptr_char_dots *a11; -t_my_struct *a12; -t_my_struct1 *a12a; -t_my_union *a12b; -t_my_enum *a13; -t_my_list *a14; -t_my_tree *a15; -t_ptr_func_int_of_float_complex *a16; -t_ptr_func_int_of_double_complex *a17; -t_ptr_func_int_of_long_double_complex *a18; - -int main() -{ - return 0; -} diff --git a/odiglet/pkg/allocator/debug/dwarf/testdata/typedef.elf b/odiglet/pkg/allocator/debug/dwarf/testdata/typedef.elf deleted file mode 100755 index b2062d2c4bb828dcb229f12869f77fd5d9522278..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12448 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
uyG6y&-61`(FbhA4 zP_*q1yIl_UXcHZFZ~rcYzNixQ+x}qy9_&D|Ucke@R7Cu(_#}=;4?h9Fku*&&;ym)w z;km)$%@2EDh&16c~%Zxd4jKXy{) z=PxK9Smz2T{u~!wFX#X$>gHTVbXc9veW3WBbY6vXd`38*1;xGISpn??jf0~8&dWN! zZ)*A#O~0sV5)@D$V#+2Pikdl1&ujW&PzMPH-(t|kPC%!d2il4EFCtlP!+7vIf?Q?0 zy-6N#l4qLacQwiPG|7ui^64gdxk*0PB!8eu#$4=*7jw5u=5MCPe0U8v%KSaoDC>1m z&p+ApeyB+%SMFFBo6Y5&=3-;H*lI5JnTy@!Vo$l)UM_EVbZPEbm$x_f8SW>zW5YCC XVn3r}TkK?sKkBd1!lL@t9;5#P8kMr% diff --git a/odiglet/pkg/allocator/debug/dwarf/type.go b/odiglet/pkg/allocator/debug/dwarf/type.go deleted file mode 100644 index 1b7a8ecd81..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/type.go +++ /dev/null @@ -1,727 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// DWARF type information structures. -// The format is heavily biased toward C, but for simplicity -// the String methods use a pseudo-Go syntax. - -package dwarf - -import "strconv" - -// A Type conventionally represents a pointer to any of the -// specific Type structures (CharType, StructType, etc.). -type Type interface { - Common() *CommonType - String() string - Size() int64 -} - -// A CommonType holds fields common to multiple types. -// If a field is not known or not applicable for a given type, -// the zero value is used. -type CommonType struct { - ByteSize int64 // size of value of this type, in bytes - Name string // name that can be used to refer to type -} - -func (c *CommonType) Common() *CommonType { return c } - -func (c *CommonType) Size() int64 { return c.ByteSize } - -// Basic types - -// A BasicType holds fields common to all basic types. -type BasicType struct { - CommonType - BitSize int64 - BitOffset int64 -} - -func (b *BasicType) Basic() *BasicType { return b } - -func (t *BasicType) String() string { - if t.Name != "" { - return t.Name - } - return "?" -} - -// A CharType represents a signed character type. -type CharType struct { - BasicType -} - -// A UcharType represents an unsigned character type. -type UcharType struct { - BasicType -} - -// An IntType represents a signed integer type. -type IntType struct { - BasicType -} - -// A UintType represents an unsigned integer type. -type UintType struct { - BasicType -} - -// A FloatType represents a floating point type. -type FloatType struct { - BasicType -} - -// A ComplexType represents a complex floating point type. -type ComplexType struct { - BasicType -} - -// A BoolType represents a boolean type. -type BoolType struct { - BasicType -} - -// An AddrType represents a machine address type. -type AddrType struct { - BasicType -} - -// An UnspecifiedType represents an implicit, unknown, ambiguous or nonexistent type. -type UnspecifiedType struct { - BasicType -} - -// qualifiers - -// A QualType represents a type that has the C/C++ "const", "restrict", or "volatile" qualifier. -type QualType struct { - CommonType - Qual string - Type Type -} - -func (t *QualType) String() string { return t.Qual + " " + t.Type.String() } - -func (t *QualType) Size() int64 { return t.Type.Size() } - -// An ArrayType represents a fixed size array type. -type ArrayType struct { - CommonType - Type Type - StrideBitSize int64 // if > 0, number of bits to hold each element - Count int64 // if == -1, an incomplete array, like char x[]. -} - -func (t *ArrayType) String() string { - return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String() -} - -func (t *ArrayType) Size() int64 { - if t.Count == -1 { - return 0 - } - return t.Count * t.Type.Size() -} - -// A VoidType represents the C void type. -type VoidType struct { - CommonType -} - -func (t *VoidType) String() string { return "void" } - -// A PtrType represents a pointer type. -type PtrType struct { - CommonType - Type Type -} - -func (t *PtrType) String() string { return "*" + t.Type.String() } - -// A StructType represents a struct, union, or C++ class type. -type StructType struct { - CommonType - StructName string - Kind string // "struct", "union", or "class". - Field []*StructField - Incomplete bool // if true, struct, union, class is declared but not defined -} - -// A StructField represents a field in a struct, union, or C++ class type. -type StructField struct { - Name string - Type Type - ByteOffset int64 - ByteSize int64 // usually zero; use Type.Size() for normal fields - BitOffset int64 // within the ByteSize bytes at ByteOffset - BitSize int64 // zero if not a bit field -} - -func (t *StructType) String() string { - if t.StructName != "" { - return t.Kind + " " + t.StructName - } - return t.Defn() -} - -func (t *StructType) Defn() string { - s := t.Kind - if t.StructName != "" { - s += " " + t.StructName - } - if t.Incomplete { - s += " /*incomplete*/" - return s - } - s += " {" - for i, f := range t.Field { - if i > 0 { - s += "; " - } - s += f.Name + " " + f.Type.String() - s += "@" + strconv.FormatInt(f.ByteOffset, 10) - if f.BitSize > 0 { - s += " : " + strconv.FormatInt(f.BitSize, 10) - s += "@" + strconv.FormatInt(f.BitOffset, 10) - } - } - s += "}" - return s -} - -// An EnumType represents an enumerated type. -// The only indication of its native integer type is its ByteSize -// (inside CommonType). -type EnumType struct { - CommonType - EnumName string - Val []*EnumValue -} - -// An EnumValue represents a single enumeration value. -type EnumValue struct { - Name string - Val int64 -} - -func (t *EnumType) String() string { - s := "enum" - if t.EnumName != "" { - s += " " + t.EnumName - } - s += " {" - for i, v := range t.Val { - if i > 0 { - s += "; " - } - s += v.Name + "=" + strconv.FormatInt(v.Val, 10) - } - s += "}" - return s -} - -// A FuncType represents a function type. -type FuncType struct { - CommonType - ReturnType Type - ParamType []Type -} - -func (t *FuncType) String() string { - s := "func(" - for i, t := range t.ParamType { - if i > 0 { - s += ", " - } - s += t.String() - } - s += ")" - if t.ReturnType != nil { - s += " " + t.ReturnType.String() - } - return s -} - -// A DotDotDotType represents the variadic ... function parameter. -type DotDotDotType struct { - CommonType -} - -func (t *DotDotDotType) String() string { return "..." } - -// A TypedefType represents a named type. -type TypedefType struct { - CommonType - Type Type -} - -func (t *TypedefType) String() string { return t.Name } - -func (t *TypedefType) Size() int64 { return t.Type.Size() } - -// typeReader is used to read from either the info section or the -// types section. -type typeReader interface { - Seek(Offset) - Next() (*Entry, error) - clone() typeReader - offset() Offset - // AddressSize returns the size in bytes of addresses in the current - // compilation unit. - AddressSize() int -} - -// Type reads the type at off in the DWARF “info” section. -func (d *Data) Type(off Offset) (Type, error) { - return d.readType("info", d.Reader(), off, d.typeCache, nil) -} - -// readType reads a type from r at off of name. It adds types to the -// type cache, appends new typedef types to typedefs, and computes the -// sizes of types. Callers should pass nil for typedefs; this is used -// for internal recursion. -func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type, typedefs *[]*TypedefType) (Type, error) { - if t, ok := typeCache[off]; ok { - return t, nil - } - r.Seek(off) - e, err := r.Next() - if err != nil { - return nil, err - } - addressSize := r.AddressSize() - if e == nil || e.Offset != off { - return nil, DecodeError{name, off, "no type at offset"} - } - - // If this is the root of the recursion, prepare to resolve - // typedef sizes once the recursion is done. This must be done - // after the type graph is constructed because it may need to - // resolve cycles in a different order than readType - // encounters them. - if typedefs == nil { - var typedefList []*TypedefType - defer func() { - for _, t := range typedefList { - t.Common().ByteSize = t.Type.Size() - } - }() - typedefs = &typedefList - } - - // Parse type from Entry. - // Must always set typeCache[off] before calling - // d.readType recursively, to handle circular types correctly. - var typ Type - - nextDepth := 0 - - // Get next child; set err if error happens. - next := func() *Entry { - if !e.Children { - return nil - } - // Only return direct children. - // Skip over composite entries that happen to be nested - // inside this one. Most DWARF generators wouldn't generate - // such a thing, but clang does. - // See golang.org/issue/6472. - for { - kid, err1 := r.Next() - if err1 != nil { - err = err1 - return nil - } - if kid == nil { - err = DecodeError{name, r.offset(), "unexpected end of DWARF entries"} - return nil - } - if kid.Tag == 0 { - if nextDepth > 0 { - nextDepth-- - continue - } - return nil - } - if kid.Children { - nextDepth++ - } - if nextDepth > 0 { - continue - } - return kid - } - } - - // Get Type referred to by Entry's AttrType field. - // Set err if error happens. Not having a type is an error. - typeOf := func(e *Entry) Type { - tval := e.Val(AttrType) - var t Type - switch toff := tval.(type) { - case Offset: - if t, err = d.readType(name, r.clone(), toff, typeCache, typedefs); err != nil { - return nil - } - case uint64: - if t, err = d.sigToType(toff); err != nil { - return nil - } - default: - // It appears that no Type means "void". - return new(VoidType) - } - return t - } - - switch e.Tag { - case TagArrayType: - // Multi-dimensional array. (DWARF v2 §5.4) - // Attributes: - // AttrType:subtype [required] - // AttrStrideSize: size in bits of each element of the array - // AttrByteSize: size of entire array - // Children: - // TagSubrangeType or TagEnumerationType giving one dimension. - // dimensions are in left to right order. - t := new(ArrayType) - typ = t - typeCache[off] = t - if t.Type = typeOf(e); err != nil { - goto Error - } - t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64) - - // Accumulate dimensions, - var dims []int64 - for kid := next(); kid != nil; kid = next() { - // TODO(rsc): Can also be TagEnumerationType - // but haven't seen that in the wild yet. - switch kid.Tag { - case TagSubrangeType: - count, ok := kid.Val(AttrCount).(int64) - if !ok { - // Old binaries may have an upper bound instead. - count, ok = kid.Val(AttrUpperBound).(int64) - if ok { - count++ // Length is one more than upper bound. - } else if len(dims) == 0 { - count = -1 // As in x[]. - } - } - dims = append(dims, count) - case TagEnumerationType: - err = DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"} - goto Error - } - } - if len(dims) == 0 { - // LLVM generates this for x[]. - dims = []int64{-1} - } - - t.Count = dims[0] - for i := len(dims) - 1; i >= 1; i-- { - t.Type = &ArrayType{Type: t.Type, Count: dims[i]} - } - - case TagBaseType: - // Basic type. (DWARF v2 §5.1) - // Attributes: - // AttrName: name of base type in programming language of the compilation unit [required] - // AttrEncoding: encoding value for type (encFloat etc) [required] - // AttrByteSize: size of type in bytes [required] - // AttrBitOffset: for sub-byte types, size in bits - // AttrBitSize: for sub-byte types, bit offset of high order bit in the AttrByteSize bytes - name, _ := e.Val(AttrName).(string) - enc, ok := e.Val(AttrEncoding).(int64) - if !ok { - err = DecodeError{name, e.Offset, "missing encoding attribute for " + name} - goto Error - } - switch enc { - default: - err = DecodeError{name, e.Offset, "unrecognized encoding attribute value"} - goto Error - - case encAddress: - typ = new(AddrType) - case encBoolean: - typ = new(BoolType) - case encComplexFloat: - typ = new(ComplexType) - if name == "complex" { - // clang writes out 'complex' instead of 'complex float' or 'complex double'. - // clang also writes out a byte size that we can use to distinguish. - // See issue 8694. - switch byteSize, _ := e.Val(AttrByteSize).(int64); byteSize { - case 8: - name = "complex float" - case 16: - name = "complex double" - } - } - case encFloat: - typ = new(FloatType) - case encSigned: - typ = new(IntType) - case encUnsigned: - typ = new(UintType) - case encSignedChar: - typ = new(CharType) - case encUnsignedChar: - typ = new(UcharType) - } - typeCache[off] = typ - t := typ.(interface { - Basic() *BasicType - }).Basic() - t.Name = name - t.BitSize, _ = e.Val(AttrBitSize).(int64) - t.BitOffset, _ = e.Val(AttrBitOffset).(int64) - - case TagClassType, TagStructType, TagUnionType: - // Structure, union, or class type. (DWARF v2 §5.5) - // Attributes: - // AttrName: name of struct, union, or class - // AttrByteSize: byte size [required] - // AttrDeclaration: if true, struct/union/class is incomplete - // Children: - // TagMember to describe one member. - // AttrName: name of member [required] - // AttrType: type of member [required] - // AttrByteSize: size in bytes - // AttrBitOffset: bit offset within bytes for bit fields - // AttrBitSize: bit size for bit fields - // AttrDataMemberLoc: location within struct [required for struct, class] - // There is much more to handle C++, all ignored for now. - t := new(StructType) - typ = t - typeCache[off] = t - switch e.Tag { - case TagClassType: - t.Kind = "class" - case TagStructType: - t.Kind = "struct" - case TagUnionType: - t.Kind = "union" - } - t.StructName, _ = e.Val(AttrName).(string) - t.Incomplete = e.Val(AttrDeclaration) != nil - t.Field = make([]*StructField, 0, 8) - var lastFieldType *Type - var lastFieldBitOffset int64 - for kid := next(); kid != nil; kid = next() { - if kid.Tag != TagMember { - continue - } - f := new(StructField) - if f.Type = typeOf(kid); err != nil { - goto Error - } - switch loc := kid.Val(AttrDataMemberLoc).(type) { - case []byte: - // TODO: Should have original compilation - // unit here, not unknownFormat. - b := makeBuf(d, unknownFormat{}, "location", 0, loc) - if b.uint8() != opPlusUconst { - err = DecodeError{name, kid.Offset, "unexpected opcode"} - goto Error - } - f.ByteOffset = int64(b.uint()) - if b.err != nil { - err = b.err - goto Error - } - case int64: - f.ByteOffset = loc - } - - haveBitOffset := false - f.Name, _ = kid.Val(AttrName).(string) - f.ByteSize, _ = kid.Val(AttrByteSize).(int64) - f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64) - f.BitSize, _ = kid.Val(AttrBitSize).(int64) - t.Field = append(t.Field, f) - - bito := f.BitOffset - if !haveBitOffset { - bito = f.ByteOffset * 8 - } - if bito == lastFieldBitOffset && t.Kind != "union" { - // Last field was zero width. Fix array length. - // (DWARF writes out 0-length arrays as if they were 1-length arrays.) - zeroArray(lastFieldType) - } - lastFieldType = &f.Type - lastFieldBitOffset = bito - } - if t.Kind != "union" { - b, ok := e.Val(AttrByteSize).(int64) - if ok && b*8 == lastFieldBitOffset { - // Final field must be zero width. Fix array length. - zeroArray(lastFieldType) - } - } - - case TagConstType, TagVolatileType, TagRestrictType: - // Type modifier (DWARF v2 §5.2) - // Attributes: - // AttrType: subtype - t := new(QualType) - typ = t - typeCache[off] = t - if t.Type = typeOf(e); err != nil { - goto Error - } - switch e.Tag { - case TagConstType: - t.Qual = "const" - case TagRestrictType: - t.Qual = "restrict" - case TagVolatileType: - t.Qual = "volatile" - } - - case TagEnumerationType: - // Enumeration type (DWARF v2 §5.6) - // Attributes: - // AttrName: enum name if any - // AttrByteSize: bytes required to represent largest value - // Children: - // TagEnumerator: - // AttrName: name of constant - // AttrConstValue: value of constant - t := new(EnumType) - typ = t - typeCache[off] = t - t.EnumName, _ = e.Val(AttrName).(string) - t.Val = make([]*EnumValue, 0, 8) - for kid := next(); kid != nil; kid = next() { - if kid.Tag == TagEnumerator { - f := new(EnumValue) - f.Name, _ = kid.Val(AttrName).(string) - f.Val, _ = kid.Val(AttrConstValue).(int64) - n := len(t.Val) - if n >= cap(t.Val) { - val := make([]*EnumValue, n, n*2) - copy(val, t.Val) - t.Val = val - } - t.Val = t.Val[0 : n+1] - t.Val[n] = f - } - } - - case TagPointerType: - // Type modifier (DWARF v2 §5.2) - // Attributes: - // AttrType: subtype [not required! void* has no AttrType] - // AttrAddrClass: address class [ignored] - t := new(PtrType) - typ = t - typeCache[off] = t - if e.Val(AttrType) == nil { - t.Type = &VoidType{} - break - } - t.Type = typeOf(e) - - case TagSubroutineType: - // Subroutine type. (DWARF v2 §5.7) - // Attributes: - // AttrType: type of return value if any - // AttrName: possible name of type [ignored] - // AttrPrototyped: whether used ANSI C prototype [ignored] - // Children: - // TagFormalParameter: typed parameter - // AttrType: type of parameter - // TagUnspecifiedParameter: final ... - t := new(FuncType) - typ = t - typeCache[off] = t - if t.ReturnType = typeOf(e); err != nil { - goto Error - } - t.ParamType = make([]Type, 0, 8) - for kid := next(); kid != nil; kid = next() { - var tkid Type - switch kid.Tag { - default: - continue - case TagFormalParameter: - if tkid = typeOf(kid); err != nil { - goto Error - } - case TagUnspecifiedParameters: - tkid = &DotDotDotType{} - } - t.ParamType = append(t.ParamType, tkid) - } - - case TagTypedef: - // Typedef (DWARF v2 §5.3) - // Attributes: - // AttrName: name [required] - // AttrType: type definition [required] - t := new(TypedefType) - typ = t - typeCache[off] = t - t.Name, _ = e.Val(AttrName).(string) - t.Type = typeOf(e) - - case TagUnspecifiedType: - // Unspecified type (DWARF v3 §5.2) - // Attributes: - // AttrName: name - t := new(UnspecifiedType) - typ = t - typeCache[off] = t - t.Name, _ = e.Val(AttrName).(string) - } - - if err != nil { - goto Error - } - - { - b, ok := e.Val(AttrByteSize).(int64) - if !ok { - b = -1 - switch t := typ.(type) { - case *TypedefType: - // Record that we need to resolve this - // type's size once the type graph is - // constructed. - *typedefs = append(*typedefs, t) - case *PtrType: - b = int64(addressSize) - } - } - typ.Common().ByteSize = b - } - return typ, nil - -Error: - // If the parse fails, take the type out of the cache - // so that the next call with this offset doesn't hit - // the cache and return success. - delete(typeCache, off) - return nil, err -} - -func zeroArray(t *Type) { - if t == nil { - return - } - at, ok := (*t).(*ArrayType) - if !ok || at.Type.Size() == 0 { - return - } - // Make a copy to avoid invalidating typeCache. - tt := *at - tt.Count = 0 - *t = &tt -} diff --git a/odiglet/pkg/allocator/debug/dwarf/type_test.go b/odiglet/pkg/allocator/debug/dwarf/type_test.go deleted file mode 100644 index 6c06731ea1..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/type_test.go +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package dwarf_test - -import ( - . "debug/dwarf" - "debug/elf" - "debug/macho" - "debug/pe" - "testing" -) - -var typedefTests = map[string]string{ - "t_ptr_volatile_int": "*volatile int", - "t_ptr_const_char": "*const char", - "t_long": "long int", - "t_ushort": "short unsigned int", - "t_func_int_of_float_double": "func(float, double) int", - "t_ptr_func_int_of_float_double": "*func(float, double) int", - "t_ptr_func_int_of_float_complex": "*func(complex float) int", - "t_ptr_func_int_of_double_complex": "*func(complex double) int", - "t_ptr_func_int_of_long_double_complex": "*func(complex long double) int", - "t_func_ptr_int_of_char_schar_uchar": "func(char, signed char, unsigned char) *int", - "t_func_void_of_char": "func(char) void", - "t_func_void_of_void": "func() void", - "t_func_void_of_ptr_char_dots": "func(*char, ...) void", - "t_my_struct": "struct my_struct {vi volatile int@0; x char@4 : 1@7; y int@4 : 4@27; z [0]int@8; array [40]long long int@8; zz [0]int@328}", - "t_my_struct1": "struct my_struct1 {zz [1]int@0}", - "t_my_union": "union my_union {vi volatile int@0; x char@0 : 1@7; y int@0 : 4@28; array [40]long long int@0}", - "t_my_enum": "enum my_enum {e1=1; e2=2; e3=-5; e4=1000000000000000}", - "t_my_list": "struct list {val short int@0; next *t_my_list@8}", - "t_my_tree": "struct tree {left *struct tree@0; right *struct tree@8; val long long unsigned int@16}", -} - -// As Apple converts gcc to a clang-based front end -// they keep breaking the DWARF output. This map lists the -// conversion from real answer to Apple answer. -var machoBug = map[string]string{ - "func(*char, ...) void": "func(*char) void", - "enum my_enum {e1=1; e2=2; e3=-5; e4=1000000000000000}": "enum my_enum {e1=1; e2=2; e3=-5; e4=-1530494976}", -} - -func elfData(t *testing.T, name string) *Data { - f, err := elf.Open(name) - if err != nil { - t.Fatal(err) - } - - d, err := f.DWARF() - if err != nil { - t.Fatal(err) - } - return d -} - -func machoData(t *testing.T, name string) *Data { - f, err := macho.Open(name) - if err != nil { - t.Fatal(err) - } - - d, err := f.DWARF() - if err != nil { - t.Fatal(err) - } - return d -} - -func peData(t *testing.T, name string) *Data { - f, err := pe.Open(name) - if err != nil { - t.Fatal(err) - } - - d, err := f.DWARF() - if err != nil { - t.Fatal(err) - } - return d -} - -func TestTypedefsELF(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf"), "elf") } - -func TestTypedefsMachO(t *testing.T) { - testTypedefs(t, machoData(t, "testdata/typedef.macho"), "macho") -} - -func TestTypedefsELFDwarf4(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf4"), "elf") } - -func testTypedefs(t *testing.T, d *Data, kind string) { - r := d.Reader() - seen := make(map[string]bool) - for { - e, err := r.Next() - if err != nil { - t.Fatal("r.Next:", err) - } - if e == nil { - break - } - if e.Tag == TagTypedef { - typ, err := d.Type(e.Offset) - if err != nil { - t.Fatal("d.Type:", err) - } - t1 := typ.(*TypedefType) - var typstr string - if ts, ok := t1.Type.(*StructType); ok { - typstr = ts.Defn() - } else { - typstr = t1.Type.String() - } - - if want, ok := typedefTests[t1.Name]; ok { - if seen[t1.Name] { - t.Errorf("multiple definitions for %s", t1.Name) - } - seen[t1.Name] = true - if typstr != want && (kind != "macho" || typstr != machoBug[want]) { - t.Errorf("%s:\n\thave %s\n\twant %s", t1.Name, typstr, want) - } - } - } - if e.Tag != TagCompileUnit { - r.SkipChildren() - } - } - - for k := range typedefTests { - if !seen[k] { - t.Errorf("missing %s", k) - } - } -} - -func TestTypedefCycle(t *testing.T) { - // See issue #13039: reading a typedef cycle starting from a - // different place than the size needed to be computed from - // used to crash. - // - // cycle.elf built with GCC 4.8.4: - // gcc -g -c -o cycle.elf cycle.c - d := elfData(t, "testdata/cycle.elf") - r := d.Reader() - offsets := []Offset{} - for { - e, err := r.Next() - if err != nil { - t.Fatal("r.Next:", err) - } - if e == nil { - break - } - switch e.Tag { - case TagBaseType, TagTypedef, TagPointerType, TagStructType: - offsets = append(offsets, e.Offset) - } - } - - // Parse each type with a fresh type cache. - for _, offset := range offsets { - d := elfData(t, "testdata/cycle.elf") - _, err := d.Type(offset) - if err != nil { - t.Fatalf("d.Type(0x%x): %s", offset, err) - } - } -} diff --git a/odiglet/pkg/allocator/debug/dwarf/typeunit.go b/odiglet/pkg/allocator/debug/dwarf/typeunit.go deleted file mode 100644 index 76b357ce28..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/typeunit.go +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package dwarf - -import ( - "fmt" - "strconv" -) - -// Parse the type units stored in a DWARF4 .debug_types section. Each -// type unit defines a single primary type and an 8-byte signature. -// Other sections may then use formRefSig8 to refer to the type. - -// The typeUnit format is a single type with a signature. It holds -// the same data as a compilation unit. -type typeUnit struct { - unit - toff Offset // Offset to signature type within data. - name string // Name of .debug_type section. - cache Type // Cache the type, nil to start. -} - -// Parse a .debug_types section. -func (d *Data) parseTypes(name string, types []byte) error { - b := makeBuf(d, unknownFormat{}, name, 0, types) - for len(b.data) > 0 { - base := b.off - n, dwarf64 := b.unitLength() - if n != Offset(uint32(n)) { - b.error("type unit length overflow") - return b.err - } - hdroff := b.off - vers := int(b.uint16()) - if vers != 4 { - b.error("unsupported DWARF version " + strconv.Itoa(vers)) - return b.err - } - var ao uint64 - if !dwarf64 { - ao = uint64(b.uint32()) - } else { - ao = b.uint64() - } - atable, err := d.parseAbbrev(ao, vers) - if err != nil { - return err - } - asize := b.uint8() - sig := b.uint64() - - var toff uint32 - if !dwarf64 { - toff = b.uint32() - } else { - to64 := b.uint64() - if to64 != uint64(uint32(to64)) { - b.error("type unit type offset overflow") - return b.err - } - toff = uint32(to64) - } - - boff := b.off - d.typeSigs[sig] = &typeUnit{ - unit: unit{ - base: base, - off: boff, - data: b.bytes(int(n - (b.off - hdroff))), - atable: atable, - asize: int(asize), - vers: vers, - is64: dwarf64, - }, - toff: Offset(toff), - name: name, - } - if b.err != nil { - return b.err - } - } - return nil -} - -// Return the type for a type signature. -func (d *Data) sigToType(sig uint64) (Type, error) { - tu := d.typeSigs[sig] - if tu == nil { - return nil, fmt.Errorf("no type unit with signature %v", sig) - } - if tu.cache != nil { - return tu.cache, nil - } - - b := makeBuf(d, tu, tu.name, tu.off, tu.data) - r := &typeUnitReader{d: d, tu: tu, b: b} - t, err := d.readType(tu.name, r, tu.toff, make(map[Offset]Type), nil) - if err != nil { - return nil, err - } - - tu.cache = t - return t, nil -} - -// typeUnitReader is a typeReader for a tagTypeUnit. -type typeUnitReader struct { - d *Data - tu *typeUnit - b buf - err error -} - -// Seek to a new position in the type unit. -func (tur *typeUnitReader) Seek(off Offset) { - tur.err = nil - doff := off - tur.tu.off - if doff < 0 || doff >= Offset(len(tur.tu.data)) { - tur.err = fmt.Errorf("%s: offset %d out of range; max %d", tur.tu.name, doff, len(tur.tu.data)) - return - } - tur.b = makeBuf(tur.d, tur.tu, tur.tu.name, off, tur.tu.data[doff:]) -} - -// AddressSize returns the size in bytes of addresses in the current type unit. -func (tur *typeUnitReader) AddressSize() int { - return tur.tu.unit.asize -} - -// Next reads the next Entry from the type unit. -func (tur *typeUnitReader) Next() (*Entry, error) { - if tur.err != nil { - return nil, tur.err - } - if len(tur.tu.data) == 0 { - return nil, nil - } - e := tur.b.entry(tur.tu.atable, tur.tu.base) - if tur.b.err != nil { - tur.err = tur.b.err - return nil, tur.err - } - return e, nil -} - -// clone returns a new reader for the type unit. -func (tur *typeUnitReader) clone() typeReader { - return &typeUnitReader{ - d: tur.d, - tu: tur.tu, - b: makeBuf(tur.d, tur.tu, tur.tu.name, tur.tu.off, tur.tu.data), - } -} - -// offset returns the current offset. -func (tur *typeUnitReader) offset() Offset { - return tur.b.off -} diff --git a/odiglet/pkg/allocator/debug/dwarf/unit.go b/odiglet/pkg/allocator/debug/dwarf/unit.go deleted file mode 100644 index 98024ca1f8..0000000000 --- a/odiglet/pkg/allocator/debug/dwarf/unit.go +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package dwarf - -import ( - "sort" - "strconv" -) - -// DWARF debug info is split into a sequence of compilation units. -// Each unit has its own abbreviation table and address size. - -type unit struct { - base Offset // byte offset of header within the aggregate info - off Offset // byte offset of data within the aggregate info - data []byte - atable abbrevTable - asize int - vers int - is64 bool // True for 64-bit DWARF format -} - -// Implement the dataFormat interface. - -func (u *unit) version() int { - return u.vers -} - -func (u *unit) dwarf64() (bool, bool) { - return u.is64, true -} - -func (u *unit) addrsize() int { - return u.asize -} - -func (d *Data) parseUnits() ([]unit, error) { - // Count units. - nunit := 0 - b := makeBuf(d, unknownFormat{}, "info", 0, d.info) - for len(b.data) > 0 { - len, _ := b.unitLength() - if len != Offset(uint32(len)) { - b.error("unit length overflow") - break - } - b.skip(int(len)) - nunit++ - } - if b.err != nil { - return nil, b.err - } - - // Again, this time writing them down. - b = makeBuf(d, unknownFormat{}, "info", 0, d.info) - units := make([]unit, nunit) - for i := range units { - u := &units[i] - u.base = b.off - var n Offset - n, u.is64 = b.unitLength() - dataOff := b.off - vers := b.uint16() - if vers != 2 && vers != 3 && vers != 4 { - b.error("unsupported DWARF version " + strconv.Itoa(int(vers))) - break - } - u.vers = int(vers) - var abbrevOff uint64 - if u.is64 { - abbrevOff = b.uint64() - } else { - abbrevOff = uint64(b.uint32()) - } - atable, err := d.parseAbbrev(abbrevOff, u.vers) - if err != nil { - if b.err == nil { - b.err = err - } - break - } - u.atable = atable - u.asize = int(b.uint8()) - u.off = b.off - u.data = b.bytes(int(n - (b.off - dataOff))) - } - if b.err != nil { - return nil, b.err - } - return units, nil -} - -// offsetToUnit returns the index of the unit containing offset off. -// It returns -1 if no unit contains this offset. -func (d *Data) offsetToUnit(off Offset) int { - // Find the unit after off - next := sort.Search(len(d.unit), func(i int) bool { - return d.unit[i].off > off - }) - if next == 0 { - return -1 - } - u := &d.unit[next-1] - if u.off <= off && off < u.off+Offset(len(u.data)) { - return next - 1 - } - return -1 -} diff --git a/odiglet/pkg/allocator/debug/elf/elf.go b/odiglet/pkg/allocator/debug/elf/elf.go deleted file mode 100644 index 18324a34d8..0000000000 --- a/odiglet/pkg/allocator/debug/elf/elf.go +++ /dev/null @@ -1,3000 +0,0 @@ -/* - * ELF constants and data structures - * - * Derived from: - * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $ - * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $ - * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $ - * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $ - * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $ - * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $ - * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $ - * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $ - * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $ - * "System V ABI" (http://www.sco.com/developers/gabi/latest/ch4.eheader.html) - * "ELF for the ARM® 64-bit Architecture (AArch64)" (ARM IHI 0056B) - * "RISC-V ELF psABI specification" (https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md) - * llvm/BinaryFormat/ELF.h - ELF constants and structures - * - * Copyright (c) 1996-1998 John D. Polstra. All rights reserved. - * Copyright (c) 2001 David E. O'Brien - * Portions Copyright 2009 The Go Authors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -package elf - -import "strconv" - -/* - * Constants - */ - -// Indexes into the Header.Ident array. -const ( - EI_CLASS = 4 /* Class of machine. */ - EI_DATA = 5 /* Data format. */ - EI_VERSION = 6 /* ELF format version. */ - EI_OSABI = 7 /* Operating system / ABI identification */ - EI_ABIVERSION = 8 /* ABI version */ - EI_PAD = 9 /* Start of padding (per SVR4 ABI). */ - EI_NIDENT = 16 /* Size of e_ident array. */ -) - -// Initial magic number for ELF files. -const ELFMAG = "\177ELF" - -// Version is found in Header.Ident[EI_VERSION] and Header.Version. -type Version byte - -const ( - EV_NONE Version = 0 - EV_CURRENT Version = 1 -) - -var versionStrings = []intName{ - {0, "EV_NONE"}, - {1, "EV_CURRENT"}, -} - -func (i Version) String() string { return stringName(uint32(i), versionStrings, false) } -func (i Version) GoString() string { return stringName(uint32(i), versionStrings, true) } - -// Class is found in Header.Ident[EI_CLASS] and Header.Class. -type Class byte - -const ( - ELFCLASSNONE Class = 0 /* Unknown class. */ - ELFCLASS32 Class = 1 /* 32-bit architecture. */ - ELFCLASS64 Class = 2 /* 64-bit architecture. */ -) - -var classStrings = []intName{ - {0, "ELFCLASSNONE"}, - {1, "ELFCLASS32"}, - {2, "ELFCLASS64"}, -} - -func (i Class) String() string { return stringName(uint32(i), classStrings, false) } -func (i Class) GoString() string { return stringName(uint32(i), classStrings, true) } - -// Data is found in Header.Ident[EI_DATA] and Header.Data. -type Data byte - -const ( - ELFDATANONE Data = 0 /* Unknown data format. */ - ELFDATA2LSB Data = 1 /* 2's complement little-endian. */ - ELFDATA2MSB Data = 2 /* 2's complement big-endian. */ -) - -var dataStrings = []intName{ - {0, "ELFDATANONE"}, - {1, "ELFDATA2LSB"}, - {2, "ELFDATA2MSB"}, -} - -func (i Data) String() string { return stringName(uint32(i), dataStrings, false) } -func (i Data) GoString() string { return stringName(uint32(i), dataStrings, true) } - -// OSABI is found in Header.Ident[EI_OSABI] and Header.OSABI. -type OSABI byte - -const ( - ELFOSABI_NONE OSABI = 0 /* UNIX System V ABI */ - ELFOSABI_HPUX OSABI = 1 /* HP-UX operating system */ - ELFOSABI_NETBSD OSABI = 2 /* NetBSD */ - ELFOSABI_LINUX OSABI = 3 /* GNU/Linux */ - ELFOSABI_HURD OSABI = 4 /* GNU/Hurd */ - ELFOSABI_86OPEN OSABI = 5 /* 86Open common IA32 ABI */ - ELFOSABI_SOLARIS OSABI = 6 /* Solaris */ - ELFOSABI_AIX OSABI = 7 /* AIX */ - ELFOSABI_IRIX OSABI = 8 /* IRIX */ - ELFOSABI_FREEBSD OSABI = 9 /* FreeBSD */ - ELFOSABI_TRU64 OSABI = 10 /* TRU64 UNIX */ - ELFOSABI_MODESTO OSABI = 11 /* Novell Modesto */ - ELFOSABI_OPENBSD OSABI = 12 /* OpenBSD */ - ELFOSABI_OPENVMS OSABI = 13 /* Open VMS */ - ELFOSABI_NSK OSABI = 14 /* HP Non-Stop Kernel */ - ELFOSABI_AROS OSABI = 15 /* Amiga Research OS */ - ELFOSABI_FENIXOS OSABI = 16 /* The FenixOS highly scalable multi-core OS */ - ELFOSABI_CLOUDABI OSABI = 17 /* Nuxi CloudABI */ - ELFOSABI_ARM OSABI = 97 /* ARM */ - ELFOSABI_STANDALONE OSABI = 255 /* Standalone (embedded) application */ -) - -var osabiStrings = []intName{ - {0, "ELFOSABI_NONE"}, - {1, "ELFOSABI_HPUX"}, - {2, "ELFOSABI_NETBSD"}, - {3, "ELFOSABI_LINUX"}, - {4, "ELFOSABI_HURD"}, - {5, "ELFOSABI_86OPEN"}, - {6, "ELFOSABI_SOLARIS"}, - {7, "ELFOSABI_AIX"}, - {8, "ELFOSABI_IRIX"}, - {9, "ELFOSABI_FREEBSD"}, - {10, "ELFOSABI_TRU64"}, - {11, "ELFOSABI_MODESTO"}, - {12, "ELFOSABI_OPENBSD"}, - {13, "ELFOSABI_OPENVMS"}, - {14, "ELFOSABI_NSK"}, - {15, "ELFOSABI_AROS"}, - {16, "ELFOSABI_FENIXOS"}, - {17, "ELFOSABI_CLOUDABI"}, - {97, "ELFOSABI_ARM"}, - {255, "ELFOSABI_STANDALONE"}, -} - -func (i OSABI) String() string { return stringName(uint32(i), osabiStrings, false) } -func (i OSABI) GoString() string { return stringName(uint32(i), osabiStrings, true) } - -// Type is found in Header.Type. -type Type uint16 - -const ( - ET_NONE Type = 0 /* Unknown type. */ - ET_REL Type = 1 /* Relocatable. */ - ET_EXEC Type = 2 /* Executable. */ - ET_DYN Type = 3 /* Shared object. */ - ET_CORE Type = 4 /* Core file. */ - ET_LOOS Type = 0xfe00 /* First operating system specific. */ - ET_HIOS Type = 0xfeff /* Last operating system-specific. */ - ET_LOPROC Type = 0xff00 /* First processor-specific. */ - ET_HIPROC Type = 0xffff /* Last processor-specific. */ -) - -var typeStrings = []intName{ - {0, "ET_NONE"}, - {1, "ET_REL"}, - {2, "ET_EXEC"}, - {3, "ET_DYN"}, - {4, "ET_CORE"}, - {0xfe00, "ET_LOOS"}, - {0xfeff, "ET_HIOS"}, - {0xff00, "ET_LOPROC"}, - {0xffff, "ET_HIPROC"}, -} - -func (i Type) String() string { return stringName(uint32(i), typeStrings, false) } -func (i Type) GoString() string { return stringName(uint32(i), typeStrings, true) } - -// Machine is found in Header.Machine. -type Machine uint16 - -const ( - EM_NONE Machine = 0 /* Unknown machine. */ - EM_M32 Machine = 1 /* AT&T WE32100. */ - EM_SPARC Machine = 2 /* Sun SPARC. */ - EM_386 Machine = 3 /* Intel i386. */ - EM_68K Machine = 4 /* Motorola 68000. */ - EM_88K Machine = 5 /* Motorola 88000. */ - EM_860 Machine = 7 /* Intel i860. */ - EM_MIPS Machine = 8 /* MIPS R3000 Big-Endian only. */ - EM_S370 Machine = 9 /* IBM System/370. */ - EM_MIPS_RS3_LE Machine = 10 /* MIPS R3000 Little-Endian. */ - EM_PARISC Machine = 15 /* HP PA-RISC. */ - EM_VPP500 Machine = 17 /* Fujitsu VPP500. */ - EM_SPARC32PLUS Machine = 18 /* SPARC v8plus. */ - EM_960 Machine = 19 /* Intel 80960. */ - EM_PPC Machine = 20 /* PowerPC 32-bit. */ - EM_PPC64 Machine = 21 /* PowerPC 64-bit. */ - EM_S390 Machine = 22 /* IBM System/390. */ - EM_V800 Machine = 36 /* NEC V800. */ - EM_FR20 Machine = 37 /* Fujitsu FR20. */ - EM_RH32 Machine = 38 /* TRW RH-32. */ - EM_RCE Machine = 39 /* Motorola RCE. */ - EM_ARM Machine = 40 /* ARM. */ - EM_SH Machine = 42 /* Hitachi SH. */ - EM_SPARCV9 Machine = 43 /* SPARC v9 64-bit. */ - EM_TRICORE Machine = 44 /* Siemens TriCore embedded processor. */ - EM_ARC Machine = 45 /* Argonaut RISC Core. */ - EM_H8_300 Machine = 46 /* Hitachi H8/300. */ - EM_H8_300H Machine = 47 /* Hitachi H8/300H. */ - EM_H8S Machine = 48 /* Hitachi H8S. */ - EM_H8_500 Machine = 49 /* Hitachi H8/500. */ - EM_IA_64 Machine = 50 /* Intel IA-64 Processor. */ - EM_MIPS_X Machine = 51 /* Stanford MIPS-X. */ - EM_COLDFIRE Machine = 52 /* Motorola ColdFire. */ - EM_68HC12 Machine = 53 /* Motorola M68HC12. */ - EM_MMA Machine = 54 /* Fujitsu MMA. */ - EM_PCP Machine = 55 /* Siemens PCP. */ - EM_NCPU Machine = 56 /* Sony nCPU. */ - EM_NDR1 Machine = 57 /* Denso NDR1 microprocessor. */ - EM_STARCORE Machine = 58 /* Motorola Star*Core processor. */ - EM_ME16 Machine = 59 /* Toyota ME16 processor. */ - EM_ST100 Machine = 60 /* STMicroelectronics ST100 processor. */ - EM_TINYJ Machine = 61 /* Advanced Logic Corp. TinyJ processor. */ - EM_X86_64 Machine = 62 /* Advanced Micro Devices x86-64 */ - EM_PDSP Machine = 63 /* Sony DSP Processor */ - EM_PDP10 Machine = 64 /* Digital Equipment Corp. PDP-10 */ - EM_PDP11 Machine = 65 /* Digital Equipment Corp. PDP-11 */ - EM_FX66 Machine = 66 /* Siemens FX66 microcontroller */ - EM_ST9PLUS Machine = 67 /* STMicroelectronics ST9+ 8/16 bit microcontroller */ - EM_ST7 Machine = 68 /* STMicroelectronics ST7 8-bit microcontroller */ - EM_68HC16 Machine = 69 /* Motorola MC68HC16 Microcontroller */ - EM_68HC11 Machine = 70 /* Motorola MC68HC11 Microcontroller */ - EM_68HC08 Machine = 71 /* Motorola MC68HC08 Microcontroller */ - EM_68HC05 Machine = 72 /* Motorola MC68HC05 Microcontroller */ - EM_SVX Machine = 73 /* Silicon Graphics SVx */ - EM_ST19 Machine = 74 /* STMicroelectronics ST19 8-bit microcontroller */ - EM_VAX Machine = 75 /* Digital VAX */ - EM_CRIS Machine = 76 /* Axis Communications 32-bit embedded processor */ - EM_JAVELIN Machine = 77 /* Infineon Technologies 32-bit embedded processor */ - EM_FIREPATH Machine = 78 /* Element 14 64-bit DSP Processor */ - EM_ZSP Machine = 79 /* LSI Logic 16-bit DSP Processor */ - EM_MMIX Machine = 80 /* Donald Knuth's educational 64-bit processor */ - EM_HUANY Machine = 81 /* Harvard University machine-independent object files */ - EM_PRISM Machine = 82 /* SiTera Prism */ - EM_AVR Machine = 83 /* Atmel AVR 8-bit microcontroller */ - EM_FR30 Machine = 84 /* Fujitsu FR30 */ - EM_D10V Machine = 85 /* Mitsubishi D10V */ - EM_D30V Machine = 86 /* Mitsubishi D30V */ - EM_V850 Machine = 87 /* NEC v850 */ - EM_M32R Machine = 88 /* Mitsubishi M32R */ - EM_MN10300 Machine = 89 /* Matsushita MN10300 */ - EM_MN10200 Machine = 90 /* Matsushita MN10200 */ - EM_PJ Machine = 91 /* picoJava */ - EM_OPENRISC Machine = 92 /* OpenRISC 32-bit embedded processor */ - EM_ARC_COMPACT Machine = 93 /* ARC International ARCompact processor (old spelling/synonym: EM_ARC_A5) */ - EM_XTENSA Machine = 94 /* Tensilica Xtensa Architecture */ - EM_VIDEOCORE Machine = 95 /* Alphamosaic VideoCore processor */ - EM_TMM_GPP Machine = 96 /* Thompson Multimedia General Purpose Processor */ - EM_NS32K Machine = 97 /* National Semiconductor 32000 series */ - EM_TPC Machine = 98 /* Tenor Network TPC processor */ - EM_SNP1K Machine = 99 /* Trebia SNP 1000 processor */ - EM_ST200 Machine = 100 /* STMicroelectronics (www.st.com) ST200 microcontroller */ - EM_IP2K Machine = 101 /* Ubicom IP2xxx microcontroller family */ - EM_MAX Machine = 102 /* MAX Processor */ - EM_CR Machine = 103 /* National Semiconductor CompactRISC microprocessor */ - EM_F2MC16 Machine = 104 /* Fujitsu F2MC16 */ - EM_MSP430 Machine = 105 /* Texas Instruments embedded microcontroller msp430 */ - EM_BLACKFIN Machine = 106 /* Analog Devices Blackfin (DSP) processor */ - EM_SE_C33 Machine = 107 /* S1C33 Family of Seiko Epson processors */ - EM_SEP Machine = 108 /* Sharp embedded microprocessor */ - EM_ARCA Machine = 109 /* Arca RISC Microprocessor */ - EM_UNICORE Machine = 110 /* Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University */ - EM_EXCESS Machine = 111 /* eXcess: 16/32/64-bit configurable embedded CPU */ - EM_DXP Machine = 112 /* Icera Semiconductor Inc. Deep Execution Processor */ - EM_ALTERA_NIOS2 Machine = 113 /* Altera Nios II soft-core processor */ - EM_CRX Machine = 114 /* National Semiconductor CompactRISC CRX microprocessor */ - EM_XGATE Machine = 115 /* Motorola XGATE embedded processor */ - EM_C166 Machine = 116 /* Infineon C16x/XC16x processor */ - EM_M16C Machine = 117 /* Renesas M16C series microprocessors */ - EM_DSPIC30F Machine = 118 /* Microchip Technology dsPIC30F Digital Signal Controller */ - EM_CE Machine = 119 /* Freescale Communication Engine RISC core */ - EM_M32C Machine = 120 /* Renesas M32C series microprocessors */ - EM_TSK3000 Machine = 131 /* Altium TSK3000 core */ - EM_RS08 Machine = 132 /* Freescale RS08 embedded processor */ - EM_SHARC Machine = 133 /* Analog Devices SHARC family of 32-bit DSP processors */ - EM_ECOG2 Machine = 134 /* Cyan Technology eCOG2 microprocessor */ - EM_SCORE7 Machine = 135 /* Sunplus S+core7 RISC processor */ - EM_DSP24 Machine = 136 /* New Japan Radio (NJR) 24-bit DSP Processor */ - EM_VIDEOCORE3 Machine = 137 /* Broadcom VideoCore III processor */ - EM_LATTICEMICO32 Machine = 138 /* RISC processor for Lattice FPGA architecture */ - EM_SE_C17 Machine = 139 /* Seiko Epson C17 family */ - EM_TI_C6000 Machine = 140 /* The Texas Instruments TMS320C6000 DSP family */ - EM_TI_C2000 Machine = 141 /* The Texas Instruments TMS320C2000 DSP family */ - EM_TI_C5500 Machine = 142 /* The Texas Instruments TMS320C55x DSP family */ - EM_TI_ARP32 Machine = 143 /* Texas Instruments Application Specific RISC Processor, 32bit fetch */ - EM_TI_PRU Machine = 144 /* Texas Instruments Programmable Realtime Unit */ - EM_MMDSP_PLUS Machine = 160 /* STMicroelectronics 64bit VLIW Data Signal Processor */ - EM_CYPRESS_M8C Machine = 161 /* Cypress M8C microprocessor */ - EM_R32C Machine = 162 /* Renesas R32C series microprocessors */ - EM_TRIMEDIA Machine = 163 /* NXP Semiconductors TriMedia architecture family */ - EM_QDSP6 Machine = 164 /* QUALCOMM DSP6 Processor */ - EM_8051 Machine = 165 /* Intel 8051 and variants */ - EM_STXP7X Machine = 166 /* STMicroelectronics STxP7x family of configurable and extensible RISC processors */ - EM_NDS32 Machine = 167 /* Andes Technology compact code size embedded RISC processor family */ - EM_ECOG1 Machine = 168 /* Cyan Technology eCOG1X family */ - EM_ECOG1X Machine = 168 /* Cyan Technology eCOG1X family */ - EM_MAXQ30 Machine = 169 /* Dallas Semiconductor MAXQ30 Core Micro-controllers */ - EM_XIMO16 Machine = 170 /* New Japan Radio (NJR) 16-bit DSP Processor */ - EM_MANIK Machine = 171 /* M2000 Reconfigurable RISC Microprocessor */ - EM_CRAYNV2 Machine = 172 /* Cray Inc. NV2 vector architecture */ - EM_RX Machine = 173 /* Renesas RX family */ - EM_METAG Machine = 174 /* Imagination Technologies META processor architecture */ - EM_MCST_ELBRUS Machine = 175 /* MCST Elbrus general purpose hardware architecture */ - EM_ECOG16 Machine = 176 /* Cyan Technology eCOG16 family */ - EM_CR16 Machine = 177 /* National Semiconductor CompactRISC CR16 16-bit microprocessor */ - EM_ETPU Machine = 178 /* Freescale Extended Time Processing Unit */ - EM_SLE9X Machine = 179 /* Infineon Technologies SLE9X core */ - EM_L10M Machine = 180 /* Intel L10M */ - EM_K10M Machine = 181 /* Intel K10M */ - EM_AARCH64 Machine = 183 /* ARM 64-bit Architecture (AArch64) */ - EM_AVR32 Machine = 185 /* Atmel Corporation 32-bit microprocessor family */ - EM_STM8 Machine = 186 /* STMicroeletronics STM8 8-bit microcontroller */ - EM_TILE64 Machine = 187 /* Tilera TILE64 multicore architecture family */ - EM_TILEPRO Machine = 188 /* Tilera TILEPro multicore architecture family */ - EM_MICROBLAZE Machine = 189 /* Xilinx MicroBlaze 32-bit RISC soft processor core */ - EM_CUDA Machine = 190 /* NVIDIA CUDA architecture */ - EM_TILEGX Machine = 191 /* Tilera TILE-Gx multicore architecture family */ - EM_CLOUDSHIELD Machine = 192 /* CloudShield architecture family */ - EM_COREA_1ST Machine = 193 /* KIPO-KAIST Core-A 1st generation processor family */ - EM_COREA_2ND Machine = 194 /* KIPO-KAIST Core-A 2nd generation processor family */ - EM_ARC_COMPACT2 Machine = 195 /* Synopsys ARCompact V2 */ - EM_OPEN8 Machine = 196 /* Open8 8-bit RISC soft processor core */ - EM_RL78 Machine = 197 /* Renesas RL78 family */ - EM_VIDEOCORE5 Machine = 198 /* Broadcom VideoCore V processor */ - EM_78KOR Machine = 199 /* Renesas 78KOR family */ - EM_56800EX Machine = 200 /* Freescale 56800EX Digital Signal Controller (DSC) */ - EM_BA1 Machine = 201 /* Beyond BA1 CPU architecture */ - EM_BA2 Machine = 202 /* Beyond BA2 CPU architecture */ - EM_XCORE Machine = 203 /* XMOS xCORE processor family */ - EM_MCHP_PIC Machine = 204 /* Microchip 8-bit PIC(r) family */ - EM_INTEL205 Machine = 205 /* Reserved by Intel */ - EM_INTEL206 Machine = 206 /* Reserved by Intel */ - EM_INTEL207 Machine = 207 /* Reserved by Intel */ - EM_INTEL208 Machine = 208 /* Reserved by Intel */ - EM_INTEL209 Machine = 209 /* Reserved by Intel */ - EM_KM32 Machine = 210 /* KM211 KM32 32-bit processor */ - EM_KMX32 Machine = 211 /* KM211 KMX32 32-bit processor */ - EM_KMX16 Machine = 212 /* KM211 KMX16 16-bit processor */ - EM_KMX8 Machine = 213 /* KM211 KMX8 8-bit processor */ - EM_KVARC Machine = 214 /* KM211 KVARC processor */ - EM_CDP Machine = 215 /* Paneve CDP architecture family */ - EM_COGE Machine = 216 /* Cognitive Smart Memory Processor */ - EM_COOL Machine = 217 /* Bluechip Systems CoolEngine */ - EM_NORC Machine = 218 /* Nanoradio Optimized RISC */ - EM_CSR_KALIMBA Machine = 219 /* CSR Kalimba architecture family */ - EM_Z80 Machine = 220 /* Zilog Z80 */ - EM_VISIUM Machine = 221 /* Controls and Data Services VISIUMcore processor */ - EM_FT32 Machine = 222 /* FTDI Chip FT32 high performance 32-bit RISC architecture */ - EM_MOXIE Machine = 223 /* Moxie processor family */ - EM_AMDGPU Machine = 224 /* AMD GPU architecture */ - EM_RISCV Machine = 243 /* RISC-V */ - EM_LANAI Machine = 244 /* Lanai 32-bit processor */ - EM_BPF Machine = 247 /* Linux BPF – in-kernel virtual machine */ - - /* Non-standard or deprecated. */ - EM_486 Machine = 6 /* Intel i486. */ - EM_MIPS_RS4_BE Machine = 10 /* MIPS R4000 Big-Endian */ - EM_ALPHA_STD Machine = 41 /* Digital Alpha (standard value). */ - EM_ALPHA Machine = 0x9026 /* Alpha (written in the absence of an ABI) */ -) - -var machineStrings = []intName{ - {0, "EM_NONE"}, - {1, "EM_M32"}, - {2, "EM_SPARC"}, - {3, "EM_386"}, - {4, "EM_68K"}, - {5, "EM_88K"}, - {7, "EM_860"}, - {8, "EM_MIPS"}, - {9, "EM_S370"}, - {10, "EM_MIPS_RS3_LE"}, - {15, "EM_PARISC"}, - {17, "EM_VPP500"}, - {18, "EM_SPARC32PLUS"}, - {19, "EM_960"}, - {20, "EM_PPC"}, - {21, "EM_PPC64"}, - {22, "EM_S390"}, - {36, "EM_V800"}, - {37, "EM_FR20"}, - {38, "EM_RH32"}, - {39, "EM_RCE"}, - {40, "EM_ARM"}, - {42, "EM_SH"}, - {43, "EM_SPARCV9"}, - {44, "EM_TRICORE"}, - {45, "EM_ARC"}, - {46, "EM_H8_300"}, - {47, "EM_H8_300H"}, - {48, "EM_H8S"}, - {49, "EM_H8_500"}, - {50, "EM_IA_64"}, - {51, "EM_MIPS_X"}, - {52, "EM_COLDFIRE"}, - {53, "EM_68HC12"}, - {54, "EM_MMA"}, - {55, "EM_PCP"}, - {56, "EM_NCPU"}, - {57, "EM_NDR1"}, - {58, "EM_STARCORE"}, - {59, "EM_ME16"}, - {60, "EM_ST100"}, - {61, "EM_TINYJ"}, - {62, "EM_X86_64"}, - {63, "EM_PDSP"}, - {64, "EM_PDP10"}, - {65, "EM_PDP11"}, - {66, "EM_FX66"}, - {67, "EM_ST9PLUS"}, - {68, "EM_ST7"}, - {69, "EM_68HC16"}, - {70, "EM_68HC11"}, - {71, "EM_68HC08"}, - {72, "EM_68HC05"}, - {73, "EM_SVX"}, - {74, "EM_ST19"}, - {75, "EM_VAX"}, - {76, "EM_CRIS"}, - {77, "EM_JAVELIN"}, - {78, "EM_FIREPATH"}, - {79, "EM_ZSP"}, - {80, "EM_MMIX"}, - {81, "EM_HUANY"}, - {82, "EM_PRISM"}, - {83, "EM_AVR"}, - {84, "EM_FR30"}, - {85, "EM_D10V"}, - {86, "EM_D30V"}, - {87, "EM_V850"}, - {88, "EM_M32R"}, - {89, "EM_MN10300"}, - {90, "EM_MN10200"}, - {91, "EM_PJ"}, - {92, "EM_OPENRISC"}, - {93, "EM_ARC_COMPACT"}, - {94, "EM_XTENSA"}, - {95, "EM_VIDEOCORE"}, - {96, "EM_TMM_GPP"}, - {97, "EM_NS32K"}, - {98, "EM_TPC"}, - {99, "EM_SNP1K"}, - {100, "EM_ST200"}, - {101, "EM_IP2K"}, - {102, "EM_MAX"}, - {103, "EM_CR"}, - {104, "EM_F2MC16"}, - {105, "EM_MSP430"}, - {106, "EM_BLACKFIN"}, - {107, "EM_SE_C33"}, - {108, "EM_SEP"}, - {109, "EM_ARCA"}, - {110, "EM_UNICORE"}, - {111, "EM_EXCESS"}, - {112, "EM_DXP"}, - {113, "EM_ALTERA_NIOS2"}, - {114, "EM_CRX"}, - {115, "EM_XGATE"}, - {116, "EM_C166"}, - {117, "EM_M16C"}, - {118, "EM_DSPIC30F"}, - {119, "EM_CE"}, - {120, "EM_M32C"}, - {131, "EM_TSK3000"}, - {132, "EM_RS08"}, - {133, "EM_SHARC"}, - {134, "EM_ECOG2"}, - {135, "EM_SCORE7"}, - {136, "EM_DSP24"}, - {137, "EM_VIDEOCORE3"}, - {138, "EM_LATTICEMICO32"}, - {139, "EM_SE_C17"}, - {140, "EM_TI_C6000"}, - {141, "EM_TI_C2000"}, - {142, "EM_TI_C5500"}, - {143, "EM_TI_ARP32"}, - {144, "EM_TI_PRU"}, - {160, "EM_MMDSP_PLUS"}, - {161, "EM_CYPRESS_M8C"}, - {162, "EM_R32C"}, - {163, "EM_TRIMEDIA"}, - {164, "EM_QDSP6"}, - {165, "EM_8051"}, - {166, "EM_STXP7X"}, - {167, "EM_NDS32"}, - {168, "EM_ECOG1"}, - {168, "EM_ECOG1X"}, - {169, "EM_MAXQ30"}, - {170, "EM_XIMO16"}, - {171, "EM_MANIK"}, - {172, "EM_CRAYNV2"}, - {173, "EM_RX"}, - {174, "EM_METAG"}, - {175, "EM_MCST_ELBRUS"}, - {176, "EM_ECOG16"}, - {177, "EM_CR16"}, - {178, "EM_ETPU"}, - {179, "EM_SLE9X"}, - {180, "EM_L10M"}, - {181, "EM_K10M"}, - {183, "EM_AARCH64"}, - {185, "EM_AVR32"}, - {186, "EM_STM8"}, - {187, "EM_TILE64"}, - {188, "EM_TILEPRO"}, - {189, "EM_MICROBLAZE"}, - {190, "EM_CUDA"}, - {191, "EM_TILEGX"}, - {192, "EM_CLOUDSHIELD"}, - {193, "EM_COREA_1ST"}, - {194, "EM_COREA_2ND"}, - {195, "EM_ARC_COMPACT2"}, - {196, "EM_OPEN8"}, - {197, "EM_RL78"}, - {198, "EM_VIDEOCORE5"}, - {199, "EM_78KOR"}, - {200, "EM_56800EX"}, - {201, "EM_BA1"}, - {202, "EM_BA2"}, - {203, "EM_XCORE"}, - {204, "EM_MCHP_PIC"}, - {205, "EM_INTEL205"}, - {206, "EM_INTEL206"}, - {207, "EM_INTEL207"}, - {208, "EM_INTEL208"}, - {209, "EM_INTEL209"}, - {210, "EM_KM32"}, - {211, "EM_KMX32"}, - {212, "EM_KMX16"}, - {213, "EM_KMX8"}, - {214, "EM_KVARC"}, - {215, "EM_CDP"}, - {216, "EM_COGE"}, - {217, "EM_COOL"}, - {218, "EM_NORC"}, - {219, "EM_CSR_KALIMBA "}, - {220, "EM_Z80 "}, - {221, "EM_VISIUM "}, - {222, "EM_FT32 "}, - {223, "EM_MOXIE"}, - {224, "EM_AMDGPU"}, - {243, "EM_RISCV"}, - {244, "EM_LANAI"}, - {247, "EM_BPF"}, - - /* Non-standard or deprecated. */ - {6, "EM_486"}, - {10, "EM_MIPS_RS4_BE"}, - {41, "EM_ALPHA_STD"}, - {0x9026, "EM_ALPHA"}, -} - -func (i Machine) String() string { return stringName(uint32(i), machineStrings, false) } -func (i Machine) GoString() string { return stringName(uint32(i), machineStrings, true) } - -// Special section indices. -type SectionIndex int - -const ( - SHN_UNDEF SectionIndex = 0 /* Undefined, missing, irrelevant. */ - SHN_LORESERVE SectionIndex = 0xff00 /* First of reserved range. */ - SHN_LOPROC SectionIndex = 0xff00 /* First processor-specific. */ - SHN_HIPROC SectionIndex = 0xff1f /* Last processor-specific. */ - SHN_LOOS SectionIndex = 0xff20 /* First operating system-specific. */ - SHN_HIOS SectionIndex = 0xff3f /* Last operating system-specific. */ - SHN_ABS SectionIndex = 0xfff1 /* Absolute values. */ - SHN_COMMON SectionIndex = 0xfff2 /* Common data. */ - SHN_XINDEX SectionIndex = 0xffff /* Escape; index stored elsewhere. */ - SHN_HIRESERVE SectionIndex = 0xffff /* Last of reserved range. */ -) - -var shnStrings = []intName{ - {0, "SHN_UNDEF"}, - {0xff00, "SHN_LOPROC"}, - {0xff20, "SHN_LOOS"}, - {0xfff1, "SHN_ABS"}, - {0xfff2, "SHN_COMMON"}, - {0xffff, "SHN_XINDEX"}, -} - -func (i SectionIndex) String() string { return stringName(uint32(i), shnStrings, false) } -func (i SectionIndex) GoString() string { return stringName(uint32(i), shnStrings, true) } - -// Section type. -type SectionType uint32 - -const ( - SHT_NULL SectionType = 0 /* inactive */ - SHT_PROGBITS SectionType = 1 /* program defined information */ - SHT_SYMTAB SectionType = 2 /* symbol table section */ - SHT_STRTAB SectionType = 3 /* string table section */ - SHT_RELA SectionType = 4 /* relocation section with addends */ - SHT_HASH SectionType = 5 /* symbol hash table section */ - SHT_DYNAMIC SectionType = 6 /* dynamic section */ - SHT_NOTE SectionType = 7 /* note section */ - SHT_NOBITS SectionType = 8 /* no space section */ - SHT_REL SectionType = 9 /* relocation section - no addends */ - SHT_SHLIB SectionType = 10 /* reserved - purpose unknown */ - SHT_DYNSYM SectionType = 11 /* dynamic symbol table section */ - SHT_INIT_ARRAY SectionType = 14 /* Initialization function pointers. */ - SHT_FINI_ARRAY SectionType = 15 /* Termination function pointers. */ - SHT_PREINIT_ARRAY SectionType = 16 /* Pre-initialization function ptrs. */ - SHT_GROUP SectionType = 17 /* Section group. */ - SHT_SYMTAB_SHNDX SectionType = 18 /* Section indexes (see SHN_XINDEX). */ - SHT_LOOS SectionType = 0x60000000 /* First of OS specific semantics */ - SHT_GNU_ATTRIBUTES SectionType = 0x6ffffff5 /* GNU object attributes */ - SHT_GNU_HASH SectionType = 0x6ffffff6 /* GNU hash table */ - SHT_GNU_LIBLIST SectionType = 0x6ffffff7 /* GNU prelink library list */ - SHT_GNU_VERDEF SectionType = 0x6ffffffd /* GNU version definition section */ - SHT_GNU_VERNEED SectionType = 0x6ffffffe /* GNU version needs section */ - SHT_GNU_VERSYM SectionType = 0x6fffffff /* GNU version symbol table */ - SHT_HIOS SectionType = 0x6fffffff /* Last of OS specific semantics */ - SHT_LOPROC SectionType = 0x70000000 /* reserved range for processor */ - SHT_HIPROC SectionType = 0x7fffffff /* specific section header types */ - SHT_LOUSER SectionType = 0x80000000 /* reserved range for application */ - SHT_HIUSER SectionType = 0xffffffff /* specific indexes */ -) - -var shtStrings = []intName{ - {0, "SHT_NULL"}, - {1, "SHT_PROGBITS"}, - {2, "SHT_SYMTAB"}, - {3, "SHT_STRTAB"}, - {4, "SHT_RELA"}, - {5, "SHT_HASH"}, - {6, "SHT_DYNAMIC"}, - {7, "SHT_NOTE"}, - {8, "SHT_NOBITS"}, - {9, "SHT_REL"}, - {10, "SHT_SHLIB"}, - {11, "SHT_DYNSYM"}, - {14, "SHT_INIT_ARRAY"}, - {15, "SHT_FINI_ARRAY"}, - {16, "SHT_PREINIT_ARRAY"}, - {17, "SHT_GROUP"}, - {18, "SHT_SYMTAB_SHNDX"}, - {0x60000000, "SHT_LOOS"}, - {0x6ffffff5, "SHT_GNU_ATTRIBUTES"}, - {0x6ffffff6, "SHT_GNU_HASH"}, - {0x6ffffff7, "SHT_GNU_LIBLIST"}, - {0x6ffffffd, "SHT_GNU_VERDEF"}, - {0x6ffffffe, "SHT_GNU_VERNEED"}, - {0x6fffffff, "SHT_GNU_VERSYM"}, - {0x70000000, "SHT_LOPROC"}, - {0x7fffffff, "SHT_HIPROC"}, - {0x80000000, "SHT_LOUSER"}, - {0xffffffff, "SHT_HIUSER"}, -} - -func (i SectionType) String() string { return stringName(uint32(i), shtStrings, false) } -func (i SectionType) GoString() string { return stringName(uint32(i), shtStrings, true) } - -// Section flags. -type SectionFlag uint32 - -const ( - SHF_WRITE SectionFlag = 0x1 /* Section contains writable data. */ - SHF_ALLOC SectionFlag = 0x2 /* Section occupies memory. */ - SHF_EXECINSTR SectionFlag = 0x4 /* Section contains instructions. */ - SHF_MERGE SectionFlag = 0x10 /* Section may be merged. */ - SHF_STRINGS SectionFlag = 0x20 /* Section contains strings. */ - SHF_INFO_LINK SectionFlag = 0x40 /* sh_info holds section index. */ - SHF_LINK_ORDER SectionFlag = 0x80 /* Special ordering requirements. */ - SHF_OS_NONCONFORMING SectionFlag = 0x100 /* OS-specific processing required. */ - SHF_GROUP SectionFlag = 0x200 /* Member of section group. */ - SHF_TLS SectionFlag = 0x400 /* Section contains TLS data. */ - SHF_COMPRESSED SectionFlag = 0x800 /* Section is compressed. */ - SHF_MASKOS SectionFlag = 0x0ff00000 /* OS-specific semantics. */ - SHF_MASKPROC SectionFlag = 0xf0000000 /* Processor-specific semantics. */ -) - -var shfStrings = []intName{ - {0x1, "SHF_WRITE"}, - {0x2, "SHF_ALLOC"}, - {0x4, "SHF_EXECINSTR"}, - {0x10, "SHF_MERGE"}, - {0x20, "SHF_STRINGS"}, - {0x40, "SHF_INFO_LINK"}, - {0x80, "SHF_LINK_ORDER"}, - {0x100, "SHF_OS_NONCONFORMING"}, - {0x200, "SHF_GROUP"}, - {0x400, "SHF_TLS"}, - {0x800, "SHF_COMPRESSED"}, -} - -func (i SectionFlag) String() string { return flagName(uint32(i), shfStrings, false) } -func (i SectionFlag) GoString() string { return flagName(uint32(i), shfStrings, true) } - -// Section compression type. -type CompressionType int - -const ( - COMPRESS_ZLIB CompressionType = 1 /* ZLIB compression. */ - COMPRESS_LOOS CompressionType = 0x60000000 /* First OS-specific. */ - COMPRESS_HIOS CompressionType = 0x6fffffff /* Last OS-specific. */ - COMPRESS_LOPROC CompressionType = 0x70000000 /* First processor-specific type. */ - COMPRESS_HIPROC CompressionType = 0x7fffffff /* Last processor-specific type. */ -) - -var compressionStrings = []intName{ - {0, "COMPRESS_ZLIB"}, - {0x60000000, "COMPRESS_LOOS"}, - {0x6fffffff, "COMPRESS_HIOS"}, - {0x70000000, "COMPRESS_LOPROC"}, - {0x7fffffff, "COMPRESS_HIPROC"}, -} - -func (i CompressionType) String() string { return stringName(uint32(i), compressionStrings, false) } -func (i CompressionType) GoString() string { return stringName(uint32(i), compressionStrings, true) } - -// Prog.Type -type ProgType int - -const ( - PT_NULL ProgType = 0 /* Unused entry. */ - PT_LOAD ProgType = 1 /* Loadable segment. */ - PT_DYNAMIC ProgType = 2 /* Dynamic linking information segment. */ - PT_INTERP ProgType = 3 /* Pathname of interpreter. */ - PT_NOTE ProgType = 4 /* Auxiliary information. */ - PT_SHLIB ProgType = 5 /* Reserved (not used). */ - PT_PHDR ProgType = 6 /* Location of program header itself. */ - PT_TLS ProgType = 7 /* Thread local storage segment */ - PT_LOOS ProgType = 0x60000000 /* First OS-specific. */ - PT_HIOS ProgType = 0x6fffffff /* Last OS-specific. */ - PT_LOPROC ProgType = 0x70000000 /* First processor-specific type. */ - PT_HIPROC ProgType = 0x7fffffff /* Last processor-specific type. */ -) - -var ptStrings = []intName{ - {0, "PT_NULL"}, - {1, "PT_LOAD"}, - {2, "PT_DYNAMIC"}, - {3, "PT_INTERP"}, - {4, "PT_NOTE"}, - {5, "PT_SHLIB"}, - {6, "PT_PHDR"}, - {7, "PT_TLS"}, - {0x60000000, "PT_LOOS"}, - {0x6fffffff, "PT_HIOS"}, - {0x70000000, "PT_LOPROC"}, - {0x7fffffff, "PT_HIPROC"}, -} - -func (i ProgType) String() string { return stringName(uint32(i), ptStrings, false) } -func (i ProgType) GoString() string { return stringName(uint32(i), ptStrings, true) } - -// Prog.Flag -type ProgFlag uint32 - -const ( - PF_X ProgFlag = 0x1 /* Executable. */ - PF_W ProgFlag = 0x2 /* Writable. */ - PF_R ProgFlag = 0x4 /* Readable. */ - PF_MASKOS ProgFlag = 0x0ff00000 /* Operating system-specific. */ - PF_MASKPROC ProgFlag = 0xf0000000 /* Processor-specific. */ -) - -var pfStrings = []intName{ - {0x1, "PF_X"}, - {0x2, "PF_W"}, - {0x4, "PF_R"}, -} - -func (i ProgFlag) String() string { return flagName(uint32(i), pfStrings, false) } -func (i ProgFlag) GoString() string { return flagName(uint32(i), pfStrings, true) } - -// Dyn.Tag -type DynTag int - -const ( - DT_NULL DynTag = 0 /* Terminating entry. */ - DT_NEEDED DynTag = 1 /* String table offset of a needed shared library. */ - DT_PLTRELSZ DynTag = 2 /* Total size in bytes of PLT relocations. */ - DT_PLTGOT DynTag = 3 /* Processor-dependent address. */ - DT_HASH DynTag = 4 /* Address of symbol hash table. */ - DT_STRTAB DynTag = 5 /* Address of string table. */ - DT_SYMTAB DynTag = 6 /* Address of symbol table. */ - DT_RELA DynTag = 7 /* Address of ElfNN_Rela relocations. */ - DT_RELASZ DynTag = 8 /* Total size of ElfNN_Rela relocations. */ - DT_RELAENT DynTag = 9 /* Size of each ElfNN_Rela relocation entry. */ - DT_STRSZ DynTag = 10 /* Size of string table. */ - DT_SYMENT DynTag = 11 /* Size of each symbol table entry. */ - DT_INIT DynTag = 12 /* Address of initialization function. */ - DT_FINI DynTag = 13 /* Address of finalization function. */ - DT_SONAME DynTag = 14 /* String table offset of shared object name. */ - DT_RPATH DynTag = 15 /* String table offset of library path. [sup] */ - DT_SYMBOLIC DynTag = 16 /* Indicates "symbolic" linking. [sup] */ - DT_REL DynTag = 17 /* Address of ElfNN_Rel relocations. */ - DT_RELSZ DynTag = 18 /* Total size of ElfNN_Rel relocations. */ - DT_RELENT DynTag = 19 /* Size of each ElfNN_Rel relocation. */ - DT_PLTREL DynTag = 20 /* Type of relocation used for PLT. */ - DT_DEBUG DynTag = 21 /* Reserved (not used). */ - DT_TEXTREL DynTag = 22 /* Indicates there may be relocations in non-writable segments. [sup] */ - DT_JMPREL DynTag = 23 /* Address of PLT relocations. */ - DT_BIND_NOW DynTag = 24 /* [sup] */ - DT_INIT_ARRAY DynTag = 25 /* Address of the array of pointers to initialization functions */ - DT_FINI_ARRAY DynTag = 26 /* Address of the array of pointers to termination functions */ - DT_INIT_ARRAYSZ DynTag = 27 /* Size in bytes of the array of initialization functions. */ - DT_FINI_ARRAYSZ DynTag = 28 /* Size in bytes of the array of termination functions. */ - DT_RUNPATH DynTag = 29 /* String table offset of a null-terminated library search path string. */ - DT_FLAGS DynTag = 30 /* Object specific flag values. */ - DT_ENCODING DynTag = 32 /* Values greater than or equal to DT_ENCODING - and less than DT_LOOS follow the rules for - the interpretation of the d_un union - as follows: even == 'd_ptr', even == 'd_val' - or none */ - DT_PREINIT_ARRAY DynTag = 32 /* Address of the array of pointers to pre-initialization functions. */ - DT_PREINIT_ARRAYSZ DynTag = 33 /* Size in bytes of the array of pre-initialization functions. */ - DT_LOOS DynTag = 0x6000000d /* First OS-specific */ - DT_HIOS DynTag = 0x6ffff000 /* Last OS-specific */ - DT_VERSYM DynTag = 0x6ffffff0 - DT_VERNEED DynTag = 0x6ffffffe - DT_VERNEEDNUM DynTag = 0x6fffffff - DT_LOPROC DynTag = 0x70000000 /* First processor-specific type. */ - DT_HIPROC DynTag = 0x7fffffff /* Last processor-specific type. */ -) - -var dtStrings = []intName{ - {0, "DT_NULL"}, - {1, "DT_NEEDED"}, - {2, "DT_PLTRELSZ"}, - {3, "DT_PLTGOT"}, - {4, "DT_HASH"}, - {5, "DT_STRTAB"}, - {6, "DT_SYMTAB"}, - {7, "DT_RELA"}, - {8, "DT_RELASZ"}, - {9, "DT_RELAENT"}, - {10, "DT_STRSZ"}, - {11, "DT_SYMENT"}, - {12, "DT_INIT"}, - {13, "DT_FINI"}, - {14, "DT_SONAME"}, - {15, "DT_RPATH"}, - {16, "DT_SYMBOLIC"}, - {17, "DT_REL"}, - {18, "DT_RELSZ"}, - {19, "DT_RELENT"}, - {20, "DT_PLTREL"}, - {21, "DT_DEBUG"}, - {22, "DT_TEXTREL"}, - {23, "DT_JMPREL"}, - {24, "DT_BIND_NOW"}, - {25, "DT_INIT_ARRAY"}, - {26, "DT_FINI_ARRAY"}, - {27, "DT_INIT_ARRAYSZ"}, - {28, "DT_FINI_ARRAYSZ"}, - {29, "DT_RUNPATH"}, - {30, "DT_FLAGS"}, - {32, "DT_ENCODING"}, - {32, "DT_PREINIT_ARRAY"}, - {33, "DT_PREINIT_ARRAYSZ"}, - {0x6000000d, "DT_LOOS"}, - {0x6ffff000, "DT_HIOS"}, - {0x6ffffff0, "DT_VERSYM"}, - {0x6ffffffe, "DT_VERNEED"}, - {0x6fffffff, "DT_VERNEEDNUM"}, - {0x70000000, "DT_LOPROC"}, - {0x7fffffff, "DT_HIPROC"}, -} - -func (i DynTag) String() string { return stringName(uint32(i), dtStrings, false) } -func (i DynTag) GoString() string { return stringName(uint32(i), dtStrings, true) } - -type DynTagValue struct { - Tag DynTag - Value uint64 -} - -// DT_FLAGS values. -type DynFlag uint64 - -const ( - DF_ORIGIN DynFlag = 0x0001 /* Indicates that the object being loaded may - make reference to the - $ORIGIN substitution string */ - DF_SYMBOLIC DynFlag = 0x0002 /* Indicates "symbolic" linking. */ - DF_TEXTREL DynFlag = 0x0004 /* Indicates there may be relocations in non-writable segments. */ - DF_BIND_NOW DynFlag = 0x0008 /* Indicates that the dynamic linker should - process all relocations for the object - containing this entry before transferring - control to the program. */ - DF_STATIC_TLS DynFlag = 0x0010 /* Indicates that the shared object or - executable contains code using a static - thread-local storage scheme. */ -) - -var dflagStrings = []intName{ - {0x0001, "DF_ORIGIN"}, - {0x0002, "DF_SYMBOLIC"}, - {0x0004, "DF_TEXTREL"}, - {0x0008, "DF_BIND_NOW"}, - {0x0010, "DF_STATIC_TLS"}, -} - -func (i DynFlag) String() string { return flagName(uint32(i), dflagStrings, false) } -func (i DynFlag) GoString() string { return flagName(uint32(i), dflagStrings, true) } - -// NType values; used in core files. -type NType int - -const ( - NT_PRSTATUS NType = 1 /* Process status. */ - NT_FPREGSET NType = 2 /* Floating point registers. */ - NT_PRPSINFO NType = 3 /* Process state info. */ -) - -var ntypeStrings = []intName{ - {1, "NT_PRSTATUS"}, - {2, "NT_FPREGSET"}, - {3, "NT_PRPSINFO"}, -} - -func (i NType) String() string { return stringName(uint32(i), ntypeStrings, false) } -func (i NType) GoString() string { return stringName(uint32(i), ntypeStrings, true) } - -/* Symbol Binding - ELFNN_ST_BIND - st_info */ -type SymBind int - -const ( - STB_LOCAL SymBind = 0 /* Local symbol */ - STB_GLOBAL SymBind = 1 /* Global symbol */ - STB_WEAK SymBind = 2 /* like global - lower precedence */ - STB_LOOS SymBind = 10 /* Reserved range for operating system */ - STB_HIOS SymBind = 12 /* specific semantics. */ - STB_LOPROC SymBind = 13 /* reserved range for processor */ - STB_HIPROC SymBind = 15 /* specific semantics. */ -) - -var stbStrings = []intName{ - {0, "STB_LOCAL"}, - {1, "STB_GLOBAL"}, - {2, "STB_WEAK"}, - {10, "STB_LOOS"}, - {12, "STB_HIOS"}, - {13, "STB_LOPROC"}, - {15, "STB_HIPROC"}, -} - -func (i SymBind) String() string { return stringName(uint32(i), stbStrings, false) } -func (i SymBind) GoString() string { return stringName(uint32(i), stbStrings, true) } - -/* Symbol type - ELFNN_ST_TYPE - st_info */ -type SymType int - -const ( - STT_NOTYPE SymType = 0 /* Unspecified type. */ - STT_OBJECT SymType = 1 /* Data object. */ - STT_FUNC SymType = 2 /* Function. */ - STT_SECTION SymType = 3 /* Section. */ - STT_FILE SymType = 4 /* Source file. */ - STT_COMMON SymType = 5 /* Uninitialized common block. */ - STT_TLS SymType = 6 /* TLS object. */ - STT_LOOS SymType = 10 /* Reserved range for operating system */ - STT_HIOS SymType = 12 /* specific semantics. */ - STT_LOPROC SymType = 13 /* reserved range for processor */ - STT_HIPROC SymType = 15 /* specific semantics. */ -) - -var sttStrings = []intName{ - {0, "STT_NOTYPE"}, - {1, "STT_OBJECT"}, - {2, "STT_FUNC"}, - {3, "STT_SECTION"}, - {4, "STT_FILE"}, - {5, "STT_COMMON"}, - {6, "STT_TLS"}, - {10, "STT_LOOS"}, - {12, "STT_HIOS"}, - {13, "STT_LOPROC"}, - {15, "STT_HIPROC"}, -} - -func (i SymType) String() string { return stringName(uint32(i), sttStrings, false) } -func (i SymType) GoString() string { return stringName(uint32(i), sttStrings, true) } - -/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */ -type SymVis int - -const ( - STV_DEFAULT SymVis = 0x0 /* Default visibility (see binding). */ - STV_INTERNAL SymVis = 0x1 /* Special meaning in relocatable objects. */ - STV_HIDDEN SymVis = 0x2 /* Not visible. */ - STV_PROTECTED SymVis = 0x3 /* Visible but not preemptible. */ -) - -var stvStrings = []intName{ - {0x0, "STV_DEFAULT"}, - {0x1, "STV_INTERNAL"}, - {0x2, "STV_HIDDEN"}, - {0x3, "STV_PROTECTED"}, -} - -func (i SymVis) String() string { return stringName(uint32(i), stvStrings, false) } -func (i SymVis) GoString() string { return stringName(uint32(i), stvStrings, true) } - -/* - * Relocation types. - */ - -// Relocation types for x86-64. -type R_X86_64 int - -const ( - R_X86_64_NONE R_X86_64 = 0 /* No relocation. */ - R_X86_64_64 R_X86_64 = 1 /* Add 64 bit symbol value. */ - R_X86_64_PC32 R_X86_64 = 2 /* PC-relative 32 bit signed sym value. */ - R_X86_64_GOT32 R_X86_64 = 3 /* PC-relative 32 bit GOT offset. */ - R_X86_64_PLT32 R_X86_64 = 4 /* PC-relative 32 bit PLT offset. */ - R_X86_64_COPY R_X86_64 = 5 /* Copy data from shared object. */ - R_X86_64_GLOB_DAT R_X86_64 = 6 /* Set GOT entry to data address. */ - R_X86_64_JMP_SLOT R_X86_64 = 7 /* Set GOT entry to code address. */ - R_X86_64_RELATIVE R_X86_64 = 8 /* Add load address of shared object. */ - R_X86_64_GOTPCREL R_X86_64 = 9 /* Add 32 bit signed pcrel offset to GOT. */ - R_X86_64_32 R_X86_64 = 10 /* Add 32 bit zero extended symbol value */ - R_X86_64_32S R_X86_64 = 11 /* Add 32 bit sign extended symbol value */ - R_X86_64_16 R_X86_64 = 12 /* Add 16 bit zero extended symbol value */ - R_X86_64_PC16 R_X86_64 = 13 /* Add 16 bit signed extended pc relative symbol value */ - R_X86_64_8 R_X86_64 = 14 /* Add 8 bit zero extended symbol value */ - R_X86_64_PC8 R_X86_64 = 15 /* Add 8 bit signed extended pc relative symbol value */ - R_X86_64_DTPMOD64 R_X86_64 = 16 /* ID of module containing symbol */ - R_X86_64_DTPOFF64 R_X86_64 = 17 /* Offset in TLS block */ - R_X86_64_TPOFF64 R_X86_64 = 18 /* Offset in static TLS block */ - R_X86_64_TLSGD R_X86_64 = 19 /* PC relative offset to GD GOT entry */ - R_X86_64_TLSLD R_X86_64 = 20 /* PC relative offset to LD GOT entry */ - R_X86_64_DTPOFF32 R_X86_64 = 21 /* Offset in TLS block */ - R_X86_64_GOTTPOFF R_X86_64 = 22 /* PC relative offset to IE GOT entry */ - R_X86_64_TPOFF32 R_X86_64 = 23 /* Offset in static TLS block */ - R_X86_64_PC64 R_X86_64 = 24 /* PC relative 64-bit sign extended symbol value. */ - R_X86_64_GOTOFF64 R_X86_64 = 25 - R_X86_64_GOTPC32 R_X86_64 = 26 - R_X86_64_GOT64 R_X86_64 = 27 - R_X86_64_GOTPCREL64 R_X86_64 = 28 - R_X86_64_GOTPC64 R_X86_64 = 29 - R_X86_64_GOTPLT64 R_X86_64 = 30 - R_X86_64_PLTOFF64 R_X86_64 = 31 - R_X86_64_SIZE32 R_X86_64 = 32 - R_X86_64_SIZE64 R_X86_64 = 33 - R_X86_64_GOTPC32_TLSDESC R_X86_64 = 34 - R_X86_64_TLSDESC_CALL R_X86_64 = 35 - R_X86_64_TLSDESC R_X86_64 = 36 - R_X86_64_IRELATIVE R_X86_64 = 37 - R_X86_64_RELATIVE64 R_X86_64 = 38 - R_X86_64_PC32_BND R_X86_64 = 39 - R_X86_64_PLT32_BND R_X86_64 = 40 - R_X86_64_GOTPCRELX R_X86_64 = 41 - R_X86_64_REX_GOTPCRELX R_X86_64 = 42 -) - -var rx86_64Strings = []intName{ - {0, "R_X86_64_NONE"}, - {1, "R_X86_64_64"}, - {2, "R_X86_64_PC32"}, - {3, "R_X86_64_GOT32"}, - {4, "R_X86_64_PLT32"}, - {5, "R_X86_64_COPY"}, - {6, "R_X86_64_GLOB_DAT"}, - {7, "R_X86_64_JMP_SLOT"}, - {8, "R_X86_64_RELATIVE"}, - {9, "R_X86_64_GOTPCREL"}, - {10, "R_X86_64_32"}, - {11, "R_X86_64_32S"}, - {12, "R_X86_64_16"}, - {13, "R_X86_64_PC16"}, - {14, "R_X86_64_8"}, - {15, "R_X86_64_PC8"}, - {16, "R_X86_64_DTPMOD64"}, - {17, "R_X86_64_DTPOFF64"}, - {18, "R_X86_64_TPOFF64"}, - {19, "R_X86_64_TLSGD"}, - {20, "R_X86_64_TLSLD"}, - {21, "R_X86_64_DTPOFF32"}, - {22, "R_X86_64_GOTTPOFF"}, - {23, "R_X86_64_TPOFF32"}, - {24, "R_X86_64_PC64"}, - {25, "R_X86_64_GOTOFF64"}, - {26, "R_X86_64_GOTPC32"}, - {27, "R_X86_64_GOT64"}, - {28, "R_X86_64_GOTPCREL64"}, - {29, "R_X86_64_GOTPC64"}, - {30, "R_X86_64_GOTPLT64"}, - {31, "R_X86_64_PLTOFF64"}, - {32, "R_X86_64_SIZE32"}, - {33, "R_X86_64_SIZE64"}, - {34, "R_X86_64_GOTPC32_TLSDESC"}, - {35, "R_X86_64_TLSDESC_CALL"}, - {36, "R_X86_64_TLSDESC"}, - {37, "R_X86_64_IRELATIVE"}, - {38, "R_X86_64_RELATIVE64"}, - {39, "R_X86_64_PC32_BND"}, - {40, "R_X86_64_PLT32_BND"}, - {41, "R_X86_64_GOTPCRELX"}, - {42, "R_X86_64_REX_GOTPCRELX"}, -} - -func (i R_X86_64) String() string { return stringName(uint32(i), rx86_64Strings, false) } -func (i R_X86_64) GoString() string { return stringName(uint32(i), rx86_64Strings, true) } - -// Relocation types for AArch64 (aka arm64) -type R_AARCH64 int - -const ( - R_AARCH64_NONE R_AARCH64 = 0 - R_AARCH64_P32_ABS32 R_AARCH64 = 1 - R_AARCH64_P32_ABS16 R_AARCH64 = 2 - R_AARCH64_P32_PREL32 R_AARCH64 = 3 - R_AARCH64_P32_PREL16 R_AARCH64 = 4 - R_AARCH64_P32_MOVW_UABS_G0 R_AARCH64 = 5 - R_AARCH64_P32_MOVW_UABS_G0_NC R_AARCH64 = 6 - R_AARCH64_P32_MOVW_UABS_G1 R_AARCH64 = 7 - R_AARCH64_P32_MOVW_SABS_G0 R_AARCH64 = 8 - R_AARCH64_P32_LD_PREL_LO19 R_AARCH64 = 9 - R_AARCH64_P32_ADR_PREL_LO21 R_AARCH64 = 10 - R_AARCH64_P32_ADR_PREL_PG_HI21 R_AARCH64 = 11 - R_AARCH64_P32_ADD_ABS_LO12_NC R_AARCH64 = 12 - R_AARCH64_P32_LDST8_ABS_LO12_NC R_AARCH64 = 13 - R_AARCH64_P32_LDST16_ABS_LO12_NC R_AARCH64 = 14 - R_AARCH64_P32_LDST32_ABS_LO12_NC R_AARCH64 = 15 - R_AARCH64_P32_LDST64_ABS_LO12_NC R_AARCH64 = 16 - R_AARCH64_P32_LDST128_ABS_LO12_NC R_AARCH64 = 17 - R_AARCH64_P32_TSTBR14 R_AARCH64 = 18 - R_AARCH64_P32_CONDBR19 R_AARCH64 = 19 - R_AARCH64_P32_JUMP26 R_AARCH64 = 20 - R_AARCH64_P32_CALL26 R_AARCH64 = 21 - R_AARCH64_P32_GOT_LD_PREL19 R_AARCH64 = 25 - R_AARCH64_P32_ADR_GOT_PAGE R_AARCH64 = 26 - R_AARCH64_P32_LD32_GOT_LO12_NC R_AARCH64 = 27 - R_AARCH64_P32_TLSGD_ADR_PAGE21 R_AARCH64 = 81 - R_AARCH64_P32_TLSGD_ADD_LO12_NC R_AARCH64 = 82 - R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21 R_AARCH64 = 103 - R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC R_AARCH64 = 104 - R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19 R_AARCH64 = 105 - R_AARCH64_P32_TLSLE_MOVW_TPREL_G1 R_AARCH64 = 106 - R_AARCH64_P32_TLSLE_MOVW_TPREL_G0 R_AARCH64 = 107 - R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC R_AARCH64 = 108 - R_AARCH64_P32_TLSLE_ADD_TPREL_HI12 R_AARCH64 = 109 - R_AARCH64_P32_TLSLE_ADD_TPREL_LO12 R_AARCH64 = 110 - R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC R_AARCH64 = 111 - R_AARCH64_P32_TLSDESC_LD_PREL19 R_AARCH64 = 122 - R_AARCH64_P32_TLSDESC_ADR_PREL21 R_AARCH64 = 123 - R_AARCH64_P32_TLSDESC_ADR_PAGE21 R_AARCH64 = 124 - R_AARCH64_P32_TLSDESC_LD32_LO12_NC R_AARCH64 = 125 - R_AARCH64_P32_TLSDESC_ADD_LO12_NC R_AARCH64 = 126 - R_AARCH64_P32_TLSDESC_CALL R_AARCH64 = 127 - R_AARCH64_P32_COPY R_AARCH64 = 180 - R_AARCH64_P32_GLOB_DAT R_AARCH64 = 181 - R_AARCH64_P32_JUMP_SLOT R_AARCH64 = 182 - R_AARCH64_P32_RELATIVE R_AARCH64 = 183 - R_AARCH64_P32_TLS_DTPMOD R_AARCH64 = 184 - R_AARCH64_P32_TLS_DTPREL R_AARCH64 = 185 - R_AARCH64_P32_TLS_TPREL R_AARCH64 = 186 - R_AARCH64_P32_TLSDESC R_AARCH64 = 187 - R_AARCH64_P32_IRELATIVE R_AARCH64 = 188 - R_AARCH64_NULL R_AARCH64 = 256 - R_AARCH64_ABS64 R_AARCH64 = 257 - R_AARCH64_ABS32 R_AARCH64 = 258 - R_AARCH64_ABS16 R_AARCH64 = 259 - R_AARCH64_PREL64 R_AARCH64 = 260 - R_AARCH64_PREL32 R_AARCH64 = 261 - R_AARCH64_PREL16 R_AARCH64 = 262 - R_AARCH64_MOVW_UABS_G0 R_AARCH64 = 263 - R_AARCH64_MOVW_UABS_G0_NC R_AARCH64 = 264 - R_AARCH64_MOVW_UABS_G1 R_AARCH64 = 265 - R_AARCH64_MOVW_UABS_G1_NC R_AARCH64 = 266 - R_AARCH64_MOVW_UABS_G2 R_AARCH64 = 267 - R_AARCH64_MOVW_UABS_G2_NC R_AARCH64 = 268 - R_AARCH64_MOVW_UABS_G3 R_AARCH64 = 269 - R_AARCH64_MOVW_SABS_G0 R_AARCH64 = 270 - R_AARCH64_MOVW_SABS_G1 R_AARCH64 = 271 - R_AARCH64_MOVW_SABS_G2 R_AARCH64 = 272 - R_AARCH64_LD_PREL_LO19 R_AARCH64 = 273 - R_AARCH64_ADR_PREL_LO21 R_AARCH64 = 274 - R_AARCH64_ADR_PREL_PG_HI21 R_AARCH64 = 275 - R_AARCH64_ADR_PREL_PG_HI21_NC R_AARCH64 = 276 - R_AARCH64_ADD_ABS_LO12_NC R_AARCH64 = 277 - R_AARCH64_LDST8_ABS_LO12_NC R_AARCH64 = 278 - R_AARCH64_TSTBR14 R_AARCH64 = 279 - R_AARCH64_CONDBR19 R_AARCH64 = 280 - R_AARCH64_JUMP26 R_AARCH64 = 282 - R_AARCH64_CALL26 R_AARCH64 = 283 - R_AARCH64_LDST16_ABS_LO12_NC R_AARCH64 = 284 - R_AARCH64_LDST32_ABS_LO12_NC R_AARCH64 = 285 - R_AARCH64_LDST64_ABS_LO12_NC R_AARCH64 = 286 - R_AARCH64_LDST128_ABS_LO12_NC R_AARCH64 = 299 - R_AARCH64_GOT_LD_PREL19 R_AARCH64 = 309 - R_AARCH64_LD64_GOTOFF_LO15 R_AARCH64 = 310 - R_AARCH64_ADR_GOT_PAGE R_AARCH64 = 311 - R_AARCH64_LD64_GOT_LO12_NC R_AARCH64 = 312 - R_AARCH64_LD64_GOTPAGE_LO15 R_AARCH64 = 313 - R_AARCH64_TLSGD_ADR_PREL21 R_AARCH64 = 512 - R_AARCH64_TLSGD_ADR_PAGE21 R_AARCH64 = 513 - R_AARCH64_TLSGD_ADD_LO12_NC R_AARCH64 = 514 - R_AARCH64_TLSGD_MOVW_G1 R_AARCH64 = 515 - R_AARCH64_TLSGD_MOVW_G0_NC R_AARCH64 = 516 - R_AARCH64_TLSLD_ADR_PREL21 R_AARCH64 = 517 - R_AARCH64_TLSLD_ADR_PAGE21 R_AARCH64 = 518 - R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 R_AARCH64 = 539 - R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC R_AARCH64 = 540 - R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 R_AARCH64 = 541 - R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC R_AARCH64 = 542 - R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 R_AARCH64 = 543 - R_AARCH64_TLSLE_MOVW_TPREL_G2 R_AARCH64 = 544 - R_AARCH64_TLSLE_MOVW_TPREL_G1 R_AARCH64 = 545 - R_AARCH64_TLSLE_MOVW_TPREL_G1_NC R_AARCH64 = 546 - R_AARCH64_TLSLE_MOVW_TPREL_G0 R_AARCH64 = 547 - R_AARCH64_TLSLE_MOVW_TPREL_G0_NC R_AARCH64 = 548 - R_AARCH64_TLSLE_ADD_TPREL_HI12 R_AARCH64 = 549 - R_AARCH64_TLSLE_ADD_TPREL_LO12 R_AARCH64 = 550 - R_AARCH64_TLSLE_ADD_TPREL_LO12_NC R_AARCH64 = 551 - R_AARCH64_TLSDESC_LD_PREL19 R_AARCH64 = 560 - R_AARCH64_TLSDESC_ADR_PREL21 R_AARCH64 = 561 - R_AARCH64_TLSDESC_ADR_PAGE21 R_AARCH64 = 562 - R_AARCH64_TLSDESC_LD64_LO12_NC R_AARCH64 = 563 - R_AARCH64_TLSDESC_ADD_LO12_NC R_AARCH64 = 564 - R_AARCH64_TLSDESC_OFF_G1 R_AARCH64 = 565 - R_AARCH64_TLSDESC_OFF_G0_NC R_AARCH64 = 566 - R_AARCH64_TLSDESC_LDR R_AARCH64 = 567 - R_AARCH64_TLSDESC_ADD R_AARCH64 = 568 - R_AARCH64_TLSDESC_CALL R_AARCH64 = 569 - R_AARCH64_TLSLE_LDST128_TPREL_LO12 R_AARCH64 = 570 - R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC R_AARCH64 = 571 - R_AARCH64_TLSLD_LDST128_DTPREL_LO12 R_AARCH64 = 572 - R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC R_AARCH64 = 573 - R_AARCH64_COPY R_AARCH64 = 1024 - R_AARCH64_GLOB_DAT R_AARCH64 = 1025 - R_AARCH64_JUMP_SLOT R_AARCH64 = 1026 - R_AARCH64_RELATIVE R_AARCH64 = 1027 - R_AARCH64_TLS_DTPMOD64 R_AARCH64 = 1028 - R_AARCH64_TLS_DTPREL64 R_AARCH64 = 1029 - R_AARCH64_TLS_TPREL64 R_AARCH64 = 1030 - R_AARCH64_TLSDESC R_AARCH64 = 1031 - R_AARCH64_IRELATIVE R_AARCH64 = 1032 -) - -var raarch64Strings = []intName{ - {0, "R_AARCH64_NONE"}, - {1, "R_AARCH64_P32_ABS32"}, - {2, "R_AARCH64_P32_ABS16"}, - {3, "R_AARCH64_P32_PREL32"}, - {4, "R_AARCH64_P32_PREL16"}, - {5, "R_AARCH64_P32_MOVW_UABS_G0"}, - {6, "R_AARCH64_P32_MOVW_UABS_G0_NC"}, - {7, "R_AARCH64_P32_MOVW_UABS_G1"}, - {8, "R_AARCH64_P32_MOVW_SABS_G0"}, - {9, "R_AARCH64_P32_LD_PREL_LO19"}, - {10, "R_AARCH64_P32_ADR_PREL_LO21"}, - {11, "R_AARCH64_P32_ADR_PREL_PG_HI21"}, - {12, "R_AARCH64_P32_ADD_ABS_LO12_NC"}, - {13, "R_AARCH64_P32_LDST8_ABS_LO12_NC"}, - {14, "R_AARCH64_P32_LDST16_ABS_LO12_NC"}, - {15, "R_AARCH64_P32_LDST32_ABS_LO12_NC"}, - {16, "R_AARCH64_P32_LDST64_ABS_LO12_NC"}, - {17, "R_AARCH64_P32_LDST128_ABS_LO12_NC"}, - {18, "R_AARCH64_P32_TSTBR14"}, - {19, "R_AARCH64_P32_CONDBR19"}, - {20, "R_AARCH64_P32_JUMP26"}, - {21, "R_AARCH64_P32_CALL26"}, - {25, "R_AARCH64_P32_GOT_LD_PREL19"}, - {26, "R_AARCH64_P32_ADR_GOT_PAGE"}, - {27, "R_AARCH64_P32_LD32_GOT_LO12_NC"}, - {81, "R_AARCH64_P32_TLSGD_ADR_PAGE21"}, - {82, "R_AARCH64_P32_TLSGD_ADD_LO12_NC"}, - {103, "R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21"}, - {104, "R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC"}, - {105, "R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19"}, - {106, "R_AARCH64_P32_TLSLE_MOVW_TPREL_G1"}, - {107, "R_AARCH64_P32_TLSLE_MOVW_TPREL_G0"}, - {108, "R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC"}, - {109, "R_AARCH64_P32_TLSLE_ADD_TPREL_HI12"}, - {110, "R_AARCH64_P32_TLSLE_ADD_TPREL_LO12"}, - {111, "R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC"}, - {122, "R_AARCH64_P32_TLSDESC_LD_PREL19"}, - {123, "R_AARCH64_P32_TLSDESC_ADR_PREL21"}, - {124, "R_AARCH64_P32_TLSDESC_ADR_PAGE21"}, - {125, "R_AARCH64_P32_TLSDESC_LD32_LO12_NC"}, - {126, "R_AARCH64_P32_TLSDESC_ADD_LO12_NC"}, - {127, "R_AARCH64_P32_TLSDESC_CALL"}, - {180, "R_AARCH64_P32_COPY"}, - {181, "R_AARCH64_P32_GLOB_DAT"}, - {182, "R_AARCH64_P32_JUMP_SLOT"}, - {183, "R_AARCH64_P32_RELATIVE"}, - {184, "R_AARCH64_P32_TLS_DTPMOD"}, - {185, "R_AARCH64_P32_TLS_DTPREL"}, - {186, "R_AARCH64_P32_TLS_TPREL"}, - {187, "R_AARCH64_P32_TLSDESC"}, - {188, "R_AARCH64_P32_IRELATIVE"}, - {256, "R_AARCH64_NULL"}, - {257, "R_AARCH64_ABS64"}, - {258, "R_AARCH64_ABS32"}, - {259, "R_AARCH64_ABS16"}, - {260, "R_AARCH64_PREL64"}, - {261, "R_AARCH64_PREL32"}, - {262, "R_AARCH64_PREL16"}, - {263, "R_AARCH64_MOVW_UABS_G0"}, - {264, "R_AARCH64_MOVW_UABS_G0_NC"}, - {265, "R_AARCH64_MOVW_UABS_G1"}, - {266, "R_AARCH64_MOVW_UABS_G1_NC"}, - {267, "R_AARCH64_MOVW_UABS_G2"}, - {268, "R_AARCH64_MOVW_UABS_G2_NC"}, - {269, "R_AARCH64_MOVW_UABS_G3"}, - {270, "R_AARCH64_MOVW_SABS_G0"}, - {271, "R_AARCH64_MOVW_SABS_G1"}, - {272, "R_AARCH64_MOVW_SABS_G2"}, - {273, "R_AARCH64_LD_PREL_LO19"}, - {274, "R_AARCH64_ADR_PREL_LO21"}, - {275, "R_AARCH64_ADR_PREL_PG_HI21"}, - {276, "R_AARCH64_ADR_PREL_PG_HI21_NC"}, - {277, "R_AARCH64_ADD_ABS_LO12_NC"}, - {278, "R_AARCH64_LDST8_ABS_LO12_NC"}, - {279, "R_AARCH64_TSTBR14"}, - {280, "R_AARCH64_CONDBR19"}, - {282, "R_AARCH64_JUMP26"}, - {283, "R_AARCH64_CALL26"}, - {284, "R_AARCH64_LDST16_ABS_LO12_NC"}, - {285, "R_AARCH64_LDST32_ABS_LO12_NC"}, - {286, "R_AARCH64_LDST64_ABS_LO12_NC"}, - {299, "R_AARCH64_LDST128_ABS_LO12_NC"}, - {309, "R_AARCH64_GOT_LD_PREL19"}, - {310, "R_AARCH64_LD64_GOTOFF_LO15"}, - {311, "R_AARCH64_ADR_GOT_PAGE"}, - {312, "R_AARCH64_LD64_GOT_LO12_NC"}, - {313, "R_AARCH64_LD64_GOTPAGE_LO15"}, - {512, "R_AARCH64_TLSGD_ADR_PREL21"}, - {513, "R_AARCH64_TLSGD_ADR_PAGE21"}, - {514, "R_AARCH64_TLSGD_ADD_LO12_NC"}, - {515, "R_AARCH64_TLSGD_MOVW_G1"}, - {516, "R_AARCH64_TLSGD_MOVW_G0_NC"}, - {517, "R_AARCH64_TLSLD_ADR_PREL21"}, - {518, "R_AARCH64_TLSLD_ADR_PAGE21"}, - {539, "R_AARCH64_TLSIE_MOVW_GOTTPREL_G1"}, - {540, "R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC"}, - {541, "R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21"}, - {542, "R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC"}, - {543, "R_AARCH64_TLSIE_LD_GOTTPREL_PREL19"}, - {544, "R_AARCH64_TLSLE_MOVW_TPREL_G2"}, - {545, "R_AARCH64_TLSLE_MOVW_TPREL_G1"}, - {546, "R_AARCH64_TLSLE_MOVW_TPREL_G1_NC"}, - {547, "R_AARCH64_TLSLE_MOVW_TPREL_G0"}, - {548, "R_AARCH64_TLSLE_MOVW_TPREL_G0_NC"}, - {549, "R_AARCH64_TLSLE_ADD_TPREL_HI12"}, - {550, "R_AARCH64_TLSLE_ADD_TPREL_LO12"}, - {551, "R_AARCH64_TLSLE_ADD_TPREL_LO12_NC"}, - {560, "R_AARCH64_TLSDESC_LD_PREL19"}, - {561, "R_AARCH64_TLSDESC_ADR_PREL21"}, - {562, "R_AARCH64_TLSDESC_ADR_PAGE21"}, - {563, "R_AARCH64_TLSDESC_LD64_LO12_NC"}, - {564, "R_AARCH64_TLSDESC_ADD_LO12_NC"}, - {565, "R_AARCH64_TLSDESC_OFF_G1"}, - {566, "R_AARCH64_TLSDESC_OFF_G0_NC"}, - {567, "R_AARCH64_TLSDESC_LDR"}, - {568, "R_AARCH64_TLSDESC_ADD"}, - {569, "R_AARCH64_TLSDESC_CALL"}, - {570, "R_AARCH64_TLSLE_LDST128_TPREL_LO12"}, - {571, "R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC"}, - {572, "R_AARCH64_TLSLD_LDST128_DTPREL_LO12"}, - {573, "R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC"}, - {1024, "R_AARCH64_COPY"}, - {1025, "R_AARCH64_GLOB_DAT"}, - {1026, "R_AARCH64_JUMP_SLOT"}, - {1027, "R_AARCH64_RELATIVE"}, - {1028, "R_AARCH64_TLS_DTPMOD64"}, - {1029, "R_AARCH64_TLS_DTPREL64"}, - {1030, "R_AARCH64_TLS_TPREL64"}, - {1031, "R_AARCH64_TLSDESC"}, - {1032, "R_AARCH64_IRELATIVE"}, -} - -func (i R_AARCH64) String() string { return stringName(uint32(i), raarch64Strings, false) } -func (i R_AARCH64) GoString() string { return stringName(uint32(i), raarch64Strings, true) } - -// Relocation types for Alpha. -type R_ALPHA int - -const ( - R_ALPHA_NONE R_ALPHA = 0 /* No reloc */ - R_ALPHA_REFLONG R_ALPHA = 1 /* Direct 32 bit */ - R_ALPHA_REFQUAD R_ALPHA = 2 /* Direct 64 bit */ - R_ALPHA_GPREL32 R_ALPHA = 3 /* GP relative 32 bit */ - R_ALPHA_LITERAL R_ALPHA = 4 /* GP relative 16 bit w/optimization */ - R_ALPHA_LITUSE R_ALPHA = 5 /* Optimization hint for LITERAL */ - R_ALPHA_GPDISP R_ALPHA = 6 /* Add displacement to GP */ - R_ALPHA_BRADDR R_ALPHA = 7 /* PC+4 relative 23 bit shifted */ - R_ALPHA_HINT R_ALPHA = 8 /* PC+4 relative 16 bit shifted */ - R_ALPHA_SREL16 R_ALPHA = 9 /* PC relative 16 bit */ - R_ALPHA_SREL32 R_ALPHA = 10 /* PC relative 32 bit */ - R_ALPHA_SREL64 R_ALPHA = 11 /* PC relative 64 bit */ - R_ALPHA_OP_PUSH R_ALPHA = 12 /* OP stack push */ - R_ALPHA_OP_STORE R_ALPHA = 13 /* OP stack pop and store */ - R_ALPHA_OP_PSUB R_ALPHA = 14 /* OP stack subtract */ - R_ALPHA_OP_PRSHIFT R_ALPHA = 15 /* OP stack right shift */ - R_ALPHA_GPVALUE R_ALPHA = 16 - R_ALPHA_GPRELHIGH R_ALPHA = 17 - R_ALPHA_GPRELLOW R_ALPHA = 18 - R_ALPHA_IMMED_GP_16 R_ALPHA = 19 - R_ALPHA_IMMED_GP_HI32 R_ALPHA = 20 - R_ALPHA_IMMED_SCN_HI32 R_ALPHA = 21 - R_ALPHA_IMMED_BR_HI32 R_ALPHA = 22 - R_ALPHA_IMMED_LO32 R_ALPHA = 23 - R_ALPHA_COPY R_ALPHA = 24 /* Copy symbol at runtime */ - R_ALPHA_GLOB_DAT R_ALPHA = 25 /* Create GOT entry */ - R_ALPHA_JMP_SLOT R_ALPHA = 26 /* Create PLT entry */ - R_ALPHA_RELATIVE R_ALPHA = 27 /* Adjust by program base */ -) - -var ralphaStrings = []intName{ - {0, "R_ALPHA_NONE"}, - {1, "R_ALPHA_REFLONG"}, - {2, "R_ALPHA_REFQUAD"}, - {3, "R_ALPHA_GPREL32"}, - {4, "R_ALPHA_LITERAL"}, - {5, "R_ALPHA_LITUSE"}, - {6, "R_ALPHA_GPDISP"}, - {7, "R_ALPHA_BRADDR"}, - {8, "R_ALPHA_HINT"}, - {9, "R_ALPHA_SREL16"}, - {10, "R_ALPHA_SREL32"}, - {11, "R_ALPHA_SREL64"}, - {12, "R_ALPHA_OP_PUSH"}, - {13, "R_ALPHA_OP_STORE"}, - {14, "R_ALPHA_OP_PSUB"}, - {15, "R_ALPHA_OP_PRSHIFT"}, - {16, "R_ALPHA_GPVALUE"}, - {17, "R_ALPHA_GPRELHIGH"}, - {18, "R_ALPHA_GPRELLOW"}, - {19, "R_ALPHA_IMMED_GP_16"}, - {20, "R_ALPHA_IMMED_GP_HI32"}, - {21, "R_ALPHA_IMMED_SCN_HI32"}, - {22, "R_ALPHA_IMMED_BR_HI32"}, - {23, "R_ALPHA_IMMED_LO32"}, - {24, "R_ALPHA_COPY"}, - {25, "R_ALPHA_GLOB_DAT"}, - {26, "R_ALPHA_JMP_SLOT"}, - {27, "R_ALPHA_RELATIVE"}, -} - -func (i R_ALPHA) String() string { return stringName(uint32(i), ralphaStrings, false) } -func (i R_ALPHA) GoString() string { return stringName(uint32(i), ralphaStrings, true) } - -// Relocation types for ARM. -type R_ARM int - -const ( - R_ARM_NONE R_ARM = 0 /* No relocation. */ - R_ARM_PC24 R_ARM = 1 - R_ARM_ABS32 R_ARM = 2 - R_ARM_REL32 R_ARM = 3 - R_ARM_PC13 R_ARM = 4 - R_ARM_ABS16 R_ARM = 5 - R_ARM_ABS12 R_ARM = 6 - R_ARM_THM_ABS5 R_ARM = 7 - R_ARM_ABS8 R_ARM = 8 - R_ARM_SBREL32 R_ARM = 9 - R_ARM_THM_PC22 R_ARM = 10 - R_ARM_THM_PC8 R_ARM = 11 - R_ARM_AMP_VCALL9 R_ARM = 12 - R_ARM_SWI24 R_ARM = 13 - R_ARM_THM_SWI8 R_ARM = 14 - R_ARM_XPC25 R_ARM = 15 - R_ARM_THM_XPC22 R_ARM = 16 - R_ARM_TLS_DTPMOD32 R_ARM = 17 - R_ARM_TLS_DTPOFF32 R_ARM = 18 - R_ARM_TLS_TPOFF32 R_ARM = 19 - R_ARM_COPY R_ARM = 20 /* Copy data from shared object. */ - R_ARM_GLOB_DAT R_ARM = 21 /* Set GOT entry to data address. */ - R_ARM_JUMP_SLOT R_ARM = 22 /* Set GOT entry to code address. */ - R_ARM_RELATIVE R_ARM = 23 /* Add load address of shared object. */ - R_ARM_GOTOFF R_ARM = 24 /* Add GOT-relative symbol address. */ - R_ARM_GOTPC R_ARM = 25 /* Add PC-relative GOT table address. */ - R_ARM_GOT32 R_ARM = 26 /* Add PC-relative GOT offset. */ - R_ARM_PLT32 R_ARM = 27 /* Add PC-relative PLT offset. */ - R_ARM_CALL R_ARM = 28 - R_ARM_JUMP24 R_ARM = 29 - R_ARM_THM_JUMP24 R_ARM = 30 - R_ARM_BASE_ABS R_ARM = 31 - R_ARM_ALU_PCREL_7_0 R_ARM = 32 - R_ARM_ALU_PCREL_15_8 R_ARM = 33 - R_ARM_ALU_PCREL_23_15 R_ARM = 34 - R_ARM_LDR_SBREL_11_10_NC R_ARM = 35 - R_ARM_ALU_SBREL_19_12_NC R_ARM = 36 - R_ARM_ALU_SBREL_27_20_CK R_ARM = 37 - R_ARM_TARGET1 R_ARM = 38 - R_ARM_SBREL31 R_ARM = 39 - R_ARM_V4BX R_ARM = 40 - R_ARM_TARGET2 R_ARM = 41 - R_ARM_PREL31 R_ARM = 42 - R_ARM_MOVW_ABS_NC R_ARM = 43 - R_ARM_MOVT_ABS R_ARM = 44 - R_ARM_MOVW_PREL_NC R_ARM = 45 - R_ARM_MOVT_PREL R_ARM = 46 - R_ARM_THM_MOVW_ABS_NC R_ARM = 47 - R_ARM_THM_MOVT_ABS R_ARM = 48 - R_ARM_THM_MOVW_PREL_NC R_ARM = 49 - R_ARM_THM_MOVT_PREL R_ARM = 50 - R_ARM_THM_JUMP19 R_ARM = 51 - R_ARM_THM_JUMP6 R_ARM = 52 - R_ARM_THM_ALU_PREL_11_0 R_ARM = 53 - R_ARM_THM_PC12 R_ARM = 54 - R_ARM_ABS32_NOI R_ARM = 55 - R_ARM_REL32_NOI R_ARM = 56 - R_ARM_ALU_PC_G0_NC R_ARM = 57 - R_ARM_ALU_PC_G0 R_ARM = 58 - R_ARM_ALU_PC_G1_NC R_ARM = 59 - R_ARM_ALU_PC_G1 R_ARM = 60 - R_ARM_ALU_PC_G2 R_ARM = 61 - R_ARM_LDR_PC_G1 R_ARM = 62 - R_ARM_LDR_PC_G2 R_ARM = 63 - R_ARM_LDRS_PC_G0 R_ARM = 64 - R_ARM_LDRS_PC_G1 R_ARM = 65 - R_ARM_LDRS_PC_G2 R_ARM = 66 - R_ARM_LDC_PC_G0 R_ARM = 67 - R_ARM_LDC_PC_G1 R_ARM = 68 - R_ARM_LDC_PC_G2 R_ARM = 69 - R_ARM_ALU_SB_G0_NC R_ARM = 70 - R_ARM_ALU_SB_G0 R_ARM = 71 - R_ARM_ALU_SB_G1_NC R_ARM = 72 - R_ARM_ALU_SB_G1 R_ARM = 73 - R_ARM_ALU_SB_G2 R_ARM = 74 - R_ARM_LDR_SB_G0 R_ARM = 75 - R_ARM_LDR_SB_G1 R_ARM = 76 - R_ARM_LDR_SB_G2 R_ARM = 77 - R_ARM_LDRS_SB_G0 R_ARM = 78 - R_ARM_LDRS_SB_G1 R_ARM = 79 - R_ARM_LDRS_SB_G2 R_ARM = 80 - R_ARM_LDC_SB_G0 R_ARM = 81 - R_ARM_LDC_SB_G1 R_ARM = 82 - R_ARM_LDC_SB_G2 R_ARM = 83 - R_ARM_MOVW_BREL_NC R_ARM = 84 - R_ARM_MOVT_BREL R_ARM = 85 - R_ARM_MOVW_BREL R_ARM = 86 - R_ARM_THM_MOVW_BREL_NC R_ARM = 87 - R_ARM_THM_MOVT_BREL R_ARM = 88 - R_ARM_THM_MOVW_BREL R_ARM = 89 - R_ARM_TLS_GOTDESC R_ARM = 90 - R_ARM_TLS_CALL R_ARM = 91 - R_ARM_TLS_DESCSEQ R_ARM = 92 - R_ARM_THM_TLS_CALL R_ARM = 93 - R_ARM_PLT32_ABS R_ARM = 94 - R_ARM_GOT_ABS R_ARM = 95 - R_ARM_GOT_PREL R_ARM = 96 - R_ARM_GOT_BREL12 R_ARM = 97 - R_ARM_GOTOFF12 R_ARM = 98 - R_ARM_GOTRELAX R_ARM = 99 - R_ARM_GNU_VTENTRY R_ARM = 100 - R_ARM_GNU_VTINHERIT R_ARM = 101 - R_ARM_THM_JUMP11 R_ARM = 102 - R_ARM_THM_JUMP8 R_ARM = 103 - R_ARM_TLS_GD32 R_ARM = 104 - R_ARM_TLS_LDM32 R_ARM = 105 - R_ARM_TLS_LDO32 R_ARM = 106 - R_ARM_TLS_IE32 R_ARM = 107 - R_ARM_TLS_LE32 R_ARM = 108 - R_ARM_TLS_LDO12 R_ARM = 109 - R_ARM_TLS_LE12 R_ARM = 110 - R_ARM_TLS_IE12GP R_ARM = 111 - R_ARM_PRIVATE_0 R_ARM = 112 - R_ARM_PRIVATE_1 R_ARM = 113 - R_ARM_PRIVATE_2 R_ARM = 114 - R_ARM_PRIVATE_3 R_ARM = 115 - R_ARM_PRIVATE_4 R_ARM = 116 - R_ARM_PRIVATE_5 R_ARM = 117 - R_ARM_PRIVATE_6 R_ARM = 118 - R_ARM_PRIVATE_7 R_ARM = 119 - R_ARM_PRIVATE_8 R_ARM = 120 - R_ARM_PRIVATE_9 R_ARM = 121 - R_ARM_PRIVATE_10 R_ARM = 122 - R_ARM_PRIVATE_11 R_ARM = 123 - R_ARM_PRIVATE_12 R_ARM = 124 - R_ARM_PRIVATE_13 R_ARM = 125 - R_ARM_PRIVATE_14 R_ARM = 126 - R_ARM_PRIVATE_15 R_ARM = 127 - R_ARM_ME_TOO R_ARM = 128 - R_ARM_THM_TLS_DESCSEQ16 R_ARM = 129 - R_ARM_THM_TLS_DESCSEQ32 R_ARM = 130 - R_ARM_THM_GOT_BREL12 R_ARM = 131 - R_ARM_THM_ALU_ABS_G0_NC R_ARM = 132 - R_ARM_THM_ALU_ABS_G1_NC R_ARM = 133 - R_ARM_THM_ALU_ABS_G2_NC R_ARM = 134 - R_ARM_THM_ALU_ABS_G3 R_ARM = 135 - R_ARM_IRELATIVE R_ARM = 160 - R_ARM_RXPC25 R_ARM = 249 - R_ARM_RSBREL32 R_ARM = 250 - R_ARM_THM_RPC22 R_ARM = 251 - R_ARM_RREL32 R_ARM = 252 - R_ARM_RABS32 R_ARM = 253 - R_ARM_RPC24 R_ARM = 254 - R_ARM_RBASE R_ARM = 255 -) - -var rarmStrings = []intName{ - {0, "R_ARM_NONE"}, - {1, "R_ARM_PC24"}, - {2, "R_ARM_ABS32"}, - {3, "R_ARM_REL32"}, - {4, "R_ARM_PC13"}, - {5, "R_ARM_ABS16"}, - {6, "R_ARM_ABS12"}, - {7, "R_ARM_THM_ABS5"}, - {8, "R_ARM_ABS8"}, - {9, "R_ARM_SBREL32"}, - {10, "R_ARM_THM_PC22"}, - {11, "R_ARM_THM_PC8"}, - {12, "R_ARM_AMP_VCALL9"}, - {13, "R_ARM_SWI24"}, - {14, "R_ARM_THM_SWI8"}, - {15, "R_ARM_XPC25"}, - {16, "R_ARM_THM_XPC22"}, - {17, "R_ARM_TLS_DTPMOD32"}, - {18, "R_ARM_TLS_DTPOFF32"}, - {19, "R_ARM_TLS_TPOFF32"}, - {20, "R_ARM_COPY"}, - {21, "R_ARM_GLOB_DAT"}, - {22, "R_ARM_JUMP_SLOT"}, - {23, "R_ARM_RELATIVE"}, - {24, "R_ARM_GOTOFF"}, - {25, "R_ARM_GOTPC"}, - {26, "R_ARM_GOT32"}, - {27, "R_ARM_PLT32"}, - {28, "R_ARM_CALL"}, - {29, "R_ARM_JUMP24"}, - {30, "R_ARM_THM_JUMP24"}, - {31, "R_ARM_BASE_ABS"}, - {32, "R_ARM_ALU_PCREL_7_0"}, - {33, "R_ARM_ALU_PCREL_15_8"}, - {34, "R_ARM_ALU_PCREL_23_15"}, - {35, "R_ARM_LDR_SBREL_11_10_NC"}, - {36, "R_ARM_ALU_SBREL_19_12_NC"}, - {37, "R_ARM_ALU_SBREL_27_20_CK"}, - {38, "R_ARM_TARGET1"}, - {39, "R_ARM_SBREL31"}, - {40, "R_ARM_V4BX"}, - {41, "R_ARM_TARGET2"}, - {42, "R_ARM_PREL31"}, - {43, "R_ARM_MOVW_ABS_NC"}, - {44, "R_ARM_MOVT_ABS"}, - {45, "R_ARM_MOVW_PREL_NC"}, - {46, "R_ARM_MOVT_PREL"}, - {47, "R_ARM_THM_MOVW_ABS_NC"}, - {48, "R_ARM_THM_MOVT_ABS"}, - {49, "R_ARM_THM_MOVW_PREL_NC"}, - {50, "R_ARM_THM_MOVT_PREL"}, - {51, "R_ARM_THM_JUMP19"}, - {52, "R_ARM_THM_JUMP6"}, - {53, "R_ARM_THM_ALU_PREL_11_0"}, - {54, "R_ARM_THM_PC12"}, - {55, "R_ARM_ABS32_NOI"}, - {56, "R_ARM_REL32_NOI"}, - {57, "R_ARM_ALU_PC_G0_NC"}, - {58, "R_ARM_ALU_PC_G0"}, - {59, "R_ARM_ALU_PC_G1_NC"}, - {60, "R_ARM_ALU_PC_G1"}, - {61, "R_ARM_ALU_PC_G2"}, - {62, "R_ARM_LDR_PC_G1"}, - {63, "R_ARM_LDR_PC_G2"}, - {64, "R_ARM_LDRS_PC_G0"}, - {65, "R_ARM_LDRS_PC_G1"}, - {66, "R_ARM_LDRS_PC_G2"}, - {67, "R_ARM_LDC_PC_G0"}, - {68, "R_ARM_LDC_PC_G1"}, - {69, "R_ARM_LDC_PC_G2"}, - {70, "R_ARM_ALU_SB_G0_NC"}, - {71, "R_ARM_ALU_SB_G0"}, - {72, "R_ARM_ALU_SB_G1_NC"}, - {73, "R_ARM_ALU_SB_G1"}, - {74, "R_ARM_ALU_SB_G2"}, - {75, "R_ARM_LDR_SB_G0"}, - {76, "R_ARM_LDR_SB_G1"}, - {77, "R_ARM_LDR_SB_G2"}, - {78, "R_ARM_LDRS_SB_G0"}, - {79, "R_ARM_LDRS_SB_G1"}, - {80, "R_ARM_LDRS_SB_G2"}, - {81, "R_ARM_LDC_SB_G0"}, - {82, "R_ARM_LDC_SB_G1"}, - {83, "R_ARM_LDC_SB_G2"}, - {84, "R_ARM_MOVW_BREL_NC"}, - {85, "R_ARM_MOVT_BREL"}, - {86, "R_ARM_MOVW_BREL"}, - {87, "R_ARM_THM_MOVW_BREL_NC"}, - {88, "R_ARM_THM_MOVT_BREL"}, - {89, "R_ARM_THM_MOVW_BREL"}, - {90, "R_ARM_TLS_GOTDESC"}, - {91, "R_ARM_TLS_CALL"}, - {92, "R_ARM_TLS_DESCSEQ"}, - {93, "R_ARM_THM_TLS_CALL"}, - {94, "R_ARM_PLT32_ABS"}, - {95, "R_ARM_GOT_ABS"}, - {96, "R_ARM_GOT_PREL"}, - {97, "R_ARM_GOT_BREL12"}, - {98, "R_ARM_GOTOFF12"}, - {99, "R_ARM_GOTRELAX"}, - {100, "R_ARM_GNU_VTENTRY"}, - {101, "R_ARM_GNU_VTINHERIT"}, - {102, "R_ARM_THM_JUMP11"}, - {103, "R_ARM_THM_JUMP8"}, - {104, "R_ARM_TLS_GD32"}, - {105, "R_ARM_TLS_LDM32"}, - {106, "R_ARM_TLS_LDO32"}, - {107, "R_ARM_TLS_IE32"}, - {108, "R_ARM_TLS_LE32"}, - {109, "R_ARM_TLS_LDO12"}, - {110, "R_ARM_TLS_LE12"}, - {111, "R_ARM_TLS_IE12GP"}, - {112, "R_ARM_PRIVATE_0"}, - {113, "R_ARM_PRIVATE_1"}, - {114, "R_ARM_PRIVATE_2"}, - {115, "R_ARM_PRIVATE_3"}, - {116, "R_ARM_PRIVATE_4"}, - {117, "R_ARM_PRIVATE_5"}, - {118, "R_ARM_PRIVATE_6"}, - {119, "R_ARM_PRIVATE_7"}, - {120, "R_ARM_PRIVATE_8"}, - {121, "R_ARM_PRIVATE_9"}, - {122, "R_ARM_PRIVATE_10"}, - {123, "R_ARM_PRIVATE_11"}, - {124, "R_ARM_PRIVATE_12"}, - {125, "R_ARM_PRIVATE_13"}, - {126, "R_ARM_PRIVATE_14"}, - {127, "R_ARM_PRIVATE_15"}, - {128, "R_ARM_ME_TOO"}, - {129, "R_ARM_THM_TLS_DESCSEQ16"}, - {130, "R_ARM_THM_TLS_DESCSEQ32"}, - {131, "R_ARM_THM_GOT_BREL12"}, - {132, "R_ARM_THM_ALU_ABS_G0_NC"}, - {133, "R_ARM_THM_ALU_ABS_G1_NC"}, - {134, "R_ARM_THM_ALU_ABS_G2_NC"}, - {135, "R_ARM_THM_ALU_ABS_G3"}, - {160, "R_ARM_IRELATIVE"}, - {249, "R_ARM_RXPC25"}, - {250, "R_ARM_RSBREL32"}, - {251, "R_ARM_THM_RPC22"}, - {252, "R_ARM_RREL32"}, - {253, "R_ARM_RABS32"}, - {254, "R_ARM_RPC24"}, - {255, "R_ARM_RBASE"}, -} - -func (i R_ARM) String() string { return stringName(uint32(i), rarmStrings, false) } -func (i R_ARM) GoString() string { return stringName(uint32(i), rarmStrings, true) } - -// Relocation types for 386. -type R_386 int - -const ( - R_386_NONE R_386 = 0 /* No relocation. */ - R_386_32 R_386 = 1 /* Add symbol value. */ - R_386_PC32 R_386 = 2 /* Add PC-relative symbol value. */ - R_386_GOT32 R_386 = 3 /* Add PC-relative GOT offset. */ - R_386_PLT32 R_386 = 4 /* Add PC-relative PLT offset. */ - R_386_COPY R_386 = 5 /* Copy data from shared object. */ - R_386_GLOB_DAT R_386 = 6 /* Set GOT entry to data address. */ - R_386_JMP_SLOT R_386 = 7 /* Set GOT entry to code address. */ - R_386_RELATIVE R_386 = 8 /* Add load address of shared object. */ - R_386_GOTOFF R_386 = 9 /* Add GOT-relative symbol address. */ - R_386_GOTPC R_386 = 10 /* Add PC-relative GOT table address. */ - R_386_32PLT R_386 = 11 - R_386_TLS_TPOFF R_386 = 14 /* Negative offset in static TLS block */ - R_386_TLS_IE R_386 = 15 /* Absolute address of GOT for -ve static TLS */ - R_386_TLS_GOTIE R_386 = 16 /* GOT entry for negative static TLS block */ - R_386_TLS_LE R_386 = 17 /* Negative offset relative to static TLS */ - R_386_TLS_GD R_386 = 18 /* 32 bit offset to GOT (index,off) pair */ - R_386_TLS_LDM R_386 = 19 /* 32 bit offset to GOT (index,zero) pair */ - R_386_16 R_386 = 20 - R_386_PC16 R_386 = 21 - R_386_8 R_386 = 22 - R_386_PC8 R_386 = 23 - R_386_TLS_GD_32 R_386 = 24 /* 32 bit offset to GOT (index,off) pair */ - R_386_TLS_GD_PUSH R_386 = 25 /* pushl instruction for Sun ABI GD sequence */ - R_386_TLS_GD_CALL R_386 = 26 /* call instruction for Sun ABI GD sequence */ - R_386_TLS_GD_POP R_386 = 27 /* popl instruction for Sun ABI GD sequence */ - R_386_TLS_LDM_32 R_386 = 28 /* 32 bit offset to GOT (index,zero) pair */ - R_386_TLS_LDM_PUSH R_386 = 29 /* pushl instruction for Sun ABI LD sequence */ - R_386_TLS_LDM_CALL R_386 = 30 /* call instruction for Sun ABI LD sequence */ - R_386_TLS_LDM_POP R_386 = 31 /* popl instruction for Sun ABI LD sequence */ - R_386_TLS_LDO_32 R_386 = 32 /* 32 bit offset from start of TLS block */ - R_386_TLS_IE_32 R_386 = 33 /* 32 bit offset to GOT static TLS offset entry */ - R_386_TLS_LE_32 R_386 = 34 /* 32 bit offset within static TLS block */ - R_386_TLS_DTPMOD32 R_386 = 35 /* GOT entry containing TLS index */ - R_386_TLS_DTPOFF32 R_386 = 36 /* GOT entry containing TLS offset */ - R_386_TLS_TPOFF32 R_386 = 37 /* GOT entry of -ve static TLS offset */ - R_386_SIZE32 R_386 = 38 - R_386_TLS_GOTDESC R_386 = 39 - R_386_TLS_DESC_CALL R_386 = 40 - R_386_TLS_DESC R_386 = 41 - R_386_IRELATIVE R_386 = 42 - R_386_GOT32X R_386 = 43 -) - -var r386Strings = []intName{ - {0, "R_386_NONE"}, - {1, "R_386_32"}, - {2, "R_386_PC32"}, - {3, "R_386_GOT32"}, - {4, "R_386_PLT32"}, - {5, "R_386_COPY"}, - {6, "R_386_GLOB_DAT"}, - {7, "R_386_JMP_SLOT"}, - {8, "R_386_RELATIVE"}, - {9, "R_386_GOTOFF"}, - {10, "R_386_GOTPC"}, - {11, "R_386_32PLT"}, - {14, "R_386_TLS_TPOFF"}, - {15, "R_386_TLS_IE"}, - {16, "R_386_TLS_GOTIE"}, - {17, "R_386_TLS_LE"}, - {18, "R_386_TLS_GD"}, - {19, "R_386_TLS_LDM"}, - {20, "R_386_16"}, - {21, "R_386_PC16"}, - {22, "R_386_8"}, - {23, "R_386_PC8"}, - {24, "R_386_TLS_GD_32"}, - {25, "R_386_TLS_GD_PUSH"}, - {26, "R_386_TLS_GD_CALL"}, - {27, "R_386_TLS_GD_POP"}, - {28, "R_386_TLS_LDM_32"}, - {29, "R_386_TLS_LDM_PUSH"}, - {30, "R_386_TLS_LDM_CALL"}, - {31, "R_386_TLS_LDM_POP"}, - {32, "R_386_TLS_LDO_32"}, - {33, "R_386_TLS_IE_32"}, - {34, "R_386_TLS_LE_32"}, - {35, "R_386_TLS_DTPMOD32"}, - {36, "R_386_TLS_DTPOFF32"}, - {37, "R_386_TLS_TPOFF32"}, - {38, "R_386_SIZE32"}, - {39, "R_386_TLS_GOTDESC"}, - {40, "R_386_TLS_DESC_CALL"}, - {41, "R_386_TLS_DESC"}, - {42, "R_386_IRELATIVE"}, - {43, "R_386_GOT32X"}, -} - -func (i R_386) String() string { return stringName(uint32(i), r386Strings, false) } -func (i R_386) GoString() string { return stringName(uint32(i), r386Strings, true) } - -// Relocation types for MIPS. -type R_MIPS int - -const ( - R_MIPS_NONE R_MIPS = 0 - R_MIPS_16 R_MIPS = 1 - R_MIPS_32 R_MIPS = 2 - R_MIPS_REL32 R_MIPS = 3 - R_MIPS_26 R_MIPS = 4 - R_MIPS_HI16 R_MIPS = 5 /* high 16 bits of symbol value */ - R_MIPS_LO16 R_MIPS = 6 /* low 16 bits of symbol value */ - R_MIPS_GPREL16 R_MIPS = 7 /* GP-relative reference */ - R_MIPS_LITERAL R_MIPS = 8 /* Reference to literal section */ - R_MIPS_GOT16 R_MIPS = 9 /* Reference to global offset table */ - R_MIPS_PC16 R_MIPS = 10 /* 16 bit PC relative reference */ - R_MIPS_CALL16 R_MIPS = 11 /* 16 bit call through glbl offset tbl */ - R_MIPS_GPREL32 R_MIPS = 12 - R_MIPS_SHIFT5 R_MIPS = 16 - R_MIPS_SHIFT6 R_MIPS = 17 - R_MIPS_64 R_MIPS = 18 - R_MIPS_GOT_DISP R_MIPS = 19 - R_MIPS_GOT_PAGE R_MIPS = 20 - R_MIPS_GOT_OFST R_MIPS = 21 - R_MIPS_GOT_HI16 R_MIPS = 22 - R_MIPS_GOT_LO16 R_MIPS = 23 - R_MIPS_SUB R_MIPS = 24 - R_MIPS_INSERT_A R_MIPS = 25 - R_MIPS_INSERT_B R_MIPS = 26 - R_MIPS_DELETE R_MIPS = 27 - R_MIPS_HIGHER R_MIPS = 28 - R_MIPS_HIGHEST R_MIPS = 29 - R_MIPS_CALL_HI16 R_MIPS = 30 - R_MIPS_CALL_LO16 R_MIPS = 31 - R_MIPS_SCN_DISP R_MIPS = 32 - R_MIPS_REL16 R_MIPS = 33 - R_MIPS_ADD_IMMEDIATE R_MIPS = 34 - R_MIPS_PJUMP R_MIPS = 35 - R_MIPS_RELGOT R_MIPS = 36 - R_MIPS_JALR R_MIPS = 37 - - R_MIPS_TLS_DTPMOD32 R_MIPS = 38 /* Module number 32 bit */ - R_MIPS_TLS_DTPREL32 R_MIPS = 39 /* Module-relative offset 32 bit */ - R_MIPS_TLS_DTPMOD64 R_MIPS = 40 /* Module number 64 bit */ - R_MIPS_TLS_DTPREL64 R_MIPS = 41 /* Module-relative offset 64 bit */ - R_MIPS_TLS_GD R_MIPS = 42 /* 16 bit GOT offset for GD */ - R_MIPS_TLS_LDM R_MIPS = 43 /* 16 bit GOT offset for LDM */ - R_MIPS_TLS_DTPREL_HI16 R_MIPS = 44 /* Module-relative offset, high 16 bits */ - R_MIPS_TLS_DTPREL_LO16 R_MIPS = 45 /* Module-relative offset, low 16 bits */ - R_MIPS_TLS_GOTTPREL R_MIPS = 46 /* 16 bit GOT offset for IE */ - R_MIPS_TLS_TPREL32 R_MIPS = 47 /* TP-relative offset, 32 bit */ - R_MIPS_TLS_TPREL64 R_MIPS = 48 /* TP-relative offset, 64 bit */ - R_MIPS_TLS_TPREL_HI16 R_MIPS = 49 /* TP-relative offset, high 16 bits */ - R_MIPS_TLS_TPREL_LO16 R_MIPS = 50 /* TP-relative offset, low 16 bits */ -) - -var rmipsStrings = []intName{ - {0, "R_MIPS_NONE"}, - {1, "R_MIPS_16"}, - {2, "R_MIPS_32"}, - {3, "R_MIPS_REL32"}, - {4, "R_MIPS_26"}, - {5, "R_MIPS_HI16"}, - {6, "R_MIPS_LO16"}, - {7, "R_MIPS_GPREL16"}, - {8, "R_MIPS_LITERAL"}, - {9, "R_MIPS_GOT16"}, - {10, "R_MIPS_PC16"}, - {11, "R_MIPS_CALL16"}, - {12, "R_MIPS_GPREL32"}, - {16, "R_MIPS_SHIFT5"}, - {17, "R_MIPS_SHIFT6"}, - {18, "R_MIPS_64"}, - {19, "R_MIPS_GOT_DISP"}, - {20, "R_MIPS_GOT_PAGE"}, - {21, "R_MIPS_GOT_OFST"}, - {22, "R_MIPS_GOT_HI16"}, - {23, "R_MIPS_GOT_LO16"}, - {24, "R_MIPS_SUB"}, - {25, "R_MIPS_INSERT_A"}, - {26, "R_MIPS_INSERT_B"}, - {27, "R_MIPS_DELETE"}, - {28, "R_MIPS_HIGHER"}, - {29, "R_MIPS_HIGHEST"}, - {30, "R_MIPS_CALL_HI16"}, - {31, "R_MIPS_CALL_LO16"}, - {32, "R_MIPS_SCN_DISP"}, - {33, "R_MIPS_REL16"}, - {34, "R_MIPS_ADD_IMMEDIATE"}, - {35, "R_MIPS_PJUMP"}, - {36, "R_MIPS_RELGOT"}, - {37, "R_MIPS_JALR"}, - {38, "R_MIPS_TLS_DTPMOD32"}, - {39, "R_MIPS_TLS_DTPREL32"}, - {40, "R_MIPS_TLS_DTPMOD64"}, - {41, "R_MIPS_TLS_DTPREL64"}, - {42, "R_MIPS_TLS_GD"}, - {43, "R_MIPS_TLS_LDM"}, - {44, "R_MIPS_TLS_DTPREL_HI16"}, - {45, "R_MIPS_TLS_DTPREL_LO16"}, - {46, "R_MIPS_TLS_GOTTPREL"}, - {47, "R_MIPS_TLS_TPREL32"}, - {48, "R_MIPS_TLS_TPREL64"}, - {49, "R_MIPS_TLS_TPREL_HI16"}, - {50, "R_MIPS_TLS_TPREL_LO16"}, -} - -func (i R_MIPS) String() string { return stringName(uint32(i), rmipsStrings, false) } -func (i R_MIPS) GoString() string { return stringName(uint32(i), rmipsStrings, true) } - -// Relocation types for PowerPC. -// -// Values that are shared by both R_PPC and R_PPC64 are prefixed with -// R_POWERPC_ in the ELF standard. For the R_PPC type, the relevant -// shared relocations have been renamed with the prefix R_PPC_. -// The original name follows the value in a comment. -type R_PPC int - -const ( - R_PPC_NONE R_PPC = 0 // R_POWERPC_NONE - R_PPC_ADDR32 R_PPC = 1 // R_POWERPC_ADDR32 - R_PPC_ADDR24 R_PPC = 2 // R_POWERPC_ADDR24 - R_PPC_ADDR16 R_PPC = 3 // R_POWERPC_ADDR16 - R_PPC_ADDR16_LO R_PPC = 4 // R_POWERPC_ADDR16_LO - R_PPC_ADDR16_HI R_PPC = 5 // R_POWERPC_ADDR16_HI - R_PPC_ADDR16_HA R_PPC = 6 // R_POWERPC_ADDR16_HA - R_PPC_ADDR14 R_PPC = 7 // R_POWERPC_ADDR14 - R_PPC_ADDR14_BRTAKEN R_PPC = 8 // R_POWERPC_ADDR14_BRTAKEN - R_PPC_ADDR14_BRNTAKEN R_PPC = 9 // R_POWERPC_ADDR14_BRNTAKEN - R_PPC_REL24 R_PPC = 10 // R_POWERPC_REL24 - R_PPC_REL14 R_PPC = 11 // R_POWERPC_REL14 - R_PPC_REL14_BRTAKEN R_PPC = 12 // R_POWERPC_REL14_BRTAKEN - R_PPC_REL14_BRNTAKEN R_PPC = 13 // R_POWERPC_REL14_BRNTAKEN - R_PPC_GOT16 R_PPC = 14 // R_POWERPC_GOT16 - R_PPC_GOT16_LO R_PPC = 15 // R_POWERPC_GOT16_LO - R_PPC_GOT16_HI R_PPC = 16 // R_POWERPC_GOT16_HI - R_PPC_GOT16_HA R_PPC = 17 // R_POWERPC_GOT16_HA - R_PPC_PLTREL24 R_PPC = 18 - R_PPC_COPY R_PPC = 19 // R_POWERPC_COPY - R_PPC_GLOB_DAT R_PPC = 20 // R_POWERPC_GLOB_DAT - R_PPC_JMP_SLOT R_PPC = 21 // R_POWERPC_JMP_SLOT - R_PPC_RELATIVE R_PPC = 22 // R_POWERPC_RELATIVE - R_PPC_LOCAL24PC R_PPC = 23 - R_PPC_UADDR32 R_PPC = 24 // R_POWERPC_UADDR32 - R_PPC_UADDR16 R_PPC = 25 // R_POWERPC_UADDR16 - R_PPC_REL32 R_PPC = 26 // R_POWERPC_REL32 - R_PPC_PLT32 R_PPC = 27 // R_POWERPC_PLT32 - R_PPC_PLTREL32 R_PPC = 28 // R_POWERPC_PLTREL32 - R_PPC_PLT16_LO R_PPC = 29 // R_POWERPC_PLT16_LO - R_PPC_PLT16_HI R_PPC = 30 // R_POWERPC_PLT16_HI - R_PPC_PLT16_HA R_PPC = 31 // R_POWERPC_PLT16_HA - R_PPC_SDAREL16 R_PPC = 32 - R_PPC_SECTOFF R_PPC = 33 // R_POWERPC_SECTOFF - R_PPC_SECTOFF_LO R_PPC = 34 // R_POWERPC_SECTOFF_LO - R_PPC_SECTOFF_HI R_PPC = 35 // R_POWERPC_SECTOFF_HI - R_PPC_SECTOFF_HA R_PPC = 36 // R_POWERPC_SECTOFF_HA - R_PPC_TLS R_PPC = 67 // R_POWERPC_TLS - R_PPC_DTPMOD32 R_PPC = 68 // R_POWERPC_DTPMOD32 - R_PPC_TPREL16 R_PPC = 69 // R_POWERPC_TPREL16 - R_PPC_TPREL16_LO R_PPC = 70 // R_POWERPC_TPREL16_LO - R_PPC_TPREL16_HI R_PPC = 71 // R_POWERPC_TPREL16_HI - R_PPC_TPREL16_HA R_PPC = 72 // R_POWERPC_TPREL16_HA - R_PPC_TPREL32 R_PPC = 73 // R_POWERPC_TPREL32 - R_PPC_DTPREL16 R_PPC = 74 // R_POWERPC_DTPREL16 - R_PPC_DTPREL16_LO R_PPC = 75 // R_POWERPC_DTPREL16_LO - R_PPC_DTPREL16_HI R_PPC = 76 // R_POWERPC_DTPREL16_HI - R_PPC_DTPREL16_HA R_PPC = 77 // R_POWERPC_DTPREL16_HA - R_PPC_DTPREL32 R_PPC = 78 // R_POWERPC_DTPREL32 - R_PPC_GOT_TLSGD16 R_PPC = 79 // R_POWERPC_GOT_TLSGD16 - R_PPC_GOT_TLSGD16_LO R_PPC = 80 // R_POWERPC_GOT_TLSGD16_LO - R_PPC_GOT_TLSGD16_HI R_PPC = 81 // R_POWERPC_GOT_TLSGD16_HI - R_PPC_GOT_TLSGD16_HA R_PPC = 82 // R_POWERPC_GOT_TLSGD16_HA - R_PPC_GOT_TLSLD16 R_PPC = 83 // R_POWERPC_GOT_TLSLD16 - R_PPC_GOT_TLSLD16_LO R_PPC = 84 // R_POWERPC_GOT_TLSLD16_LO - R_PPC_GOT_TLSLD16_HI R_PPC = 85 // R_POWERPC_GOT_TLSLD16_HI - R_PPC_GOT_TLSLD16_HA R_PPC = 86 // R_POWERPC_GOT_TLSLD16_HA - R_PPC_GOT_TPREL16 R_PPC = 87 // R_POWERPC_GOT_TPREL16 - R_PPC_GOT_TPREL16_LO R_PPC = 88 // R_POWERPC_GOT_TPREL16_LO - R_PPC_GOT_TPREL16_HI R_PPC = 89 // R_POWERPC_GOT_TPREL16_HI - R_PPC_GOT_TPREL16_HA R_PPC = 90 // R_POWERPC_GOT_TPREL16_HA - R_PPC_EMB_NADDR32 R_PPC = 101 - R_PPC_EMB_NADDR16 R_PPC = 102 - R_PPC_EMB_NADDR16_LO R_PPC = 103 - R_PPC_EMB_NADDR16_HI R_PPC = 104 - R_PPC_EMB_NADDR16_HA R_PPC = 105 - R_PPC_EMB_SDAI16 R_PPC = 106 - R_PPC_EMB_SDA2I16 R_PPC = 107 - R_PPC_EMB_SDA2REL R_PPC = 108 - R_PPC_EMB_SDA21 R_PPC = 109 - R_PPC_EMB_MRKREF R_PPC = 110 - R_PPC_EMB_RELSEC16 R_PPC = 111 - R_PPC_EMB_RELST_LO R_PPC = 112 - R_PPC_EMB_RELST_HI R_PPC = 113 - R_PPC_EMB_RELST_HA R_PPC = 114 - R_PPC_EMB_BIT_FLD R_PPC = 115 - R_PPC_EMB_RELSDA R_PPC = 116 -) - -var rppcStrings = []intName{ - {0, "R_PPC_NONE"}, - {1, "R_PPC_ADDR32"}, - {2, "R_PPC_ADDR24"}, - {3, "R_PPC_ADDR16"}, - {4, "R_PPC_ADDR16_LO"}, - {5, "R_PPC_ADDR16_HI"}, - {6, "R_PPC_ADDR16_HA"}, - {7, "R_PPC_ADDR14"}, - {8, "R_PPC_ADDR14_BRTAKEN"}, - {9, "R_PPC_ADDR14_BRNTAKEN"}, - {10, "R_PPC_REL24"}, - {11, "R_PPC_REL14"}, - {12, "R_PPC_REL14_BRTAKEN"}, - {13, "R_PPC_REL14_BRNTAKEN"}, - {14, "R_PPC_GOT16"}, - {15, "R_PPC_GOT16_LO"}, - {16, "R_PPC_GOT16_HI"}, - {17, "R_PPC_GOT16_HA"}, - {18, "R_PPC_PLTREL24"}, - {19, "R_PPC_COPY"}, - {20, "R_PPC_GLOB_DAT"}, - {21, "R_PPC_JMP_SLOT"}, - {22, "R_PPC_RELATIVE"}, - {23, "R_PPC_LOCAL24PC"}, - {24, "R_PPC_UADDR32"}, - {25, "R_PPC_UADDR16"}, - {26, "R_PPC_REL32"}, - {27, "R_PPC_PLT32"}, - {28, "R_PPC_PLTREL32"}, - {29, "R_PPC_PLT16_LO"}, - {30, "R_PPC_PLT16_HI"}, - {31, "R_PPC_PLT16_HA"}, - {32, "R_PPC_SDAREL16"}, - {33, "R_PPC_SECTOFF"}, - {34, "R_PPC_SECTOFF_LO"}, - {35, "R_PPC_SECTOFF_HI"}, - {36, "R_PPC_SECTOFF_HA"}, - {67, "R_PPC_TLS"}, - {68, "R_PPC_DTPMOD32"}, - {69, "R_PPC_TPREL16"}, - {70, "R_PPC_TPREL16_LO"}, - {71, "R_PPC_TPREL16_HI"}, - {72, "R_PPC_TPREL16_HA"}, - {73, "R_PPC_TPREL32"}, - {74, "R_PPC_DTPREL16"}, - {75, "R_PPC_DTPREL16_LO"}, - {76, "R_PPC_DTPREL16_HI"}, - {77, "R_PPC_DTPREL16_HA"}, - {78, "R_PPC_DTPREL32"}, - {79, "R_PPC_GOT_TLSGD16"}, - {80, "R_PPC_GOT_TLSGD16_LO"}, - {81, "R_PPC_GOT_TLSGD16_HI"}, - {82, "R_PPC_GOT_TLSGD16_HA"}, - {83, "R_PPC_GOT_TLSLD16"}, - {84, "R_PPC_GOT_TLSLD16_LO"}, - {85, "R_PPC_GOT_TLSLD16_HI"}, - {86, "R_PPC_GOT_TLSLD16_HA"}, - {87, "R_PPC_GOT_TPREL16"}, - {88, "R_PPC_GOT_TPREL16_LO"}, - {89, "R_PPC_GOT_TPREL16_HI"}, - {90, "R_PPC_GOT_TPREL16_HA"}, - {101, "R_PPC_EMB_NADDR32"}, - {102, "R_PPC_EMB_NADDR16"}, - {103, "R_PPC_EMB_NADDR16_LO"}, - {104, "R_PPC_EMB_NADDR16_HI"}, - {105, "R_PPC_EMB_NADDR16_HA"}, - {106, "R_PPC_EMB_SDAI16"}, - {107, "R_PPC_EMB_SDA2I16"}, - {108, "R_PPC_EMB_SDA2REL"}, - {109, "R_PPC_EMB_SDA21"}, - {110, "R_PPC_EMB_MRKREF"}, - {111, "R_PPC_EMB_RELSEC16"}, - {112, "R_PPC_EMB_RELST_LO"}, - {113, "R_PPC_EMB_RELST_HI"}, - {114, "R_PPC_EMB_RELST_HA"}, - {115, "R_PPC_EMB_BIT_FLD"}, - {116, "R_PPC_EMB_RELSDA"}, -} - -func (i R_PPC) String() string { return stringName(uint32(i), rppcStrings, false) } -func (i R_PPC) GoString() string { return stringName(uint32(i), rppcStrings, true) } - -// Relocation types for 64-bit PowerPC or Power Architecture processors. -// -// Values that are shared by both R_PPC and R_PPC64 are prefixed with -// R_POWERPC_ in the ELF standard. For the R_PPC64 type, the relevant -// shared relocations have been renamed with the prefix R_PPC64_. -// The original name follows the value in a comment. -type R_PPC64 int - -const ( - R_PPC64_NONE R_PPC64 = 0 // R_POWERPC_NONE - R_PPC64_ADDR32 R_PPC64 = 1 // R_POWERPC_ADDR32 - R_PPC64_ADDR24 R_PPC64 = 2 // R_POWERPC_ADDR24 - R_PPC64_ADDR16 R_PPC64 = 3 // R_POWERPC_ADDR16 - R_PPC64_ADDR16_LO R_PPC64 = 4 // R_POWERPC_ADDR16_LO - R_PPC64_ADDR16_HI R_PPC64 = 5 // R_POWERPC_ADDR16_HI - R_PPC64_ADDR16_HA R_PPC64 = 6 // R_POWERPC_ADDR16_HA - R_PPC64_ADDR14 R_PPC64 = 7 // R_POWERPC_ADDR14 - R_PPC64_ADDR14_BRTAKEN R_PPC64 = 8 // R_POWERPC_ADDR14_BRTAKEN - R_PPC64_ADDR14_BRNTAKEN R_PPC64 = 9 // R_POWERPC_ADDR14_BRNTAKEN - R_PPC64_REL24 R_PPC64 = 10 // R_POWERPC_REL24 - R_PPC64_REL14 R_PPC64 = 11 // R_POWERPC_REL14 - R_PPC64_REL14_BRTAKEN R_PPC64 = 12 // R_POWERPC_REL14_BRTAKEN - R_PPC64_REL14_BRNTAKEN R_PPC64 = 13 // R_POWERPC_REL14_BRNTAKEN - R_PPC64_GOT16 R_PPC64 = 14 // R_POWERPC_GOT16 - R_PPC64_GOT16_LO R_PPC64 = 15 // R_POWERPC_GOT16_LO - R_PPC64_GOT16_HI R_PPC64 = 16 // R_POWERPC_GOT16_HI - R_PPC64_GOT16_HA R_PPC64 = 17 // R_POWERPC_GOT16_HA - R_PPC64_JMP_SLOT R_PPC64 = 21 // R_POWERPC_JMP_SLOT - R_PPC64_REL32 R_PPC64 = 26 // R_POWERPC_REL32 - R_PPC64_ADDR64 R_PPC64 = 38 - R_PPC64_ADDR16_HIGHER R_PPC64 = 39 - R_PPC64_ADDR16_HIGHERA R_PPC64 = 40 - R_PPC64_ADDR16_HIGHEST R_PPC64 = 41 - R_PPC64_ADDR16_HIGHESTA R_PPC64 = 42 - R_PPC64_REL64 R_PPC64 = 44 - R_PPC64_TOC16 R_PPC64 = 47 - R_PPC64_TOC16_LO R_PPC64 = 48 - R_PPC64_TOC16_HI R_PPC64 = 49 - R_PPC64_TOC16_HA R_PPC64 = 50 - R_PPC64_TOC R_PPC64 = 51 - R_PPC64_PLTGOT16 R_PPC64 = 52 - R_PPC64_PLTGOT16_LO R_PPC64 = 53 - R_PPC64_PLTGOT16_HI R_PPC64 = 54 - R_PPC64_PLTGOT16_HA R_PPC64 = 55 - R_PPC64_ADDR16_DS R_PPC64 = 56 - R_PPC64_ADDR16_LO_DS R_PPC64 = 57 - R_PPC64_GOT16_DS R_PPC64 = 58 - R_PPC64_GOT16_LO_DS R_PPC64 = 59 - R_PPC64_PLT16_LO_DS R_PPC64 = 60 - R_PPC64_SECTOFF_DS R_PPC64 = 61 - R_PPC64_SECTOFF_LO_DS R_PPC64 = 61 - R_PPC64_TOC16_DS R_PPC64 = 63 - R_PPC64_TOC16_LO_DS R_PPC64 = 64 - R_PPC64_PLTGOT16_DS R_PPC64 = 65 - R_PPC64_PLTGOT_LO_DS R_PPC64 = 66 - R_PPC64_TLS R_PPC64 = 67 // R_POWERPC_TLS - R_PPC64_DTPMOD64 R_PPC64 = 68 // R_POWERPC_DTPMOD64 - R_PPC64_TPREL16 R_PPC64 = 69 // R_POWERPC_TPREL16 - R_PPC64_TPREL16_LO R_PPC64 = 70 // R_POWERPC_TPREL16_LO - R_PPC64_TPREL16_HI R_PPC64 = 71 // R_POWERPC_TPREL16_HI - R_PPC64_TPREL16_HA R_PPC64 = 72 // R_POWERPC_TPREL16_HA - R_PPC64_TPREL64 R_PPC64 = 73 // R_POWERPC_TPREL64 - R_PPC64_DTPREL16 R_PPC64 = 74 // R_POWERPC_DTPREL16 - R_PPC64_DTPREL16_LO R_PPC64 = 75 // R_POWERPC_DTPREL16_LO - R_PPC64_DTPREL16_HI R_PPC64 = 76 // R_POWERPC_DTPREL16_HI - R_PPC64_DTPREL16_HA R_PPC64 = 77 // R_POWERPC_DTPREL16_HA - R_PPC64_DTPREL64 R_PPC64 = 78 // R_POWERPC_DTPREL64 - R_PPC64_GOT_TLSGD16 R_PPC64 = 79 // R_POWERPC_GOT_TLSGD16 - R_PPC64_GOT_TLSGD16_LO R_PPC64 = 80 // R_POWERPC_GOT_TLSGD16_LO - R_PPC64_GOT_TLSGD16_HI R_PPC64 = 81 // R_POWERPC_GOT_TLSGD16_HI - R_PPC64_GOT_TLSGD16_HA R_PPC64 = 82 // R_POWERPC_GOT_TLSGD16_HA - R_PPC64_GOT_TLSLD16 R_PPC64 = 83 // R_POWERPC_GOT_TLSLD16 - R_PPC64_GOT_TLSLD16_LO R_PPC64 = 84 // R_POWERPC_GOT_TLSLD16_LO - R_PPC64_GOT_TLSLD16_HI R_PPC64 = 85 // R_POWERPC_GOT_TLSLD16_HI - R_PPC64_GOT_TLSLD16_HA R_PPC64 = 86 // R_POWERPC_GOT_TLSLD16_HA - R_PPC64_GOT_TPREL16_DS R_PPC64 = 87 // R_POWERPC_GOT_TPREL16_DS - R_PPC64_GOT_TPREL16_LO_DS R_PPC64 = 88 // R_POWERPC_GOT_TPREL16_LO_DS - R_PPC64_GOT_TPREL16_HI R_PPC64 = 89 // R_POWERPC_GOT_TPREL16_HI - R_PPC64_GOT_TPREL16_HA R_PPC64 = 90 // R_POWERPC_GOT_TPREL16_HA - R_PPC64_GOT_DTPREL16_DS R_PPC64 = 91 // R_POWERPC_GOT_DTPREL16_DS - R_PPC64_GOT_DTPREL16_LO_DS R_PPC64 = 92 // R_POWERPC_GOT_DTPREL16_LO_DS - R_PPC64_GOT_DTPREL16_HI R_PPC64 = 93 // R_POWERPC_GOT_DTPREL16_HI - R_PPC64_GOT_DTPREL16_HA R_PPC64 = 94 // R_POWERPC_GOT_DTPREL16_HA - R_PPC64_TPREL16_DS R_PPC64 = 95 - R_PPC64_TPREL16_LO_DS R_PPC64 = 96 - R_PPC64_TPREL16_HIGHER R_PPC64 = 97 - R_PPC64_TPREL16_HIGHERA R_PPC64 = 98 - R_PPC64_TPREL16_HIGHEST R_PPC64 = 99 - R_PPC64_TPREL16_HIGHESTA R_PPC64 = 100 - R_PPC64_DTPREL16_DS R_PPC64 = 101 - R_PPC64_DTPREL16_LO_DS R_PPC64 = 102 - R_PPC64_DTPREL16_HIGHER R_PPC64 = 103 - R_PPC64_DTPREL16_HIGHERA R_PPC64 = 104 - R_PPC64_DTPREL16_HIGHEST R_PPC64 = 105 - R_PPC64_DTPREL16_HIGHESTA R_PPC64 = 106 - R_PPC64_TLSGD R_PPC64 = 107 - R_PPC64_TLSLD R_PPC64 = 108 - R_PPC64_TOCSAVE R_PPC64 = 109 - R_PPC64_ADDR16_HIGH R_PPC64 = 110 - R_PPC64_ADDR16_HIGHA R_PPC64 = 111 - R_PPC64_TPREL16_HIGH R_PPC64 = 112 - R_PPC64_TPREL16_HIGHA R_PPC64 = 113 - R_PPC64_DTPREL16_HIGH R_PPC64 = 114 - R_PPC64_DTPREL16_HIGHA R_PPC64 = 115 - R_PPC64_REL24_NOTOC R_PPC64 = 116 - R_PPC64_ADDR64_LOCAL R_PPC64 = 117 - R_PPC64_ENTRY R_PPC64 = 118 - R_PPC64_REL16DX_HA R_PPC64 = 246 // R_POWERPC_REL16DX_HA - R_PPC64_JMP_IREL R_PPC64 = 247 - R_PPC64_IRELATIVE R_PPC64 = 248 // R_POWERPC_IRELATIVE - R_PPC64_REL16 R_PPC64 = 249 // R_POWERPC_REL16 - R_PPC64_REL16_LO R_PPC64 = 250 // R_POWERPC_REL16_LO - R_PPC64_REL16_HI R_PPC64 = 251 // R_POWERPC_REL16_HI - R_PPC64_REL16_HA R_PPC64 = 252 // R_POWERPC_REL16_HA -) - -var rppc64Strings = []intName{ - {0, "R_PPC64_NONE"}, - {1, "R_PPC64_ADDR32"}, - {2, "R_PPC64_ADDR24"}, - {3, "R_PPC64_ADDR16"}, - {4, "R_PPC64_ADDR16_LO"}, - {5, "R_PPC64_ADDR16_HI"}, - {6, "R_PPC64_ADDR16_HA"}, - {7, "R_PPC64_ADDR14"}, - {8, "R_PPC64_ADDR14_BRTAKEN"}, - {9, "R_PPC64_ADDR14_BRNTAKEN"}, - {10, "R_PPC64_REL24"}, - {11, "R_PPC64_REL14"}, - {12, "R_PPC64_REL14_BRTAKEN"}, - {13, "R_PPC64_REL14_BRNTAKEN"}, - {14, "R_PPC64_GOT16"}, - {15, "R_PPC64_GOT16_LO"}, - {16, "R_PPC64_GOT16_HI"}, - {17, "R_PPC64_GOT16_HA"}, - {21, "R_PPC64_JMP_SLOT"}, - {26, "R_PPC64_REL32"}, - {38, "R_PPC64_ADDR64"}, - {39, "R_PPC64_ADDR16_HIGHER"}, - {40, "R_PPC64_ADDR16_HIGHERA"}, - {41, "R_PPC64_ADDR16_HIGHEST"}, - {42, "R_PPC64_ADDR16_HIGHESTA"}, - {44, "R_PPC64_REL64"}, - {47, "R_PPC64_TOC16"}, - {48, "R_PPC64_TOC16_LO"}, - {49, "R_PPC64_TOC16_HI"}, - {50, "R_PPC64_TOC16_HA"}, - {51, "R_PPC64_TOC"}, - {52, "R_PPC64_PLTGOT16"}, - {53, "R_PPC64_PLTGOT16_LO"}, - {54, "R_PPC64_PLTGOT16_HI"}, - {55, "R_PPC64_PLTGOT16_HA"}, - {56, "R_PPC64_ADDR16_DS"}, - {57, "R_PPC64_ADDR16_LO_DS"}, - {58, "R_PPC64_GOT16_DS"}, - {59, "R_PPC64_GOT16_LO_DS"}, - {60, "R_PPC64_PLT16_LO_DS"}, - {61, "R_PPC64_SECTOFF_DS"}, - {61, "R_PPC64_SECTOFF_LO_DS"}, - {63, "R_PPC64_TOC16_DS"}, - {64, "R_PPC64_TOC16_LO_DS"}, - {65, "R_PPC64_PLTGOT16_DS"}, - {66, "R_PPC64_PLTGOT_LO_DS"}, - {67, "R_PPC64_TLS"}, - {68, "R_PPC64_DTPMOD64"}, - {69, "R_PPC64_TPREL16"}, - {70, "R_PPC64_TPREL16_LO"}, - {71, "R_PPC64_TPREL16_HI"}, - {72, "R_PPC64_TPREL16_HA"}, - {73, "R_PPC64_TPREL64"}, - {74, "R_PPC64_DTPREL16"}, - {75, "R_PPC64_DTPREL16_LO"}, - {76, "R_PPC64_DTPREL16_HI"}, - {77, "R_PPC64_DTPREL16_HA"}, - {78, "R_PPC64_DTPREL64"}, - {79, "R_PPC64_GOT_TLSGD16"}, - {80, "R_PPC64_GOT_TLSGD16_LO"}, - {81, "R_PPC64_GOT_TLSGD16_HI"}, - {82, "R_PPC64_GOT_TLSGD16_HA"}, - {83, "R_PPC64_GOT_TLSLD16"}, - {84, "R_PPC64_GOT_TLSLD16_LO"}, - {85, "R_PPC64_GOT_TLSLD16_HI"}, - {86, "R_PPC64_GOT_TLSLD16_HA"}, - {87, "R_PPC64_GOT_TPREL16_DS"}, - {88, "R_PPC64_GOT_TPREL16_LO_DS"}, - {89, "R_PPC64_GOT_TPREL16_HI"}, - {90, "R_PPC64_GOT_TPREL16_HA"}, - {91, "R_PPC64_GOT_DTPREL16_DS"}, - {92, "R_PPC64_GOT_DTPREL16_LO_DS"}, - {93, "R_PPC64_GOT_DTPREL16_HI"}, - {94, "R_PPC64_GOT_DTPREL16_HA"}, - {95, "R_PPC64_TPREL16_DS"}, - {96, "R_PPC64_TPREL16_LO_DS"}, - {97, "R_PPC64_TPREL16_HIGHER"}, - {98, "R_PPC64_TPREL16_HIGHERA"}, - {99, "R_PPC64_TPREL16_HIGHEST"}, - {100, "R_PPC64_TPREL16_HIGHESTA"}, - {101, "R_PPC64_DTPREL16_DS"}, - {102, "R_PPC64_DTPREL16_LO_DS"}, - {103, "R_PPC64_DTPREL16_HIGHER"}, - {104, "R_PPC64_DTPREL16_HIGHERA"}, - {105, "R_PPC64_DTPREL16_HIGHEST"}, - {106, "R_PPC64_DTPREL16_HIGHESTA"}, - {107, "R_PPC64_TLSGD"}, - {108, "R_PPC64_TLSLD"}, - {109, "R_PPC64_TOCSAVE"}, - {110, "R_PPC64_ADDR16_HIGH"}, - {111, "R_PPC64_ADDR16_HIGHA"}, - {112, "R_PPC64_TPREL16_HIGH"}, - {113, "R_PPC64_TPREL16_HIGHA"}, - {114, "R_PPC64_DTPREL16_HIGH"}, - {115, "R_PPC64_DTPREL16_HIGHA"}, - {116, "R_PPC64_REL24_NOTOC"}, - {117, "R_PPC64_ADDR64_LOCAL"}, - {118, "R_PPC64_ENTRY"}, - {246, "R_PPC64_REL16DX_HA"}, - {247, "R_PPC64_JMP_IREL"}, - {248, "R_PPC64_IRELATIVE"}, - {249, "R_PPC64_REL16"}, - {250, "R_PPC64_REL16_LO"}, - {251, "R_PPC64_REL16_HI"}, - {252, "R_PPC64_REL16_HA"}, -} - -func (i R_PPC64) String() string { return stringName(uint32(i), rppc64Strings, false) } -func (i R_PPC64) GoString() string { return stringName(uint32(i), rppc64Strings, true) } - -// Relocation types for RISC-V processors. -type R_RISCV int - -const ( - R_RISCV_NONE R_RISCV = 0 /* No relocation. */ - R_RISCV_32 R_RISCV = 1 /* Add 32 bit zero extended symbol value */ - R_RISCV_64 R_RISCV = 2 /* Add 64 bit symbol value. */ - R_RISCV_RELATIVE R_RISCV = 3 /* Add load address of shared object. */ - R_RISCV_COPY R_RISCV = 4 /* Copy data from shared object. */ - R_RISCV_JUMP_SLOT R_RISCV = 5 /* Set GOT entry to code address. */ - R_RISCV_TLS_DTPMOD32 R_RISCV = 6 /* 32 bit ID of module containing symbol */ - R_RISCV_TLS_DTPMOD64 R_RISCV = 7 /* ID of module containing symbol */ - R_RISCV_TLS_DTPREL32 R_RISCV = 8 /* 32 bit relative offset in TLS block */ - R_RISCV_TLS_DTPREL64 R_RISCV = 9 /* Relative offset in TLS block */ - R_RISCV_TLS_TPREL32 R_RISCV = 10 /* 32 bit relative offset in static TLS block */ - R_RISCV_TLS_TPREL64 R_RISCV = 11 /* Relative offset in static TLS block */ - R_RISCV_BRANCH R_RISCV = 16 /* PC-relative branch */ - R_RISCV_JAL R_RISCV = 17 /* PC-relative jump */ - R_RISCV_CALL R_RISCV = 18 /* PC-relative call */ - R_RISCV_CALL_PLT R_RISCV = 19 /* PC-relative call (PLT) */ - R_RISCV_GOT_HI20 R_RISCV = 20 /* PC-relative GOT reference */ - R_RISCV_TLS_GOT_HI20 R_RISCV = 21 /* PC-relative TLS IE GOT offset */ - R_RISCV_TLS_GD_HI20 R_RISCV = 22 /* PC-relative TLS GD reference */ - R_RISCV_PCREL_HI20 R_RISCV = 23 /* PC-relative reference */ - R_RISCV_PCREL_LO12_I R_RISCV = 24 /* PC-relative reference */ - R_RISCV_PCREL_LO12_S R_RISCV = 25 /* PC-relative reference */ - R_RISCV_HI20 R_RISCV = 26 /* Absolute address */ - R_RISCV_LO12_I R_RISCV = 27 /* Absolute address */ - R_RISCV_LO12_S R_RISCV = 28 /* Absolute address */ - R_RISCV_TPREL_HI20 R_RISCV = 29 /* TLS LE thread offset */ - R_RISCV_TPREL_LO12_I R_RISCV = 30 /* TLS LE thread offset */ - R_RISCV_TPREL_LO12_S R_RISCV = 31 /* TLS LE thread offset */ - R_RISCV_TPREL_ADD R_RISCV = 32 /* TLS LE thread usage */ - R_RISCV_ADD8 R_RISCV = 33 /* 8-bit label addition */ - R_RISCV_ADD16 R_RISCV = 34 /* 16-bit label addition */ - R_RISCV_ADD32 R_RISCV = 35 /* 32-bit label addition */ - R_RISCV_ADD64 R_RISCV = 36 /* 64-bit label addition */ - R_RISCV_SUB8 R_RISCV = 37 /* 8-bit label subtraction */ - R_RISCV_SUB16 R_RISCV = 38 /* 16-bit label subtraction */ - R_RISCV_SUB32 R_RISCV = 39 /* 32-bit label subtraction */ - R_RISCV_SUB64 R_RISCV = 40 /* 64-bit label subtraction */ - R_RISCV_GNU_VTINHERIT R_RISCV = 41 /* GNU C++ vtable hierarchy */ - R_RISCV_GNU_VTENTRY R_RISCV = 42 /* GNU C++ vtable member usage */ - R_RISCV_ALIGN R_RISCV = 43 /* Alignment statement */ - R_RISCV_RVC_BRANCH R_RISCV = 44 /* PC-relative branch offset */ - R_RISCV_RVC_JUMP R_RISCV = 45 /* PC-relative jump offset */ - R_RISCV_RVC_LUI R_RISCV = 46 /* Absolute address */ - R_RISCV_GPREL_I R_RISCV = 47 /* GP-relative reference */ - R_RISCV_GPREL_S R_RISCV = 48 /* GP-relative reference */ - R_RISCV_TPREL_I R_RISCV = 49 /* TP-relative TLS LE load */ - R_RISCV_TPREL_S R_RISCV = 50 /* TP-relative TLS LE store */ - R_RISCV_RELAX R_RISCV = 51 /* Instruction pair can be relaxed */ - R_RISCV_SUB6 R_RISCV = 52 /* Local label subtraction */ - R_RISCV_SET6 R_RISCV = 53 /* Local label subtraction */ - R_RISCV_SET8 R_RISCV = 54 /* Local label subtraction */ - R_RISCV_SET16 R_RISCV = 55 /* Local label subtraction */ - R_RISCV_SET32 R_RISCV = 56 /* Local label subtraction */ - R_RISCV_32_PCREL R_RISCV = 57 /* 32-bit PC relative */ -) - -var rriscvStrings = []intName{ - {0, "R_RISCV_NONE"}, - {1, "R_RISCV_32"}, - {2, "R_RISCV_64"}, - {3, "R_RISCV_RELATIVE"}, - {4, "R_RISCV_COPY"}, - {5, "R_RISCV_JUMP_SLOT"}, - {6, "R_RISCV_TLS_DTPMOD32"}, - {7, "R_RISCV_TLS_DTPMOD64"}, - {8, "R_RISCV_TLS_DTPREL32"}, - {9, "R_RISCV_TLS_DTPREL64"}, - {10, "R_RISCV_TLS_TPREL32"}, - {11, "R_RISCV_TLS_TPREL64"}, - {16, "R_RISCV_BRANCH"}, - {17, "R_RISCV_JAL"}, - {18, "R_RISCV_CALL"}, - {19, "R_RISCV_CALL_PLT"}, - {20, "R_RISCV_GOT_HI20"}, - {21, "R_RISCV_TLS_GOT_HI20"}, - {22, "R_RISCV_TLS_GD_HI20"}, - {23, "R_RISCV_PCREL_HI20"}, - {24, "R_RISCV_PCREL_LO12_I"}, - {25, "R_RISCV_PCREL_LO12_S"}, - {26, "R_RISCV_HI20"}, - {27, "R_RISCV_LO12_I"}, - {28, "R_RISCV_LO12_S"}, - {29, "R_RISCV_TPREL_HI20"}, - {30, "R_RISCV_TPREL_LO12_I"}, - {31, "R_RISCV_TPREL_LO12_S"}, - {32, "R_RISCV_TPREL_ADD"}, - {33, "R_RISCV_ADD8"}, - {34, "R_RISCV_ADD16"}, - {35, "R_RISCV_ADD32"}, - {36, "R_RISCV_ADD64"}, - {37, "R_RISCV_SUB8"}, - {38, "R_RISCV_SUB16"}, - {39, "R_RISCV_SUB32"}, - {40, "R_RISCV_SUB64"}, - {41, "R_RISCV_GNU_VTINHERIT"}, - {42, "R_RISCV_GNU_VTENTRY"}, - {43, "R_RISCV_ALIGN"}, - {44, "R_RISCV_RVC_BRANCH"}, - {45, "R_RISCV_RVC_JUMP"}, - {46, "R_RISCV_RVC_LUI"}, - {47, "R_RISCV_GPREL_I"}, - {48, "R_RISCV_GPREL_S"}, - {49, "R_RISCV_TPREL_I"}, - {50, "R_RISCV_TPREL_S"}, - {51, "R_RISCV_RELAX"}, - {52, "R_RISCV_SUB6"}, - {53, "R_RISCV_SET6"}, - {54, "R_RISCV_SET8"}, - {55, "R_RISCV_SET16"}, - {56, "R_RISCV_SET32"}, - {57, "R_RISCV_32_PCREL"}, -} - -func (i R_RISCV) String() string { return stringName(uint32(i), rriscvStrings, false) } -func (i R_RISCV) GoString() string { return stringName(uint32(i), rriscvStrings, true) } - -// Relocation types for s390x processors. -type R_390 int - -const ( - R_390_NONE R_390 = 0 - R_390_8 R_390 = 1 - R_390_12 R_390 = 2 - R_390_16 R_390 = 3 - R_390_32 R_390 = 4 - R_390_PC32 R_390 = 5 - R_390_GOT12 R_390 = 6 - R_390_GOT32 R_390 = 7 - R_390_PLT32 R_390 = 8 - R_390_COPY R_390 = 9 - R_390_GLOB_DAT R_390 = 10 - R_390_JMP_SLOT R_390 = 11 - R_390_RELATIVE R_390 = 12 - R_390_GOTOFF R_390 = 13 - R_390_GOTPC R_390 = 14 - R_390_GOT16 R_390 = 15 - R_390_PC16 R_390 = 16 - R_390_PC16DBL R_390 = 17 - R_390_PLT16DBL R_390 = 18 - R_390_PC32DBL R_390 = 19 - R_390_PLT32DBL R_390 = 20 - R_390_GOTPCDBL R_390 = 21 - R_390_64 R_390 = 22 - R_390_PC64 R_390 = 23 - R_390_GOT64 R_390 = 24 - R_390_PLT64 R_390 = 25 - R_390_GOTENT R_390 = 26 - R_390_GOTOFF16 R_390 = 27 - R_390_GOTOFF64 R_390 = 28 - R_390_GOTPLT12 R_390 = 29 - R_390_GOTPLT16 R_390 = 30 - R_390_GOTPLT32 R_390 = 31 - R_390_GOTPLT64 R_390 = 32 - R_390_GOTPLTENT R_390 = 33 - R_390_GOTPLTOFF16 R_390 = 34 - R_390_GOTPLTOFF32 R_390 = 35 - R_390_GOTPLTOFF64 R_390 = 36 - R_390_TLS_LOAD R_390 = 37 - R_390_TLS_GDCALL R_390 = 38 - R_390_TLS_LDCALL R_390 = 39 - R_390_TLS_GD32 R_390 = 40 - R_390_TLS_GD64 R_390 = 41 - R_390_TLS_GOTIE12 R_390 = 42 - R_390_TLS_GOTIE32 R_390 = 43 - R_390_TLS_GOTIE64 R_390 = 44 - R_390_TLS_LDM32 R_390 = 45 - R_390_TLS_LDM64 R_390 = 46 - R_390_TLS_IE32 R_390 = 47 - R_390_TLS_IE64 R_390 = 48 - R_390_TLS_IEENT R_390 = 49 - R_390_TLS_LE32 R_390 = 50 - R_390_TLS_LE64 R_390 = 51 - R_390_TLS_LDO32 R_390 = 52 - R_390_TLS_LDO64 R_390 = 53 - R_390_TLS_DTPMOD R_390 = 54 - R_390_TLS_DTPOFF R_390 = 55 - R_390_TLS_TPOFF R_390 = 56 - R_390_20 R_390 = 57 - R_390_GOT20 R_390 = 58 - R_390_GOTPLT20 R_390 = 59 - R_390_TLS_GOTIE20 R_390 = 60 -) - -var r390Strings = []intName{ - {0, "R_390_NONE"}, - {1, "R_390_8"}, - {2, "R_390_12"}, - {3, "R_390_16"}, - {4, "R_390_32"}, - {5, "R_390_PC32"}, - {6, "R_390_GOT12"}, - {7, "R_390_GOT32"}, - {8, "R_390_PLT32"}, - {9, "R_390_COPY"}, - {10, "R_390_GLOB_DAT"}, - {11, "R_390_JMP_SLOT"}, - {12, "R_390_RELATIVE"}, - {13, "R_390_GOTOFF"}, - {14, "R_390_GOTPC"}, - {15, "R_390_GOT16"}, - {16, "R_390_PC16"}, - {17, "R_390_PC16DBL"}, - {18, "R_390_PLT16DBL"}, - {19, "R_390_PC32DBL"}, - {20, "R_390_PLT32DBL"}, - {21, "R_390_GOTPCDBL"}, - {22, "R_390_64"}, - {23, "R_390_PC64"}, - {24, "R_390_GOT64"}, - {25, "R_390_PLT64"}, - {26, "R_390_GOTENT"}, - {27, "R_390_GOTOFF16"}, - {28, "R_390_GOTOFF64"}, - {29, "R_390_GOTPLT12"}, - {30, "R_390_GOTPLT16"}, - {31, "R_390_GOTPLT32"}, - {32, "R_390_GOTPLT64"}, - {33, "R_390_GOTPLTENT"}, - {34, "R_390_GOTPLTOFF16"}, - {35, "R_390_GOTPLTOFF32"}, - {36, "R_390_GOTPLTOFF64"}, - {37, "R_390_TLS_LOAD"}, - {38, "R_390_TLS_GDCALL"}, - {39, "R_390_TLS_LDCALL"}, - {40, "R_390_TLS_GD32"}, - {41, "R_390_TLS_GD64"}, - {42, "R_390_TLS_GOTIE12"}, - {43, "R_390_TLS_GOTIE32"}, - {44, "R_390_TLS_GOTIE64"}, - {45, "R_390_TLS_LDM32"}, - {46, "R_390_TLS_LDM64"}, - {47, "R_390_TLS_IE32"}, - {48, "R_390_TLS_IE64"}, - {49, "R_390_TLS_IEENT"}, - {50, "R_390_TLS_LE32"}, - {51, "R_390_TLS_LE64"}, - {52, "R_390_TLS_LDO32"}, - {53, "R_390_TLS_LDO64"}, - {54, "R_390_TLS_DTPMOD"}, - {55, "R_390_TLS_DTPOFF"}, - {56, "R_390_TLS_TPOFF"}, - {57, "R_390_20"}, - {58, "R_390_GOT20"}, - {59, "R_390_GOTPLT20"}, - {60, "R_390_TLS_GOTIE20"}, -} - -func (i R_390) String() string { return stringName(uint32(i), r390Strings, false) } -func (i R_390) GoString() string { return stringName(uint32(i), r390Strings, true) } - -// Relocation types for SPARC. -type R_SPARC int - -const ( - R_SPARC_NONE R_SPARC = 0 - R_SPARC_8 R_SPARC = 1 - R_SPARC_16 R_SPARC = 2 - R_SPARC_32 R_SPARC = 3 - R_SPARC_DISP8 R_SPARC = 4 - R_SPARC_DISP16 R_SPARC = 5 - R_SPARC_DISP32 R_SPARC = 6 - R_SPARC_WDISP30 R_SPARC = 7 - R_SPARC_WDISP22 R_SPARC = 8 - R_SPARC_HI22 R_SPARC = 9 - R_SPARC_22 R_SPARC = 10 - R_SPARC_13 R_SPARC = 11 - R_SPARC_LO10 R_SPARC = 12 - R_SPARC_GOT10 R_SPARC = 13 - R_SPARC_GOT13 R_SPARC = 14 - R_SPARC_GOT22 R_SPARC = 15 - R_SPARC_PC10 R_SPARC = 16 - R_SPARC_PC22 R_SPARC = 17 - R_SPARC_WPLT30 R_SPARC = 18 - R_SPARC_COPY R_SPARC = 19 - R_SPARC_GLOB_DAT R_SPARC = 20 - R_SPARC_JMP_SLOT R_SPARC = 21 - R_SPARC_RELATIVE R_SPARC = 22 - R_SPARC_UA32 R_SPARC = 23 - R_SPARC_PLT32 R_SPARC = 24 - R_SPARC_HIPLT22 R_SPARC = 25 - R_SPARC_LOPLT10 R_SPARC = 26 - R_SPARC_PCPLT32 R_SPARC = 27 - R_SPARC_PCPLT22 R_SPARC = 28 - R_SPARC_PCPLT10 R_SPARC = 29 - R_SPARC_10 R_SPARC = 30 - R_SPARC_11 R_SPARC = 31 - R_SPARC_64 R_SPARC = 32 - R_SPARC_OLO10 R_SPARC = 33 - R_SPARC_HH22 R_SPARC = 34 - R_SPARC_HM10 R_SPARC = 35 - R_SPARC_LM22 R_SPARC = 36 - R_SPARC_PC_HH22 R_SPARC = 37 - R_SPARC_PC_HM10 R_SPARC = 38 - R_SPARC_PC_LM22 R_SPARC = 39 - R_SPARC_WDISP16 R_SPARC = 40 - R_SPARC_WDISP19 R_SPARC = 41 - R_SPARC_GLOB_JMP R_SPARC = 42 - R_SPARC_7 R_SPARC = 43 - R_SPARC_5 R_SPARC = 44 - R_SPARC_6 R_SPARC = 45 - R_SPARC_DISP64 R_SPARC = 46 - R_SPARC_PLT64 R_SPARC = 47 - R_SPARC_HIX22 R_SPARC = 48 - R_SPARC_LOX10 R_SPARC = 49 - R_SPARC_H44 R_SPARC = 50 - R_SPARC_M44 R_SPARC = 51 - R_SPARC_L44 R_SPARC = 52 - R_SPARC_REGISTER R_SPARC = 53 - R_SPARC_UA64 R_SPARC = 54 - R_SPARC_UA16 R_SPARC = 55 -) - -var rsparcStrings = []intName{ - {0, "R_SPARC_NONE"}, - {1, "R_SPARC_8"}, - {2, "R_SPARC_16"}, - {3, "R_SPARC_32"}, - {4, "R_SPARC_DISP8"}, - {5, "R_SPARC_DISP16"}, - {6, "R_SPARC_DISP32"}, - {7, "R_SPARC_WDISP30"}, - {8, "R_SPARC_WDISP22"}, - {9, "R_SPARC_HI22"}, - {10, "R_SPARC_22"}, - {11, "R_SPARC_13"}, - {12, "R_SPARC_LO10"}, - {13, "R_SPARC_GOT10"}, - {14, "R_SPARC_GOT13"}, - {15, "R_SPARC_GOT22"}, - {16, "R_SPARC_PC10"}, - {17, "R_SPARC_PC22"}, - {18, "R_SPARC_WPLT30"}, - {19, "R_SPARC_COPY"}, - {20, "R_SPARC_GLOB_DAT"}, - {21, "R_SPARC_JMP_SLOT"}, - {22, "R_SPARC_RELATIVE"}, - {23, "R_SPARC_UA32"}, - {24, "R_SPARC_PLT32"}, - {25, "R_SPARC_HIPLT22"}, - {26, "R_SPARC_LOPLT10"}, - {27, "R_SPARC_PCPLT32"}, - {28, "R_SPARC_PCPLT22"}, - {29, "R_SPARC_PCPLT10"}, - {30, "R_SPARC_10"}, - {31, "R_SPARC_11"}, - {32, "R_SPARC_64"}, - {33, "R_SPARC_OLO10"}, - {34, "R_SPARC_HH22"}, - {35, "R_SPARC_HM10"}, - {36, "R_SPARC_LM22"}, - {37, "R_SPARC_PC_HH22"}, - {38, "R_SPARC_PC_HM10"}, - {39, "R_SPARC_PC_LM22"}, - {40, "R_SPARC_WDISP16"}, - {41, "R_SPARC_WDISP19"}, - {42, "R_SPARC_GLOB_JMP"}, - {43, "R_SPARC_7"}, - {44, "R_SPARC_5"}, - {45, "R_SPARC_6"}, - {46, "R_SPARC_DISP64"}, - {47, "R_SPARC_PLT64"}, - {48, "R_SPARC_HIX22"}, - {49, "R_SPARC_LOX10"}, - {50, "R_SPARC_H44"}, - {51, "R_SPARC_M44"}, - {52, "R_SPARC_L44"}, - {53, "R_SPARC_REGISTER"}, - {54, "R_SPARC_UA64"}, - {55, "R_SPARC_UA16"}, -} - -func (i R_SPARC) String() string { return stringName(uint32(i), rsparcStrings, false) } -func (i R_SPARC) GoString() string { return stringName(uint32(i), rsparcStrings, true) } - -// Magic number for the elf trampoline, chosen wisely to be an immediate value. -const ARM_MAGIC_TRAMP_NUMBER = 0x5c000003 - -// ELF32 File header. -type Header32 struct { - Ident [EI_NIDENT]byte /* File identification. */ - Type uint16 /* File type. */ - Machine uint16 /* Machine architecture. */ - Version uint32 /* ELF format version. */ - Entry uint32 /* Entry point. */ - Phoff uint32 /* Program header file offset. */ - Shoff uint32 /* Section header file offset. */ - Flags uint32 /* Architecture-specific flags. */ - Ehsize uint16 /* Size of ELF header in bytes. */ - Phentsize uint16 /* Size of program header entry. */ - Phnum uint16 /* Number of program header entries. */ - Shentsize uint16 /* Size of section header entry. */ - Shnum uint16 /* Number of section header entries. */ - Shstrndx uint16 /* Section name strings section. */ -} - -// ELF32 Section header. -type Section32 struct { - Name uint32 /* Section name (index into the section header string table). */ - Type uint32 /* Section type. */ - Flags uint32 /* Section flags. */ - Addr uint32 /* Address in memory image. */ - Off uint32 /* Offset in file. */ - Size uint32 /* Size in bytes. */ - Link uint32 /* Index of a related section. */ - Info uint32 /* Depends on section type. */ - Addralign uint32 /* Alignment in bytes. */ - Entsize uint32 /* Size of each entry in section. */ -} - -// ELF32 Program header. -type Prog32 struct { - Type uint32 /* Entry type. */ - Off uint32 /* File offset of contents. */ - Vaddr uint32 /* Virtual address in memory image. */ - Paddr uint32 /* Physical address (not used). */ - Filesz uint32 /* Size of contents in file. */ - Memsz uint32 /* Size of contents in memory. */ - Flags uint32 /* Access permission flags. */ - Align uint32 /* Alignment in memory and file. */ -} - -// ELF32 Dynamic structure. The ".dynamic" section contains an array of them. -type Dyn32 struct { - Tag int32 /* Entry type. */ - Val uint32 /* Integer/Address value. */ -} - -// ELF32 Compression header. -type Chdr32 struct { - Type uint32 - Size uint32 - Addralign uint32 -} - -/* - * Relocation entries. - */ - -// ELF32 Relocations that don't need an addend field. -type Rel32 struct { - Off uint32 /* Location to be relocated. */ - Info uint32 /* Relocation type and symbol index. */ -} - -// ELF32 Relocations that need an addend field. -type Rela32 struct { - Off uint32 /* Location to be relocated. */ - Info uint32 /* Relocation type and symbol index. */ - Addend int32 /* Addend. */ -} - -func R_SYM32(info uint32) uint32 { return info >> 8 } -func R_TYPE32(info uint32) uint32 { return info & 0xff } -func R_INFO32(sym, typ uint32) uint32 { return sym<<8 | typ } - -// ELF32 Symbol. -type Sym32 struct { - Name uint32 - Value uint32 - Size uint32 - Info uint8 - Other uint8 - Shndx uint16 -} - -const Sym32Size = 16 - -func ST_BIND(info uint8) SymBind { return SymBind(info >> 4) } -func ST_TYPE(info uint8) SymType { return SymType(info & 0xF) } -func ST_INFO(bind SymBind, typ SymType) uint8 { - return uint8(bind)<<4 | uint8(typ)&0xf -} -func ST_VISIBILITY(other uint8) SymVis { return SymVis(other & 3) } - -/* - * ELF64 - */ - -// ELF64 file header. -type Header64 struct { - Ident [EI_NIDENT]byte /* File identification. */ - Type uint16 /* File type. */ - Machine uint16 /* Machine architecture. */ - Version uint32 /* ELF format version. */ - Entry uint64 /* Entry point. */ - Phoff uint64 /* Program header file offset. */ - Shoff uint64 /* Section header file offset. */ - Flags uint32 /* Architecture-specific flags. */ - Ehsize uint16 /* Size of ELF header in bytes. */ - Phentsize uint16 /* Size of program header entry. */ - Phnum uint16 /* Number of program header entries. */ - Shentsize uint16 /* Size of section header entry. */ - Shnum uint16 /* Number of section header entries. */ - Shstrndx uint16 /* Section name strings section. */ -} - -// ELF64 Section header. -type Section64 struct { - Name uint32 /* Section name (index into the section header string table). */ - Type uint32 /* Section type. */ - Flags uint64 /* Section flags. */ - Addr uint64 /* Address in memory image. */ - Off uint64 /* Offset in file. */ - Size uint64 /* Size in bytes. */ - Link uint32 /* Index of a related section. */ - Info uint32 /* Depends on section type. */ - Addralign uint64 /* Alignment in bytes. */ - Entsize uint64 /* Size of each entry in section. */ -} - -// ELF64 Program header. -type Prog64 struct { - Type uint32 /* Entry type. */ - Flags uint32 /* Access permission flags. */ - Off uint64 /* File offset of contents. */ - Vaddr uint64 /* Virtual address in memory image. */ - Paddr uint64 /* Physical address (not used). */ - Filesz uint64 /* Size of contents in file. */ - Memsz uint64 /* Size of contents in memory. */ - Align uint64 /* Alignment in memory and file. */ -} - -// ELF64 Dynamic structure. The ".dynamic" section contains an array of them. -type Dyn64 struct { - Tag int64 /* Entry type. */ - Val uint64 /* Integer/address value */ -} - -// ELF64 Compression header. -type Chdr64 struct { - Type uint32 - _ uint32 /* Reserved. */ - Size uint64 - Addralign uint64 -} - -/* - * Relocation entries. - */ - -/* ELF64 relocations that don't need an addend field. */ -type Rel64 struct { - Off uint64 /* Location to be relocated. */ - Info uint64 /* Relocation type and symbol index. */ -} - -/* ELF64 relocations that need an addend field. */ -type Rela64 struct { - Off uint64 /* Location to be relocated. */ - Info uint64 /* Relocation type and symbol index. */ - Addend int64 /* Addend. */ -} - -func R_SYM64(info uint64) uint32 { return uint32(info >> 32) } -func R_TYPE64(info uint64) uint32 { return uint32(info) } -func R_INFO(sym, typ uint32) uint64 { return uint64(sym)<<32 | uint64(typ) } - -// ELF64 symbol table entries. -type Sym64 struct { - Name uint32 /* String table index of name. */ - Info uint8 /* Type and binding information. */ - Other uint8 /* Reserved (not used). */ - Shndx uint16 /* Section index of symbol. */ - Value uint64 /* Symbol value. */ - Size uint64 /* Size of associated object. */ -} - -const Sym64Size = 24 - -type intName struct { - i uint32 - s string -} - -func stringName(i uint32, names []intName, goSyntax bool) string { - for _, n := range names { - if n.i == i { - if goSyntax { - return "elf." + n.s - } - return n.s - } - } - - // second pass - look for smaller to add with. - // assume sorted already - for j := len(names) - 1; j >= 0; j-- { - n := names[j] - if n.i < i { - s := n.s - if goSyntax { - s = "elf." + s - } - return s + "+" + strconv.FormatUint(uint64(i-n.i), 10) - } - } - - return strconv.FormatUint(uint64(i), 10) -} - -func flagName(i uint32, names []intName, goSyntax bool) string { - s := "" - for _, n := range names { - if n.i&i == n.i { - if len(s) > 0 { - s += "+" - } - if goSyntax { - s += "elf." - } - s += n.s - i -= n.i - } - } - if len(s) == 0 { - return "0x" + strconv.FormatUint(uint64(i), 16) - } - if i != 0 { - s += "+0x" + strconv.FormatUint(uint64(i), 16) - } - return s -} diff --git a/odiglet/pkg/allocator/debug/elf/elf_test.go b/odiglet/pkg/allocator/debug/elf/elf_test.go deleted file mode 100644 index f8985a8992..0000000000 --- a/odiglet/pkg/allocator/debug/elf/elf_test.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package elf - -import ( - "fmt" - "testing" -) - -type nameTest struct { - val interface{} - str string -} - -var nameTests = []nameTest{ - {ELFOSABI_LINUX, "ELFOSABI_LINUX"}, - {ET_EXEC, "ET_EXEC"}, - {EM_860, "EM_860"}, - {SHN_LOPROC, "SHN_LOPROC"}, - {SHT_PROGBITS, "SHT_PROGBITS"}, - {SHF_MERGE + SHF_TLS, "SHF_MERGE+SHF_TLS"}, - {PT_LOAD, "PT_LOAD"}, - {PF_W + PF_R + 0x50, "PF_W+PF_R+0x50"}, - {DT_SYMBOLIC, "DT_SYMBOLIC"}, - {DF_BIND_NOW, "DF_BIND_NOW"}, - {NT_FPREGSET, "NT_FPREGSET"}, - {STB_GLOBAL, "STB_GLOBAL"}, - {STT_COMMON, "STT_COMMON"}, - {STV_HIDDEN, "STV_HIDDEN"}, - {R_X86_64_PC32, "R_X86_64_PC32"}, - {R_ALPHA_OP_PUSH, "R_ALPHA_OP_PUSH"}, - {R_ARM_THM_ABS5, "R_ARM_THM_ABS5"}, - {R_386_GOT32, "R_386_GOT32"}, - {R_PPC_GOT16_HI, "R_PPC_GOT16_HI"}, - {R_SPARC_GOT22, "R_SPARC_GOT22"}, - {ET_LOOS + 5, "ET_LOOS+5"}, - {ProgFlag(0x50), "0x50"}, -} - -func TestNames(t *testing.T) { - for i, tt := range nameTests { - s := fmt.Sprint(tt.val) - if s != tt.str { - t.Errorf("#%d: Sprint(%d) = %q, want %q", i, tt.val, s, tt.str) - } - } -} diff --git a/odiglet/pkg/allocator/debug/elf/exports.go b/odiglet/pkg/allocator/debug/elf/exports.go deleted file mode 100644 index 5feab4993e..0000000000 --- a/odiglet/pkg/allocator/debug/elf/exports.go +++ /dev/null @@ -1,32 +0,0 @@ -package elf - -/* - Any symbol in the dynamic symbol table (in .dynsym) for which .st_shndx == SHN_UNDEF - (references undefined section) is an import, and every other symbol is defined and exported. -*/ - -// Export - describes a single export entry -type Export struct { - Name string - VirtualAddress uint64 -} - -// Exports - gets exports -func (f *File) Exports() ([]Export, error) { - - var exports []Export - symbols, err := f.DynamicSymbols() - if err != nil { - return nil, err - } - for _, s := range symbols { - if s.Section != SHN_UNDEF { - exports = append(exports, Export{ - Name: s.Name, - VirtualAddress: s.Value, - }) - } - } - - return exports, nil -} diff --git a/odiglet/pkg/allocator/debug/elf/file.go b/odiglet/pkg/allocator/debug/elf/file.go deleted file mode 100644 index 4d21e9cf57..0000000000 --- a/odiglet/pkg/allocator/debug/elf/file.go +++ /dev/null @@ -1,964 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package elf implements access to ELF object files. -package elf - -import ( - "bytes" - "compress/zlib" - "debug/dwarf" - "encoding/binary" - "errors" - "fmt" - "io" - "os" - "strings" -) - -// seekStart, seekCurrent, seekEnd are copies of -// io.SeekStart, io.SeekCurrent, and io.SeekEnd. -// We can't use the ones from package io because -// we want this code to build with Go 1.4 during -// cmd/dist bootstrap. -const ( - seekStart int = 0 - seekCurrent int = 1 - seekEnd int = 2 -) - -// TODO: error reporting detail - -/* - * Internal ELF representation - */ - -// A FileHeader represents an ELF file header. -type FileHeader struct { - Class Class - Data Data - Version Version - OSABI OSABI - ABIVersion uint8 - ByteOrder binary.ByteOrder - Type Type - Machine Machine - Entry uint64 - SHTOffset int64 - ShStrIndex int -} - -// A File represents an open ELF file. -type File struct { - FileHeader - Sections []*Section - Progs []*Prog - closer io.Closer - gnuNeed []verneed - gnuVersym []byte - Insertion []byte - InsertionEOF []byte - - DynTags []DynTagValue -} - -// A SectionHeader represents a single ELF section header. -type SectionHeader struct { - Name string - Type SectionType - Flags SectionFlag - Addr uint64 - Offset uint64 - Size uint64 - Link uint32 - Info uint32 - Addralign uint64 - Entsize uint64 - - Shnum int // Section Header Number - Shname uint32 // Section Header Name (index) - - // FileSize is the size of this section in the file in bytes. - // If a section is compressed, FileSize is the size of the - // compressed data, while Size (above) is the size of the - // uncompressed data. - FileSize uint64 -} - -// A Section represents a single section in an ELF file. -type Section struct { - SectionHeader - - // Embed ReaderAt for ReadAt method. - // Do not embed SectionReader directly - // to avoid having Read and Seek. - // If a client wants Read and Seek it must use - // Open() to avoid fighting over the seek offset - // with other clients. - // - // ReaderAt may be nil if the section is not easily available - // in a random-access form. For example, a compressed section - // may have a nil ReaderAt. - io.ReaderAt - sr *io.SectionReader - - compressionType CompressionType - compressionOffset int64 -} - -// Data reads and returns the contents of the ELF section. -// Even if the section is stored compressed in the ELF file, -// Data returns uncompressed data. -func (s *Section) Data() ([]byte, error) { - dat := make([]byte, s.Size) - n, err := io.ReadFull(s.Open(), dat) - return dat[0:n], err -} - -// stringTable reads and returns the string table given by the -// specified link value. -func (f *File) stringTable(link uint32) ([]byte, error) { - if link <= 0 || link >= uint32(len(f.Sections)) { - return nil, errors.New("section has invalid string table link") - } - return f.Sections[link].Data() -} - -// Open returns a new ReadSeeker reading the ELF section. -// Even if the section is stored compressed in the ELF file, -// the ReadSeeker reads uncompressed data. -func (s *Section) Open() io.ReadSeeker { - if s.Flags&SHF_COMPRESSED == 0 { - return io.NewSectionReader(s.sr, 0, 1<<63-1) - } - if s.compressionType == COMPRESS_ZLIB { - return &readSeekerFromReader{ - reset: func() (io.Reader, error) { - fr := io.NewSectionReader(s.sr, s.compressionOffset, int64(s.FileSize)-s.compressionOffset) - return zlib.NewReader(fr) - }, - size: int64(s.Size), - } - } - err := &FormatError{int64(s.Offset), "unknown compression type", s.compressionType} - return errorReader{err} -} - -// A ProgHeader represents a single ELF program header. -type ProgHeader struct { - Type ProgType - Flags ProgFlag - Off uint64 - Vaddr uint64 - Paddr uint64 - Filesz uint64 - Memsz uint64 - Align uint64 -} - -// A Prog represents a single ELF program header in an ELF binary. -type Prog struct { - ProgHeader - - // Embed ReaderAt for ReadAt method. - // Do not embed SectionReader directly - // to avoid having Read and Seek. - // If a client wants Read and Seek it must use - // Open() to avoid fighting over the seek offset - // with other clients. - io.ReaderAt - sr *io.SectionReader -} - -// Open returns a new ReadSeeker reading the ELF program body. -func (p *Prog) Open() io.ReadSeeker { return io.NewSectionReader(p.sr, 0, 1<<63-1) } - -// A Symbol represents an entry in an ELF symbol table section. -type Symbol struct { - Name string - NameIndex uint32 - Info, Other byte - Section SectionIndex - SectIndex uint16 - Value, Size uint64 -} - -// ToSym64 - Convert to a Sym64 -func (s Symbol) ToSym64() (retval Sym64) { - - retval.Name = s.NameIndex - retval.Info = s.Info - retval.Other = s.Other - retval.Shndx = s.SectIndex - retval.Value = s.Value - retval.Size = s.Size - return -} - -// ToSym32 - Convert to a Sym32 -func (s Symbol) ToSym32() (retval Sym32) { - - retval.Name = s.NameIndex - retval.Info = s.Info - retval.Other = s.Other - retval.Shndx = s.SectIndex - retval.Value = uint32(s.Value) - retval.Size = uint32(s.Size) - return -} - -/* - * ELF reader - */ - -type FormatError struct { - off int64 - msg string - val interface{} -} - -func (e *FormatError) Error() string { - msg := e.msg - if e.val != nil { - msg += fmt.Sprintf(" '%v' ", e.val) - } - msg += fmt.Sprintf("in record at byte %#x", e.off) - return msg -} - -// Open opens the named file using os.Open and prepares it for use as an ELF binary. -func Open(name string) (*File, error) { - f, err := os.Open(name) - if err != nil { - return nil, err - } - ff, err := NewFile(f) - if err != nil { - f.Close() - return nil, err - } - ff.closer = f - return ff, nil -} - -// Close closes the File. -// If the File was created using NewFile directly instead of Open, -// Close has no effect. -func (f *File) Close() error { - var err error - if f.closer != nil { - err = f.closer.Close() - f.closer = nil - } - return err -} - -// SectionByType returns the first section in f with the -// given type, or nil if there is no such section. -func (f *File) SectionByType(typ SectionType) *Section { - for _, s := range f.Sections { - if s.Type == typ { - return s - } - } - return nil -} - -// SectionByName returns the first section in f with the -// given name, or nil if there is no such section. -func (f *File) SectionByName(name string) *Section { - for _, s := range f.Sections { - if s.Name == name { - return s - } - } - return nil -} - -// NewFile creates a new File for accessing an ELF binary in an underlying reader. -// The ELF binary is expected to start at position 0 in the ReaderAt. -func NewFile(r io.ReaderAt) (*File, error) { - sr := io.NewSectionReader(r, 0, 1<<63-1) - // Read and decode ELF identifier - var ident [16]uint8 - if _, err := r.ReadAt(ident[0:], 0); err != nil { - return nil, err - } - if ident[0] != '\x7f' || ident[1] != 'E' || ident[2] != 'L' || ident[3] != 'F' { - return nil, &FormatError{0, "bad magic number", ident[0:4]} - } - - f := new(File) - f.Class = Class(ident[EI_CLASS]) - switch f.Class { - case ELFCLASS32: - case ELFCLASS64: - // ok - default: - return nil, &FormatError{0, "unknown ELF class", f.Class} - } - - f.Data = Data(ident[EI_DATA]) - switch f.Data { - case ELFDATA2LSB: - f.ByteOrder = binary.LittleEndian - case ELFDATA2MSB: - f.ByteOrder = binary.BigEndian - default: - return nil, &FormatError{0, "unknown ELF data encoding", f.Data} - } - - f.Version = Version(ident[EI_VERSION]) - if f.Version != EV_CURRENT { - return nil, &FormatError{0, "unknown ELF version", f.Version} - } - - f.OSABI = OSABI(ident[EI_OSABI]) - f.ABIVersion = ident[EI_ABIVERSION] - - // Read ELF file header - var phoff int64 - var phentsize, phnum int - var shentsize, shnum int - f.ShStrIndex = -1 - switch f.Class { - case ELFCLASS32: - hdr := new(Header32) - sr.Seek(0, seekStart) - if err := binary.Read(sr, f.ByteOrder, hdr); err != nil { - return nil, err - } - f.Type = Type(hdr.Type) - f.Machine = Machine(hdr.Machine) - f.Entry = uint64(hdr.Entry) - if v := Version(hdr.Version); v != f.Version { - return nil, &FormatError{0, "mismatched ELF version", v} - } - phoff = int64(hdr.Phoff) - phentsize = int(hdr.Phentsize) - phnum = int(hdr.Phnum) - f.SHTOffset = int64(hdr.Shoff) - shentsize = int(hdr.Shentsize) - shnum = int(hdr.Shnum) - f.ShStrIndex = int(hdr.Shstrndx) - case ELFCLASS64: - hdr := new(Header64) - sr.Seek(0, seekStart) - if err := binary.Read(sr, f.ByteOrder, hdr); err != nil { - return nil, err - } - f.Type = Type(hdr.Type) - f.Machine = Machine(hdr.Machine) - f.Entry = hdr.Entry - if v := Version(hdr.Version); v != f.Version { - return nil, &FormatError{0, "mismatched ELF version", v} - } - phoff = int64(hdr.Phoff) - phentsize = int(hdr.Phentsize) - phnum = int(hdr.Phnum) - f.SHTOffset = int64(hdr.Shoff) - shentsize = int(hdr.Shentsize) - shnum = int(hdr.Shnum) - f.ShStrIndex = int(hdr.Shstrndx) - } - - if shnum > 0 && f.SHTOffset > 0 && (f.ShStrIndex < 0 || f.ShStrIndex >= shnum) { - return nil, &FormatError{0, "invalid ELF shstrndx", f.ShStrIndex} - } - - // Read program headers - f.Progs = make([]*Prog, phnum) - for i := 0; i < phnum; i++ { - off := phoff + int64(i)*int64(phentsize) - sr.Seek(off, seekStart) - p := new(Prog) - switch f.Class { - case ELFCLASS32: - ph := new(Prog32) - if err := binary.Read(sr, f.ByteOrder, ph); err != nil { - return nil, err - } - p.ProgHeader = ProgHeader{ - Type: ProgType(ph.Type), - Flags: ProgFlag(ph.Flags), - Off: uint64(ph.Off), - Vaddr: uint64(ph.Vaddr), - Paddr: uint64(ph.Paddr), - Filesz: uint64(ph.Filesz), - Memsz: uint64(ph.Memsz), - Align: uint64(ph.Align), - } - case ELFCLASS64: - ph := new(Prog64) - if err := binary.Read(sr, f.ByteOrder, ph); err != nil { - return nil, err - } - p.ProgHeader = ProgHeader{ - Type: ProgType(ph.Type), - Flags: ProgFlag(ph.Flags), - Off: ph.Off, - Vaddr: ph.Vaddr, - Paddr: ph.Paddr, - Filesz: ph.Filesz, - Memsz: ph.Memsz, - Align: ph.Align, - } - } - p.sr = io.NewSectionReader(r, int64(p.Off), int64(p.Filesz)) - p.ReaderAt = p.sr - f.Progs[i] = p - } - - // Read section headers - f.Sections = make([]*Section, shnum) - names := make([]uint32, shnum) - for i := 0; i < shnum; i++ { - off := f.SHTOffset + int64(i)*int64(shentsize) - sr.Seek(off, seekStart) - s := new(Section) - switch f.Class { - case ELFCLASS32: - sh := new(Section32) - if err := binary.Read(sr, f.ByteOrder, sh); err != nil { - return nil, err - } - names[i] = sh.Name - s.SectionHeader = SectionHeader{ - Type: SectionType(sh.Type), - Flags: SectionFlag(sh.Flags), - Addr: uint64(sh.Addr), - Offset: uint64(sh.Off), - FileSize: uint64(sh.Size), - Link: sh.Link, - Info: sh.Info, - Addralign: uint64(sh.Addralign), - Entsize: uint64(sh.Entsize), - Shnum: i, - Shname: sh.Name, - } - - case ELFCLASS64: - sh := new(Section64) - if err := binary.Read(sr, f.ByteOrder, sh); err != nil { - return nil, err - } - names[i] = sh.Name - s.SectionHeader = SectionHeader{ - Type: SectionType(sh.Type), - Flags: SectionFlag(sh.Flags), - Offset: sh.Off, - FileSize: sh.Size, - Addr: sh.Addr, - Link: sh.Link, - Info: sh.Info, - Addralign: sh.Addralign, - Entsize: sh.Entsize, - Shnum: i, - Shname: sh.Name, - } - } - s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.FileSize)) - - if s.Flags&SHF_COMPRESSED == 0 { - s.ReaderAt = s.sr - s.Size = s.FileSize - } else { - // Read the compression header. - switch f.Class { - case ELFCLASS32: - ch := new(Chdr32) - if err := binary.Read(s.sr, f.ByteOrder, ch); err != nil { - return nil, err - } - s.compressionType = CompressionType(ch.Type) - s.Size = uint64(ch.Size) - s.Addralign = uint64(ch.Addralign) - s.compressionOffset = int64(binary.Size(ch)) - case ELFCLASS64: - ch := new(Chdr64) - if err := binary.Read(s.sr, f.ByteOrder, ch); err != nil { - return nil, err - } - s.compressionType = CompressionType(ch.Type) - s.Size = ch.Size - s.Addralign = ch.Addralign - s.compressionOffset = int64(binary.Size(ch)) - } - } - - f.Sections[i] = s - } - - if err := f.parseDynTags(); err != nil { - return nil, err - } - - if len(f.Sections) == 0 { - return f, nil - } - - // Load section header string table. - shstrtab, err := f.Sections[f.ShStrIndex].Data() - if err != nil { - return nil, err - } - for i, s := range f.Sections { - var ok bool - s.Name, ok = getString(shstrtab, int(names[i])) - if !ok { - return nil, &FormatError{f.SHTOffset + int64(i*shentsize), "bad section name index", names[i]} - } - } - - return f, nil -} - -// getSymbols returns a slice of Symbols from parsing the symbol table -// with the given type, along with the associated string table. -func (f *File) getSymbols(typ SectionType) ([]Symbol, []byte, error) { - switch f.Class { - case ELFCLASS64: - return f.getSymbols64(typ) - - case ELFCLASS32: - return f.getSymbols32(typ) - } - - return nil, nil, errors.New("not implemented") -} - -// ErrNoSymbols is returned by File.Symbols and File.DynamicSymbols -// if there is no such section in the File. -var ErrNoSymbols = errors.New("no symbol section") - -func (f *File) getSymbols32(typ SectionType) ([]Symbol, []byte, error) { - symtabSection := f.SectionByType(typ) - if symtabSection == nil { - return nil, nil, ErrNoSymbols - } - - data, err := symtabSection.Data() - if err != nil { - return nil, nil, errors.New("cannot load symbol section") - } - symtab := bytes.NewReader(data) - if symtab.Len()%Sym32Size != 0 { - return nil, nil, errors.New("length of symbol section is not a multiple of SymSize") - } - - strdata, err := f.stringTable(symtabSection.Link) - if err != nil { - return nil, nil, errors.New("cannot load string table section") - } - - // The first entry is all zeros. - var skip [Sym32Size]byte - symtab.Read(skip[:]) - - symbols := make([]Symbol, symtab.Len()/Sym32Size) - - i := 0 - var sym Sym32 - for symtab.Len() > 0 { - binary.Read(symtab, f.ByteOrder, &sym) - str, _ := getString(strdata, int(sym.Name)) - symbols[i].Name = str - symbols[i].Info = sym.Info - symbols[i].Other = sym.Other - symbols[i].Section = SectionIndex(sym.Shndx) - symbols[i].Value = uint64(sym.Value) - symbols[i].Size = uint64(sym.Size) - i++ - } - - return symbols, strdata, nil -} - -func (f *File) getSymbols64(typ SectionType) ([]Symbol, []byte, error) { - symtabSection := f.SectionByType(typ) - if symtabSection == nil { - return nil, nil, ErrNoSymbols - } - - data, err := symtabSection.Data() - if err != nil { - return nil, nil, errors.New("cannot load symbol section") - } - symtab := bytes.NewReader(data) - if symtab.Len()%Sym64Size != 0 { - return nil, nil, errors.New("length of symbol section is not a multiple of Sym64Size") - } - - strdata, err := f.stringTable(symtabSection.Link) - if err != nil { - return nil, nil, errors.New("cannot load string table section") - } - - // The first entry is all zeros. - var skip [Sym64Size]byte - symtab.Read(skip[:]) - - symbols := make([]Symbol, symtab.Len()/Sym64Size) - - i := 0 - var sym Sym64 - for symtab.Len() > 0 { - binary.Read(symtab, f.ByteOrder, &sym) - str, _ := getString(strdata, int(sym.Name)) - symbols[i].Name = str - symbols[i].NameIndex = sym.Name - symbols[i].Info = sym.Info - symbols[i].Other = sym.Other - symbols[i].Section = SectionIndex(sym.Shndx) - symbols[i].SectIndex = sym.Shndx - symbols[i].Value = sym.Value - symbols[i].Size = sym.Size - i++ - } - - return symbols, strdata, nil -} - -// getString extracts a string from an ELF string table. -func getString(section []byte, start int) (string, bool) { - if start < 0 || start >= len(section) { - return "", false - } - - for end := start; end < len(section); end++ { - if section[end] == 0 { - return string(section[start:end]), true - } - } - return "", false -} - -// Section returns a section with the given name, or nil if no such -// section exists. -func (f *File) Section(name string) *Section { - for _, s := range f.Sections { - if s.Name == name { - return s - } - } - return nil -} - -// DWARF - No idea what this does -func (f *File) DWARF() (*dwarf.Data, error) { - dwarfSuffix := func(s *Section) string { - switch { - case strings.HasPrefix(s.Name, ".debug_"): - return s.Name[7:] - case strings.HasPrefix(s.Name, ".zdebug_"): - return s.Name[8:] - default: - return "" - } - - } - // sectionData gets the data for s, checks its size, and - // applies any applicable relations. - sectionData := func(i int, s *Section) ([]byte, error) { - b, err := s.Data() - if err != nil && uint64(len(b)) < s.Size { - return nil, err - } - - if len(b) >= 12 && string(b[:4]) == "ZLIB" { - dlen := binary.BigEndian.Uint64(b[4:12]) - dbuf := make([]byte, dlen) - r, err := zlib.NewReader(bytes.NewBuffer(b[12:])) - if err != nil { - return nil, err - } - if _, err := io.ReadFull(r, dbuf); err != nil { - return nil, err - } - if err := r.Close(); err != nil { - return nil, err - } - b = dbuf - } - - for _, r := range f.Sections { - if r.Type != SHT_RELA && r.Type != SHT_REL { - continue - } - if int(r.Info) != i { - continue - } - rd, err := r.Data() - if err != nil { - return nil, err - } - err = f.applyRelocations(b, rd) - if err != nil { - return nil, err - } - } - return b, nil - } - - // There are many other DWARF sections, but these - // are the ones the debug/dwarf package uses. - // Don't bother loading others. - var dat = map[string][]byte{"abbrev": nil, "info": nil, "str": nil, "line": nil, "ranges": nil} - for i, s := range f.Sections { - suffix := dwarfSuffix(s) - if suffix == "" { - continue - } - if _, ok := dat[suffix]; !ok { - continue - } - b, err := sectionData(i, s) - if err != nil { - return nil, err - } - dat[suffix] = b - } - - d, err := dwarf.New(dat["abbrev"], nil, nil, dat["info"], dat["line"], nil, dat["ranges"], dat["str"]) - if err != nil { - return nil, err - } - - // Look for DWARF4 .debug_types sections. - for i, s := range f.Sections { - suffix := dwarfSuffix(s) - if suffix != "types" { - continue - } - - b, err := sectionData(i, s) - if err != nil { - return nil, err - } - - err = d.AddTypes(fmt.Sprintf("types-%d", i), b) - if err != nil { - return nil, err - } - } - - return d, nil -} - -// Symbols returns the symbol table for f. The symbols will be listed in the order -// they appear in f. -// -// For compatibility with Go 1.0, Symbols omits the null symbol at index 0. -// After retrieving the symbols as symtab, an externally supplied index x -// corresponds to symtab[x-1], not symtab[x]. -func (f *File) Symbols() ([]Symbol, error) { - sym, _, err := f.getSymbols(SHT_SYMTAB) - return sym, err -} - -// DynamicSymbols returns the dynamic symbol table for f. The symbols -// will be listed in the order they appear in f. -// -// For compatibility with Symbols, DynamicSymbols omits the null symbol at index 0. -// After retrieving the symbols as symtab, an externally supplied index x -// corresponds to symtab[x-1], not symtab[x]. -func (f *File) DynamicSymbols() ([]Symbol, error) { - sym, _, err := f.getSymbols(SHT_DYNSYM) - return sym, err -} - -type ImportedSymbol struct { - Name string - Version string - Library string -} - -// ImportedSymbols returns the names of all symbols -// referred to by the binary f that are expected to be -// satisfied by other libraries at dynamic load time. -// It does not return weak symbols. -func (f *File) ImportedSymbols() ([]ImportedSymbol, error) { - sym, str, err := f.getSymbols(SHT_DYNSYM) - if err != nil { - return nil, err - } - f.gnuVersionInit(str) - var all []ImportedSymbol - for i, s := range sym { - if ST_BIND(s.Info) == STB_GLOBAL && s.Section == SHN_UNDEF { - all = append(all, ImportedSymbol{Name: s.Name}) - f.gnuVersion(i, &all[len(all)-1]) - } - } - return all, nil -} - -type verneed struct { - File string - Name string -} - -// gnuVersionInit parses the GNU version tables -// for use by calls to gnuVersion. -func (f *File) gnuVersionInit(str []byte) { - // Accumulate verneed information. - vn := f.SectionByType(SHT_GNU_VERNEED) - if vn == nil { - return - } - d, _ := vn.Data() - - var need []verneed - i := 0 - for { - if i+16 > len(d) { - break - } - vers := f.ByteOrder.Uint16(d[i : i+2]) - if vers != 1 { - break - } - cnt := f.ByteOrder.Uint16(d[i+2 : i+4]) - fileoff := f.ByteOrder.Uint32(d[i+4 : i+8]) - aux := f.ByteOrder.Uint32(d[i+8 : i+12]) - next := f.ByteOrder.Uint32(d[i+12 : i+16]) - file, _ := getString(str, int(fileoff)) - - var name string - j := i + int(aux) - for c := 0; c < int(cnt); c++ { - if j+16 > len(d) { - break - } - // hash := f.ByteOrder.Uint32(d[j:j+4]) - // flags := f.ByteOrder.Uint16(d[j+4:j+6]) - other := f.ByteOrder.Uint16(d[j+6 : j+8]) - nameoff := f.ByteOrder.Uint32(d[j+8 : j+12]) - next := f.ByteOrder.Uint32(d[j+12 : j+16]) - name, _ = getString(str, int(nameoff)) - ndx := int(other) - if ndx >= len(need) { - a := make([]verneed, 2*(ndx+1)) - copy(a, need) - need = a - } - - need[ndx] = verneed{file, name} - if next == 0 { - break - } - j += int(next) - } - - if next == 0 { - break - } - i += int(next) - } - - // Versym parallels symbol table, indexing into verneed. - vs := f.SectionByType(SHT_GNU_VERSYM) - if vs == nil { - return - } - d, _ = vs.Data() - - f.gnuNeed = need - f.gnuVersym = d -} - -// gnuVersion adds Library and Version information to sym, -// which came from offset i of the symbol table. -func (f *File) gnuVersion(i int, sym *ImportedSymbol) { - // Each entry is two bytes. - i = (i + 1) * 2 - if i >= len(f.gnuVersym) { - return - } - j := int(f.ByteOrder.Uint16(f.gnuVersym[i:])) - if j < 2 || j >= len(f.gnuNeed) { - return - } - n := &f.gnuNeed[j] - sym.Library = n.File - sym.Version = n.Name -} - -// ImportedLibraries returns the names of all libraries -// referred to by the binary f that are expected to be -// linked with the binary at dynamic link time. -func (f *File) ImportedLibraries() ([]string, error) { - return f.DynString(DT_NEEDED) -} - -func (f *File) parseDynTags() error { - s := f.SectionByType(SHT_DYNAMIC) - if s == nil { - return nil // nothing to do - } - - var m []DynTagValue - d, err := s.Data() - if err != nil { - return err - } - //fmt.Printf("%+v\nd: %x len(%d)\n", s, d, len(d)) - - r := bytes.NewBuffer(d) - for { - var t, v uint64 - if err := binary.Read(r, f.ByteOrder, &t); err != nil { - if err == io.EOF { - break - } else if err != nil { - return err - } - } - if err := binary.Read(r, f.ByteOrder, &v); err != nil { - if err == io.EOF { - break - } else if err != nil { - return err - } - } - m = append(m, DynTagValue{Tag: DynTag(t), Value: v}) - //fmt.Printf("%x -> %x\n", t, v) - } - f.DynTags = m - return nil -} - -// DynString returns the strings listed for the given tag in the file's dynamic -// section. -// -// The tag must be one that takes string values: DT_NEEDED, DT_SONAME, DT_RPATH, or -// DT_RUNPATH. -func (f *File) DynString(tag DynTag) ([]string, error) { - switch tag { - case DT_NEEDED, DT_SONAME, DT_RPATH, DT_RUNPATH: - default: - return nil, fmt.Errorf("non-string-valued tag %v", tag) - } - - ds := f.SectionByType(SHT_DYNAMIC) - if ds == nil { - // not dynamic, so no libraries - return nil, nil - } - - str, err := f.stringTable(ds.Link) - if err != nil { - return nil, err - } - var all []string - for _, taggedValue := range f.DynTags { - if taggedValue.Tag == tag { - s, ok := getString(str, int(taggedValue.Value)) - if ok { - all = append(all, s) - } - } - } - return all, nil -} diff --git a/odiglet/pkg/allocator/debug/elf/file_test.go b/odiglet/pkg/allocator/debug/elf/file_test.go deleted file mode 100644 index d7c1e9f800..0000000000 --- a/odiglet/pkg/allocator/debug/elf/file_test.go +++ /dev/null @@ -1,812 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package elf - -import ( - "bytes" - "compress/gzip" - "debug/dwarf" - "encoding/binary" - "io" - "math/rand" - "net" - "os" - "path" - "reflect" - "runtime" - "testing" -) - -type fileTest struct { - file string - hdr FileHeader - sections []SectionHeader - progs []ProgHeader - needed []string -} - -var fileTests = []fileTest{ - { - "testdata/gcc-386-freebsd-exec", - FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_FREEBSD, 0, binary.LittleEndian, ET_EXEC, EM_386, 0x80483cc}, - []SectionHeader{ - {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, - {".interp", SHT_PROGBITS, SHF_ALLOC, 0x80480d4, 0xd4, 0x15, 0x0, 0x0, 0x1, 0x0, 0x15}, - {".hash", SHT_HASH, SHF_ALLOC, 0x80480ec, 0xec, 0x90, 0x3, 0x0, 0x4, 0x4, 0x90}, - {".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x804817c, 0x17c, 0x110, 0x4, 0x1, 0x4, 0x10, 0x110}, - {".dynstr", SHT_STRTAB, SHF_ALLOC, 0x804828c, 0x28c, 0xbb, 0x0, 0x0, 0x1, 0x0, 0xbb}, - {".rel.plt", SHT_REL, SHF_ALLOC, 0x8048348, 0x348, 0x20, 0x3, 0x7, 0x4, 0x8, 0x20}, - {".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x8048368, 0x368, 0x11, 0x0, 0x0, 0x4, 0x0, 0x11}, - {".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804837c, 0x37c, 0x50, 0x0, 0x0, 0x4, 0x4, 0x50}, - {".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x80483cc, 0x3cc, 0x180, 0x0, 0x0, 0x4, 0x0, 0x180}, - {".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804854c, 0x54c, 0xc, 0x0, 0x0, 0x4, 0x0, 0xc}, - {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x8048558, 0x558, 0xa3, 0x0, 0x0, 0x1, 0x0, 0xa3}, - {".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80495fc, 0x5fc, 0xc, 0x0, 0x0, 0x4, 0x0, 0xc}, - {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x8049608, 0x608, 0x4, 0x0, 0x0, 0x4, 0x0, 0x4}, - {".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x804960c, 0x60c, 0x98, 0x4, 0x0, 0x4, 0x8, 0x98}, - {".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496a4, 0x6a4, 0x8, 0x0, 0x0, 0x4, 0x0, 0x8}, - {".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496ac, 0x6ac, 0x8, 0x0, 0x0, 0x4, 0x0, 0x8}, - {".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b4, 0x6b4, 0x4, 0x0, 0x0, 0x4, 0x0, 0x4}, - {".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b8, 0x6b8, 0x1c, 0x0, 0x0, 0x4, 0x4, 0x1c}, - {".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x80496d4, 0x6d4, 0x20, 0x0, 0x0, 0x4, 0x0, 0x20}, - {".comment", SHT_PROGBITS, 0x0, 0x0, 0x6d4, 0x12d, 0x0, 0x0, 0x1, 0x0, 0x12d}, - {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x801, 0x20, 0x0, 0x0, 0x1, 0x0, 0x20}, - {".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0x821, 0x1b, 0x0, 0x0, 0x1, 0x0, 0x1b}, - {".debug_info", SHT_PROGBITS, 0x0, 0x0, 0x83c, 0x11d, 0x0, 0x0, 0x1, 0x0, 0x11d}, - {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0x959, 0x41, 0x0, 0x0, 0x1, 0x0, 0x41}, - {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x99a, 0x35, 0x0, 0x0, 0x1, 0x0, 0x35}, - {".debug_frame", SHT_PROGBITS, 0x0, 0x0, 0x9d0, 0x30, 0x0, 0x0, 0x4, 0x0, 0x30}, - {".debug_str", SHT_PROGBITS, 0x0, 0x0, 0xa00, 0xd, 0x0, 0x0, 0x1, 0x0, 0xd}, - {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xa0d, 0xf8, 0x0, 0x0, 0x1, 0x0, 0xf8}, - {".symtab", SHT_SYMTAB, 0x0, 0x0, 0xfb8, 0x4b0, 0x1d, 0x38, 0x4, 0x10, 0x4b0}, - {".strtab", SHT_STRTAB, 0x0, 0x0, 0x1468, 0x206, 0x0, 0x0, 0x1, 0x0, 0x206}, - }, - []ProgHeader{ - {PT_PHDR, PF_R + PF_X, 0x34, 0x8048034, 0x8048034, 0xa0, 0xa0, 0x4}, - {PT_INTERP, PF_R, 0xd4, 0x80480d4, 0x80480d4, 0x15, 0x15, 0x1}, - {PT_LOAD, PF_R + PF_X, 0x0, 0x8048000, 0x8048000, 0x5fb, 0x5fb, 0x1000}, - {PT_LOAD, PF_R + PF_W, 0x5fc, 0x80495fc, 0x80495fc, 0xd8, 0xf8, 0x1000}, - {PT_DYNAMIC, PF_R + PF_W, 0x60c, 0x804960c, 0x804960c, 0x98, 0x98, 0x4}, - }, - []string{"libc.so.6"}, - }, - { - "testdata/gcc-amd64-linux-exec", - FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0, binary.LittleEndian, ET_EXEC, EM_X86_64, 0x4003e0}, - []SectionHeader{ - {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, - {".interp", SHT_PROGBITS, SHF_ALLOC, 0x400200, 0x200, 0x1c, 0x0, 0x0, 0x1, 0x0, 0x1c}, - {".note.ABI-tag", SHT_NOTE, SHF_ALLOC, 0x40021c, 0x21c, 0x20, 0x0, 0x0, 0x4, 0x0, 0x20}, - {".hash", SHT_HASH, SHF_ALLOC, 0x400240, 0x240, 0x24, 0x5, 0x0, 0x8, 0x4, 0x24}, - {".gnu.hash", SHT_LOOS + 268435446, SHF_ALLOC, 0x400268, 0x268, 0x1c, 0x5, 0x0, 0x8, 0x0, 0x1c}, - {".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x400288, 0x288, 0x60, 0x6, 0x1, 0x8, 0x18, 0x60}, - {".dynstr", SHT_STRTAB, SHF_ALLOC, 0x4002e8, 0x2e8, 0x3d, 0x0, 0x0, 0x1, 0x0, 0x3d}, - {".gnu.version", SHT_HIOS, SHF_ALLOC, 0x400326, 0x326, 0x8, 0x5, 0x0, 0x2, 0x2, 0x8}, - {".gnu.version_r", SHT_LOOS + 268435454, SHF_ALLOC, 0x400330, 0x330, 0x20, 0x6, 0x1, 0x8, 0x0, 0x20}, - {".rela.dyn", SHT_RELA, SHF_ALLOC, 0x400350, 0x350, 0x18, 0x5, 0x0, 0x8, 0x18, 0x18}, - {".rela.plt", SHT_RELA, SHF_ALLOC, 0x400368, 0x368, 0x30, 0x5, 0xc, 0x8, 0x18, 0x30}, - {".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400398, 0x398, 0x18, 0x0, 0x0, 0x4, 0x0, 0x18}, - {".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003b0, 0x3b0, 0x30, 0x0, 0x0, 0x4, 0x10, 0x30}, - {".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003e0, 0x3e0, 0x1b4, 0x0, 0x0, 0x10, 0x0, 0x1b4}, - {".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400594, 0x594, 0xe, 0x0, 0x0, 0x4, 0x0, 0xe}, - {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x4005a4, 0x5a4, 0x11, 0x0, 0x0, 0x4, 0x0, 0x11}, - {".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, 0x4005b8, 0x5b8, 0x24, 0x0, 0x0, 0x4, 0x0, 0x24}, - {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x4005e0, 0x5e0, 0xa4, 0x0, 0x0, 0x8, 0x0, 0xa4}, - {".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600688, 0x688, 0x10, 0x0, 0x0, 0x8, 0x0, 0x10}, - {".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600698, 0x698, 0x10, 0x0, 0x0, 0x8, 0x0, 0x10}, - {".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x6006a8, 0x6a8, 0x8, 0x0, 0x0, 0x8, 0x0, 0x8}, - {".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x6006b0, 0x6b0, 0x1a0, 0x6, 0x0, 0x8, 0x10, 0x1a0}, - {".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600850, 0x850, 0x8, 0x0, 0x0, 0x8, 0x8, 0x8}, - {".got.plt", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600858, 0x858, 0x28, 0x0, 0x0, 0x8, 0x8, 0x28}, - {".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600880, 0x880, 0x18, 0x0, 0x0, 0x8, 0x0, 0x18}, - {".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x600898, 0x898, 0x8, 0x0, 0x0, 0x4, 0x0, 0x8}, - {".comment", SHT_PROGBITS, 0x0, 0x0, 0x898, 0x126, 0x0, 0x0, 0x1, 0x0, 0x126}, - {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x9c0, 0x90, 0x0, 0x0, 0x10, 0x0, 0x90}, - {".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0xa50, 0x25, 0x0, 0x0, 0x1, 0x0, 0x25}, - {".debug_info", SHT_PROGBITS, 0x0, 0x0, 0xa75, 0x1a7, 0x0, 0x0, 0x1, 0x0, 0x1a7}, - {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xc1c, 0x6f, 0x0, 0x0, 0x1, 0x0, 0x6f}, - {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0xc8b, 0x13f, 0x0, 0x0, 0x1, 0x0, 0x13f}, - {".debug_str", SHT_PROGBITS, SHF_MERGE + SHF_STRINGS, 0x0, 0xdca, 0xb1, 0x0, 0x0, 0x1, 0x1, 0xb1}, - {".debug_ranges", SHT_PROGBITS, 0x0, 0x0, 0xe80, 0x90, 0x0, 0x0, 0x10, 0x0, 0x90}, - {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xf10, 0x149, 0x0, 0x0, 0x1, 0x0, 0x149}, - {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x19a0, 0x6f0, 0x24, 0x39, 0x8, 0x18, 0x6f0}, - {".strtab", SHT_STRTAB, 0x0, 0x0, 0x2090, 0x1fc, 0x0, 0x0, 0x1, 0x0, 0x1fc}, - }, - []ProgHeader{ - {PT_PHDR, PF_R + PF_X, 0x40, 0x400040, 0x400040, 0x1c0, 0x1c0, 0x8}, - {PT_INTERP, PF_R, 0x200, 0x400200, 0x400200, 0x1c, 0x1c, 1}, - {PT_LOAD, PF_R + PF_X, 0x0, 0x400000, 0x400000, 0x684, 0x684, 0x200000}, - {PT_LOAD, PF_R + PF_W, 0x688, 0x600688, 0x600688, 0x210, 0x218, 0x200000}, - {PT_DYNAMIC, PF_R + PF_W, 0x6b0, 0x6006b0, 0x6006b0, 0x1a0, 0x1a0, 0x8}, - {PT_NOTE, PF_R, 0x21c, 0x40021c, 0x40021c, 0x20, 0x20, 0x4}, - {PT_LOOS + 0x474E550, PF_R, 0x5b8, 0x4005b8, 0x4005b8, 0x24, 0x24, 0x4}, - {PT_LOOS + 0x474E551, PF_R + PF_W, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8}, - }, - []string{"libc.so.6"}, - }, - { - "testdata/hello-world-core.gz", - FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_CORE, EM_X86_64, 0x0}, - []SectionHeader{}, - []ProgHeader{ - {Type: PT_NOTE, Flags: 0x0, Off: 0x3f8, Vaddr: 0x0, Paddr: 0x0, Filesz: 0x8ac, Memsz: 0x0, Align: 0x0}, - {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x1000, Vaddr: 0x400000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1000, Align: 0x1000}, - {Type: PT_LOAD, Flags: PF_R, Off: 0x1000, Vaddr: 0x401000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000}, - {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x2000, Vaddr: 0x402000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000}, - {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3000, Vaddr: 0x7f54078b8000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1b5000, Align: 0x1000}, - {Type: PT_LOAD, Flags: 0x0, Off: 0x3000, Vaddr: 0x7f5407a6d000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1ff000, Align: 0x1000}, - {Type: PT_LOAD, Flags: PF_R, Off: 0x3000, Vaddr: 0x7f5407c6c000, Paddr: 0x0, Filesz: 0x4000, Memsz: 0x4000, Align: 0x1000}, - {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x7000, Vaddr: 0x7f5407c70000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000}, - {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x9000, Vaddr: 0x7f5407c72000, Paddr: 0x0, Filesz: 0x5000, Memsz: 0x5000, Align: 0x1000}, - {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0xe000, Vaddr: 0x7f5407c77000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x22000, Align: 0x1000}, - {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0xe000, Vaddr: 0x7f5407e81000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000}, - {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x11000, Vaddr: 0x7f5407e96000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000}, - {Type: PT_LOAD, Flags: PF_R, Off: 0x14000, Vaddr: 0x7f5407e99000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000}, - {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x15000, Vaddr: 0x7f5407e9a000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000}, - {Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x17000, Vaddr: 0x7fff79972000, Paddr: 0x0, Filesz: 0x23000, Memsz: 0x23000, Align: 0x1000}, - {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3a000, Vaddr: 0x7fff799f8000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000}, - {Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3b000, Vaddr: 0xffffffffff600000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000}, - }, - nil, - }, - { - "testdata/compressed-32.obj", - FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_REL, EM_386, 0x0}, - []SectionHeader{ - {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, - {".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0x0, 0x34, 0x17, 0x0, 0x0, 0x1, 0x0, 0x17}, - {".rel.text", SHT_REL, SHF_INFO_LINK, 0x0, 0x3dc, 0x10, 0x13, 0x1, 0x4, 0x8, 0x10}, - {".data", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, - {".bss", SHT_NOBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x4b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, - {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x4b, 0xd, 0x0, 0x0, 0x1, 0x0, 0xd}, - {".debug_info", SHT_PROGBITS, SHF_COMPRESSED, 0x0, 0x58, 0xb4, 0x0, 0x0, 0x1, 0x0, 0x84}, - {".rel.debug_info", SHT_REL, SHF_INFO_LINK, 0x0, 0x3ec, 0xa0, 0x13, 0x6, 0x4, 0x8, 0xa0}, - {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xdc, 0x5a, 0x0, 0x0, 0x1, 0x0, 0x5a}, - {".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x136, 0x20, 0x0, 0x0, 0x1, 0x0, 0x20}, - {".rel.debug_aranges", SHT_REL, SHF_INFO_LINK, 0x0, 0x48c, 0x10, 0x13, 0x9, 0x4, 0x8, 0x10}, - {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x156, 0x5c, 0x0, 0x0, 0x1, 0x0, 0x5c}, - {".rel.debug_line", SHT_REL, SHF_INFO_LINK, 0x0, 0x49c, 0x8, 0x13, 0xb, 0x4, 0x8, 0x8}, - {".debug_str", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS | SHF_COMPRESSED, 0x0, 0x1b2, 0x10f, 0x0, 0x0, 0x1, 0x1, 0xb3}, - {".comment", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS, 0x0, 0x265, 0x2a, 0x0, 0x0, 0x1, 0x1, 0x2a}, - {".note.GNU-stack", SHT_PROGBITS, 0x0, 0x0, 0x28f, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, - {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x290, 0x38, 0x0, 0x0, 0x4, 0x0, 0x38}, - {".rel.eh_frame", SHT_REL, SHF_INFO_LINK, 0x0, 0x4a4, 0x8, 0x13, 0x10, 0x4, 0x8, 0x8}, - {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0x4ac, 0xab, 0x0, 0x0, 0x1, 0x0, 0xab}, - {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x2c8, 0x100, 0x14, 0xe, 0x4, 0x10, 0x100}, - {".strtab", SHT_STRTAB, 0x0, 0x0, 0x3c8, 0x13, 0x0, 0x0, 0x1, 0x0, 0x13}, - }, - []ProgHeader{}, - nil, - }, - { - "testdata/compressed-64.obj", - FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_REL, EM_X86_64, 0x0}, - []SectionHeader{ - {"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, - {".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0x0, 0x40, 0x1b, 0x0, 0x0, 0x1, 0x0, 0x1b}, - {".rela.text", SHT_RELA, SHF_INFO_LINK, 0x0, 0x488, 0x30, 0x13, 0x1, 0x8, 0x18, 0x30}, - {".data", SHT_PROGBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, - {".bss", SHT_NOBITS, SHF_WRITE | SHF_ALLOC, 0x0, 0x5b, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, - {".rodata", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x5b, 0xd, 0x0, 0x0, 0x1, 0x0, 0xd}, - {".debug_info", SHT_PROGBITS, SHF_COMPRESSED, 0x0, 0x68, 0xba, 0x0, 0x0, 0x1, 0x0, 0x72}, - {".rela.debug_info", SHT_RELA, SHF_INFO_LINK, 0x0, 0x4b8, 0x1c8, 0x13, 0x6, 0x8, 0x18, 0x1c8}, - {".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xda, 0x5c, 0x0, 0x0, 0x1, 0x0, 0x5c}, - {".debug_aranges", SHT_PROGBITS, SHF_COMPRESSED, 0x0, 0x136, 0x30, 0x0, 0x0, 0x1, 0x0, 0x2f}, - {".rela.debug_aranges", SHT_RELA, SHF_INFO_LINK, 0x0, 0x680, 0x30, 0x13, 0x9, 0x8, 0x18, 0x30}, - {".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x165, 0x60, 0x0, 0x0, 0x1, 0x0, 0x60}, - {".rela.debug_line", SHT_RELA, SHF_INFO_LINK, 0x0, 0x6b0, 0x18, 0x13, 0xb, 0x8, 0x18, 0x18}, - {".debug_str", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS | SHF_COMPRESSED, 0x0, 0x1c5, 0x104, 0x0, 0x0, 0x1, 0x1, 0xc3}, - {".comment", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS, 0x0, 0x288, 0x2a, 0x0, 0x0, 0x1, 0x1, 0x2a}, - {".note.GNU-stack", SHT_PROGBITS, 0x0, 0x0, 0x2b2, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0}, - {".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x0, 0x2b8, 0x38, 0x0, 0x0, 0x8, 0x0, 0x38}, - {".rela.eh_frame", SHT_RELA, SHF_INFO_LINK, 0x0, 0x6c8, 0x18, 0x13, 0x10, 0x8, 0x18, 0x18}, - {".shstrtab", SHT_STRTAB, 0x0, 0x0, 0x6e0, 0xb0, 0x0, 0x0, 0x1, 0x0, 0xb0}, - {".symtab", SHT_SYMTAB, 0x0, 0x0, 0x2f0, 0x180, 0x14, 0xe, 0x8, 0x18, 0x180}, - {".strtab", SHT_STRTAB, 0x0, 0x0, 0x470, 0x13, 0x0, 0x0, 0x1, 0x0, 0x13}, - }, - []ProgHeader{}, - nil, - }, -} - -func TestOpen(t *testing.T) { - for i := range fileTests { - tt := &fileTests[i] - - var f *File - var err error - if path.Ext(tt.file) == ".gz" { - var r io.ReaderAt - if r, err = decompress(tt.file); err == nil { - f, err = NewFile(r) - } - } else { - f, err = Open(tt.file) - } - if err != nil { - t.Errorf("cannot open file %s: %v", tt.file, err) - continue - } - defer f.Close() - if !reflect.DeepEqual(f.FileHeader, tt.hdr) { - t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr) - continue - } - for i, s := range f.Sections { - if i >= len(tt.sections) { - break - } - sh := &tt.sections[i] - if !reflect.DeepEqual(&s.SectionHeader, sh) { - t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &s.SectionHeader, sh) - } - } - for i, p := range f.Progs { - if i >= len(tt.progs) { - break - } - ph := &tt.progs[i] - if !reflect.DeepEqual(&p.ProgHeader, ph) { - t.Errorf("open %s, program %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &p.ProgHeader, ph) - } - } - tn := len(tt.sections) - fn := len(f.Sections) - if tn != fn { - t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn) - } - tn = len(tt.progs) - fn = len(f.Progs) - if tn != fn { - t.Errorf("open %s: len(Progs) = %d, want %d", tt.file, fn, tn) - } - tl := tt.needed - fl, err := f.ImportedLibraries() - if err != nil { - t.Error(err) - } - if !reflect.DeepEqual(tl, fl) { - t.Errorf("open %s: DT_NEEDED = %v, want %v", tt.file, tl, fl) - } - } -} - -// elf.NewFile requires io.ReaderAt, which compress/gzip cannot -// provide. Decompress the file to a bytes.Reader. -func decompress(gz string) (io.ReaderAt, error) { - in, err := os.Open(gz) - if err != nil { - return nil, err - } - defer in.Close() - r, err := gzip.NewReader(in) - if err != nil { - return nil, err - } - var out bytes.Buffer - _, err = io.Copy(&out, r) - return bytes.NewReader(out.Bytes()), err -} - -type relocationTestEntry struct { - entryNumber int - entry *dwarf.Entry -} - -type relocationTest struct { - file string - entries []relocationTestEntry -} - -var relocationTests = []relocationTest{ - { - "testdata/go-relocation-test-gcc441-x86-64.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "go-relocation-test.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - }, - }}, - }, - }, - { - "testdata/go-relocation-test-gcc441-x86.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "t.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: uint64(0x5), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - }, - }}, - }, - }, - { - "testdata/go-relocation-test-gcc424-x86-64.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: uint64(0x6), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - }, - }}, - }, - }, - { - "testdata/go-relocation-test-gcc482-aarch64.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(0x24), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - }, - }}, - }, - }, - { - "testdata/go-relocation-test-gcc492-arm.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 20141224 (prerelease) -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -mtls-dialect=gnu -g", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc492.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/root/go/src/debug/elf/testdata", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(0x28), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - }, - }}, - }, - }, - { - "testdata/go-relocation-test-clang-arm.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrStmtList, Val: int64(0x0), Class: dwarf.ClassLinePtr}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(48), Class: dwarf.ClassConstant}, - }, - }}, - }, - }, - { - "testdata/go-relocation-test-gcc5-ppc.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C11 5.0.0 20150116 (experimental) -Asystem=linux -Asystem=unix -Asystem=posix -g", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc5-ppc.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(0x44), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - }, - }}, - }, - }, - { - "testdata/go-relocation-test-gcc482-ppc64le.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -Asystem=linux -Asystem=unix -Asystem=posix -msecure-plt -mtune=power8 -mcpu=power7 -gdwarf-2 -fstack-protector", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482-ppc64le.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: uint64(0x24), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - }, - }}, - }, - }, - { - "testdata/go-relocation-test-gcc492-mips64.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -meb -mabi=64 -march=mips3 -mtune=mips64 -mllsc -mno-shared -g", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(100), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - }, - }}, - }, - }, - { - "testdata/go-relocation-test-gcc531-s390x.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C11 5.3.1 20160316 -march=zEC12 -m64 -mzarch -g -fstack-protector-strong", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(58), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - }, - }}, - }, - }, - { - "testdata/go-relocation-test-gcc620-sparc64.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C11 6.2.0 20160914 -mcpu=v9 -g -fstack-protector-strong", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(0x2c), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - }, - }}, - }, - }, - { - "testdata/go-relocation-test-gcc492-mipsle.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.2 -mel -march=mips2 -mtune=mips32 -mllsc -mno-shared -mabi=32 -g", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(0x58), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - }, - }}, - }, - }, - { - "testdata/go-relocation-test-gcc540-mips.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C11 5.4.0 20160609 -meb -mips32 -mtune=mips32r2 -mfpxx -mllsc -mno-shared -mabi=32 -g -gdwarf-2", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: uint64(0x5c), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - }, - }}, - }, - }, - { - "testdata/go-relocation-test-gcc493-mips64le.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C 4.9.3 -mel -mabi=64 -mllsc -mno-shared -g -fstack-protector-strong", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(1), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: int64(100), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - }, - }}, - }, - }, - { - "testdata/go-relocation-test-gcc720-riscv64.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "GNU C11 7.2.0 -march=rv64imafdc -mabi=lp64d -g -gdwarf-2", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "hello.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLowpc, Val: uint64(0x0), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrHighpc, Val: uint64(0x2c), Class: dwarf.ClassAddress}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - }, - }}, - }, - }, - { - "testdata/go-relocation-test-clang-x86.obj", - []relocationTestEntry{ - {0, &dwarf.Entry{ - Offset: 0xb, - Tag: dwarf.TagCompileUnit, - Children: true, - Field: []dwarf.Field{ - {Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)", Class: dwarf.ClassString}, - {Attr: dwarf.AttrLanguage, Val: int64(12), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c", Class: dwarf.ClassString}, - {Attr: dwarf.AttrStmtList, Val: int64(0), Class: dwarf.ClassLinePtr}, - {Attr: dwarf.AttrCompDir, Val: "/tmp", Class: dwarf.ClassString}, - }, - }}, - }, - }, - { - "testdata/gcc-amd64-openbsd-debug-with-rela.obj", - []relocationTestEntry{ - {203, &dwarf.Entry{ - Offset: 0xc62, - Tag: dwarf.TagMember, - Children: false, - Field: []dwarf.Field{ - {Attr: dwarf.AttrName, Val: "it_interval", Class: dwarf.ClassString}, - {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrDeclLine, Val: int64(236), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference}, - {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}, Class: dwarf.ClassExprLoc}, - }, - }}, - {204, &dwarf.Entry{ - Offset: 0xc70, - Tag: dwarf.TagMember, - Children: false, - Field: []dwarf.Field{ - {Attr: dwarf.AttrName, Val: "it_value", Class: dwarf.ClassString}, - {Attr: dwarf.AttrDeclFile, Val: int64(7), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrDeclLine, Val: int64(237), Class: dwarf.ClassConstant}, - {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f), Class: dwarf.ClassReference}, - {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}, Class: dwarf.ClassExprLoc}, - }, - }}, - }, - }, -} - -func TestDWARFRelocations(t *testing.T) { - for i, test := range relocationTests { - f, err := Open(test.file) - if err != nil { - t.Error(err) - continue - } - dwarf, err := f.DWARF() - if err != nil { - t.Error(err) - continue - } - for _, testEntry := range test.entries { - reader := dwarf.Reader() - for j := 0; j < testEntry.entryNumber; j++ { - entry, err := reader.Next() - if entry == nil || err != nil { - t.Errorf("Failed to skip to entry %d: %v", testEntry.entryNumber, err) - continue - } - } - entry, err := reader.Next() - if err != nil { - t.Error(err) - continue - } - if !reflect.DeepEqual(testEntry.entry, entry) { - t.Errorf("#%d/%d: mismatch: got:%#v want:%#v", i, testEntry.entryNumber, entry, testEntry.entry) - continue - } - } - } -} - -func TestCompressedDWARF(t *testing.T) { - // Test file built with GCC 4.8.4 and as 2.24 using: - // gcc -Wa,--compress-debug-sections -g -c -o zdebug-test-gcc484-x86-64.obj hello.c - f, err := Open("testdata/zdebug-test-gcc484-x86-64.obj") - if err != nil { - t.Fatal(err) - } - dwarf, err := f.DWARF() - if err != nil { - t.Fatal(err) - } - reader := dwarf.Reader() - n := 0 - for { - entry, err := reader.Next() - if err != nil { - t.Fatal(err) - } - if entry == nil { - break - } - n++ - } - if n != 18 { - t.Fatalf("want %d DWARF entries, got %d", 18, n) - } -} - -func TestCompressedSection(t *testing.T) { - // Test files built with gcc -g -S hello.c and assembled with - // --compress-debug-sections=zlib-gabi. - f, err := Open("testdata/compressed-64.obj") - if err != nil { - t.Fatal(err) - } - sec := f.Section(".debug_info") - wantData := []byte{ - 182, 0, 0, 0, 4, 0, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7, - 0, 0, 0, 0, 2, 1, 8, 0, 0, 0, 0, 2, 2, 7, 0, 0, - 0, 0, 2, 4, 7, 0, 0, 0, 0, 2, 1, 6, 0, 0, 0, 0, - 2, 2, 5, 0, 0, 0, 0, 3, 4, 5, 105, 110, 116, 0, 2, 8, - 5, 0, 0, 0, 0, 2, 8, 7, 0, 0, 0, 0, 4, 8, 114, 0, - 0, 0, 2, 1, 6, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 4, - 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, - 1, 156, 179, 0, 0, 0, 6, 0, 0, 0, 0, 1, 4, 87, 0, 0, - 0, 2, 145, 108, 6, 0, 0, 0, 0, 1, 4, 179, 0, 0, 0, 2, - 145, 96, 0, 4, 8, 108, 0, 0, 0, 0, - } - - // Test Data method. - b, err := sec.Data() - if err != nil { - t.Fatal(err) - } - if !bytes.Equal(wantData, b) { - t.Fatalf("want data %x, got %x", wantData, b) - } - - // Test Open method and seeking. - buf, have, count := make([]byte, len(b)), make([]bool, len(b)), 0 - sf := sec.Open() - if got, err := sf.Seek(0, io.SeekEnd); got != int64(len(b)) || err != nil { - t.Fatalf("want seek end %d, got %d error %v", len(b), got, err) - } - if n, err := sf.Read(buf); n != 0 || err != io.EOF { - t.Fatalf("want EOF with 0 bytes, got %v with %d bytes", err, n) - } - pos := int64(len(buf)) - for count < len(buf) { - // Construct random seek arguments. - whence := rand.Intn(3) - target := rand.Int63n(int64(len(buf))) - var offset int64 - switch whence { - case io.SeekStart: - offset = target - case io.SeekCurrent: - offset = target - pos - case io.SeekEnd: - offset = target - int64(len(buf)) - } - pos, err = sf.Seek(offset, whence) - if err != nil { - t.Fatal(err) - } - if pos != target { - t.Fatalf("want position %d, got %d", target, pos) - } - - // Read data from the new position. - end := pos + 16 - if end > int64(len(buf)) { - end = int64(len(buf)) - } - n, err := io.ReadFull(sf, buf[pos:end]) - if err != nil { - t.Fatal(err) - } - for i := 0; i < n; i++ { - if !have[pos] { - have[pos] = true - count++ - } - pos++ - } - } - if !bytes.Equal(wantData, buf) { - t.Fatalf("want data %x, got %x", wantData, buf) - } -} - -func TestNoSectionOverlaps(t *testing.T) { - // Ensure cmd/link outputs sections without overlaps. - switch runtime.GOOS { - case "aix", "android", "darwin", "js", "nacl", "plan9", "windows": - t.Skipf("cmd/link doesn't produce ELF binaries on %s", runtime.GOOS) - } - _ = net.ResolveIPAddr // force dynamic linkage - f, err := Open(os.Args[0]) - if err != nil { - t.Error(err) - return - } - for i, si := range f.Sections { - sih := si.SectionHeader - if sih.Type == SHT_NOBITS { - continue - } - for j, sj := range f.Sections { - sjh := sj.SectionHeader - if i == j || sjh.Type == SHT_NOBITS || sih.Offset == sjh.Offset && sih.Size == 0 { - continue - } - if sih.Offset >= sjh.Offset && sih.Offset < sjh.Offset+sjh.Size { - t.Errorf("ld produced ELF with section %s within %s: 0x%x <= 0x%x..0x%x < 0x%x", - sih.Name, sjh.Name, sjh.Offset, sih.Offset, sih.Offset+sih.Size, sjh.Offset+sjh.Size) - } - } - } -} diff --git a/odiglet/pkg/allocator/debug/elf/reader.go b/odiglet/pkg/allocator/debug/elf/reader.go deleted file mode 100644 index a45843619e..0000000000 --- a/odiglet/pkg/allocator/debug/elf/reader.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package elf - -import ( - "io" - "os" -) - -// errorReader returns error from all operations. -type errorReader struct { - error -} - -func (r errorReader) Read(p []byte) (n int, err error) { - return 0, r.error -} - -func (r errorReader) ReadAt(p []byte, off int64) (n int, err error) { - return 0, r.error -} - -func (r errorReader) Seek(offset int64, whence int) (int64, error) { - return 0, r.error -} - -func (r errorReader) Close() error { - return r.error -} - -// readSeekerFromReader converts an io.Reader into an io.ReadSeeker. -// In general Seek may not be efficient, but it is optimized for -// common cases such as seeking to the end to find the length of the -// data. -type readSeekerFromReader struct { - reset func() (io.Reader, error) - r io.Reader - size int64 - offset int64 -} - -func (r *readSeekerFromReader) start() { - x, err := r.reset() - if err != nil { - r.r = errorReader{err} - } else { - r.r = x - } - r.offset = 0 -} - -func (r *readSeekerFromReader) Read(p []byte) (n int, err error) { - if r.r == nil { - r.start() - } - n, err = r.r.Read(p) - r.offset += int64(n) - return n, err -} - -func (r *readSeekerFromReader) Seek(offset int64, whence int) (int64, error) { - var newOffset int64 - switch whence { - case seekStart: - newOffset = offset - case seekCurrent: - newOffset = r.offset + offset - case seekEnd: - newOffset = r.size + offset - default: - return 0, os.ErrInvalid - } - - switch { - case newOffset == r.offset: - return newOffset, nil - - case newOffset < 0, newOffset > r.size: - return 0, os.ErrInvalid - - case newOffset == 0: - r.r = nil - - case newOffset == r.size: - r.r = errorReader{io.EOF} - - default: - if newOffset < r.offset { - // Restart at the beginning. - r.start() - } - // Read until we reach offset. - var buf [512]byte - for r.offset < newOffset { - b := buf[:] - if newOffset-r.offset < int64(len(buf)) { - b = buf[:newOffset-r.offset] - } - if _, err := r.Read(b); err != nil { - return 0, err - } - } - } - r.offset = newOffset - return r.offset, nil -} diff --git a/odiglet/pkg/allocator/debug/elf/relocations.go b/odiglet/pkg/allocator/debug/elf/relocations.go deleted file mode 100644 index 33ae41e835..0000000000 --- a/odiglet/pkg/allocator/debug/elf/relocations.go +++ /dev/null @@ -1,529 +0,0 @@ -package elf - -import ( - "bytes" - "encoding/binary" - "errors" -) - -// applyRelocations applies relocations to dst. rels is a relocations section -// in REL or RELA format. -func (f *File) applyRelocations(dst []byte, rels []byte) error { - switch { - case f.Class == ELFCLASS64 && f.Machine == EM_X86_64: - return f.applyRelocationsAMD64(dst, rels) - case f.Class == ELFCLASS32 && f.Machine == EM_386: - return f.applyRelocations386(dst, rels) - case f.Class == ELFCLASS32 && f.Machine == EM_ARM: - return f.applyRelocationsARM(dst, rels) - case f.Class == ELFCLASS64 && f.Machine == EM_AARCH64: - return f.applyRelocationsARM64(dst, rels) - case f.Class == ELFCLASS32 && f.Machine == EM_PPC: - return f.applyRelocationsPPC(dst, rels) - case f.Class == ELFCLASS64 && f.Machine == EM_PPC64: - return f.applyRelocationsPPC64(dst, rels) - case f.Class == ELFCLASS32 && f.Machine == EM_MIPS: - return f.applyRelocationsMIPS(dst, rels) - case f.Class == ELFCLASS64 && f.Machine == EM_MIPS: - return f.applyRelocationsMIPS64(dst, rels) - case f.Class == ELFCLASS64 && f.Machine == EM_RISCV: - return f.applyRelocationsRISCV64(dst, rels) - case f.Class == ELFCLASS64 && f.Machine == EM_S390: - return f.applyRelocationss390x(dst, rels) - case f.Class == ELFCLASS64 && f.Machine == EM_SPARCV9: - return f.applyRelocationsSPARC64(dst, rels) - default: - return errors.New("applyRelocations: not implemented") - } -} - -func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error { - // 24 is the size of Rela64. - if len(rels)%24 != 0 { - return errors.New("length of relocation section is not a multiple of 24") - } - - symbols, _, err := f.getSymbols(SHT_SYMTAB) - if err != nil { - return err - } - - b := bytes.NewReader(rels) - var rela Rela64 - - for b.Len() > 0 { - binary.Read(b, f.ByteOrder, &rela) - symNo := rela.Info >> 32 - t := R_X86_64(rela.Info & 0xffff) - - if symNo == 0 || symNo > uint64(len(symbols)) { - continue - } - sym := &symbols[symNo-1] - if SymType(sym.Info&0xf) != STT_SECTION { - // We don't handle non-section relocations for now. - continue - } - - // There are relocations, so this must be a normal - // object file, and we only look at section symbols, - // so we assume that the symbol value is 0. - - switch t { - case R_X86_64_64: - if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { - continue - } - f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) - case R_X86_64_32: - if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { - continue - } - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) - } - } - - return nil -} - -func (f *File) applyRelocations386(dst []byte, rels []byte) error { - // 8 is the size of Rel32. - if len(rels)%8 != 0 { - return errors.New("length of relocation section is not a multiple of 8") - } - - symbols, _, err := f.getSymbols(SHT_SYMTAB) - if err != nil { - return err - } - - b := bytes.NewReader(rels) - var rel Rel32 - - for b.Len() > 0 { - binary.Read(b, f.ByteOrder, &rel) - symNo := rel.Info >> 8 - t := R_386(rel.Info & 0xff) - - if symNo == 0 || symNo > uint32(len(symbols)) { - continue - } - sym := &symbols[symNo-1] - - if t == R_386_32 { - if rel.Off+4 >= uint32(len(dst)) { - continue - } - val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4]) - val += uint32(sym.Value) - f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val) - } - } - - return nil -} - -func (f *File) applyRelocationsARM(dst []byte, rels []byte) error { - // 8 is the size of Rel32. - if len(rels)%8 != 0 { - return errors.New("length of relocation section is not a multiple of 8") - } - - symbols, _, err := f.getSymbols(SHT_SYMTAB) - if err != nil { - return err - } - - b := bytes.NewReader(rels) - var rel Rel32 - - for b.Len() > 0 { - binary.Read(b, f.ByteOrder, &rel) - symNo := rel.Info >> 8 - t := R_ARM(rel.Info & 0xff) - - if symNo == 0 || symNo > uint32(len(symbols)) { - continue - } - sym := &symbols[symNo-1] - - switch t { - case R_ARM_ABS32: - if rel.Off+4 >= uint32(len(dst)) { - continue - } - val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4]) - val += uint32(sym.Value) - f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val) - } - } - - return nil -} - -func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error { - // 24 is the size of Rela64. - if len(rels)%24 != 0 { - return errors.New("length of relocation section is not a multiple of 24") - } - - symbols, _, err := f.getSymbols(SHT_SYMTAB) - if err != nil { - return err - } - - b := bytes.NewReader(rels) - var rela Rela64 - - for b.Len() > 0 { - binary.Read(b, f.ByteOrder, &rela) - symNo := rela.Info >> 32 - t := R_AARCH64(rela.Info & 0xffff) - - if symNo == 0 || symNo > uint64(len(symbols)) { - continue - } - sym := &symbols[symNo-1] - if SymType(sym.Info&0xf) != STT_SECTION { - // We don't handle non-section relocations for now. - continue - } - - // There are relocations, so this must be a normal - // object file, and we only look at section symbols, - // so we assume that the symbol value is 0. - - switch t { - case R_AARCH64_ABS64: - if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { - continue - } - f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) - case R_AARCH64_ABS32: - if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { - continue - } - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) - } - } - - return nil -} - -func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error { - // 12 is the size of Rela32. - if len(rels)%12 != 0 { - return errors.New("length of relocation section is not a multiple of 12") - } - - symbols, _, err := f.getSymbols(SHT_SYMTAB) - if err != nil { - return err - } - - b := bytes.NewReader(rels) - var rela Rela32 - - for b.Len() > 0 { - binary.Read(b, f.ByteOrder, &rela) - symNo := rela.Info >> 8 - t := R_PPC(rela.Info & 0xff) - - if symNo == 0 || symNo > uint32(len(symbols)) { - continue - } - sym := &symbols[symNo-1] - if SymType(sym.Info&0xf) != STT_SECTION { - // We don't handle non-section relocations for now. - continue - } - - switch t { - case R_PPC_ADDR32: - if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 { - continue - } - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) - } - } - - return nil -} - -func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error { - // 24 is the size of Rela64. - if len(rels)%24 != 0 { - return errors.New("length of relocation section is not a multiple of 24") - } - - symbols, _, err := f.getSymbols(SHT_SYMTAB) - if err != nil { - return err - } - - b := bytes.NewReader(rels) - var rela Rela64 - - for b.Len() > 0 { - binary.Read(b, f.ByteOrder, &rela) - symNo := rela.Info >> 32 - t := R_PPC64(rela.Info & 0xffff) - - if symNo == 0 || symNo > uint64(len(symbols)) { - continue - } - sym := &symbols[symNo-1] - if SymType(sym.Info&0xf) != STT_SECTION { - // We don't handle non-section relocations for now. - continue - } - - switch t { - case R_PPC64_ADDR64: - if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { - continue - } - f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) - case R_PPC64_ADDR32: - if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { - continue - } - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) - } - } - - return nil -} - -func (f *File) applyRelocationsMIPS(dst []byte, rels []byte) error { - // 8 is the size of Rel32. - if len(rels)%8 != 0 { - return errors.New("length of relocation section is not a multiple of 8") - } - - symbols, _, err := f.getSymbols(SHT_SYMTAB) - if err != nil { - return err - } - - b := bytes.NewReader(rels) - var rel Rel32 - - for b.Len() > 0 { - binary.Read(b, f.ByteOrder, &rel) - symNo := rel.Info >> 8 - t := R_MIPS(rel.Info & 0xff) - - if symNo == 0 || symNo > uint32(len(symbols)) { - continue - } - sym := &symbols[symNo-1] - - switch t { - case R_MIPS_32: - if rel.Off+4 >= uint32(len(dst)) { - continue - } - val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4]) - val += uint32(sym.Value) - f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val) - } - } - - return nil -} - -func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error { - // 24 is the size of Rela64. - if len(rels)%24 != 0 { - return errors.New("length of relocation section is not a multiple of 24") - } - - symbols, _, err := f.getSymbols(SHT_SYMTAB) - if err != nil { - return err - } - - b := bytes.NewReader(rels) - var rela Rela64 - - for b.Len() > 0 { - binary.Read(b, f.ByteOrder, &rela) - var symNo uint64 - var t R_MIPS - if f.ByteOrder == binary.BigEndian { - symNo = rela.Info >> 32 - t = R_MIPS(rela.Info & 0xff) - } else { - symNo = rela.Info & 0xffffffff - t = R_MIPS(rela.Info >> 56) - } - - if symNo == 0 || symNo > uint64(len(symbols)) { - continue - } - sym := &symbols[symNo-1] - if SymType(sym.Info&0xf) != STT_SECTION { - // We don't handle non-section relocations for now. - continue - } - - switch t { - case R_MIPS_64: - if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { - continue - } - f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) - case R_MIPS_32: - if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { - continue - } - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) - } - } - - return nil -} - -func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error { - // 24 is the size of Rela64. - if len(rels)%24 != 0 { - return errors.New("length of relocation section is not a multiple of 24") - } - - symbols, _, err := f.getSymbols(SHT_SYMTAB) - if err != nil { - return err - } - - b := bytes.NewReader(rels) - var rela Rela64 - - for b.Len() > 0 { - binary.Read(b, f.ByteOrder, &rela) - symNo := rela.Info >> 32 - t := R_RISCV(rela.Info & 0xffff) - - if symNo == 0 || symNo > uint64(len(symbols)) { - continue - } - sym := &symbols[symNo-1] - switch SymType(sym.Info & 0xf) { - case STT_SECTION, STT_NOTYPE: - break - default: - continue - } - - switch t { - case R_RISCV_64: - if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { - continue - } - val := sym.Value + uint64(rela.Addend) - f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val) - case R_RISCV_32: - if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { - continue - } - val := uint32(sym.Value) + uint32(rela.Addend) - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val) - } - } - - return nil -} - -func (f *File) applyRelocationss390x(dst []byte, rels []byte) error { - // 24 is the size of Rela64. - if len(rels)%24 != 0 { - return errors.New("length of relocation section is not a multiple of 24") - } - - symbols, _, err := f.getSymbols(SHT_SYMTAB) - if err != nil { - return err - } - - b := bytes.NewReader(rels) - var rela Rela64 - - for b.Len() > 0 { - binary.Read(b, f.ByteOrder, &rela) - symNo := rela.Info >> 32 - t := R_390(rela.Info & 0xffff) - - if symNo == 0 || symNo > uint64(len(symbols)) { - continue - } - sym := &symbols[symNo-1] - switch SymType(sym.Info & 0xf) { - case STT_SECTION, STT_NOTYPE: - break - default: - continue - } - - switch t { - case R_390_64: - if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { - continue - } - val := sym.Value + uint64(rela.Addend) - f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val) - case R_390_32: - if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { - continue - } - val := uint32(sym.Value) + uint32(rela.Addend) - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val) - } - } - - return nil -} - -func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error { - // 24 is the size of Rela64. - if len(rels)%24 != 0 { - return errors.New("length of relocation section is not a multiple of 24") - } - - symbols, _, err := f.getSymbols(SHT_SYMTAB) - if err != nil { - return err - } - - b := bytes.NewReader(rels) - var rela Rela64 - - for b.Len() > 0 { - binary.Read(b, f.ByteOrder, &rela) - symNo := rela.Info >> 32 - t := R_SPARC(rela.Info & 0xff) - - if symNo == 0 || symNo > uint64(len(symbols)) { - continue - } - sym := &symbols[symNo-1] - if SymType(sym.Info&0xf) != STT_SECTION { - // We don't handle non-section relocations for now. - continue - } - - switch t { - case R_SPARC_64, R_SPARC_UA64: - if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 { - continue - } - f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend)) - case R_SPARC_32, R_SPARC_UA32: - if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 { - continue - } - f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend)) - } - } - - return nil -} diff --git a/odiglet/pkg/allocator/debug/elf/symbols_test.go b/odiglet/pkg/allocator/debug/elf/symbols_test.go deleted file mode 100644 index 1b79520e3c..0000000000 --- a/odiglet/pkg/allocator/debug/elf/symbols_test.go +++ /dev/null @@ -1,834 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package elf - -import ( - "io" - "path" - "reflect" - "testing" -) - -// TODO: remove duplicate code -func TestSymbols(t *testing.T) { - do := func(file string, ts []Symbol, getfunc func(*File) ([]Symbol, error)) { - var f *File - var err error - if path.Ext(file) == ".gz" { - var r io.ReaderAt - if r, err = decompress(file); err == nil { - f, err = NewFile(r) - } - } else { - f, err = Open(file) - } - if err != nil { - t.Errorf("TestSymbols: cannot open file %s: %v", file, err) - return - } - defer f.Close() - fs, err := getfunc(f) - if err != nil && err != ErrNoSymbols { - t.Error(err) - return - } else if err == ErrNoSymbols { - fs = []Symbol{} - } - if !reflect.DeepEqual(ts, fs) { - t.Errorf("%s: Symbols = %v, want %v", file, ts, fs) - } - } - for file, ts := range symbolsGolden { - do(file, ts, (*File).Symbols) - } - for file, ts := range dynamicSymbolsGolden { - do(file, ts, (*File).DynamicSymbols) - } -} - -// golden symbol table data generated by testdata/getgoldsym.c - -var symbolsGolden = map[string][]Symbol{ - "testdata/gcc-amd64-linux-exec": { - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x1, - Value: 0x400200, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x2, - Value: 0x40021C, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x3, - Value: 0x400240, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x4, - Value: 0x400268, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x5, - Value: 0x400288, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x6, - Value: 0x4002E8, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x7, - Value: 0x400326, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x8, - Value: 0x400330, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x9, - Value: 0x400350, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0xA, - Value: 0x400368, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0xB, - Value: 0x400398, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0xC, - Value: 0x4003B0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0xD, - Value: 0x4003E0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0xE, - Value: 0x400594, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0xF, - Value: 0x4005A4, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x10, - Value: 0x4005B8, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x11, - Value: 0x4005E0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x12, - Value: 0x600688, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x13, - Value: 0x600698, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x14, - Value: 0x6006A8, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x15, - Value: 0x6006B0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x16, - Value: 0x600850, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x17, - Value: 0x600858, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x18, - Value: 0x600880, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x19, - Value: 0x600898, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x1A, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x1B, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x1C, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x1D, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x1E, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x1F, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x20, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x21, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "init.c", - Info: 0x4, - Other: 0x0, - Section: 0xFFF1, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "initfini.c", - Info: 0x4, - Other: 0x0, - Section: 0xFFF1, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "call_gmon_start", - Info: 0x2, - Other: 0x0, - Section: 0xD, - Value: 0x40040C, - Size: 0x0, - }, - Symbol{ - Name: "crtstuff.c", - Info: 0x4, - Other: 0x0, - Section: 0xFFF1, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "__CTOR_LIST__", - Info: 0x1, - Other: 0x0, - Section: 0x12, - Value: 0x600688, - Size: 0x0, - }, - Symbol{ - Name: "__DTOR_LIST__", - Info: 0x1, - Other: 0x0, - Section: 0x13, - Value: 0x600698, - Size: 0x0, - }, - Symbol{ - Name: "__JCR_LIST__", - Info: 0x1, - Other: 0x0, - Section: 0x14, - Value: 0x6006A8, - Size: 0x0, - }, - Symbol{ - Name: "__do_global_dtors_aux", - Info: 0x2, - Other: 0x0, - Section: 0xD, - Value: 0x400430, - Size: 0x0, - }, - Symbol{ - Name: "completed.6183", - Info: 0x1, - Other: 0x0, - Section: 0x19, - Value: 0x600898, - Size: 0x1, - }, - Symbol{ - Name: "p.6181", - Info: 0x1, - Other: 0x0, - Section: 0x18, - Value: 0x600890, - Size: 0x0, - }, - Symbol{ - Name: "frame_dummy", - Info: 0x2, - Other: 0x0, - Section: 0xD, - Value: 0x400470, - Size: 0x0, - }, - Symbol{ - Name: "crtstuff.c", - Info: 0x4, - Other: 0x0, - Section: 0xFFF1, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "__CTOR_END__", - Info: 0x1, - Other: 0x0, - Section: 0x12, - Value: 0x600690, - Size: 0x0, - }, - Symbol{ - Name: "__DTOR_END__", - Info: 0x1, - Other: 0x0, - Section: 0x13, - Value: 0x6006A0, - Size: 0x0, - }, - Symbol{ - Name: "__FRAME_END__", - Info: 0x1, - Other: 0x0, - Section: 0x11, - Value: 0x400680, - Size: 0x0, - }, - Symbol{ - Name: "__JCR_END__", - Info: 0x1, - Other: 0x0, - Section: 0x14, - Value: 0x6006A8, - Size: 0x0, - }, - Symbol{ - Name: "__do_global_ctors_aux", - Info: 0x2, - Other: 0x0, - Section: 0xD, - Value: 0x400560, - Size: 0x0, - }, - Symbol{ - Name: "initfini.c", - Info: 0x4, - Other: 0x0, - Section: 0xFFF1, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "hello.c", - Info: 0x4, - Other: 0x0, - Section: 0xFFF1, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "_GLOBAL_OFFSET_TABLE_", - Info: 0x1, - Other: 0x2, - Section: 0x17, - Value: 0x600858, - Size: 0x0, - }, - Symbol{ - Name: "__init_array_end", - Info: 0x0, - Other: 0x2, - Section: 0x12, - Value: 0x600684, - Size: 0x0, - }, - Symbol{ - Name: "__init_array_start", - Info: 0x0, - Other: 0x2, - Section: 0x12, - Value: 0x600684, - Size: 0x0, - }, - Symbol{ - Name: "_DYNAMIC", - Info: 0x1, - Other: 0x2, - Section: 0x15, - Value: 0x6006B0, - Size: 0x0, - }, - Symbol{ - Name: "data_start", - Info: 0x20, - Other: 0x0, - Section: 0x18, - Value: 0x600880, - Size: 0x0, - }, - Symbol{ - Name: "__libc_csu_fini", - Info: 0x12, - Other: 0x0, - Section: 0xD, - Value: 0x4004C0, - Size: 0x2, - }, - Symbol{ - Name: "_start", - Info: 0x12, - Other: 0x0, - Section: 0xD, - Value: 0x4003E0, - Size: 0x0, - }, - Symbol{ - Name: "__gmon_start__", - Info: 0x20, - Other: 0x0, - Section: 0x0, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "_Jv_RegisterClasses", - Info: 0x20, - Other: 0x0, - Section: 0x0, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "puts@@GLIBC_2.2.5", - Info: 0x12, - Other: 0x0, - Section: 0x0, - Value: 0x0, - Size: 0x18C, - }, - Symbol{ - Name: "_fini", - Info: 0x12, - Other: 0x0, - Section: 0xE, - Value: 0x400594, - Size: 0x0, - }, - Symbol{ - Name: "__libc_start_main@@GLIBC_2.2.5", - Info: 0x12, - Other: 0x0, - Section: 0x0, - Value: 0x0, - Size: 0x1C2, - }, - Symbol{ - Name: "_IO_stdin_used", - Info: 0x11, - Other: 0x0, - Section: 0xF, - Value: 0x4005A4, - Size: 0x4, - }, - Symbol{ - Name: "__data_start", - Info: 0x10, - Other: 0x0, - Section: 0x18, - Value: 0x600880, - Size: 0x0, - }, - Symbol{ - Name: "__dso_handle", - Info: 0x11, - Other: 0x2, - Section: 0x18, - Value: 0x600888, - Size: 0x0, - }, - Symbol{ - Name: "__libc_csu_init", - Info: 0x12, - Other: 0x0, - Section: 0xD, - Value: 0x4004D0, - Size: 0x89, - }, - Symbol{ - Name: "__bss_start", - Info: 0x10, - Other: 0x0, - Section: 0xFFF1, - Value: 0x600898, - Size: 0x0, - }, - Symbol{ - Name: "_end", - Info: 0x10, - Other: 0x0, - Section: 0xFFF1, - Value: 0x6008A0, - Size: 0x0, - }, - Symbol{ - Name: "_edata", - Info: 0x10, - Other: 0x0, - Section: 0xFFF1, - Value: 0x600898, - Size: 0x0, - }, - Symbol{ - Name: "main", - Info: 0x12, - Other: 0x0, - Section: 0xD, - Value: 0x400498, - Size: 0x1B, - }, - Symbol{ - Name: "_init", - Info: 0x12, - Other: 0x0, - Section: 0xB, - Value: 0x400398, - Size: 0x0, - }, - }, - "testdata/go-relocation-test-clang-x86.obj": { - Symbol{ - Name: "go-relocation-test-clang.c", - Info: 0x4, - Other: 0x0, - Section: 0xFFF1, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: ".Linfo_string0", - Info: 0x0, - Other: 0x0, - Section: 0xC, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: ".Linfo_string1", - Info: 0x0, - Other: 0x0, - Section: 0xC, - Value: 0x2C, - Size: 0x0, - }, - Symbol{ - Name: ".Linfo_string2", - Info: 0x0, - Other: 0x0, - Section: 0xC, - Value: 0x47, - Size: 0x0, - }, - Symbol{ - Name: ".Linfo_string3", - Info: 0x0, - Other: 0x0, - Section: 0xC, - Value: 0x4C, - Size: 0x0, - }, - Symbol{ - Name: ".Linfo_string4", - Info: 0x0, - Other: 0x0, - Section: 0xC, - Value: 0x4E, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x1, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x2, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x3, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x4, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x6, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x7, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x8, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0xA, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0xC, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0xD, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0xE, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0xF, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "", - Info: 0x3, - Other: 0x0, - Section: 0x10, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "v", - Info: 0x11, - Other: 0x0, - Section: 0xFFF2, - Value: 0x4, - Size: 0x4, - }, - }, - "testdata/hello-world-core.gz": {}, -} - -var dynamicSymbolsGolden = map[string][]Symbol{ - "testdata/gcc-amd64-linux-exec": { - Symbol{ - Name: "__gmon_start__", - Info: 0x20, - Other: 0x0, - Section: 0x0, - Value: 0x0, - Size: 0x0, - }, - Symbol{ - Name: "puts", - Info: 0x12, - Other: 0x0, - Section: 0x0, - Value: 0x0, - Size: 0x18C, - }, - Symbol{ - Name: "__libc_start_main", - Info: 0x12, - Other: 0x0, - Section: 0x0, - Value: 0x0, - Size: 0x1C2, - }, - }, - "testdata/go-relocation-test-clang-x86.obj": {}, - "testdata/hello-world-core.gz": {}, -} diff --git a/odiglet/pkg/allocator/debug/elf/testdata/compressed-32.obj b/odiglet/pkg/allocator/debug/elf/testdata/compressed-32.obj deleted file mode 100644 index 2bfdb4424075881a6055055b760186e031b9cf6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2208 zcma)6YfKzf6h1Sv%YqBbV|j{(ZFpG9GD};6NNc6LDmFe+TOrsgxQ|&_*@xL3DA+~| zr72B|6k?DlwJr6P6b+*I!^T*(t2CtAH2!EpW7ANzHT+P2*rXcqoY{ME${#(+z2AA= zbM85F=Dz&UV-E|00GtGn;9m)#*_g0YYp@z}APX7~{OH1dz zYFC26h~2g;5)Jya7$2jJVs($tpF#Q(MEl|Sy(QjU$uQswl;w79%81WiO_>cGH+T43QY5RXqPfU)T5c}wNPSQ$F1}zH%^Il5v&HYUOb;3T1qVbpYrgxEc`CXPsp!>jkDBu5F4T;c2Ta!c zKim8Dv8kSOH%D%s@1JctP`dHZ>$SV*zJGt}lX?Hn!UH!pJR7M0?w6Bs-=LUh5{K;1 z6<_lmKRM^?b*4L?uFEzwtU7z~y+zN+QpM-D7H&+Yf4b(4>5K8HE9X~Pw|5*Y?^$15 zwy>l1-WhpPzGZL!AU-y6WO(d{zhC=fbF?VX^ZPq*E>5&;g$9?a&bGSI(-~GfZPjwE zTwS@YQcQ_f~w=AVnupeDex9ZH1h^Le5wr zTb3hI?OFKkafFvi^X3y1atFfjLZ=!7NJS3;ubzo0VhXyoU}E|^5_$nKhx9mOcN5~( z>8B=r1;cd=?_*fcuz_JC!)F+J89vW&7sEXa`v@`LFq4ll)b58H)kF5J3~h)w`T%mQ zC#1SPh-x%}?VO7$L0MJ0RgkqGNcO~HAV(t!fsEQ;)*1-=Bj`eZT&vsTi7H*_wQO}q z-QhNc4lb*Lfw004U@nlokx)npW1etCRpf>z8Y^R}+uM;iqqMjBqwbJ`cm1DKgnl%u ze4^-`)xRWsjtfywQ&o?P=rWEh^$8y*?L18^O<^gM`9wd8vYvQ6`nKf%Uw&2SLuaV{ zL=;ayy*%DV)N4HZ73c-*$Hj^J)uKXQ$0AH)9g5#;$9WZ^Qd9mFu=HqvpP zOf@Ljh+)KSO(^U09>zqxf28MmL&)N$)znSrm`rQciumSrn*uoOrx{05vHg AwEzGB diff --git a/odiglet/pkg/allocator/debug/elf/testdata/compressed-64.obj b/odiglet/pkg/allocator/debug/elf/testdata/compressed-64.obj deleted file mode 100644 index ffae56a931cb13ac30d0b145ef51c6d6359a564e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3280 zcmbVOeN0g$FeD1KU^awxBo- zfyE^-lWlPYIMUA0^45Tj3UFy_DR*-DcSkr%{=EYfafA{s8{>a<~ zFkOYm^kk>(^99#fpACk5Z3{6!02>vSBRcfMXA=_>pAbXA%hv2#tLU|@&q>{M#Pchu zuQlIcY#7MAJGSigBh5|g=C}3S)-?FnnXcTsa`&ywYySFeY3Qt_W~{h$eH07JJgzQxFt%MkC#Aqz15FsK?(+EjgPSLG7ge2RA z2P~p#qj8h5&;mZLyhEEU0=1+hlQ_OL$B?I4eX+V1?QXu6T3T8>L@=eaSugh7PDn-% z+3`4~8Av5K3jdih=~JyZt%2a^4Ekk=)&H?D$)!-#c~U)$s>s3#w{`^6zYOKOXlt%sY=Y zRJMy7?l1HtowQZ$uRG+wGy2M>?tjOoUn)BHMtY=p@LjQK=IZd97cR}6ZvJLf+4si| zewlu5>U`;e%fps+yC$pl7F3^dwLRSbkHh!=qk9|Ov9BzL4}2IEi+UgPlIqIJjn<+@ zPb8p3tR?nRd&%1SBC6(m&RJqFE?FH%ajUsF3VU`CA!-)#Gg8wA=)Mam4nL55cvP6o zy@txnl%13SdIEuxC6PaF=$XZZ)4J3u5^*Vjnn)w*iAa+5U>YSQ0j|Gdk)$W!8x!D} z3Gn3!aB~8jUK~zfCE1$#s5Pe;FmGdH5R(t(M zTv)|`uW3yr1Nnf%kL^5*!-r94@fkmYxCKWz7Yp}|&Q~K2eC=Ccoq)x82zeVce6V>? zFX!-!sBhtLR7ov|&!Aq<;j^eq9DWe>P7ePYb+&J|{wEOM!|}UN@4=C;&tZ;#6!jAv z&MunvJ+e7a*?HjOKZ0?1+=@87EA9It_V8}MB6;YjgyLf-n}uYbWLM;^X1C<=gyd%^4V)1QNr4U-To*B)Hy|??nvd99gMPmpps4~u zMYdPhHLeXSQtMObBzL;oLy}*{UEKU&rLIsLZ7m_13m#P1{fujiUoNJD9lDo`0XX(y zOJnDpeiYR_tV6+95o8tpL4Lk7?gFEZ09Pw(r~)x>*565e`LhA>S$@_J00ZIk!@X27 zwlS4OzrZ+#aAX7TUq%gj^&7|f#n1uj2k(fbVfEWaF+L`R$R&7Cfxi-3;kj^cRg48j z@_HmXw9bsH!J6n?Z~Z-ZptSEF`X5Wf*8j9lOb9Py{uWR)!mr;)ZF>1fF+a-#^@Fb+ zpTC=85VM#W=p1AU6HUg|g(u6;#y)CM{TCSVNgpv2hUnIT{&T(v%jh%#R@_ z(VwS}BT&kSIC9%0BNW%GUreWd&|{fDt1Emb`MU?HX3&2W6pirf2c2I#(B}~BK?nH% W2LBQG{BWl9@^|6=f%mQzKL7s`iZe?9 diff --git a/odiglet/pkg/allocator/debug/elf/testdata/gcc-386-freebsd-exec b/odiglet/pkg/allocator/debug/elf/testdata/gcc-386-freebsd-exec deleted file mode 100644 index 7af9c58ca73945561c470a5e7ad29f39d0405a6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5742 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 C>2l%# diff --git a/odiglet/pkg/allocator/debug/elf/testdata/gcc-amd64-openbsd-debug-with-rela.obj b/odiglet/pkg/allocator/debug/elf/testdata/gcc-amd64-openbsd-debug-with-rela.obj deleted file mode 100644 index f62b1ea1cada83530e45320cc58394933753dddb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6544 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 U!nG_h_6^|VLtlgW)MMiP4~j0k8UO$Q diff --git a/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-clang-arm.obj b/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-clang-arm.obj deleted file mode 100644 index 1cc7e4b11143698a3abc3f72b88411e41f3d4989..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3092 zcmb_eOKcle6uoc8le%$ZCuzP-00X5>N;9$ZD=oi9N}^IZELxETzc98Zj*)-ZlaNY9 zNPGmMDuNY4MQRq6SagHL1{Sb^EhrK~V#6XpBoJ&s?5GImzM1EFBZRu)O7Go!&b{xx z|C@PvF}EayFewm0VRw`Jdzaq)>}PH^&y5||$(Ko-fN9NNSk7jr=gu!pT%?YUxac%`L~pE5 z^ov1rNDPZ3#;AB6fiV=+ay*BmtydWUg9$doQ*4QtFpYOF`{ol+rtwnTM^Ceo39Xpr zz_!*D5f>zS#C^%bmYM7x97$p@9Y}41?Cm%^WG2rf9!wk`esp*$fs7Uz0rl8nWIRe{ z@{vRW9xFx6&}kHd?nEubU&$`if@gptXx*(;>UIGTV#(1DSVm`j!xFC=-3T27FKMd5 zI)+kp%4`zdg%Y}WcIBE!Jd47*(}W^gaPwuSmM&DBS}DEhHe2O-Ej?||+L?)LCOzgk zrPkzy#oXfj#l_X>+05ixx#m>H(_?w3{RZRhu}*r`hCd3YSt`g*VQhxI z^6ccqPNrY1H!H=?|9K$1_4^Q$#O36nE?pC?D zMRw86ZA9JH;oW@pyU zwpZfz#ytq(y~5#^!q<}5Pl zySO<&rlE3hzF7sJxo?&$D9UF1K8k-u7=^w!VC(aE4fA*o9M6N-K+S{arsq2VkOQYg z`L2ObHv29DJgkB=-+Qq2et$y0Jb&(&dDZW;u=RZJ0E~cBqI^$+(DVJK<%8MIcOJHC z!#QpO+{;EF%C`ip=lfI3*9D&%AHSpAMxBwb0sMCcB!qojJ_$6Gl(YUTrC@tZyhj|b zQN)X6#ynd=JkB^11K95`4JbK|%^Y}4{oq}dLhkQxjlr`t!G8Skx-xb6? zE+hO(#oY|zl%Z$lrleqVg%Mbe}SyWAyv}ryAx_d=tTz>?fr9>EjT< z8j$xgqz=+`fN-4zy&gJY_0kIw+(*wuFutx4+!1*j_=MaY@h50Bg7F~^Fz>yfKKeZ3 zPtgtFGE7~QX*M9#-AM<^!o%@4)Id~`A8$qE^hdO`rp#Qy1GVtsWn zsb7bPA83z|?^`eCuaAJwG1)o($oc;sjVAtf*4jTMM~n7pLiGTG_zSy=z;dm0in&u! zZjQORC^yU8Y?PZ}ZYIi2GdCUOrkKmhdMfJ4N)KuW-{r`-GSVaKj69d4pW}h%@2Y`6&WBiIx%vG!&}fA&M*DFaDi%D8_3Q5{9) diff --git a/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-clang-x86.obj b/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-clang-x86.obj deleted file mode 100644 index e909cf4e6e19a63276f497b70a170492ade64156..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1900 zcmb7F%W4!s6uq6E@imh%F;PTC11d(yw0S|I5zR(}7=j2QiV%Bd+R2ca?$BKcX5}Uy z;8JkyQgGwS&+s!`>DEO&r@CsoCXf&>+`8w~ee~_>s_GAqRv&ww=Zg_feDN%ST^`EG zyf%|EE~7%6PnUFPH4ibP_DqAIY+2XUL%Ag0sCTnAR`zQnCob1eVqW~(ld*@@dzGci z&>0c`1|}XTm-$;8W-&es>Pb7Pr%^X)hN_dqbrof*-t2~PJ7^+8(4uW` z5$Gy(2P$#_nzzk)cG!s(MiHGou@j{k3Qn|>q}`3?>MGriHzy`@lg>`xom*VEebmG6 zsNNQyrK|o=NeNm}W4pZ`HX3QPBY}$ED+!uOuNR@gppj(~;Dt@p)^Frb+c5QDw6GpOzZE`<(t@7WC?Bqz6j=s5 z2W4+mK9BJ>2T;1uDFP$bw+C)9U7w&!1V*fna~9L}6MB)ri1qP2xc$9Bf9!|-(c1oQ z0oxov`31d1V8r^agS+)wPCXpOe!W+~%;9mNltG^7P>=LcKN_niF}&oYBbGkJoW*n> z7I)sn+2=B@&IBW@LFEB<>+QM3@qGridkRn(_k+NQP5TO-UlO_FZCT_QoMWKlP_FX` z^b6Fj_YE7ngE=dUYbvVz#n#21LVDKg< zci)WM?S`ChSBT#~t@)fU*d&hldgm1rzHsLh;!Cw4K)wtg;P?wT;tOwyLVT<=*O6UO zN9E5x?$;x(|6rAu+d8hQPTZcC0XjEGX9wxbAl2KBca?{q5#PeY(($bEPstyNhe@6* Y4~<=;#Xgy$#U{~zEhOuFEQz)M0D2R@nE(I) diff --git a/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc424-x86-64.obj b/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc424-x86-64.obj deleted file mode 100644 index a7c6d6e562c1c70342d9d1cf41194b7ef3fdedf6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3088 zcmbVO&1(};5TCc3wy9}r+WG}mj8L%^vueqyN*gHJYD*EJAR^S=xJir6rX-tMMX?8w z3JRXYiy)pn>eZ9rMg0prdhrkN?4i!=zG=3TNBtPs_vZcPG_4+RIcERIfdNFg4YbfX1vOuZAPoYD5y#;U-wsPB{y8I z1^Li#g!xLTR2VBbB{&^cSEF2Vuv8h8dL&`Jwo@I;K?rae*A|T7sMN2%UL2#MU?~*r zMjNH+j!!|svzCRifRzE*LQ$aBvprqu=enrFQ9x_Jl0=dsdtdgkm7+rTc2Ycvx_6Z_ zC|l>C_`{I}Ac~cN+QyTn#k1W>v!2pM#ImgOJ}g+vaxBlZm-vKFQ7h{Q;M6uwx7iZT z)k3s3JvB9+8^Nm{{liUz)3{p=T@UB59?wgxh5mX7&Mh}|!SNamRDG{mS#&+G?yrG^ z4dQBOIVjh504vLZzXK@O-6|vg(xP6*39-+1_^vj+0KJhgLE+Zjph8%wR;~KjNKQ}- zeFu-2Z-j2?c3TPl6&S(*x;I(VqD~}nzE5q2W2jJk;`NP8GwdK{8Gi!pbi4l>Pd&nY zm!x9;LJ~CiP8u)@xlaQMb!1W`*EkyGnaKa+o;d1lJi&gPJMf{ik{pUBxPr6HNhW@o z=CvPB(svdOCjO;N9Kk%q--VClcM+30De{^Ii?m1x$1`*T6%+r4=0BqyiN6~kj^}+f z5F@JXFC6M5FaMH1KwlI8JHz=2lKc-4GoAmN2ItV86zTg6jS?gOVSOMzC+Cp9n`kiY z|FdELedsIq{{}Icleo@ney%@ZB+~a4VkZ9YhWn!rx8#3s$cYfFX#SJ5NQmVBfHsMd z`wJbP2#r+f+mERHc90{-e~qGAgN&!Oi7H3Uin5^t4xqjlA9;RqGx5LH@BdM>Cq?on zZAqQ{Qt)#tiLq`QD@OY;orG}H4hc8iJmK`EY8N~Df|zh!EMc-iH&GkjE0B0;19f=2 z*g&1vE;bCdgNWEL(1ssDWFS$u?ccTC{(O~Nzl(I8$*Nq{46=W&3!Hg8jZ+@_4zsLk zMdn!-IOo~WIOWkT79sRIMk4d@e>w8y-X*^r4Jgt-7ols1n+fjLZE2(}X}5^PM7@}J zV~E0$5Itg>Q=1x3iiNYtq}l}$P>=vuTnoUqxc){4KpjKHuEii zt66q~TCneE2Yw6?%cZ9X#}0fJ74I8+QJ-1 zQ$Fg7NbTJNwVPGbBSWcu-0msFXc2{-T+L)ludLCyE2sUm9=IMj?VuI$O_2hBHvs36 z8@S+j?KXH3d7{1j@9#7wpy`Oug%cK;>$pq`n_&h8 zinj$|zN+b>>hWjMKy&l2@icu@Uni+w&FLY{FP&3ck_-$gX)dm{hr(J1O` z#KJipL|LAZDaP+2*K?BT6Wdpq3)6k+MPjNC=_o?#&~q|`ORxU`F+C?mPBOSgN`iFX zEwt$vxqA#seMzDFR?%SUf6CB59jV^`OT_e?RBMmHc~TOj`_es|>d$k1iKp`$!KK&V zM~rfcABrKp<3eWyU@rBAzd_s-|Ct?T{}TU}<25(K~E; zN&1X5^Q?(2$*JrBeEXTiM7E6+OMRGjLb$0z!c8YnIK655$qwHDCY(2`nQY*fSRYPL zLO6}2f67DeVWCSbh`-?UT_O@(^2qmq^2jWcpFF4HPZ*KJk-x}) R!sVv)JUI$Nq6tk-=`Vm&no0lw diff --git a/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc441-x86.obj b/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc441-x86.obj deleted file mode 100644 index 0d59fe303b6dad25698a1e7c0644d285460797a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1884 zcma)7O;1x%5S{y8(Q2VkP@|$rNgzNX578zjfS}edjB#OPLt;o<>{420?)s0Sa@64Q;duHxOU*Fuif7=)%Dn@+ic_NYLA_c2v zXGYD)5fLwt)j>bKm|4oKjS;*C(4Uk{W(9dzvx?y; zQ?`tWf{F}Ua*=^pd!{PJEd7Q0sexJ}5(zBDSvPh6Y2SIUo-gJLK_OU>`KZ1Nq*z?c z&#ad_ji}=SbA^ue7G~o_5tgHv7Z1g}Oq=n+RO&r?Jq?T{DYne@Z2HDKZ^+s~d#@gq z$`Z7rmebp6Md9;Ef+wY@Btf~|h8dPSTbreFxfMQ>pcU@KNUc$ACjFgSBh>7jW+fTg z?UWm(dI+-K@=~kR*dpZkQC@;dvtAEzLqVe%g#iv^t{s&sPu;R`d$ZaCi`&wF&Ev@8 zwc!a_;TudIxn9HsaOUwkDa%fEXU&@i!h8N#-UZ~4PlbG}t)j6N0BSRaI~P706^$(d zIHn-<4{YczH1D4KVSnuF0fw%DDPJ)z(TGK3_uwb_3P;^~^12uBsc4LMm#n*-sCyhS-N!4~x`rIHaPl-_(byjRB;QT&jR505_(@Q{kFdGs zA_ip*PR^NjW{l%gtTk@~;H1rPljePn^EC9DfrO~L4~%yF36!^R3W+@SNBM%0+{dHD zxv)>&2W@?OFl8Tn-)O|5b(1w2I^ZJ#coJ$DgM2(E)=csp;9c?lRg_PC)k!=hKYuGu z-T(Ecue*0yeqTk#^%OMDW_#lIb;SJSNzv!a>51R{GjNzM*8&&BV#hekGb^iD_`v1TvlM5^xhCS$2sry67PUb5KIhOz+H)neMfx zCvHCc058FVxFGSOqKKlmfS`$oMLY#^mt6FJ@D`CJR=roX^XAQvgBEmG)vrFg`n}iv z{+ZR6T*m<+2Y!a0CMduIuO}}laS8UqBy3;b`eECH&94r^-LH%AH<~`dYZI?ex3B;9 z{jc7o-^slZw_53u;GHyU)kyydFP{V`sB!}}=af<3+`=vrT&JLzt2Lj&Q4Nj|^Zb!! zl7m}N8prvC3{4!Z42~|1sFZO&{}DBn%JJVI_stuuk-^` zkGYRfDJlZ$NtHx5>2e2P;Z@`=EYRKgr!)o*5-NB(P*2NQ+)Ara-b|Bn9(VF`y;?oK zxDZx#^ln`Vl_x)}yFLbYlTNdq#I=BCc=ojm!AfvETnrb2ay=-ob@HfsxxAjGd0frY z3|eVY5Bfr?jVOa1L}~4)nP^YSc{FdYLzLC4&}pPu-XG1iRoLU2*P)cI)4UevSJz`o zc?IC?%F4;$(1l7j$-75an@NGo^p)5-3F@^T9Rx^nu1nWUqP224lXJ9(5Wl=lUFZci6157|mN$mk6 z*%He#A2InNFrP(kV`RGXgm!pYGnhh7b!5HME+BdiFT#yuhhV6w`{0dyO`@GdIsa?? zJjPPaojrmwQA0DBU@lDh7yT3pc28v6V259r3$uMspkdhjpr|A6aRAMa-jURo`MrXe zos%LL7<`iygKXco&}L)g{xO5cj93zF-;0P1>;E2YJS2&y{&(YL_y0Cxc20y~i^11P zG0669p>0_Ghg@IgMD=N;cKvq|qny$wii*Z~L2L=YTDe$fO`mi`5%5Ad+(pBU2~@?7-%<9JED%w-ZWd+$)>F$TXO#UQ&^((S!N?hm-o zZ4SVXpxR4zeOeR4>fhw^qfE&Rvg;eBK9T%<`0G(0$ci^~;?&2mP6!`1VZzlME0fR3EA%j!=HLP z!#aIuh{XT0R(I@zGYqRN2>u@H=Pmp@*5x_G|03fJ%l|g(T?=1g{hEbKy$=|-=kuB6 lzsCBv7Jip?^F7L0LMB-!cK*{GXXCPd=y}amE$hej{}%-U_$L4W diff --git a/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc482-ppc64le.obj b/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc482-ppc64le.obj deleted file mode 100644 index dad7445486e8897ad351ec2c8fad09f0d8ee494d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3016 zcmbtWy>HV{5I@JIw4@FF013oED)B9B(o)e-K>ZR_NC+V$SQx-@olw!(sr?M8ghV!w z7+8>Cg8>ExR>XqDzre)I%mNz{L%FlxrOz)$AUG+xyWjop?!EJSP9B`UbfI7vz+%8| z*zy=ujTOKvFud zeiEjyf>8%$JzX4dS;nYwuryvYOZ!Tr#+WhEk8~U6hRlK4;+Y~r^Zm~jhm@QFX%}D} z*ycE56}CsZyeAd54|K70rDAFxMH4_?GY@VKrQLx;kaGTJEXoHP3d_a)W6{bd0lweys5~nah{2m6yuXcGaFLTMN-f zB)sOiwN*cEZ@IC*s(7s+BDWcNZX9}6YfYddV&6O03hsGf6+O2Vr_M~-YOLII!n%dk z>ydEWJ60R*QWRrwg$rPsfQnc{Bw8=s|3v7|_>V7&1T~ zB>Rh{$_ry*ct3Fxv7?QqaB5&jB24vdwuILfV6QmB0lOAOV2i*78)xmI9x7|=1|ewGQh zq-LdaDXwG0osnRL97S~Q4UFaO|4K1U;(XfwAb#}y3&ixAl-ZErb#fHZxdF!V`gdf1 zo-_3)Nblc4jB4^a(M;rnZ1kD|skuMv$B5_U*W^3);2-jz%6yFm54-Q^Y=rwV`sO$J zk7Rz8iBj|a8GeOE-u#~DJiig-az4*>6fynoQtgkj|2uLN(brFY-d5ksMje^33wb;7 zqxYvXmDj&2?;pKiRMGpZG1VqsAAH|bF}BUz6HDvJ+X>-$Dr>&5Jku7-jGlo_385c)%m{wiUZkW diff --git a/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc492-arm.obj b/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc492-arm.obj deleted file mode 100644 index ed45be2c55fda61466e4860e42fab07cc9228978..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2648 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 MBck6jDn<4G4}(uLU;qFB diff --git a/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc492-mipsle.obj b/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc492-mipsle.obj deleted file mode 100644 index a5fbcfbbdd24265cf41850440a90719d2545e263..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2864 zcma)8ONbm*6uni|zt~QvlZi27el;?~M9oxUG6;!AM>CoXMvaK5AatsGDm|^$)lGFx zJ}M}JqN^bb#YNCSHZGJwbP*)cEEHTQxE1^a+z4)>C`1gj=e(-d^D+_i!mD$C@7()d zy?Wg*KX~XN%d$j^B_&z5MBJiCu`1Omm9R~2k(+g@!b|-N6Px7or491g(&*(gj>x8a zL{3js<@}N>Uo4HumrEixd^2MruP%;$H7%>IxXyUVm8yKdIQq*)2lE#(f6^7IKa|CQeJY3PF*LE(SmTx9vQybuS!1m& zRPk2qF)5etg$r$DY6<05!#g{SQl53+h*Q~HzPmgz!a36$-hN=jLZpzF)IU3HZvgiu zmST}?XQ=6|pneyIt#;J1{;mw+J*WeOcVVUb>ou5$l8R-$JvLnW5X_bpcA}=M9^9pc zsMl&n!JJD&d9U|e?{3Wd@$ytX_(d30mBCL zS}z32$!@?-j)@%Dzkjd0Z6>I<{3z{c^3I*Nr5d;DMhqO;K92NDTZcA_OJ^qB`7k3Zop-@h7xX0#v{K2n@t@p>oQiC+gMafI@%HMk=esfcv$Sw&~GY#=ym5}@!E4ieWA(7?p;Xlq;tuo0=0B@s{8eN z92_I5j{315HG_;VO$u94fELJFLu=wSI_-9VZ8N4Fjr}%~urSY0lDJi0NI>#0Vt)KN z`EBsMGu2sfH8}8?;uvQ;&0l4PkzHP453R6yBP@%9+sqV4)|w{xZdhTjTVbmkW8ib7 zFwm(u!gstZj^M*J#F6!)SHSbK7V9@VWOtj5eATT!tLpoy)v)8Wu+#9vTC*$Ng@l{V zygW*=+X8TmHnwIPZQyobIa`X2C9`WAt@1qESn`?-Z_03lh-+b#h=$3-yd4>;y9M^X z%;qJ@_`?}Kli`sJn;AwKzL?=F8NN2c^1t zNoQcQrWV$vy$9oVBkx@12Pk1J<{iQ?zrSx`yBJ!?M>&XLuJ<6C&>ZU4LY(&F7$)Ck z*rw=M4NmHM9n7m5iCTXiKK$l)2O&)2TC`|Bo*%Qn!|3mQ__)S0hJGK%p__c?K)@e$ zEt>C5ILy3tXw=n7K%Ms*bhGXi)Mf9i%kNg#Jq_LDn*!fn__S!gci=GjO4wYz&*as7 zTpRgzW&{!V{>pR$`8Yn#Q0Fyqz%XwhI`1MpW`A!WZ)%X0)}?tK!|bn${`7kJ&FTL5 zU+T|(pMS-aoChECwCMHnUeRZsv9DqLpp$?)kEqWI!yll~VK{jY@rGty^0POS?<%h2 KTjA59`ThZhn>Wb- diff --git a/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc493-mips64le.obj b/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc493-mips64le.obj deleted file mode 100644 index 20bbd6c4e894418692a5c2f4c5bd4ac384165dbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4160 zcmbVOPiP!v6n`_bNw;p3rir$RP1`wGO*J!aZHQVmU2SU()KVy-heDa%%>KdMnPqmi zrd4S0=0Rx{6ruPBw0Kh#JV>iWR0<*#PesJ^*kcuhf`|3JZ{C}1zDzECVdj1B_x^tG z`}R%F9X|TJX&4}6Kps{kK>@CAOx7C!?2=lR;C|Q!*LzoLQ}9F2hVOghaJlE){=@>9 zeA>DBA@YkgXJiSjf9}DE37g=@F9F_M1~{}p+__eQjdyIc18{C#wJ^>y##zQV%SE_S z%fn5jBfXF@m8@m}{t+yjTVR?iThaD({Z6mf6Tc!ZcH*-OpSs^{hST1sS%Yl z#>HFt)II=(!W=?a057r9 z+-5}Q#{dRg%xsV-gitTg~EFzH3gRZ8zvNYJtCCQ_GrRP_tJdM~=N@ zAGBxOC*6Iv)AF16^2&{8W@m8GY<4Qhg3#&Iy$C}%HQT9nVz2V5(~iQ}uf$>Gbm9o3 zLIq7A4Xvb>*9el7l>5=R)dnxBRiIN3qj+^0T%&SJ)a0V>6Yj3lIP1q}+CI6T1~_u? z;C_4Rh#$mZ$fdXUx{poU?S}6Z-C1|vo&;81!Ph2y@XGcKFy7cTv_qYM=!i?_4-FTO zer$e}yEu4gXy@Y4j^ls+wT#CN&u+$7E$D(lw=rjc+d0#Uy)yDRN_bsXk>B*(*k6pn zUGQQL+;XP_?u+xsPq<+_ZiInI*yd`}tD&e|+6xi5tp&f_t+}Y0ok2WIA}GDmoN5Hs z5CfCdDX(0P{L}2tP~-(QUqU8Wvk~~>f<=N`30p1f-73dw!`vi1=j09q>D&i1GVageQ2xJ4+9=v>M+n_QLsO(lMuIH!8Wn6sO-i z5ucbz-zK6h2}|+IEK6Zx{}$sD%sFs+G4?RdH#E&FeULbEBOhmb!CNfPY503AAJ%Xd z;i!gRV)=xIf6cO|;Y%#nHT)-*yBaQbXEpqFmY108{rNz%e~0DIHT*Z01$w^BWxSJj+x+ z<&pmvWIqowu20sl*iUDA{%MYRxBh$4AMbb@`zocWl#+i+D?p5BFGL6Mc{uS`vb=8a zLiQ=R_zO<=USf$2@!Kre%!N^}`{@`8S^cl`K#@Ge3DWbwf>>7mkt{I7w#ry~QBfum zfBn34xr4U&zjs?X^}TG)|6LzOOTDZBv8??s@&2!|1MQ!Nw7&myh-KyfgZ)mTzMu5` z@1ioxf0i3k?03es?*BGoS@plbgIWBke)B|ko{_XWbi6{IP=ck_alhiF3eb4pTMY=l--V#IRx-ql&Pxd*5 diff --git a/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc5-ppc.obj b/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc5-ppc.obj deleted file mode 100644 index f4165af0982d3b87761a4a540900e687b39e980f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2356 zcma)6&2Jl35TCc+O&07lUmy}CqDvLPLG{)~1hqwNlg7{nPz6XF_^4p*Z0!Ym*V=t9 z4hp1FMFj^$Di8;R)B{zIT)6gcK>P>587^=@LP83^dArZvSg2*>c{B5ykN4*7JnudK z@(aQcG$cU}LC*o!@5=X#TFdk>&3*OQ!7sbEac5u9%9p>=^6t6fV1JM7{aaKz;}D$; zh%TbWyGS{;N6xh(nY(u3&h_68{`tszYjEirIc>kwiHT{-39iC_YmLnc~8w*PYE;%~^A+Zq<3ZT3f5u zYR@`lf6(*epzDXy>#RDJjbta0e)mi#2>XMP*$;!9)r%4~TU2UAmDuk@O-}|Ed(6Cl@(zec|i#ivk|Yq7>hnHx_t%qGd8z@b?~)y6DWhtXykC zh`;`vA_$%(9t*nnhg0d6s=Y+1To{w6Mi(|WPdjBy*6O{-ipWiNy3%Vv$~cv6tzmvV zSNa1Bn0p-%+c z8hKUl#F&kd7!l$h99b&9IA%|c+0$e8?3g_R`)G#M=hE}9=ooh1XF}9N==EiiwZylTAv;Nr4#xNF~Gw=TIAUp|0IWhjDgF)6wEGuBVU6s$i68MSC)-y7IohRMf zaezDr_lv6`hI7<=h2(nqdC=!Oo5evW`V{NMOlP6vPG$N!gXrUJEcjlk555E4$1BkF zS)tNTF!9ZXq|;hgoS|>l^LLq4AmZ>A4w0_MZ(Pp`s~q=3E>g#_)UyKB#7rs|-X|Sl06YVJ0Gz95 M@$9aGHL0Y30Z^?JZ2$lO diff --git a/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc531-s390x.obj b/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc531-s390x.obj deleted file mode 100644 index caacb9b90a58936dcbd4481ffaeaca6716aedece..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3864 zcmbuBO>7%Q6o6;fPGZZA^G8cUpe#}-sff4Uq)ppEiy=+gLWHVT6-5HIYiDCy_$OVj z`x8M4Hzc4a7r1aJm!3GJhawP2$+3vPa6ufnMM#x;DG~=H4&lA|v7g7@3p{!E&HLuP znc3O5^Zf4I!n|o3tRV*518o8tJJ{0eK zEwc9ejiz}wvbJ@D@qtRr7%-kr4kaSV(d2+J*wg7O5SQAxq|Dn2H{rOEmnjl zh8zgW%gpujIaVuF{h&2k4$Z?(zIxu8bsX!EJ!L!AWZIcdPdU?8s_go?!m*XPS!WWA z>4R`vL1d-!R%)phxVg7d%YHTRazWKk)dC;ZDCffY)$`SgD_(GY*~7J5VeI7W?2I*j zK3lH@buneinXGfu*{`iZ?9C&njFq#@xRx|VclF)kDaqIb;Kzjvn_=@G#6OIE)N`}@ z_sebEM<2;sdUyf1|Jci=du8mCD52MFIJe1z}};ZG5+#>4J$!p9IuIRIMuy{sVU zX~GF+#|VFubetgkOTu3v{4n8X3BO19>x4f^_$9(82`>;nM|hR+UkJzd2q#pVTpeuB zLp*8T?)0)6pPjw%;<_ODLqbgpby%n)LOIgss5H}zA3e+U zpr)^IZ2&1H*0BIpzz_t@Go+;B~ceeE+xyy8i+&+ykAT1BTC_a~Bw{UFVoQ|$k~hy!yLP=CxLIaH z!4bNkTE16u?ZCShFniGrTxMr$HD>!&VesBXFI&%FELN7P;KSQ)HtTy=zzu^X^4&__ z!_X!x6)Tbr2hCSy=pS>4)!+3iZDL9U<$F;kr@O`^Pg7g|7cH*mOMZAa2I5(s-UgY*POc z*kSYkE#q*XaR1c*7&`wuz}0x#bDDV8qNsHUtLcw%@52=qe_saJDo|?Wk9rL*WovE` zy^g4U>W}Y8*)%T!NAS5(P6^extLI1XIb0$87w?x5YX6k2;*n#W(!VqQ&e+PalnHnV8N;T&H7xx(+2><{9 diff --git a/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc540-mips.obj b/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc540-mips.obj deleted file mode 100644 index 270c7775968f0e6d74875fa017d5f153e88e0cf8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3064 zcmb7GU1%It6h3!$Hrcw_?WSq8nzR`uYoa#OZ5jiujYhND6suOO4?-lJO(vVg-PvV! z(xm<%3W5)6S|~n9(Si^5r9=>_qN#aMY!O88r4OQgl0L?QASkTgxpVJkvUv~>Idjf; z?sv~U_jmL9Y!LP5iI(3)hw-b~nDy5-vJ%;`H;ob?u|k)wl3-x5Mld`lRCHE5&J_$Sh4!QTVzn|I6Q>RxNH>X&C#`VnEQ-zmViV`qRYlvlVlE`M5oB6yOObVPr6g= z5E-zHeo7`EMu;e;Toi3?NAzeHQQQ`fbi~q!k`E;ZI=Ihx+xw4o2(+}tDU2WOGH%1D zN=!1|WtR)dz_+9&nk3^r_9vkyRQv?|DaD5?rB^Mk#%$%9s=%mh-y_7|=@el{dG1g_ za--~-kQSFabi2{tmAGW|f>*A3MN58oxfi^8spz@076TdG8rd2?^7Ql8#Qy!(gZ7A> zvxal~M{}dOgVs>RE#OnC)ej8A1`D1$79yYVTy1Fyrd+PizJD2;KK zBK~F<9e-|Um}bzpQJzEqF1I~df5$5 z*Ie#?is;D1#35@i?-ojq7tU#DE^nI@lNx_$pKWZ@TOu(+8v?*bt0}t2t`Q00>5^s8Az~`IU6kxvNO#$B71aN@wfYEcB z+7Yftv*t`lmK(vY#CnJ2QJJ2`(odJGGfsKBSfkoPP!Icnx|3_ecsseKexeS>gRqSE z5_R+1;pOhm!a}YmmF@eK9aVNr*}Sq( zD*J-6CzUNK>nZz+vTrE+wi@ppWzP^Lc-#+E`$c6@e;da!e_7uH%3>W-9LMhy;&%OX zC2$I`fgjp=?fGum4&0@H>{%yp$S&0DWczNhc;^~tWx zx`l-zw;UJ-y&CrAT(V(0>>c_}q2Rlxke|Eo-f@0SbbQAvx+=9|lss3nQ69C0ZZl+{M(!~RJAfAMm)ur}U9mJ876{~A0lmdREx~_FT00N%K!iX diff --git a/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc620-sparc64.obj b/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc620-sparc64.obj deleted file mode 100644 index d65c23e1cbeaad5acc30d7d256931443ac8aea2a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5952 zcmbtXYiwLc6`r|w?X2zCvE#Nlw4@t}CM~hob}%Ms)5c9m8aGvm1e6K_+kITytL&@y z?j{ZeHKaU@L~sL2RiPHOAgWLh4*@MgASyrz@uvm;L`Wbc5JLUeBGE#D@O?AquIFAm zf8c2E%sJnj$IO}MK79C|Bc7*Km$cdq-T}HTV75~5)Eq06*Q%{g{^=*j&kd`wS5II1 z^iOwPde}$9qr(pv6*}Sf@fZJ?jU6rpwOVsLce)wYDroW#sthV++c%TlfX0b=rnro9 zubF%PhjRQKnX#8K! zyn^W4`v9oSt0+p!@~?qk&079-^23(@2l+9}|C4;q@^6s8+4BD)KV|uUlizFk|B#>S zN2xLVZ~|mZZebkG{<}qVmJuq zQ_8k&kI@x_jw&WYZDEnow?TVF`27xlJ9*>u2`mloJHu4(c^2#m%YJ>0{YIDVeKWL5 zi03_z?{6cDwtqDSz1I^lJ4%~9K!-x(8pHJua4M8(EcqAC>aOS?@Gq=rGZ?k1^oYJ` zXmr3Ix_)RxZ{0NfCiuNh`9rr3+%_-|8~?3pVBik4V|cu4{u`$g=TAEh`Dhf!*?*7KvZ7~BCrlV}_oh3WonNbHRD0iy%k2n-8= zxE2`UV%nP52e#Q>@7l(J%#A&Ea2s8Y_H;YpVGWYT?Qvk%hDFxO@in%~y=e5G%jh?T z29*Y(1)rYmMB!wuTAExemnWlEF)Yu{Ow_84&ho@!qcb@>S#6YSol2mLq6ix(ma6S2 zp`(;J>GEZEA!=7D!9sqCA=_tKK?D{%7;&pjusAcJ(Phs>g&+)T)u?UNFbn3iqNnSQ z9rJt)pfLaLLaDP*2pSbtXx1u)=E6c0v{eM-2CNkoqT;E*XhciRu$|*U7*#(K6l}$g zz}DJP{d8Du2ZdG}#tXILVq|vtA5O2BAg6pjfe<+Z7Y7)-0b?wPs_{M7itU z_vH>vPv>Uyd-7AcJyX-OQ~Rc8aufA(t8@FQeYuIn+{8lEE|yPDw8CaPD7Ty8MAQyp zuL|W(SSUAZoqEG`U{7JXfb1Yj!N^DE?>Ss()jH@%s~M?cxOhqxB6PFcsydCRy4VOR zx$;smq(&LzUIRE*@mg&Z*0h-)w%LKgDYF(kw#l)X=rlS}P}yUYO(vK#o8xY1Iy2$x z#VQ8U2$tcz&?;7@Z3SyeZ@1Nqt=?f%m~gT-GiI(iVY4%sLT41sP8+#l3voncL=2>a z1b13?`nbS=nu$g1dJ}7!I;Q`2Sf|>>QY~;-gjqnQk?TqpC7e`iL8IAS;Bbu|sL6J{ zWn6MCpd;$8Lx*n7-TbbgR4q2_Qka<8Eqm;i)Y{`*0_v^TRWBXhSFQF=y6!tAk_EC7Lit z>G9!RVQ}1x3F7h2F_@>E)53fb!`+r3+Vj;A<9H4j8bRsc9v^z7Yw@}G7YwQtZY6U= z%!(XWeAuw>vHuw74H`+>lCW)&9f57IBAaK@{D zWniUWOX0t^xX1I{(f4FMd#Q6nOFq3DQ~F%@Aa5rM$B(|>z{=Z`!oMZ>9Vwja3FO_4 z!u2EfjhEhcT(2PSb0}Q>{RURv7n8Whbqw;JLE-4DzZh6~KThJ_wBWx?;hz=!w@F;B z2%g$^YD{qc6?Wo!EsOi9{Oe~0r!M=PI){Dk566$*E&4qFT)fZX=Kk#kpFX#Tfo76Y2DVfe2S#3qQR^5tf|9^mnrZ{T5_$4eX!YrF#! zMhjuFE+-ns@&8f|4zxI7&Rv=lVcZ45%lbAb{s(vEIfHbIe%Vio=fx<#I8IhnxXyMu zxG#8I)nX=9$9@R2Z?V7s#h!a6_9y#|ZVkzLU-w>%<57ucLTqo0oZ@4a_m4OjSyz7_ z$ARqFP2kkS^D0HT>WRD;L47E*M6@9l8wht z{%L$y%OCSbisx_Gid}oQGs)?FCu$={h54@3apm@xe0txBUiJmc=(DK#29^6Z5ua=7 QD)Ia0&_?3iyVQ;UU&XIN4FCWD diff --git a/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc720-riscv64.obj b/odiglet/pkg/allocator/debug/elf/testdata/go-relocation-test-gcc720-riscv64.obj deleted file mode 100644 index 91ae6487a3abc3313b48b02afb6fc6b6af5ba50d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9576 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 diff --git a/odiglet/pkg/allocator/debug/elf/testdata/hello-world-core.gz b/odiglet/pkg/allocator/debug/elf/testdata/hello-world-core.gz deleted file mode 100644 index 6d76ab0934a740bbd2966b9a56188c3881368183..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12678 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 Y@4Wcyk!Kd*zJ2x!==|qi55c|v1+3q&^Z)<= diff --git a/odiglet/pkg/allocator/debug/elf/testdata/hello.c b/odiglet/pkg/allocator/debug/elf/testdata/hello.c deleted file mode 100644 index 34d9ee7923..0000000000 --- a/odiglet/pkg/allocator/debug/elf/testdata/hello.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -void -main(int argc, char *argv[]) -{ - printf("hello, world\n"); -} diff --git a/odiglet/pkg/allocator/debug/elf/testdata/zdebug-test-gcc484-x86-64.obj b/odiglet/pkg/allocator/debug/elf/testdata/zdebug-test-gcc484-x86-64.obj deleted file mode 100644 index a595a01df45c31a5f266f71103eca7a835242996..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3216 zcmbtWeN0ygjgYPu^dzA;$T{`#d0 z;e*CPUV|3*M`tLiJmm}2>21~X3Bmece=xzOwGdZ*&CGi%aV&rAd}i5^LsO=W> z3Po5S|2fa7Nen}8Oh-&BqHp*DHNC}g6TGgpFeV9Y>0KPkPWo-G9UacnEnd}{PrUj4 z*Bgd}<>mI@x1P!3eaHGfoA>uOTw8pmt@6=1T^EXeWiB=MT)~64`?n3(^*wvW@tt|L zIypTl{+y-n#zN~CM{nj|H(fhCF}1mKWY}Gj@X|jY4(z_-`((_*AL%+iI_79w436pp zCr5P42h!(nUpTwYE%+n8OuLys*|q6M?s#gY2kkPOxAFJaSiMek2c+Mm~WZKo?run?0fx zbB|l*jZ|{m9irf|`#eani5?LN*49=exLvX$S^YM<)!R_pb5_R9U+`z zZqeCbhiC=pXmZ*^QMf1)>Ripub|tO9P9u& z|7*Mv$3o69{3wamk5z(LX6x@z!62j&7EJXr3$1K?A-1UXuaWfcG6{hG!5Ojrdjw-_ zP7I+duwW8p7Ft=~T5Mr4aNb0~j8LR3u)g~+thRrHR`yq(|6Lej_wT_Nn-d}{2?+gF z66@>2Mz#7DQlHKl^luG**!rCqgPe4qSd<9v44@BW7Fub2%6qXzE&d@gP!EJ6Wr4;~ z{wj%Q+)xucki>z;QUB8oDLEH027;t-6h6GZ%XM74A3>bYV4d(!{Ib?5!sIaA@snXN+(NPJT6U(uu6Z zVJGp5{?OkKI6KuW(!V&N4mFESPSoP{w95IYFC3$?ONp{sni<&b(y~l&Hv)lwlqAUu z8Dj|t8+~(_TOh#T`34kBG(W|?GK^9PXXiDG;NY)31%mB?q~d4h~7as+n?7M|5HSNhrt(! Zt~^I7gNe=qn?IYxu{cj~xLcI>%fF{QORN9@ diff --git a/odiglet/pkg/allocator/debug/elf/write.go b/odiglet/pkg/allocator/debug/elf/write.go deleted file mode 100644 index 06325e174c..0000000000 --- a/odiglet/pkg/allocator/debug/elf/write.go +++ /dev/null @@ -1,282 +0,0 @@ -package elf - -import ( - "bufio" - "bytes" - "encoding/binary" - "io/ioutil" - "log" - "sort" -) - -// Bytes - returns the bytes of an Elf file -func (f *File) Bytes() ([]byte, uint64, error) { - - bytesWritten := uint64(0) - elfBuf := bytes.NewBuffer(nil) - w := bufio.NewWriter(elfBuf) - - // Write Elf Magic - w.WriteByte('\x7f') - w.WriteByte('E') - w.WriteByte('L') - w.WriteByte('F') - bytesWritten += 4 - - // ident[EI_CLASS] - w.WriteByte(byte(f.Class)) - // ident[EI_DATA] - w.WriteByte(byte(f.Data)) - // ident[EI_VERSION] - w.WriteByte(byte(f.Version)) - // ident[EI_OSABI] - w.WriteByte(byte(f.OSABI)) - // ident[EI_ABIVERSION] - w.WriteByte(byte(f.ABIVersion)) - // ident[EI_PAD] ( 7 bytes ) - w.Write([]byte{0, 0, 0, 0, 0, 0, 0}) - bytesWritten += 12 - - // Type - binary.Write(w, f.ByteOrder, uint16(f.Type)) - // Machine - binary.Write(w, f.ByteOrder, uint16(f.Machine)) - // Version - binary.Write(w, f.ByteOrder, uint32(f.Version)) - bytesWritten += 8 - - phsize := 0 - - switch f.Class { - case ELFCLASS32: - phsize = 0x20 - // Entry 32 - binary.Write(w, f.ByteOrder, uint32(f.Entry)) - // PH Offset 32 - binary.Write(w, f.ByteOrder, uint32(0x34)) - // SH Offset 32 // 0x20 0x28 4 8 e_shoff Points to the start of the section header table. - binary.Write(w, f.ByteOrder, int32(f.FileHeader.SHTOffset)) - // Flags - binary.Write(w, f.ByteOrder, uint32(0)) // todo - // EH Size - binary.Write(w, f.ByteOrder, uint16(52)) - // PH Size // 0x2A 0x36 2 e_phentsize Contains the size of a program header table entry. - binary.Write(w, f.ByteOrder, uint16(phsize)) - // PH Num // 0x2C 0x38 2 e_phnum Contains the number of entries in the program header table. - binary.Write(w, f.ByteOrder, uint16(len(f.Progs))) - // SH Size // 0x2E 0x3A 2 e_shentsize Contains the size of a section header table entry. - binary.Write(w, f.ByteOrder, uint16(0x28)) - bytesWritten += 24 - - case ELFCLASS64: - phsize = 0x38 - // Entry 64 - binary.Write(w, f.ByteOrder, uint64(f.Entry)) - // PH Offset 64 - binary.Write(w, f.ByteOrder, uint64(0x40)) - // SH Offset 64 // 0x20 0x28 4 8 e_shoff Points to the start of the section header table. - binary.Write(w, f.ByteOrder, int64(f.FileHeader.SHTOffset)) - // Flags - binary.Write(w, f.ByteOrder, uint32(0)) // I think right? - // EH Size - binary.Write(w, f.ByteOrder, uint16(64)) - // PH Size // 0x2A 0x36 2 e_phentsize Contains the size of a program header table entry. - binary.Write(w, f.ByteOrder, uint16(phsize)) - // PH Num // 0x2C 0x38 2 e_phnum Contains the number of entries in the program header table. - binary.Write(w, f.ByteOrder, uint16(len(f.Progs))) - // SH Size // 0x2E 0x3A 2 e_shentsize Contains the size of a section header table entry. - binary.Write(w, f.ByteOrder, uint16(0x40)) - bytesWritten += 36 - } - - // SH Num // 0x30 0x3C 2 e_shnum Contains the number of entries in the section header table. - binary.Write(w, f.ByteOrder, uint16(len(f.Sections))) - // SH Str Ndx // 0x32 0x3E 2 e_shstrndx Contains index of the section header table entry that contains the section names. - binary.Write(w, f.ByteOrder, uint16(f.ShStrIndex)) - bytesWritten += 4 - - // Program Header - for _, p := range f.Progs { - // Type (segment) - binary.Write(w, f.ByteOrder, uint32(p.Type)) - bytesWritten += 4 - - switch f.Class { - case ELFCLASS32: - // Offset of Segment in File - binary.Write(w, f.ByteOrder, uint32(p.Off)) - - // Vaddr - binary.Write(w, f.ByteOrder, uint32(p.Vaddr)) - - // Paddr - binary.Write(w, f.ByteOrder, uint32(p.Paddr)) - - // File Size - binary.Write(w, f.ByteOrder, uint32(p.Filesz)) - - // Memory Size - binary.Write(w, f.ByteOrder, uint32(p.Memsz)) - - // Flags (segment) - binary.Write(w, f.ByteOrder, uint32(p.Flags)) - - // Alignment - binary.Write(w, f.ByteOrder, uint32(p.Align)) - - bytesWritten += 28 - - case ELFCLASS64: - // Flags (segment) - binary.Write(w, f.ByteOrder, uint32(p.Flags)) - - // Offset of Segment in File - binary.Write(w, f.ByteOrder, uint64(p.Off)) - - // Vaddr - binary.Write(w, f.ByteOrder, uint64(p.Vaddr)) - - // Paddr - binary.Write(w, f.ByteOrder, uint64(p.Paddr)) - - // File Size - binary.Write(w, f.ByteOrder, uint64(p.Filesz)) - - // Memory Size - binary.Write(w, f.ByteOrder, uint64(p.Memsz)) - - // Alignment - binary.Write(w, f.ByteOrder, uint64(p.Align)) - - bytesWritten += 52 - } - } - - sortedSections := make([]*Section, len(f.Sections)) - copy(sortedSections, f.Sections) - sort.Slice(sortedSections, func(a, b int) bool { return sortedSections[a].Offset < sortedSections[b].Offset }) - for _, s := range sortedSections { - - //log.Printf("Writing section: %s type: %+v\n", s.Name, s.Type) - //log.Printf("written: %x offset: %x\n", bytesWritten, s.Offset) - - if s.Type == SHT_NULL || s.Type == SHT_NOBITS || s.FileSize == 0 { - //log.Println("continuing...") - continue - } - - if bytesWritten > s.Offset { - log.Printf("Overlapping Sections in Generated Elf: %+v\n", s.Name) - continue - } - if s.Offset != 0 && bytesWritten < s.Offset { - pad := make([]byte, s.Offset-bytesWritten) - w.Write(pad) - //log.Printf("Padding before section %s at %x: length:%x to:%x\n", s.Name, bytesWritten, len(pad), s.Offset) - bytesWritten += uint64(len(pad)) - } - - slen := 0 - switch s.Type { - case SHT_DYNAMIC: - for _, taggedValue := range f.DynTags { - //log.Printf("writing %d (%x) -> %d (%x)\n", taggedValue.Tag, taggedValue.Tag, taggedValue.Value, taggedValue.Value) - switch f.Class { - case ELFCLASS32: - binary.Write(w, f.ByteOrder, uint32(taggedValue.Tag)) - binary.Write(w, f.ByteOrder, uint32(taggedValue.Value)) - bytesWritten += 8 - case ELFCLASS64: - binary.Write(w, f.ByteOrder, uint64(taggedValue.Tag)) - binary.Write(w, f.ByteOrder, uint64(taggedValue.Value)) - bytesWritten += 16 - } - } - default: - section, err := ioutil.ReadAll(s.Open()) - if err != nil { - return nil, 0, err - } - - binary.Write(w, f.ByteOrder, section) - slen = len(section) - //log.Printf("Wrote %s section at %x, length %x\n", s.Name, bytesWritten, slen) - bytesWritten += uint64(slen) - } - - // todo: f.Insertion should be renamed InsertionLoadEnd or similar - if s.Type == SHT_PROGBITS && len(f.Insertion) > 0 && s.Size-uint64(slen) >= uint64(len(f.Insertion)) { - binary.Write(w, f.ByteOrder, f.Insertion) - bytesWritten += uint64(len(f.Insertion)) - } - w.Flush() - } - - // Pad to Section Header Table - if bytesWritten < uint64(f.FileHeader.SHTOffset) { - pad := make([]byte, uint64(f.FileHeader.SHTOffset)-bytesWritten) - w.Write(pad) - log.Printf("Padding before SHT at %x: length:%x to:%x\n", bytesWritten, len(pad), f.FileHeader.SHTOffset) - bytesWritten += uint64(len(pad)) - } - - // Write Section Header Table - log.Printf("Start section header table at: %x\n", bytesWritten) - for _, s := range f.Sections { - switch f.Class { - case ELFCLASS32: - binary.Write(w, f.ByteOrder, &Section32{ - Name: s.Shname, - Type: uint32(s.Type), - Flags: uint32(s.Flags), - Addr: uint32(s.Addr), - Off: uint32(s.Offset), - Size: uint32(s.Size), - Link: s.Link, - Info: s.Info, - Addralign: uint32(s.Addralign), - Entsize: uint32(s.Entsize)}) - case ELFCLASS64: - binary.Write(w, f.ByteOrder, &Section64{ - Name: s.Shname, - Type: uint32(s.Type), - Flags: uint64(s.Flags), - Addr: s.Addr, - Off: s.Offset, - Size: s.Size, - Link: s.Link, - Info: s.Info, - Addralign: s.Addralign, - Entsize: s.Entsize}) - } - } - - // Do I have a PT_NOTE segment to add at the end? - - //if len(f.InsertionEOF) > 0 { - // binary.Write(w, f.ByteOrder, f.InsertionEOF) - // bytesWritten += uint64(len(f.InsertionEOF)) - //} - - w.Flush() - return elfBuf.Bytes(), bytesWritten, nil -} - -//// WriteFile - Creates a new file and writes it using the Bytes func above -//func (elfFile *File) WriteFile(destFile string) error { -// f, err := os.Create(destFile) -// if err != nil { -// return err -// } -// defer f.Close() -// elfData, err := f.Bytes() -// if err != nil { -// return err -// } -// _, err = f.Write(elfData) -// if err != nil { -// return err -// } -// -// return nil -//} diff --git a/odiglet/pkg/allocator/debug/goobj2/file.go b/odiglet/pkg/allocator/debug/goobj2/file.go deleted file mode 100644 index eb5b783323..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/file.go +++ /dev/null @@ -1,929 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package goobj implements reading of Go object files and archives. - -// This file is a modified version of cmd/internal/goobj/readnew.go - -package goobj2 - -import ( - "bufio" - "bytes" - "errors" - "fmt" - "github.com/keyval-dev/odigos/odiglet/pkg/allocator/debug/goobj2/internal/goobj2" - "github.com/keyval-dev/odigos/odiglet/pkg/allocator/debug/goobj2/internal/objabi" - "io" - "io/ioutil" - "net/url" - "os" - "os/exec" - "path/filepath" - "strconv" - "strings" -) - -const ( - CompilerObjName = "__.PKGDEF" - - archiveHeaderLen = 60 -) - -// A Package is a parsed Go object file or archive defining a Go package. -type Package struct { - ArchiveMembers []ArchiveMember - ImportPath string - - os string - arch string -} - -func (p Package) OS() string { - return p.os -} - -func (p Package) Arch() string { - return p.arch -} - -type ArchiveMember struct { - ArchiveHeader ArchiveHeader - ObjHeader goobj2.Header - Imports []goobj2.ImportedPkg - Packages []string - DWARFFileList []string - SymDefs []*Sym - NonPkgSymDefs []*Sym - NonPkgSymRefs []*Sym - SymRefs []SymRef - - IsDataObj bool - - textSyms []*Sym - - symMap map[int]*Sym -} - -func (a ArchiveMember) IsCompilerObj() bool { - return a.ArchiveHeader.Name == CompilerObjName -} - -type ArchiveHeader struct { - Name string - Date string - UID string - GID string - Mode string - Size int64 - Data []byte -} - -// A Sym is a named symbol in an object file. -type Sym struct { - Name string - ABI uint16 - Kind SymKind // kind of symbol - Flag uint8 - Size uint32 // size of corresponding data - Align uint32 - Type *SymRef // symbol for Go type information - Data []byte // memory image of symbol - Reloc []Reloc // relocations to apply to Data - Func *Func // additional data for functions -} - -type SymRef struct { - Name string - goobj2.SymRef -} - -// A Reloc describes a relocation applied to a memory image to refer -// to an address within a particular symbol. -type Reloc struct { - Name string - // The bytes at [Offset, Offset+Size) within the containing Sym - // should be updated to refer to the address Add bytes after the start - // of the symbol Sym. - Offset int64 - Size int64 - Sym goobj2.SymRef - Add int64 - - // The Type records the form of address expected in the bytes - // described by the previous fields: absolute, PC-relative, and so on. - // TODO(rsc): The interpretation of Type is not exposed by this package. - Type objabi.RelocType -} - -// Func contains additional per-symbol information specific to functions. -type Func struct { - Args int64 // size in bytes of argument frame: inputs and outputs - Frame int64 // size in bytes of local variable frame - PCSP []byte // PC → SP offset map - PCFile []byte // PC → file number map (index into File) - PCLine []byte // PC → line number map - PCInline []byte // PC → inline tree index map - PCData [][]byte // PC → runtime support data map - FuncData []FuncData // non-PC-specific runtime support data - File []SymRef // paths indexed by PCFile - InlTree []*InlinedCall - - FuncInfo *SymRef - DwarfInfo *SymRef - DwarfLoc *SymRef - DwarfRanges *SymRef - DwarfDebugLines *SymRef - - dataSymIdx int -} - -// A FuncData is a single function-specific data value. -type FuncData struct { - Sym *SymRef // symbol holding data - Offset uint32 // offset into symbol for funcdata pointer -} - -// An InlinedCall is a node in an InlTree. -// See cmd/internal/obj.InlTree for details. -type InlinedCall struct { - Parent int32 - File SymRef - Line int32 - Func SymRef - ParentPC int32 -} - -// A SymKind describes the kind of memory represented by a symbol. -type SymKind uint8 - -// Defined SymKind values. -// Copied from cmd/internal/objabi -const ( - // An otherwise invalid zero value for the type - Sxxx SymKind = iota - // Executable instructions - STEXT - // Read only static data - SRODATA - // Static data that does not contain any pointers - SNOPTRDATA - // Static data - SDATA - // Statically data that is initially all 0s - SBSS - // Statically data that is initially all 0s and does not contain pointers - SNOPTRBSS - // Thread-local data that is initially all 0s - STLSBSS - // Debugging data - SDWARFINFO - SDWARFRANGE - SDWARFLOC - SDWARFLINES - // ABI alias. An ABI alias symbol is an empty symbol with a - // single relocation with 0 size that references the native - // function implementation symbol. - // - // TODO(austin): Remove this and all uses once the compiler - // generates real ABI wrappers rather than symbol aliases. - SABIALIAS - // Coverage instrumentation counter for libfuzzer. - SLIBFUZZER_EXTRA_COUNTER -) - -type ImportCfg struct { - ImportMap map[string]string - Packages map[string]ExportInfo -} - -type ExportInfo struct { - Path string - IsSharedLib bool -} - -func ParseImportCfg(path string) (importCfg ImportCfg, err error) { - data, err := ioutil.ReadFile(path) - if err != nil { - return importCfg, fmt.Errorf("error reading importcfg: %v", err) - } - - lines := bytes.Count(data, []byte("\n")) - if lines == -1 { - return importCfg, errors.New("error parsing importcfg: could not find any newlines") - } - - importCfg.ImportMap = make(map[string]string) - importCfg.Packages = make(map[string]ExportInfo, lines) - - for lineNum, line := range strings.Split(string(data), "\n") { - lineNum++ // 1-based - line = strings.TrimSpace(line) - if line == "" { - continue - } - if line == "" || strings.HasPrefix(line, "#") { - continue - } - - var verb, args string - if i := strings.Index(line, " "); i < 0 { - verb = line - } else { - verb, args = line[:i], strings.TrimSpace(line[i+1:]) - } - var before, after string - if i := strings.Index(args, "="); i >= 0 { - before, after = args[:i], args[i+1:] - } - switch verb { - default: - return importCfg, fmt.Errorf("error parsing importcfg: %s:%d: unknown directive %q", path, lineNum, verb) - case "importmap": - if before == "" || after == "" { - return importCfg, fmt.Errorf(`error parsing importcfg: %s:%d: invalid importmap: syntax is "importmap path=path"`, path, lineNum) - } - importCfg.ImportMap[before] = after - case "packagefile": - if before == "" || after == "" { - return importCfg, fmt.Errorf(`error parsing importcfg: %s:%d: invalid packagefile: syntax is "packagefile path=filename"`, path, lineNum) - } - importCfg.Packages[before] = ExportInfo{after, false} - case "packageshlib": - if before == "" || after == "" { - return importCfg, fmt.Errorf(`error parsing importcfg: %s:%d: invalid packageshlib: syntax is "packageshlib path=filename"`, path, lineNum) - } - importCfg.Packages[before] = ExportInfo{after, true} - } - } - - return importCfg, nil -} - -var ( - archiveHeader = []byte("!\n") - archiveMagic = []byte("`\n") - goobjHeader = []byte("go objec") // truncated to size of archiveHeader - - archivePathPrefix = filepath.Join("$GOROOT", "pkg") - - errCorruptArchive = errors.New("corrupt archive") - errTruncatedArchive = errors.New("truncated archive") - errCorruptObject = errors.New("corrupt object file") - errNotObject = errors.New("unrecognized object file format") -) - -// An objReader is an object file reader. -type objReader struct { - p *Package - b *bufio.Reader - f *os.File - err error - offset int64 - limit int64 - tmp [256]byte - pkgprefix string - objStart int64 -} - -// init initializes r to read package p from f. -func (r *objReader) init(f *os.File, p *Package) { - r.f = f - r.p = p - r.offset, _ = f.Seek(0, io.SeekCurrent) - r.limit, _ = f.Seek(0, io.SeekEnd) - f.Seek(r.offset, io.SeekStart) - r.b = bufio.NewReader(f) - if p != nil { - r.pkgprefix = objabi.PathToPrefix(p.ImportPath) + "." - } -} - -// error records that an error occurred. -// It returns only the first error, so that an error -// caused by an earlier error does not discard information -// about the earlier error. -func (r *objReader) error(err error) error { - if r.err == nil { - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - r.err = err - } - // panic("corrupt") // useful for debugging - return r.err -} - -// peek returns the next n bytes without advancing the reader. -func (r *objReader) peek(n int) ([]byte, error) { - if r.err != nil { - return nil, r.err - } - if r.offset >= r.limit { - r.error(io.ErrUnexpectedEOF) - return nil, r.err - } - b, err := r.b.Peek(n) - if err != nil { - if err != bufio.ErrBufferFull { - r.error(err) - } - } - return b, err -} - -// readByte reads and returns a byte from the input file. -// On I/O error or EOF, it records the error but returns byte 0. -// A sequence of 0 bytes will eventually terminate any -// parsing state in the object file. In particular, it ends the -// reading of a varint. -func (r *objReader) readByte() byte { - if r.err != nil { - return 0 - } - if r.offset >= r.limit { - r.error(io.ErrUnexpectedEOF) - return 0 - } - b, err := r.b.ReadByte() - if err != nil { - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - r.error(err) - b = 0 - } else { - r.offset++ - } - return b -} - -// read reads exactly len(b) bytes from the input file. -// If an error occurs, read returns the error but also -// records it, so it is safe for callers to ignore the result -// as long as delaying the report is not a problem. -func (r *objReader) readFull(b []byte) error { - if r.err != nil { - return r.err - } - if r.offset+int64(len(b)) > r.limit { - return r.error(io.ErrUnexpectedEOF) - } - n, err := io.ReadFull(r.b, b) - r.offset += int64(n) - if err != nil { - return r.error(err) - } - return nil -} - -// readInt reads a zigzag varint from the input file. -func (r *objReader) readInt() int64 { - var u uint64 - - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - r.error(errCorruptObject) - return 0 - } - c := r.readByte() - u |= uint64(c&0x7F) << shift - if c&0x80 == 0 { - break - } - } - - return int64(u>>1) ^ (int64(u) << 63 >> 63) -} - -// skip skips n bytes in the input. -func (r *objReader) skip(n int64) { - if n < 0 { - r.error(fmt.Errorf("debug/goobj: internal error: misuse of skip")) - } - if n < int64(len(r.tmp)) { - // Since the data is so small, a just reading from the buffered - // reader is better than flushing the buffer and seeking. - r.readFull(r.tmp[:n]) - } else if n <= int64(r.b.Buffered()) { - // Even though the data is not small, it has already been read. - // Advance the buffer instead of seeking. - for n > int64(len(r.tmp)) { - r.readFull(r.tmp[:]) - n -= int64(len(r.tmp)) - } - r.readFull(r.tmp[:n]) - } else { - // Seek, giving up buffered data. - _, err := r.f.Seek(r.offset+n, io.SeekStart) - if err != nil { - r.error(err) - } - r.offset += n - r.b.Reset(r.f) - } -} - -// ImportMap is a function that returns the path of a Go object -// from a given import path. If the import path is not known, -// an empty string should be returned. -type ImportMap = func(importPath string) (objectPath string) - -// Parse parses an object file or archive from objPath, assuming that -// its import path is pkgpath. A function that returns paths of object -// files from import paths can optionally be passed in as importMap -// to optimize looking up paths to dependencies' object files. -func Parse(objPath, pkgPath string, importMap ImportMap) (*Package, error) { - p := new(Package) - p.ImportPath = pkgPath - - if _, err := parse(objPath, p, importMap, false); err != nil { - return nil, err - } - - return p, nil -} - -func parse(objPath string, p *Package, importMap ImportMap, returnReader bool) (rr *goobj2.Reader, err error) { - f, openErr := os.Open(objPath) - if err != nil { - return nil, openErr - } - defer func() { - closeErr := f.Close() - if closeErr != nil && err == nil { - err = closeErr - } - }() - - var rd objReader - rd.init(f, p) - err = rd.readFull(rd.tmp[:8]) - if err != nil { - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - return nil, err - } - - switch { - default: - return nil, errNotObject - case bytes.Equal(rd.tmp[:8], archiveHeader): - rr, err = rd.parseArchive(importMap, returnReader) - if err != nil { - return nil, err - } - case bytes.Equal(rd.tmp[:8], goobjHeader): - var am *ArchiveMember - rr, am, _, err = rd.parseObject(goobjHeader, importMap, returnReader) - if err != nil { - return nil, err - } - p.ArchiveMembers = append(p.ArchiveMembers, *am) - } - - return rr, nil -} - -// trimSpace removes trailing spaces from b and returns the corresponding string. -// This effectively parses the form used in archive headers. -func trimSpace(b []byte) string { - return string(bytes.TrimRight(b, " ")) -} - -// parseArchive parses a Unix archive of Go object files. -func (r *objReader) parseArchive(importMap ImportMap, returnReader bool) (*goobj2.Reader, error) { - for r.offset < r.limit { - if err := r.readFull(r.tmp[:archiveHeaderLen]); err != nil { - return nil, err - } - data := r.tmp[:archiveHeaderLen] - - // Each file is preceded by this text header (slice indices in first column): - // 0:16 name - // 16:28 date - // 28:34 uid - // 34:40 gid - // 40:48 mode - // 48:58 size - // 58:60 magic - `\n - // The fields are space-padded on the right. - // The size is in decimal. - // The file data - size bytes - follows the header. - // Headers are 2-byte aligned, so if size is odd, an extra padding - // byte sits between the file data and the next header. - // The file data that follows is padded to an even number of bytes: - // if size is odd, an extra padding byte is inserted between the next header. - if len(data) < archiveHeaderLen { - return nil, errTruncatedArchive - } - if !bytes.Equal(data[58:60], archiveMagic) { - return nil, errCorruptArchive - } - - var ar ArchiveHeader - ar.Name = trimSpace(data[0:16]) - ar.Date = trimSpace(data[16:28]) - ar.UID = trimSpace(data[28:34]) - ar.GID = trimSpace(data[34:40]) - ar.Mode = trimSpace(data[40:48]) - size, err := strconv.ParseInt(trimSpace(data[48:58]), 10, 64) - if err != nil { - return nil, errCorruptArchive - } - - data = data[archiveHeaderLen:] - fsize := size + size&1 - if fsize < 0 || fsize < size { - return nil, errCorruptArchive - } - ar.Size = size - - var am *ArchiveMember - switch ar.Name { - case CompilerObjName: - ar.Data = make([]byte, size) - if err := r.readFull(ar.Data); err != nil { - return nil, err - } - if fsize != size { - ar.Data = append(ar.Data, 0x00) - } - - am = new(ArchiveMember) - am.ArchiveHeader = ar - am.IsDataObj = true - default: - oldLimit := r.limit - r.limit = r.offset + size - - p, err := r.peek(8) - if err != nil { - return nil, err - } - if bytes.Equal(p, goobjHeader) { - var rr *goobj2.Reader - rr, am, data, err = r.parseObject(nil, importMap, returnReader) - if err != nil { - return nil, fmt.Errorf("parsing archive member %q: %v", ar.Name, err) - } - if returnReader { - return rr, nil - } - ar.Data = data - am.ArchiveHeader = ar - } else { - ar.Data = make([]byte, size) - if err := r.readFull(ar.Data); err != nil { - return nil, err - } - if fsize != size { - ar.Data = append(ar.Data, 0x00) - } - am = &ArchiveMember{ArchiveHeader: ar, IsDataObj: true} - } - - r.skip(r.limit - r.offset) - r.limit = oldLimit - } - if size&1 != 0 { - r.skip(1) - } - - if r.p != nil && am != nil { - r.p.ArchiveMembers = append(r.p.ArchiveMembers, *am) - } - } - - return nil, nil -} - -// parseObject parses a single Go object file. -// The prefix is the bytes already read from the file, -// typically in order to detect that this is an object file. -// The object file consists of a textual header ending in "\n!\n" -// and then the part we want to parse begins. -// The format of that part is defined in a comment at the top -// of src/liblink/objfile.c. -func (r *objReader) parseObject(prefix []byte, importMap ImportMap, returnReader bool) (*goobj2.Reader, *ArchiveMember, []byte, error) { - h := make([]byte, 0, 256) - h = append(h, prefix...) - var c1, c2, c3 byte - for { - c1, c2, c3 = c2, c3, r.readByte() - h = append(h, c3) - // The new export format can contain 0 bytes. - // Don't consider them errors, only look for r.err != nil. - if r.err != nil { - return nil, nil, nil, errCorruptObject - } - if c1 == '\n' && c2 == '!' && c3 == '\n' { - break - } - } - - hs := strings.Fields(string(h)) - if len(hs) >= 4 && r.p != nil { - r.p.os = hs[2] - r.p.arch = hs[3] - } - - p, err := r.peek(8) - if err != nil { - return nil, nil, nil, err - } - if !bytes.Equal(p, []byte(goobj2.Magic)) { - return nil, nil, nil, errNotObject - } - - r.objStart = r.offset - length := r.limit - r.offset - objbytes := make([]byte, length) - r.readFull(objbytes) - rr := goobj2.NewReaderFromBytes(objbytes, false) - if rr == nil { - return nil, nil, nil, errCorruptObject - } - if returnReader { - return rr, nil, nil, nil - } - - var am ArchiveMember - am.symMap = make(map[int]*Sym) - - // Header - am.ObjHeader = rr.Header() - - // Imports - for _, p := range rr.Autolib() { - am.Imports = append(am.Imports, p) - } - - // Referenced packages - am.Packages = rr.Pkglist() - am.Packages = am.Packages[1:] // skip first package which is always an empty string - - // Dwarf file table - am.DWARFFileList = make([]string, rr.NDwarfFile()) - for i := 0; i < len(am.DWARFFileList); i++ { - am.DWARFFileList[i] = rr.DwarfFile(i) - } - - // Name of referenced indexed symbols. - nrefName := rr.NRefName() - refNames := make(map[goobj2.SymRef]string, nrefName) - am.SymRefs = make([]SymRef, 0, nrefName) - for i := 0; i < nrefName; i++ { - rn := rr.RefName(i) - sym, name := rn.Sym(), rn.Name(rr) - refNames[sym] = name - am.SymRefs = append(am.SymRefs, SymRef{name, sym}) - } - - resolveSymRefName := func(s goobj2.SymRef) string { - var i int - switch p := s.PkgIdx; p { - case goobj2.PkgIdxInvalid: - if s.SymIdx != 0 { - panic("bad sym ref") - } - return "" - case goobj2.PkgIdxNone: - i = int(s.SymIdx) + rr.NSym() - case goobj2.PkgIdxBuiltin: - name, _ := goobj2.BuiltinName(int(s.SymIdx)) - return name - case goobj2.PkgIdxSelf: - i = int(s.SymIdx) - default: - return refNames[s] - } - sym := rr.Sym(i) - return sym.Name(rr) - } - - // Symbols - pcdataBase := rr.PcdataBase() - ndef := rr.NSym() + rr.NNonpkgdef() - var inlFuncsToResolve []*InlinedCall - - parseSym := func(i, j int, symDefs []*Sym) { - osym := rr.Sym(i) - - sym := &Sym{ - Name: osym.Name(rr), - ABI: osym.ABI(), - Kind: SymKind(osym.Type()), - Flag: osym.Flag(), - Size: osym.Siz(), - Align: osym.Align(), - } - symDefs[j] = sym - am.symMap[i] = sym - - if i >= ndef { - return // not a defined symbol from here - } - - if sym.Kind == STEXT { - am.textSyms = append(am.textSyms, sym) - } - - // Symbol data - sym.Data = rr.Data(i) - - // Reloc - relocs := rr.Relocs(i) - sym.Reloc = make([]Reloc, len(relocs)) - for j := range relocs { - rel := &relocs[j] - s := rel.Sym() - sym.Reloc[j] = Reloc{ - Name: resolveSymRefName(s), - Offset: int64(rel.Off()), - Size: int64(rel.Siz()), - Type: objabi.RelocType(rel.Type()), - Add: rel.Add(), - Sym: s, - } - } - - // Aux symbol info - isym := -1 - funcdata := make([]*SymRef, 0, 4) - var funcInfo, dinfo, dloc, dranges, dlines *SymRef - auxs := rr.Auxs(i) - for j := range auxs { - a := &auxs[j] - switch a.Type() { - case goobj2.AuxGotype: - s := a.Sym() - sym.Type = &SymRef{resolveSymRefName(s), s} - case goobj2.AuxFuncInfo: - sr := a.Sym() - if sr.PkgIdx != goobj2.PkgIdxSelf { - panic("funcinfo symbol not defined in current package") - } - funcInfo = &SymRef{resolveSymRefName(sr), sr} - isym = int(a.Sym().SymIdx) - case goobj2.AuxFuncdata: - sr := a.Sym() - funcdata = append(funcdata, &SymRef{resolveSymRefName(sr), sr}) - case goobj2.AuxDwarfInfo: - sr := a.Sym() - dinfo = &SymRef{resolveSymRefName(sr), sr} - case goobj2.AuxDwarfLoc: - sr := a.Sym() - dloc = &SymRef{resolveSymRefName(sr), sr} - case goobj2.AuxDwarfRanges: - sr := a.Sym() - dranges = &SymRef{resolveSymRefName(sr), sr} - case goobj2.AuxDwarfLines: - sr := a.Sym() - dlines = &SymRef{resolveSymRefName(sr), sr} - default: - panic("unknown aux type") - } - } - - // Symbol Info - if isym == -1 { - return - } - b := rr.Data(isym) - info := goobj2.FuncInfo{} - info.Read(b) - - info.Pcdata = append(info.Pcdata, info.PcdataEnd) // for the ease of knowing where it ends - f := &Func{ - Args: int64(info.Args), - Frame: int64(info.Locals), - PCSP: rr.BytesAt(pcdataBase+info.Pcsp, int(info.Pcfile-info.Pcsp)), - PCFile: rr.BytesAt(pcdataBase+info.Pcfile, int(info.Pcline-info.Pcfile)), - PCLine: rr.BytesAt(pcdataBase+info.Pcline, int(info.Pcinline-info.Pcline)), - PCInline: rr.BytesAt(pcdataBase+info.Pcinline, int(info.Pcdata[0]-info.Pcinline)), - PCData: make([][]byte, len(info.Pcdata)-1), // -1 as we appended one above - FuncData: make([]FuncData, len(info.Funcdataoff)), - File: make([]SymRef, len(info.File)), - InlTree: make([]*InlinedCall, len(info.InlTree)), - FuncInfo: funcInfo, - dataSymIdx: isym, - } - sym.Func = f - for k := range f.PCData { - f.PCData[k] = rr.BytesAt(pcdataBase+info.Pcdata[k], int(info.Pcdata[k+1]-info.Pcdata[k])) - } - for k := range f.FuncData { - f.FuncData[k] = FuncData{funcdata[k], info.Funcdataoff[k]} - } - for k := range f.File { - f.File[k] = SymRef{resolveSymRefName(info.File[k]), info.File[k]} - } - for k := range f.InlTree { - inl := &info.InlTree[k] - f.InlTree[k] = &InlinedCall{ - Parent: inl.Parent, - File: SymRef{resolveSymRefName(inl.File), inl.File}, - Line: inl.Line, - Func: SymRef{resolveSymRefName(inl.Func), inl.Func}, - ParentPC: inl.ParentPC, - } - - if f.InlTree[k].Func.Name == "" { - inlFuncsToResolve = append(inlFuncsToResolve, f.InlTree[k]) - } - } - if dinfo != nil { - f.DwarfInfo = dinfo - } - if dloc != nil { - f.DwarfLoc = dloc - } - if dranges != nil { - f.DwarfRanges = dranges - } - if dlines != nil { - f.DwarfDebugLines = dlines - } - } - - // Symbol definitions - nsymDefs := rr.NSym() - am.SymDefs = make([]*Sym, nsymDefs) - for i := 0; i < nsymDefs; i++ { - parseSym(i, i, am.SymDefs) - } - - // Non-pkg symbol definitions - nNonPkgDefs := rr.NNonpkgdef() - am.NonPkgSymDefs = make([]*Sym, nNonPkgDefs) - parsedSyms := nsymDefs - for i := 0; i < nNonPkgDefs; i++ { - parseSym(i+parsedSyms, i, am.NonPkgSymDefs) - } - - // Non-pkg symbol references - nNonPkgRefs := rr.NNonpkgref() - am.NonPkgSymRefs = make([]*Sym, nNonPkgRefs) - parsedSyms += nNonPkgDefs - for i := 0; i < nNonPkgRefs; i++ { - parseSym(i+parsedSyms, i, am.NonPkgSymRefs) - } - - // Symbol references were already parsed above - - // Resolve missing inlined function names - if len(inlFuncsToResolve) == 0 { - return nil, &am, h, nil - } - - objReaders := make([]*goobj2.Reader, len(am.Packages)) - for _, inl := range inlFuncsToResolve { - if pkgIdx := inl.Func.PkgIdx; objReaders[pkgIdx-1] == nil { - pkgName := am.Packages[pkgIdx-1] - archivePath, err := getArchivePath(pkgName, importMap) - if err != nil { - return nil, nil, nil, fmt.Errorf("error resolving path of objfile %s: %v", pkgName, err) - } - rr, err := parse(archivePath, nil, nil, true) - if err != nil { - return nil, nil, nil, fmt.Errorf("error parsing objfile %s: %v", pkgName, err) - } - objReaders[pkgIdx-1] = rr - } - - rr := objReaders[inl.Func.PkgIdx-1] - inl.Func.Name = rr.Sym(int(inl.Func.SymIdx)).Name(rr) - } - - return nil, &am, h, nil -} - -func getArchivePath(pkg string, importMap ImportMap) (s string, err error) { - // try to get the archive path from the importMap first - if importMap != nil { - if path := importMap(pkg); path != "" { - return path, nil - } - } - - // for whatever reason, the Go compiler will url-encode - // packages paths that have certain symbols in them, - // like a period. ex gopkg.in/yaml.v2 => gopkg/in/yaml%2ev2 - if strings.ContainsRune(pkg, '%') { - pkg, err = url.QueryUnescape(pkg) - if err != nil { - return "", err - } - } - - cmd := exec.Command("go", "list", "-export", "-f", "{{.Export}}", pkg) - path, err := cmd.Output() - if err != nil { - return "", err - } - - return strings.TrimSpace(string(path)), nil -} diff --git a/odiglet/pkg/allocator/debug/goobj2/file_test.go b/odiglet/pkg/allocator/debug/goobj2/file_test.go deleted file mode 100644 index 5cab08b0a9..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/file_test.go +++ /dev/null @@ -1,92 +0,0 @@ -package goobj2 - -import ( - "bytes" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "strings" - "testing" -) - -func getNewObjPath(objPath string) string { - return filepath.Join(filepath.Dir(objPath), "new_"+filepath.Base(objPath)) -} - -type test struct { - name string - path string - pkg string - obj bool -} - -func TestWrite(t *testing.T) { - var tests []test - - filepath.Walk("testdata", func(path string, info os.FileInfo, err error) error { - if err != nil { - t.Fatalf("failed to walk testdata dir: %v", err) - } - - if info.IsDir() { - return nil - } - - tests = append(tests, test{info.Name(), path, "", false}) - - return nil - }) - - tempDir := t.TempDir() - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - basename := strings.TrimSuffix(tt.name, filepath.Ext(tt.name)) - var objPath string - if tt.obj { - objPath = tt.path - } else { - objPath = filepath.Join(tempDir, basename+".o") - cmd := exec.Command("go", "tool", "compile", "-o", objPath, tt.path) - if err := cmd.Run(); err != nil { - t.Fatalf("failed to compile: %v", err) - } - } - - // parse obj file - pkg, err := Parse(objPath, tt.pkg) - if err != nil { - t.Fatalf("failed to parse object file: %v", err) - } - //ioutil.WriteFile(objPath+"_parsed", []byte(pretty.Sprint(pkg)), 0777) - - // write obj file - newObjPath := getNewObjPath(objPath) - WriteObjFile2(pkg, newObjPath) - - // compare bytes of the original and written object files - objBytes, err := ioutil.ReadFile(objPath) - if err != nil { - t.Fatalf("failed to read object file: %v", err) - } - newObjBytes, err := ioutil.ReadFile(newObjPath) - if err != nil { - t.Fatalf("failed to read new object file: %v", err) - } - - if !bytes.Equal(objBytes, newObjBytes) { - t.Error("object files are not the same") - } - - // compare parsed packages of the two object files - _, err = Parse(newObjPath, tt.pkg) - if err != nil { - t.Fatalf("failed to parse new object file: %v", err) - } - - /*if !reflect.DeepEqual(pkg, pkg2) { - t.Errorf("Packages are not equal:\n%v", strings.Join(pretty.Diff(pkg, pkg2), "\n")) - }*/ - }) - } -} diff --git a/odiglet/pkg/allocator/debug/goobj2/internal/bio/buf.go b/odiglet/pkg/allocator/debug/goobj2/internal/bio/buf.go deleted file mode 100644 index 470c9797b2..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/internal/bio/buf.go +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package bio implements common I/O abstractions used within the Go toolchain. -package bio - -import ( - "bufio" - "io" - "log" - "os" -) - -// Reader implements a seekable buffered io.Reader. -type Reader struct { - f *os.File - *bufio.Reader -} - -// Writer implements a seekable buffered io.Writer. -type Writer struct { - f *os.File - *bufio.Writer -} - -// Create creates the file named name and returns a Writer -// for that file. -func Create(name string) (*Writer, error) { - f, err := os.Create(name) - if err != nil { - return nil, err - } - return &Writer{f: f, Writer: bufio.NewWriter(f)}, nil -} - -// Open returns a Reader for the file named name. -func Open(name string) (*Reader, error) { - f, err := os.Open(name) - if err != nil { - return nil, err - } - return &Reader{f: f, Reader: bufio.NewReader(f)}, nil -} - -func (r *Reader) MustSeek(offset int64, whence int) int64 { - if whence == 1 { - offset -= int64(r.Buffered()) - } - off, err := r.f.Seek(offset, whence) - if err != nil { - log.Fatalf("seeking in output: %v", err) - } - r.Reset(r.f) - return off -} - -func (w *Writer) MustSeek(offset int64, whence int) int64 { - if err := w.Flush(); err != nil { - log.Fatalf("writing output: %v", err) - } - off, err := w.f.Seek(offset, whence) - if err != nil { - log.Fatalf("seeking in output: %v", err) - } - return off -} - -func (r *Reader) Offset() int64 { - off, err := r.f.Seek(0, 1) - if err != nil { - log.Fatalf("seeking in output [0, 1]: %v", err) - } - off -= int64(r.Buffered()) - return off -} - -func (w *Writer) Offset() int64 { - if err := w.Flush(); err != nil { - log.Fatalf("writing output: %v", err) - } - off, err := w.f.Seek(0, 1) - if err != nil { - log.Fatalf("seeking in output [0, 1]: %v", err) - } - return off -} - -func (r *Reader) Close() error { - return r.f.Close() -} - -func (w *Writer) Close() error { - err := w.Flush() - err1 := w.f.Close() - if err == nil { - err = err1 - } - return err -} - -func (r *Reader) File() *os.File { - return r.f -} - -func (w *Writer) File() *os.File { - return w.f -} - -// Slice reads the next length bytes of r into a slice. -// -// This slice may be backed by mmap'ed memory. Currently, this memory -// will never be unmapped. The second result reports whether the -// backing memory is read-only. -func (r *Reader) Slice(length uint64) ([]byte, bool, error) { - if length == 0 { - return []byte{}, false, nil - } - - data, ok := r.sliceOS(length) - if ok { - return data, true, nil - } - - data = make([]byte, length) - _, err := io.ReadFull(r, data) - if err != nil { - return nil, false, err - } - return data, false, nil -} - -// SliceRO returns a slice containing the next length bytes of r -// backed by a read-only mmap'd data. If the mmap cannot be -// established (limit exceeded, region too small, etc) a nil slice -// will be returned. If mmap succeeds, it will never be unmapped. -func (r *Reader) SliceRO(length uint64) []byte { - data, ok := r.sliceOS(length) - if ok { - return data - } - return nil -} diff --git a/odiglet/pkg/allocator/debug/goobj2/internal/bio/buf_mmap.go b/odiglet/pkg/allocator/debug/goobj2/internal/bio/buf_mmap.go deleted file mode 100644 index 89ae39f736..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/internal/bio/buf_mmap.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd -// +build darwin dragonfly freebsd linux netbsd openbsd - -package bio - -import ( - "runtime" - "sync/atomic" - "syscall" -) - -// mmapLimit is the maximum number of mmaped regions to create before -// falling back to reading into a heap-allocated slice. This exists -// because some operating systems place a limit on the number of -// distinct mapped regions per process. As of this writing: -// -// Darwin unlimited -// DragonFly 1000000 (vm.max_proc_mmap) -// FreeBSD unlimited -// Linux 65530 (vm.max_map_count) // TODO: query /proc/sys/vm/max_map_count? -// NetBSD unlimited -// OpenBSD unlimited -var mmapLimit int32 = 1<<31 - 1 - -func init() { - // Linux is the only practically concerning OS. - if runtime.GOOS == "linux" { - mmapLimit = 30000 - } -} - -func (r *Reader) sliceOS(length uint64) ([]byte, bool) { - // For small slices, don't bother with the overhead of a - // mapping, especially since we have no way to unmap it. - const threshold = 16 << 10 - if length < threshold { - return nil, false - } - - // Have we reached the mmap limit? - if atomic.AddInt32(&mmapLimit, -1) < 0 { - atomic.AddInt32(&mmapLimit, 1) - return nil, false - } - - // Page-align the offset. - off := r.Offset() - align := syscall.Getpagesize() - aoff := off &^ int64(align-1) - - data, err := syscall.Mmap(int(r.f.Fd()), aoff, int(length+uint64(off-aoff)), syscall.PROT_READ, syscall.MAP_SHARED|syscall.MAP_FILE) - if err != nil { - return nil, false - } - - data = data[off-aoff:] - r.MustSeek(int64(length), 1) - return data, true -} diff --git a/odiglet/pkg/allocator/debug/goobj2/internal/bio/buf_nommap.go b/odiglet/pkg/allocator/debug/goobj2/internal/bio/buf_nommap.go deleted file mode 100644 index 533a93180c..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/internal/bio/buf_nommap.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd -// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd - -package bio - -func (r *Reader) sliceOS(length uint64) ([]byte, bool) { - return nil, false -} diff --git a/odiglet/pkg/allocator/debug/goobj2/internal/bio/must.go b/odiglet/pkg/allocator/debug/goobj2/internal/bio/must.go deleted file mode 100644 index 3604b29175..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/internal/bio/must.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bio - -import ( - "io" - "log" -) - -// MustClose closes Closer c and calls log.Fatal if it returns a non-nil error. -func MustClose(c io.Closer) { - if err := c.Close(); err != nil { - log.Fatal(err) - } -} - -// MustWriter returns a Writer that wraps the provided Writer, -// except that it calls log.Fatal instead of returning a non-nil error. -func MustWriter(w io.Writer) io.Writer { - return mustWriter{w} -} - -type mustWriter struct { - w io.Writer -} - -func (w mustWriter) Write(b []byte) (int, error) { - n, err := w.w.Write(b) - if err != nil { - log.Fatal(err) - } - return n, nil -} - -func (w mustWriter) WriteString(s string) (int, error) { - n, err := io.WriteString(w.w, s) - if err != nil { - log.Fatal(err) - } - return n, nil -} diff --git a/odiglet/pkg/allocator/debug/goobj2/internal/goobj2/extras.go b/odiglet/pkg/allocator/debug/goobj2/internal/goobj2/extras.go deleted file mode 100644 index e498423596..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/internal/goobj2/extras.go +++ /dev/null @@ -1,5 +0,0 @@ -package goobj2 - -func (r Reader) Header() Header { - return r.h -} diff --git a/odiglet/pkg/allocator/debug/goobj2/internal/goobj2/goobj2.go b/odiglet/pkg/allocator/debug/goobj2/internal/goobj2/goobj2.go deleted file mode 100644 index ef3a027141..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/internal/goobj2/goobj2.go +++ /dev/null @@ -1,1220 +0,0 @@ -// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT. -//go:generate bundle -import cmd/internal/bio=github.com/keyval-dev/odigos/odiglet/pkg/allocator/debug/goobj2/internal/bio -import internal/unsafeheader=github.com/keyval-dev/odigos/odiglet/pkg/allcotaor/debug/goobj2/internal/unsafeheader -o goobj2.go -prefix= cmd/internal/goobj2 - -package goobj2 - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "github.com/keyval-dev/odigos/odiglet/pkg/allocator/debug/goobj2/internal/bio" - "github.com/keyval-dev/odigos/odiglet/pkg/allocator/debug/goobj2/internal/unsafeheader" - "io" - "unsafe" -) - -// Builtin (compiler-generated) function references appear -// frequently. We assign special indices for them, so they -// don't need to be referenced by name. - -// NBuiltin returns the number of listed builtin -// symbols. -func NBuiltin() int { - return len(builtins) -} - -// BuiltinName returns the name and ABI of the i-th -// builtin symbol. -func BuiltinName(i int) (string, int) { - return builtins[i].name, builtins[i].abi -} - -// BuiltinIdx returns the index of the builtin with the -// given name and abi, or -1 if it is not a builtin. -func BuiltinIdx(name string, abi int) int { - i, ok := builtinMap[name] - if !ok { - return -1 - } - if builtins[i].abi != abi { - return -1 - } - return i -} - -//go:generate go run mkbuiltin.go - -var builtinMap map[string]int - -func init() { - builtinMap = make(map[string]int, len(builtins)) - for i, b := range builtins { - builtinMap[b.name] = i - } -} - -var builtins = [...]struct { - name string - abi int -}{ - {"runtime.newobject", 1}, - {"runtime.panicdivide", 1}, - {"runtime.panicshift", 1}, - {"runtime.panicmakeslicelen", 1}, - {"runtime.panicmakeslicecap", 1}, - {"runtime.throwinit", 1}, - {"runtime.panicwrap", 1}, - {"runtime.gopanic", 1}, - {"runtime.gorecover", 1}, - {"runtime.goschedguarded", 1}, - {"runtime.goPanicIndex", 1}, - {"runtime.goPanicIndexU", 1}, - {"runtime.goPanicSliceAlen", 1}, - {"runtime.goPanicSliceAlenU", 1}, - {"runtime.goPanicSliceAcap", 1}, - {"runtime.goPanicSliceAcapU", 1}, - {"runtime.goPanicSliceB", 1}, - {"runtime.goPanicSliceBU", 1}, - {"runtime.goPanicSlice3Alen", 1}, - {"runtime.goPanicSlice3AlenU", 1}, - {"runtime.goPanicSlice3Acap", 1}, - {"runtime.goPanicSlice3AcapU", 1}, - {"runtime.goPanicSlice3B", 1}, - {"runtime.goPanicSlice3BU", 1}, - {"runtime.goPanicSlice3C", 1}, - {"runtime.goPanicSlice3CU", 1}, - {"runtime.printbool", 1}, - {"runtime.printfloat", 1}, - {"runtime.printint", 1}, - {"runtime.printhex", 1}, - {"runtime.printuint", 1}, - {"runtime.printcomplex", 1}, - {"runtime.printstring", 1}, - {"runtime.printpointer", 1}, - {"runtime.printiface", 1}, - {"runtime.printeface", 1}, - {"runtime.printslice", 1}, - {"runtime.printnl", 1}, - {"runtime.printsp", 1}, - {"runtime.printlock", 1}, - {"runtime.printunlock", 1}, - {"runtime.concatstring2", 1}, - {"runtime.concatstring3", 1}, - {"runtime.concatstring4", 1}, - {"runtime.concatstring5", 1}, - {"runtime.concatstrings", 1}, - {"runtime.cmpstring", 1}, - {"runtime.intstring", 1}, - {"runtime.slicebytetostring", 1}, - {"runtime.slicebytetostringtmp", 1}, - {"runtime.slicerunetostring", 1}, - {"runtime.stringtoslicebyte", 1}, - {"runtime.stringtoslicerune", 1}, - {"runtime.slicecopy", 1}, - {"runtime.slicestringcopy", 1}, - {"runtime.decoderune", 1}, - {"runtime.countrunes", 1}, - {"runtime.convI2I", 1}, - {"runtime.convT16", 1}, - {"runtime.convT32", 1}, - {"runtime.convT64", 1}, - {"runtime.convTstring", 1}, - {"runtime.convTslice", 1}, - {"runtime.convT2E", 1}, - {"runtime.convT2Enoptr", 1}, - {"runtime.convT2I", 1}, - {"runtime.convT2Inoptr", 1}, - {"runtime.assertE2I", 1}, - {"runtime.assertE2I2", 1}, - {"runtime.assertI2I", 1}, - {"runtime.assertI2I2", 1}, - {"runtime.panicdottypeE", 1}, - {"runtime.panicdottypeI", 1}, - {"runtime.panicnildottype", 1}, - {"runtime.ifaceeq", 1}, - {"runtime.efaceeq", 1}, - {"runtime.fastrand", 1}, - {"runtime.makemap64", 1}, - {"runtime.makemap", 1}, - {"runtime.makemap_small", 1}, - {"runtime.mapaccess1", 1}, - {"runtime.mapaccess1_fast32", 1}, - {"runtime.mapaccess1_fast64", 1}, - {"runtime.mapaccess1_faststr", 1}, - {"runtime.mapaccess1_fat", 1}, - {"runtime.mapaccess2", 1}, - {"runtime.mapaccess2_fast32", 1}, - {"runtime.mapaccess2_fast64", 1}, - {"runtime.mapaccess2_faststr", 1}, - {"runtime.mapaccess2_fat", 1}, - {"runtime.mapassign", 1}, - {"runtime.mapassign_fast32", 1}, - {"runtime.mapassign_fast32ptr", 1}, - {"runtime.mapassign_fast64", 1}, - {"runtime.mapassign_fast64ptr", 1}, - {"runtime.mapassign_faststr", 1}, - {"runtime.mapiterinit", 1}, - {"runtime.mapdelete", 1}, - {"runtime.mapdelete_fast32", 1}, - {"runtime.mapdelete_fast64", 1}, - {"runtime.mapdelete_faststr", 1}, - {"runtime.mapiternext", 1}, - {"runtime.mapclear", 1}, - {"runtime.makechan64", 1}, - {"runtime.makechan", 1}, - {"runtime.chanrecv1", 1}, - {"runtime.chanrecv2", 1}, - {"runtime.chansend1", 1}, - {"runtime.closechan", 1}, - {"runtime.writeBarrier", 0}, - {"runtime.typedmemmove", 1}, - {"runtime.typedmemclr", 1}, - {"runtime.typedslicecopy", 1}, - {"runtime.selectnbsend", 1}, - {"runtime.selectnbrecv", 1}, - {"runtime.selectnbrecv2", 1}, - {"runtime.selectsetpc", 1}, - {"runtime.selectgo", 1}, - {"runtime.block", 1}, - {"runtime.makeslice", 1}, - {"runtime.makeslice64", 1}, - {"runtime.growslice", 1}, - {"runtime.memmove", 1}, - {"runtime.memclrNoHeapPointers", 1}, - {"runtime.memclrHasPointers", 1}, - {"runtime.memequal", 1}, - {"runtime.memequal0", 1}, - {"runtime.memequal8", 1}, - {"runtime.memequal16", 1}, - {"runtime.memequal32", 1}, - {"runtime.memequal64", 1}, - {"runtime.memequal128", 1}, - {"runtime.f32equal", 1}, - {"runtime.f64equal", 1}, - {"runtime.c64equal", 1}, - {"runtime.c128equal", 1}, - {"runtime.strequal", 1}, - {"runtime.interequal", 1}, - {"runtime.nilinterequal", 1}, - {"runtime.memhash", 1}, - {"runtime.memhash0", 1}, - {"runtime.memhash8", 1}, - {"runtime.memhash16", 1}, - {"runtime.memhash32", 1}, - {"runtime.memhash64", 1}, - {"runtime.memhash128", 1}, - {"runtime.f32hash", 1}, - {"runtime.f64hash", 1}, - {"runtime.c64hash", 1}, - {"runtime.c128hash", 1}, - {"runtime.strhash", 1}, - {"runtime.interhash", 1}, - {"runtime.nilinterhash", 1}, - {"runtime.int64div", 1}, - {"runtime.uint64div", 1}, - {"runtime.int64mod", 1}, - {"runtime.uint64mod", 1}, - {"runtime.float64toint64", 1}, - {"runtime.float64touint64", 1}, - {"runtime.float64touint32", 1}, - {"runtime.int64tofloat64", 1}, - {"runtime.uint64tofloat64", 1}, - {"runtime.uint32tofloat64", 1}, - {"runtime.complex128div", 1}, - {"runtime.racefuncenter", 1}, - {"runtime.racefuncenterfp", 1}, - {"runtime.racefuncexit", 1}, - {"runtime.raceread", 1}, - {"runtime.racewrite", 1}, - {"runtime.racereadrange", 1}, - {"runtime.racewriterange", 1}, - {"runtime.msanread", 1}, - {"runtime.msanwrite", 1}, - {"runtime.checkptrAlignment", 1}, - {"runtime.checkptrArithmetic", 1}, - {"runtime.libfuzzerTraceCmp1", 1}, - {"runtime.libfuzzerTraceCmp2", 1}, - {"runtime.libfuzzerTraceCmp4", 1}, - {"runtime.libfuzzerTraceCmp8", 1}, - {"runtime.libfuzzerTraceConstCmp1", 1}, - {"runtime.libfuzzerTraceConstCmp2", 1}, - {"runtime.libfuzzerTraceConstCmp4", 1}, - {"runtime.libfuzzerTraceConstCmp8", 1}, - {"runtime.x86HasPOPCNT", 0}, - {"runtime.x86HasSSE41", 0}, - {"runtime.x86HasFMA", 0}, - {"runtime.armHasVFPv4", 0}, - {"runtime.arm64HasATOMICS", 0}, - {"runtime.deferproc", 1}, - {"runtime.deferprocStack", 1}, - {"runtime.deferreturn", 1}, - {"runtime.newproc", 1}, - {"runtime.panicoverflow", 1}, - {"runtime.sigpanic", 1}, - {"runtime.gcWriteBarrier", 0}, - {"runtime.morestack", 0}, - {"runtime.morestackc", 0}, - {"runtime.morestack_noctxt", 0}, -} - -// FuncInfo is serialized as a symbol (aux symbol). The symbol data is -// the binary encoding of the struct below. -// -// TODO: make each pcdata a separate symbol? -type FuncInfo struct { - Args uint32 - Locals uint32 - - Pcsp uint32 - Pcfile uint32 - Pcline uint32 - Pcinline uint32 - Pcdata []uint32 - PcdataEnd uint32 - Funcdataoff []uint32 - File []SymRef // TODO: just use string? - - InlTree []InlTreeNode -} - -func (a *FuncInfo) Write(w *bytes.Buffer) { - var b [4]byte - writeUint32 := func(x uint32) { - binary.LittleEndian.PutUint32(b[:], x) - w.Write(b[:]) - } - - writeUint32(a.Args) - writeUint32(a.Locals) - - writeUint32(a.Pcsp) - writeUint32(a.Pcfile) - writeUint32(a.Pcline) - writeUint32(a.Pcinline) - writeUint32(uint32(len(a.Pcdata))) - for _, x := range a.Pcdata { - writeUint32(x) - } - writeUint32(a.PcdataEnd) - writeUint32(uint32(len(a.Funcdataoff))) - for _, x := range a.Funcdataoff { - writeUint32(x) - } - writeUint32(uint32(len(a.File))) - for _, f := range a.File { - writeUint32(f.PkgIdx) - writeUint32(f.SymIdx) - } - writeUint32(uint32(len(a.InlTree))) - for i := range a.InlTree { - a.InlTree[i].Write(w) - } -} - -func (a *FuncInfo) Read(b []byte) { - readUint32 := func() uint32 { - x := binary.LittleEndian.Uint32(b) - b = b[4:] - return x - } - - a.Args = readUint32() - a.Locals = readUint32() - - a.Pcsp = readUint32() - a.Pcfile = readUint32() - a.Pcline = readUint32() - a.Pcinline = readUint32() - pcdatalen := readUint32() - a.Pcdata = make([]uint32, pcdatalen) - for i := range a.Pcdata { - a.Pcdata[i] = readUint32() - } - a.PcdataEnd = readUint32() - funcdataofflen := readUint32() - a.Funcdataoff = make([]uint32, funcdataofflen) - for i := range a.Funcdataoff { - a.Funcdataoff[i] = readUint32() - } - filelen := readUint32() - a.File = make([]SymRef, filelen) - for i := range a.File { - a.File[i] = SymRef{readUint32(), readUint32()} - } - inltreelen := readUint32() - a.InlTree = make([]InlTreeNode, inltreelen) - for i := range a.InlTree { - b = a.InlTree[i].Read(b) - } -} - -// FuncInfoLengths is a cache containing a roadmap of offsets and -// lengths for things within a serialized FuncInfo. Each length field -// stores the number of items (e.g. files, inltree nodes, etc), and the -// corresponding "off" field stores the byte offset of the start of -// the items in question. -type FuncInfoLengths struct { - NumPcdata uint32 - PcdataOff uint32 - NumFuncdataoff uint32 - FuncdataoffOff uint32 - NumFile uint32 - FileOff uint32 - NumInlTree uint32 - InlTreeOff uint32 - Initialized bool -} - -func (*FuncInfo) ReadFuncInfoLengths(b []byte) FuncInfoLengths { - var result FuncInfoLengths - - const numpcdataOff = 24 - result.NumPcdata = binary.LittleEndian.Uint32(b[numpcdataOff:]) - result.PcdataOff = numpcdataOff + 4 - - numfuncdataoffOff := result.PcdataOff + 4*(result.NumPcdata+1) - result.NumFuncdataoff = binary.LittleEndian.Uint32(b[numfuncdataoffOff:]) - result.FuncdataoffOff = numfuncdataoffOff + 4 - - numfileOff := result.FuncdataoffOff + 4*result.NumFuncdataoff - result.NumFile = binary.LittleEndian.Uint32(b[numfileOff:]) - result.FileOff = numfileOff + 4 - - const symRefSize = 4 + 4 - numinltreeOff := result.FileOff + symRefSize*result.NumFile - result.NumInlTree = binary.LittleEndian.Uint32(b[numinltreeOff:]) - result.InlTreeOff = numinltreeOff + 4 - - result.Initialized = true - - return result -} - -func (*FuncInfo) ReadArgs(b []byte) uint32 { return binary.LittleEndian.Uint32(b) } - -func (*FuncInfo) ReadLocals(b []byte) uint32 { return binary.LittleEndian.Uint32(b[4:]) } - -// return start and end offsets. -func (*FuncInfo) ReadPcsp(b []byte) (uint32, uint32) { - return binary.LittleEndian.Uint32(b[8:]), binary.LittleEndian.Uint32(b[12:]) -} - -// return start and end offsets. -func (*FuncInfo) ReadPcfile(b []byte) (uint32, uint32) { - return binary.LittleEndian.Uint32(b[12:]), binary.LittleEndian.Uint32(b[16:]) -} - -// return start and end offsets. -func (*FuncInfo) ReadPcline(b []byte) (uint32, uint32) { - return binary.LittleEndian.Uint32(b[16:]), binary.LittleEndian.Uint32(b[20:]) -} - -// return start and end offsets. -func (*FuncInfo) ReadPcinline(b []byte, pcdataoffset uint32) (uint32, uint32) { - return binary.LittleEndian.Uint32(b[20:]), binary.LittleEndian.Uint32(b[pcdataoffset:]) -} - -// return start and end offsets. -func (*FuncInfo) ReadPcdata(b []byte, pcdataoffset uint32, k uint32) (uint32, uint32) { - return binary.LittleEndian.Uint32(b[pcdataoffset+4*k:]), binary.LittleEndian.Uint32(b[pcdataoffset+4+4*k:]) -} - -func (*FuncInfo) ReadFuncdataoff(b []byte, funcdataofffoff uint32, k uint32) int64 { - return int64(binary.LittleEndian.Uint32(b[funcdataofffoff+4*k:])) -} - -func (*FuncInfo) ReadFile(b []byte, filesoff uint32, k uint32) SymRef { - p := binary.LittleEndian.Uint32(b[filesoff+8*k:]) - s := binary.LittleEndian.Uint32(b[filesoff+4+8*k:]) - return SymRef{p, s} -} - -func (*FuncInfo) ReadInlTree(b []byte, inltreeoff uint32, k uint32) InlTreeNode { - const inlTreeNodeSize = 4 * 7 - var result InlTreeNode - result.Read(b[inltreeoff+k*inlTreeNodeSize:]) - return result -} - -// InlTreeNode is the serialized form of FileInfo.InlTree. -type InlTreeNode struct { - Parent int32 - File SymRef - Line int32 - Func SymRef - ParentPC int32 -} - -func (inl *InlTreeNode) Write(w *bytes.Buffer) { - var b [4]byte - writeUint32 := func(x uint32) { - binary.LittleEndian.PutUint32(b[:], x) - w.Write(b[:]) - } - writeUint32(uint32(inl.Parent)) - writeUint32(inl.File.PkgIdx) - writeUint32(inl.File.SymIdx) - writeUint32(uint32(inl.Line)) - writeUint32(inl.Func.PkgIdx) - writeUint32(inl.Func.SymIdx) - writeUint32(uint32(inl.ParentPC)) -} - -// Read an InlTreeNode from b, return the remaining bytes. -func (inl *InlTreeNode) Read(b []byte) []byte { - readUint32 := func() uint32 { - x := binary.LittleEndian.Uint32(b) - b = b[4:] - return x - } - inl.Parent = int32(readUint32()) - inl.File = SymRef{readUint32(), readUint32()} - inl.Line = int32(readUint32()) - inl.Func = SymRef{readUint32(), readUint32()} - inl.ParentPC = int32(readUint32()) - return b -} - -// New object file format. -// -// Header struct { -// Magic [...]byte // "\x00go115ld" -// Fingerprint [8]byte -// Flags uint32 -// Offsets [...]uint32 // byte offset of each block below -// } -// -// Strings [...]struct { -// Data [...]byte -// } -// -// Autolib [...]struct { // imported packages (for file loading) -// Pkg string -// Fingerprint [8]byte -// } -// -// PkgIndex [...]string // referenced packages by index -// -// DwarfFiles [...]string -// -// SymbolDefs [...]struct { -// Name string -// ABI uint16 -// Type uint8 -// Flag uint8 -// Size uint32 -// } -// NonPkgDefs [...]struct { // non-pkg symbol definitions -// ... // same as SymbolDefs -// } -// NonPkgRefs [...]struct { // non-pkg symbol references -// ... // same as SymbolDefs -// } -// -// RelocIndex [...]uint32 // index to Relocs -// AuxIndex [...]uint32 // index to Aux -// DataIndex [...]uint32 // offset to Data -// -// Relocs [...]struct { -// Off int32 -// Size uint8 -// Type uint8 -// Add int64 -// Sym symRef -// } -// -// Aux [...]struct { -// Type uint8 -// Sym symRef -// } -// -// Data [...]byte -// Pcdata [...]byte -// -// // blocks only used by tools (objdump, nm) -// -// RefNames [...]struct { // referenced symbol names -// Sym symRef -// Name string -// // TODO: include ABI version as well? -// } -// -// string is encoded as is a uint32 length followed by a uint32 offset -// that points to the corresponding string bytes. -// -// symRef is struct { PkgIdx, SymIdx uint32 }. -// -// Slice type (e.g. []symRef) is encoded as a length prefix (uint32) -// followed by that number of elements. -// -// The types below correspond to the encoded data structure in the -// object file. - -// Symbol indexing. -// -// Each symbol is referenced with a pair of indices, { PkgIdx, SymIdx }, -// as the symRef struct above. -// -// PkgIdx is either a predeclared index (see PkgIdxNone below) or -// an index of an imported package. For the latter case, PkgIdx is the -// index of the package in the PkgIndex array. 0 is an invalid index. -// -// SymIdx is the index of the symbol in the given package. -// - If PkgIdx is PkgIdxSelf, SymIdx is the index of the symbol in the -// SymbolDefs array. -// - If PkgIdx is PkgIdxNone, SymIdx is the index of the symbol in the -// NonPkgDefs array (could natually overflow to NonPkgRefs array). -// - Otherwise, SymIdx is the index of the symbol in some other package's -// SymbolDefs array. -// -// {0, 0} represents a nil symbol. Otherwise PkgIdx should not be 0. -// -// RelocIndex, AuxIndex, and DataIndex contains indices/offsets to -// Relocs/Aux/Data blocks, one element per symbol, first for all the -// defined symbols, then all the defined non-package symbols, in the -// same order of SymbolDefs/NonPkgDefs arrays. For N total defined -// symbols, the array is of length N+1. The last element is the total -// number of relocations (aux symbols, data blocks, etc.). -// -// They can be accessed by index. For the i-th symbol, its relocations -// are the RelocIndex[i]-th (inclusive) to RelocIndex[i+1]-th (exclusive) -// elements in the Relocs array. Aux/Data are likewise. (The index is -// 0-based.) - -// Auxiliary symbols. -// -// Each symbol may (or may not) be associated with a number of auxiliary -// symbols. They are described in the Aux block. See Aux struct below. -// Currently a symbol's Gotype and FuncInfo are auxiliary symbols. We -// may make use of aux symbols in more cases, e.g. DWARF symbols. - -const stringRefSize = 8 // two uint32s - -type FingerprintType [8]byte - -func (fp FingerprintType) IsZero() bool { return fp == FingerprintType{} } - -// Package Index. -const ( - PkgIdxNone = (1<<31 - 1) - iota // Non-package symbols - PkgIdxBuiltin // Predefined symbols // TODO: not used for now, we could use it for compiler-generated symbols like runtime.newobject - PkgIdxSelf // Symbols defined in the current package - PkgIdxInvalid = 0 - // The index of other referenced packages starts from 1. -) - -// Blocks -const ( - BlkAutolib = iota - BlkPkgIdx - BlkDwarfFile - BlkSymdef - BlkNonpkgdef - BlkNonpkgref - BlkRelocIdx - BlkAuxIdx - BlkDataIdx - BlkReloc - BlkAux - BlkData - BlkPcdata - BlkRefName - BlkEnd - NBlk -) - -// File header. -// TODO: probably no need to export this. -type Header struct { - Magic string - Fingerprint FingerprintType - Flags uint32 - Offsets [NBlk]uint32 -} - -const Magic = "\x00go115ld" - -func (h *Header) Write(w *Writer) { - w.RawString(h.Magic) - w.Bytes(h.Fingerprint[:]) - w.Uint32(h.Flags) - for _, x := range h.Offsets { - w.Uint32(x) - } -} - -func (h *Header) Read(r *Reader) error { - b := r.BytesAt(0, len(Magic)) - h.Magic = string(b) - if h.Magic != Magic { - return errors.New("wrong magic, not a Go object file") - } - off := uint32(len(h.Magic)) - copy(h.Fingerprint[:], r.BytesAt(off, len(h.Fingerprint))) - off += 8 - h.Flags = r.uint32At(off) - off += 4 - for i := range h.Offsets { - h.Offsets[i] = r.uint32At(off) - off += 4 - } - return nil -} - -func (h *Header) Size() int { - return len(h.Magic) + 4 + 4*len(h.Offsets) -} - -// Autolib -type ImportedPkg struct { - Pkg string - Fingerprint FingerprintType -} - -const importedPkgSize = stringRefSize + 8 - -func (p *ImportedPkg) Write(w *Writer) { - w.StringRef(p.Pkg) - w.Bytes(p.Fingerprint[:]) -} - -// Symbol definition. -// -// Serialized format: -// -// Sym struct { -// Name string -// ABI uint16 -// Type uint8 -// Flag uint8 -// Siz uint32 -// Align uint32 -// } -type Sym [SymSize]byte - -const SymSize = stringRefSize + 2 + 1 + 1 + 4 + 4 - -const SymABIstatic = ^uint16(0) - -const ( - ObjFlagShared = 1 << iota -) - -const ( - SymFlagDupok = 1 << iota - SymFlagLocal - SymFlagTypelink - SymFlagLeaf - SymFlagNoSplit - SymFlagReflectMethod - SymFlagGoType - SymFlagTopFrame -) - -func (s *Sym) Name(r *Reader) string { - len := binary.LittleEndian.Uint32(s[:]) - off := binary.LittleEndian.Uint32(s[4:]) - return r.StringAt(off, len) -} - -func (s *Sym) ABI() uint16 { return binary.LittleEndian.Uint16(s[8:]) } - -func (s *Sym) Type() uint8 { return s[10] } - -func (s *Sym) Flag() uint8 { return s[11] } - -func (s *Sym) Siz() uint32 { return binary.LittleEndian.Uint32(s[12:]) } - -func (s *Sym) Align() uint32 { return binary.LittleEndian.Uint32(s[16:]) } - -func (s *Sym) Dupok() bool { return s.Flag()&SymFlagDupok != 0 } - -func (s *Sym) Local() bool { return s.Flag()&SymFlagLocal != 0 } - -func (s *Sym) Typelink() bool { return s.Flag()&SymFlagTypelink != 0 } - -func (s *Sym) Leaf() bool { return s.Flag()&SymFlagLeaf != 0 } - -func (s *Sym) NoSplit() bool { return s.Flag()&SymFlagNoSplit != 0 } - -func (s *Sym) ReflectMethod() bool { return s.Flag()&SymFlagReflectMethod != 0 } - -func (s *Sym) IsGoType() bool { return s.Flag()&SymFlagGoType != 0 } - -func (s *Sym) TopFrame() bool { return s.Flag()&SymFlagTopFrame != 0 } - -func (s *Sym) SetName(x string, w *Writer) { - binary.LittleEndian.PutUint32(s[:], uint32(len(x))) - binary.LittleEndian.PutUint32(s[4:], w.stringOff(x)) -} - -func (s *Sym) SetABI(x uint16) { binary.LittleEndian.PutUint16(s[8:], x) } - -func (s *Sym) SetType(x uint8) { s[10] = x } - -func (s *Sym) SetFlag(x uint8) { s[11] = x } - -func (s *Sym) SetSiz(x uint32) { binary.LittleEndian.PutUint32(s[12:], x) } - -func (s *Sym) SetAlign(x uint32) { binary.LittleEndian.PutUint32(s[16:], x) } - -func (s *Sym) Write(w *Writer) { w.Bytes(s[:]) } - -// for testing -func (s *Sym) fromBytes(b []byte) { copy(s[:], b) } - -// Symbol reference. -type SymRef struct { - PkgIdx uint32 - SymIdx uint32 -} - -// Relocation. -// -// Serialized format: -// -// Reloc struct { -// Off int32 -// Siz uint8 -// Type uint8 -// Add int64 -// Sym SymRef -// } -type Reloc [RelocSize]byte - -const RelocSize = 4 + 1 + 1 + 8 + 8 - -func (r *Reloc) Off() int32 { return int32(binary.LittleEndian.Uint32(r[:])) } - -func (r *Reloc) Siz() uint8 { return r[4] } - -func (r *Reloc) Type() uint8 { return r[5] } - -func (r *Reloc) Add() int64 { return int64(binary.LittleEndian.Uint64(r[6:])) } - -func (r *Reloc) Sym() SymRef { - return SymRef{binary.LittleEndian.Uint32(r[14:]), binary.LittleEndian.Uint32(r[18:])} -} - -func (r *Reloc) SetOff(x int32) { binary.LittleEndian.PutUint32(r[:], uint32(x)) } - -func (r *Reloc) SetSiz(x uint8) { r[4] = x } - -func (r *Reloc) SetType(x uint8) { r[5] = x } - -func (r *Reloc) SetAdd(x int64) { binary.LittleEndian.PutUint64(r[6:], uint64(x)) } - -func (r *Reloc) SetSym(x SymRef) { - binary.LittleEndian.PutUint32(r[14:], x.PkgIdx) - binary.LittleEndian.PutUint32(r[18:], x.SymIdx) -} - -func (r *Reloc) Set(off int32, size uint8, typ uint8, add int64, sym SymRef) { - r.SetOff(off) - r.SetSiz(size) - r.SetType(typ) - r.SetAdd(add) - r.SetSym(sym) -} - -func (r *Reloc) Write(w *Writer) { w.Bytes(r[:]) } - -// for testing -func (r *Reloc) fromBytes(b []byte) { copy(r[:], b) } - -// Aux symbol info. -// -// Serialized format: -// -// Aux struct { -// Type uint8 -// Sym SymRef -// } -type Aux [AuxSize]byte - -const AuxSize = 1 + 8 - -// Aux Type -const ( - AuxGotype = iota - AuxFuncInfo - AuxFuncdata - AuxDwarfInfo - AuxDwarfLoc - AuxDwarfRanges - AuxDwarfLines - - // TODO: more. Pcdata? -) - -func (a *Aux) Type() uint8 { return a[0] } - -func (a *Aux) Sym() SymRef { - return SymRef{binary.LittleEndian.Uint32(a[1:]), binary.LittleEndian.Uint32(a[5:])} -} - -func (a *Aux) SetType(x uint8) { a[0] = x } - -func (a *Aux) SetSym(x SymRef) { - binary.LittleEndian.PutUint32(a[1:], x.PkgIdx) - binary.LittleEndian.PutUint32(a[5:], x.SymIdx) -} - -func (a *Aux) Write(w *Writer) { w.Bytes(a[:]) } - -// for testing -func (a *Aux) fromBytes(b []byte) { copy(a[:], b) } - -// Referenced symbol name. -// -// Serialized format: -// -// RefName struct { -// Sym symRef -// Name string -// } -type RefName [RefNameSize]byte - -const RefNameSize = 8 + stringRefSize - -func (n *RefName) Sym() SymRef { - return SymRef{binary.LittleEndian.Uint32(n[:]), binary.LittleEndian.Uint32(n[4:])} -} - -func (n *RefName) Name(r *Reader) string { - len := binary.LittleEndian.Uint32(n[8:]) - off := binary.LittleEndian.Uint32(n[12:]) - return r.StringAt(off, len) -} - -func (n *RefName) SetSym(x SymRef) { - binary.LittleEndian.PutUint32(n[:], x.PkgIdx) - binary.LittleEndian.PutUint32(n[4:], x.SymIdx) -} - -func (n *RefName) SetName(x string, w *Writer) { - binary.LittleEndian.PutUint32(n[8:], uint32(len(x))) - binary.LittleEndian.PutUint32(n[12:], w.stringOff(x)) -} - -func (n *RefName) Write(w *Writer) { w.Bytes(n[:]) } - -type Writer struct { - wr *bio.Writer - stringMap map[string]uint32 - off uint32 // running offset -} - -func NewWriter(wr *bio.Writer) *Writer { - return &Writer{wr: wr, stringMap: make(map[string]uint32)} -} - -func (w *Writer) AddString(s string) { - if _, ok := w.stringMap[s]; ok { - return - } - w.stringMap[s] = w.off - w.RawString(s) -} - -func (w *Writer) stringOff(s string) uint32 { - off, ok := w.stringMap[s] - if !ok { - panic(fmt.Sprintf("writeStringRef: string not added: %q", s)) - } - return off -} - -func (w *Writer) StringRef(s string) { - w.Uint32(uint32(len(s))) - w.Uint32(w.stringOff(s)) -} - -func (w *Writer) RawString(s string) { - w.wr.WriteString(s) - w.off += uint32(len(s)) -} - -func (w *Writer) Bytes(s []byte) { - w.wr.Write(s) - w.off += uint32(len(s)) -} - -func (w *Writer) Uint64(x uint64) { - var b [8]byte - binary.LittleEndian.PutUint64(b[:], x) - w.wr.Write(b[:]) - w.off += 8 -} - -func (w *Writer) Uint32(x uint32) { - var b [4]byte - binary.LittleEndian.PutUint32(b[:], x) - w.wr.Write(b[:]) - w.off += 4 -} - -func (w *Writer) Uint16(x uint16) { - var b [2]byte - binary.LittleEndian.PutUint16(b[:], x) - w.wr.Write(b[:]) - w.off += 2 -} - -func (w *Writer) Uint8(x uint8) { - w.wr.WriteByte(x) - w.off++ -} - -func (w *Writer) Offset() uint32 { - return w.off -} - -type Reader struct { - b []byte // mmapped bytes, if not nil - readonly bool // whether b is backed with read-only memory - - rd io.ReaderAt - start uint32 - h Header // keep block offsets -} - -func NewReaderFromBytes(b []byte, readonly bool) *Reader { - r := &Reader{b: b, readonly: readonly, rd: bytes.NewReader(b), start: 0} - err := r.h.Read(r) - if err != nil { - return nil - } - return r -} - -func (r *Reader) BytesAt(off uint32, len int) []byte { - if len == 0 { - return nil - } - end := int(off) + len - return r.b[int(off):end:end] -} - -func (r *Reader) uint64At(off uint32) uint64 { - b := r.BytesAt(off, 8) - return binary.LittleEndian.Uint64(b) -} - -func (r *Reader) int64At(off uint32) int64 { - return int64(r.uint64At(off)) -} - -func (r *Reader) uint32At(off uint32) uint32 { - b := r.BytesAt(off, 4) - return binary.LittleEndian.Uint32(b) -} - -func (r *Reader) int32At(off uint32) int32 { - return int32(r.uint32At(off)) -} - -func (r *Reader) uint16At(off uint32) uint16 { - b := r.BytesAt(off, 2) - return binary.LittleEndian.Uint16(b) -} - -func (r *Reader) uint8At(off uint32) uint8 { - b := r.BytesAt(off, 1) - return b[0] -} - -func (r *Reader) StringAt(off uint32, len uint32) string { - b := r.b[off : off+len] - if r.readonly { - return toString(b) // backed by RO memory, ok to make unsafe string - } - return string(b) -} - -func toString(b []byte) string { - if len(b) == 0 { - return "" - } - - var s string - hdr := (*unsafeheader.String)(unsafe.Pointer(&s)) - hdr.Data = unsafe.Pointer(&b[0]) - hdr.Len = len(b) - - return s -} - -func (r *Reader) StringRef(off uint32) string { - l := r.uint32At(off) - return r.StringAt(r.uint32At(off+4), l) -} - -func (r *Reader) Fingerprint() FingerprintType { - return r.h.Fingerprint -} - -func (r *Reader) Autolib() []ImportedPkg { - n := (r.h.Offsets[BlkAutolib+1] - r.h.Offsets[BlkAutolib]) / importedPkgSize - s := make([]ImportedPkg, n) - off := r.h.Offsets[BlkAutolib] - for i := range s { - s[i].Pkg = r.StringRef(off) - copy(s[i].Fingerprint[:], r.BytesAt(off+stringRefSize, len(s[i].Fingerprint))) - off += importedPkgSize - } - return s -} - -func (r *Reader) Pkglist() []string { - n := (r.h.Offsets[BlkPkgIdx+1] - r.h.Offsets[BlkPkgIdx]) / stringRefSize - s := make([]string, n) - off := r.h.Offsets[BlkPkgIdx] - for i := range s { - s[i] = r.StringRef(off) - off += stringRefSize - } - return s -} - -func (r *Reader) NPkg() int { - return int(r.h.Offsets[BlkPkgIdx+1]-r.h.Offsets[BlkPkgIdx]) / stringRefSize -} - -func (r *Reader) Pkg(i int) string { - off := r.h.Offsets[BlkPkgIdx] + uint32(i)*stringRefSize - return r.StringRef(off) -} - -func (r *Reader) NDwarfFile() int { - return int(r.h.Offsets[BlkDwarfFile+1]-r.h.Offsets[BlkDwarfFile]) / stringRefSize -} - -func (r *Reader) DwarfFile(i int) string { - off := r.h.Offsets[BlkDwarfFile] + uint32(i)*stringRefSize - return r.StringRef(off) -} - -func (r *Reader) NSym() int { - return int(r.h.Offsets[BlkSymdef+1]-r.h.Offsets[BlkSymdef]) / SymSize -} - -func (r *Reader) NNonpkgdef() int { - return int(r.h.Offsets[BlkNonpkgdef+1]-r.h.Offsets[BlkNonpkgdef]) / SymSize -} - -func (r *Reader) NNonpkgref() int { - return int(r.h.Offsets[BlkNonpkgref+1]-r.h.Offsets[BlkNonpkgref]) / SymSize -} - -// SymOff returns the offset of the i-th symbol. -func (r *Reader) SymOff(i int) uint32 { - return r.h.Offsets[BlkSymdef] + uint32(i*SymSize) -} - -// Sym returns a pointer to the i-th symbol. -func (r *Reader) Sym(i int) *Sym { - off := r.SymOff(i) - return (*Sym)(unsafe.Pointer(&r.b[off])) -} - -// NReloc returns the number of relocations of the i-th symbol. -func (r *Reader) NReloc(i int) int { - relocIdxOff := r.h.Offsets[BlkRelocIdx] + uint32(i*4) - return int(r.uint32At(relocIdxOff+4) - r.uint32At(relocIdxOff)) -} - -// RelocOff returns the offset of the j-th relocation of the i-th symbol. -func (r *Reader) RelocOff(i int, j int) uint32 { - relocIdxOff := r.h.Offsets[BlkRelocIdx] + uint32(i*4) - relocIdx := r.uint32At(relocIdxOff) - return r.h.Offsets[BlkReloc] + (relocIdx+uint32(j))*uint32(RelocSize) -} - -// Reloc returns a pointer to the j-th relocation of the i-th symbol. -func (r *Reader) Reloc(i int, j int) *Reloc { - off := r.RelocOff(i, j) - return (*Reloc)(unsafe.Pointer(&r.b[off])) -} - -// Relocs returns a pointer to the relocations of the i-th symbol. -func (r *Reader) Relocs(i int) []Reloc { - off := r.RelocOff(i, 0) - n := r.NReloc(i) - return (*[1 << 20]Reloc)(unsafe.Pointer(&r.b[off]))[:n:n] -} - -// NAux returns the number of aux symbols of the i-th symbol. -func (r *Reader) NAux(i int) int { - auxIdxOff := r.h.Offsets[BlkAuxIdx] + uint32(i*4) - return int(r.uint32At(auxIdxOff+4) - r.uint32At(auxIdxOff)) -} - -// AuxOff returns the offset of the j-th aux symbol of the i-th symbol. -func (r *Reader) AuxOff(i int, j int) uint32 { - auxIdxOff := r.h.Offsets[BlkAuxIdx] + uint32(i*4) - auxIdx := r.uint32At(auxIdxOff) - return r.h.Offsets[BlkAux] + (auxIdx+uint32(j))*uint32(AuxSize) -} - -// Aux returns a pointer to the j-th aux symbol of the i-th symbol. -func (r *Reader) Aux(i int, j int) *Aux { - off := r.AuxOff(i, j) - return (*Aux)(unsafe.Pointer(&r.b[off])) -} - -// Auxs returns the aux symbols of the i-th symbol. -func (r *Reader) Auxs(i int) []Aux { - off := r.AuxOff(i, 0) - n := r.NAux(i) - return (*[1 << 20]Aux)(unsafe.Pointer(&r.b[off]))[:n:n] -} - -// DataOff returns the offset of the i-th symbol's data. -func (r *Reader) DataOff(i int) uint32 { - dataIdxOff := r.h.Offsets[BlkDataIdx] + uint32(i*4) - return r.h.Offsets[BlkData] + r.uint32At(dataIdxOff) -} - -// DataSize returns the size of the i-th symbol's data. -func (r *Reader) DataSize(i int) int { - dataIdxOff := r.h.Offsets[BlkDataIdx] + uint32(i*4) - return int(r.uint32At(dataIdxOff+4) - r.uint32At(dataIdxOff)) -} - -// Data returns the i-th symbol's data. -func (r *Reader) Data(i int) []byte { - dataIdxOff := r.h.Offsets[BlkDataIdx] + uint32(i*4) - base := r.h.Offsets[BlkData] - off := r.uint32At(dataIdxOff) - end := r.uint32At(dataIdxOff + 4) - return r.BytesAt(base+off, int(end-off)) -} - -// AuxDataBase returns the base offset of the aux data block. -func (r *Reader) PcdataBase() uint32 { - return r.h.Offsets[BlkPcdata] -} - -// NRefName returns the number of referenced symbol names. -func (r *Reader) NRefName() int { - return int(r.h.Offsets[BlkRefName+1]-r.h.Offsets[BlkRefName]) / RefNameSize -} - -// RefName returns a pointer to the i-th referenced symbol name. -// Note: here i is not a local symbol index, just a counter. -func (r *Reader) RefName(i int) *RefName { - off := r.h.Offsets[BlkRefName] + uint32(i*RefNameSize) - return (*RefName)(unsafe.Pointer(&r.b[off])) -} - -// ReadOnly returns whether r.BytesAt returns read-only bytes. -func (r *Reader) ReadOnly() bool { - return r.readonly -} - -// Flags returns the flag bits read from the object file header. -func (r *Reader) Flags() uint32 { - return r.h.Flags -} diff --git a/odiglet/pkg/allocator/debug/goobj2/internal/objabi/objabi.go b/odiglet/pkg/allocator/debug/goobj2/internal/objabi/objabi.go deleted file mode 100644 index c254bf2aae..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/internal/objabi/objabi.go +++ /dev/null @@ -1,1249 +0,0 @@ -// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT. -//go:generate bundle -o objabi.go -pkg objabi -prefix= cmd/internal/objabi - -// Originally, Go object files were Plan 9 object files, but no longer. -// Now they are more like standard object files, in that each symbol is defined -// by an associated memory image (bytes) and a list of relocations to apply -// during linking. We do not (yet?) use a standard file format, however. -// For now, the format is chosen to be as simple as possible to read and write. -// It may change for reasons of efficiency, or we may even switch to a -// standard file format if there are compelling benefits to doing so. -// See golang.org/s/go13linker for more background. -// -// The file format is: -// -// - magic header: "\x00go114ld" -// - byte 1 - version number -// - sequence of strings giving dependencies (imported packages) -// - empty string (marks end of sequence) -// - number of entries in the following sequence -// - sequence of filename strings to generate debug information -// - sequence of symbol references used by the defined symbols -// - byte 0xff (marks end of sequence) -// - sequence of integer lengths: -// - total data length -// - total number of relocations -// - total number of pcdata -// - total number of automatics -// - total number of funcdata -// - total number of files -// - data, the content of the defined symbols -// - sequence of defined symbols -// - byte 0xff (marks end of sequence) -// - magic footer: "\xffgo114ld" -// -// All integers are stored in a zigzag varint format. -// See golang.org/s/go12symtab for a definition. -// -// Data blocks and strings are both stored as an integer -// followed by that many bytes. -// -// A symbol reference is a string name followed by an ABI or -1 for static. -// -// A symbol points to other symbols using an index into the symbol -// reference sequence. Index 0 corresponds to a nil symbol pointer. -// In the symbol layout described below "symref index" stands for this -// index. -// -// Each symbol is laid out as the following fields: -// -// - byte 0xfe (sanity check for synchronization) -// - type [byte] -// - name & ABI [symref index] -// - flags [int] -// 1<<0 dupok -// 1<<1 local -// 1<<2 add to typelink table -// - size [int] -// - gotype [symref index] -// - p [data block] -// - nr [int] -// - r [nr relocations, sorted by off] -// -// If type == STEXT, there are a few more fields: -// -// - args [int] -// - locals [int] -// - nosplit [int] -// - flags [int] -// 1<<0 leaf -// 1<<1 C function -// 1<<2 function may call reflect.Type.Method -// 1<<3 function compiled with -shared -// - nlocal [int] -// - local [nlocal automatics] -// - pcln [pcln table] -// -// Each relocation has the encoding: -// -// - off [int] -// - siz [int] -// - type [int] -// - add [int] -// - sym [symref index] -// -// Each local has the encoding: -// -// - asym [symref index] -// - offset [int] -// - type [int] -// - gotype [symref index] -// -// The pcln table has the encoding: -// -// - pcsp [data block] -// - pcfile [data block] -// - pcline [data block] -// - pcinline [data block] -// - npcdata [int] -// - pcdata [npcdata data blocks] -// - nfuncdata [int] -// - funcdata [nfuncdata symref index] -// - funcdatasym [nfuncdata ints] -// - nfile [int] -// - file [nfile symref index] -// - ninlinedcall [int] -// - inlinedcall [ninlinedcall int symref int symref] -// -// The file layout and meaning of type integers are architecture-independent. -// -// TODO(rsc): The file format is good for a first pass but needs work. -// - There are SymID in the object file that should really just be strings. -// - -package objabi - -import ( - "flag" - "fmt" - "io" - "io/ioutil" - "log" - "os" - "path/filepath" - "runtime" - "strconv" - "strings" -) - -// Auto.name -const ( - A_AUTO = 1 + iota - A_PARAM - A_DELETED_AUTO -) - -func Flagcount(name, usage string, val *int) { - flag.Var((*count)(val), name, usage) -} - -func Flagfn1(name, usage string, f func(string)) { - flag.Var(fn1(f), name, usage) -} - -func Flagprint(w io.Writer) { - flag.CommandLine.SetOutput(w) - flag.PrintDefaults() -} - -func Flagparse(usage func()) { - flag.Usage = usage - os.Args = expandArgs(os.Args) - flag.Parse() -} - -// expandArgs expands "response files" arguments in the provided slice. -// -// A "response file" argument starts with '@' and the rest of that -// argument is a filename with CR-or-CRLF-separated arguments. Each -// argument in the named files can also contain response file -// arguments. See Issue 18468. -// -// The returned slice 'out' aliases 'in' iff the input did not contain -// any response file arguments. -// -// TODO: handle relative paths of recursive expansions in different directories? -// Is there a spec for this? Are relative paths allowed? -func expandArgs(in []string) (out []string) { - // out is nil until we see a "@" argument. - for i, s := range in { - if strings.HasPrefix(s, "@") { - if out == nil { - out = make([]string, 0, len(in)*2) - out = append(out, in[:i]...) - } - slurp, err := ioutil.ReadFile(s[1:]) - if err != nil { - log.Fatal(err) - } - args := strings.Split(strings.TrimSpace(strings.Replace(string(slurp), "\r", "", -1)), "\n") - out = append(out, expandArgs(args)...) - } else if out != nil { - out = append(out, s) - } - } - if out == nil { - return in - } - return -} - -func AddVersionFlag() { - flag.Var(versionFlag{}, "V", "print version and exit") -} - -var buildID string // filled in by linker - -type versionFlag struct{} - -func (versionFlag) IsBoolFlag() bool { return true } - -func (versionFlag) Get() interface{} { return nil } - -func (versionFlag) String() string { return "" } - -func (versionFlag) Set(s string) error { - name := os.Args[0] - name = name[strings.LastIndex(name, `/`)+1:] - name = name[strings.LastIndex(name, `\`)+1:] - name = strings.TrimSuffix(name, ".exe") - - // If there's an active experiment, include that, - // to distinguish go1.10.2 with an experiment - // from go1.10.2 without an experiment. - p := Expstring() - if p == DefaultExpstring() { - p = "" - } - sep := "" - if p != "" { - sep = " " - } - - // The go command invokes -V=full to get a unique identifier - // for this tool. It is assumed that the release version is sufficient - // for releases, but during development we include the full - // build ID of the binary, so that if the compiler is changed and - // rebuilt, we notice and rebuild all packages. - if s == "full" { - if strings.HasPrefix(Version, "devel") { - p += " buildID=" + buildID - } - } - - fmt.Printf("%s version %s%s%s\n", name, Version, sep, p) - os.Exit(0) - return nil -} - -// count is a flag.Value that is like a flag.Bool and a flag.Int. -// If used as -name, it increments the count, but -name=x sets the count. -// Used for verbose flag -v. -type count int - -func (c *count) String() string { - return fmt.Sprint(int(*c)) -} - -func (c *count) Set(s string) error { - switch s { - case "true": - *c++ - case "false": - *c = 0 - default: - n, err := strconv.Atoi(s) - if err != nil { - return fmt.Errorf("invalid count %q", s) - } - *c = count(n) - } - return nil -} - -func (c *count) Get() interface{} { - return int(*c) -} - -func (c *count) IsBoolFlag() bool { - return true -} - -func (c *count) IsCountFlag() bool { - return true -} - -type fn1 func(string) - -func (f fn1) Set(s string) error { - f(s) - return nil -} - -func (f fn1) String() string { return "" } - -// This file defines the IDs for PCDATA and FUNCDATA instructions -// in Go binaries. -// -// These must agree with ../../../runtime/funcdata.h and -// ../../../runtime/symtab.go. - -const ( - PCDATA_RegMapIndex = 0 // if !go115ReduceLiveness - PCDATA_UnsafePoint = 0 // if go115ReduceLiveness - PCDATA_StackMapIndex = 1 - PCDATA_InlTreeIndex = 2 - - FUNCDATA_ArgsPointerMaps = 0 - FUNCDATA_LocalsPointerMaps = 1 - FUNCDATA_RegPointerMaps = 2 // if !go115ReduceLiveness - FUNCDATA_StackObjects = 3 - FUNCDATA_InlTree = 4 - FUNCDATA_OpenCodedDeferInfo = 5 - - // ArgsSizeUnknown is set in Func.argsize to mark all functions - // whose argument size is unknown (C vararg functions, and - // assembly code without an explicit specification). - // This value is generated by the compiler, assembler, or linker. - ArgsSizeUnknown = -0x80000000 -) - -// Special PCDATA values. -const ( - // PCDATA_RegMapIndex values. - // - // Only if !go115ReduceLiveness. - PCDATA_RegMapUnsafe = -2 // Unsafe for async preemption - - // PCDATA_UnsafePoint values. - PCDATA_UnsafePointSafe = -1 // Safe for async preemption - PCDATA_UnsafePointUnsafe = -2 // Unsafe for async preemption - - // PCDATA_Restart1(2) apply on a sequence of instructions, within - // which if an async preemption happens, we should back off the PC - // to the start of the sequence when resuming. - // We need two so we can distinguish the start/end of the sequence - // in case that two sequences are next to each other. - PCDATA_Restart1 = -3 - PCDATA_Restart2 = -4 - - // Like PCDATA_Restart1, but back to function entry if async preempted. - PCDATA_RestartAtEntry = -5 -) - -// A FuncID identifies particular functions that need to be treated -// specially by the runtime. -// Note that in some situations involving plugins, there may be multiple -// copies of a particular special runtime function. -// Note: this list must match the list in runtime/symtab.go. -type FuncID uint8 - -const ( - FuncID_normal FuncID = iota // not a special function - FuncID_runtime_main - FuncID_goexit - FuncID_jmpdefer - FuncID_mcall - FuncID_morestack - FuncID_mstart - FuncID_rt0_go - FuncID_asmcgocall - FuncID_sigpanic - FuncID_runfinq - FuncID_gcBgMarkWorker - FuncID_systemstack_switch - FuncID_systemstack - FuncID_cgocallback_gofunc - FuncID_gogo - FuncID_externalthreadhandler - FuncID_debugCallV1 - FuncID_gopanic - FuncID_panicwrap - FuncID_handleAsyncEvent - FuncID_asyncPreempt - FuncID_wrapper // any autogenerated code (hash/eq algorithms, method wrappers, etc.) -) - -// Get the function ID for the named function in the named file. -// The function should be package-qualified. -func GetFuncID(name, file string) FuncID { - switch name { - case "runtime.main": - return FuncID_runtime_main - case "runtime.goexit": - return FuncID_goexit - case "runtime.jmpdefer": - return FuncID_jmpdefer - case "runtime.mcall": - return FuncID_mcall - case "runtime.morestack": - return FuncID_morestack - case "runtime.mstart": - return FuncID_mstart - case "runtime.rt0_go": - return FuncID_rt0_go - case "runtime.asmcgocall": - return FuncID_asmcgocall - case "runtime.sigpanic": - return FuncID_sigpanic - case "runtime.runfinq": - return FuncID_runfinq - case "runtime.gcBgMarkWorker": - return FuncID_gcBgMarkWorker - case "runtime.systemstack_switch": - return FuncID_systemstack_switch - case "runtime.systemstack": - return FuncID_systemstack - case "runtime.cgocallback_gofunc": - return FuncID_cgocallback_gofunc - case "runtime.gogo": - return FuncID_gogo - case "runtime.externalthreadhandler": - return FuncID_externalthreadhandler - case "runtime.debugCallV1": - return FuncID_debugCallV1 - case "runtime.gopanic": - return FuncID_gopanic - case "runtime.panicwrap": - return FuncID_panicwrap - case "runtime.handleAsyncEvent": - return FuncID_handleAsyncEvent - case "runtime.asyncPreempt": - return FuncID_asyncPreempt - case "runtime.deferreturn": - // Don't show in the call stack (used when invoking defer functions) - return FuncID_wrapper - case "runtime.runOpenDeferFrame": - // Don't show in the call stack (used when invoking defer functions) - return FuncID_wrapper - case "runtime.reflectcallSave": - // Don't show in the call stack (used when invoking defer functions) - return FuncID_wrapper - } - if file == "" { - return FuncID_wrapper - } - if strings.HasPrefix(name, "runtime.call") { - if _, err := strconv.Atoi(name[12:]); err == nil { - // runtime.callXX reflect call wrappers. - return FuncID_wrapper - } - } - if strings.HasSuffix(name, "-fm") { - return FuncID_wrapper - } - return FuncID_normal -} - -// HeadType is the executable header type. -type HeadType uint8 - -const ( - Hunknown HeadType = iota - Hdarwin - Hdragonfly - Hfreebsd - Hjs - Hlinux - Hnetbsd - Hopenbsd - Hplan9 - Hsolaris - Hwindows - Haix -) - -func (h *HeadType) Set(s string) error { - switch s { - case "aix": - *h = Haix - case "darwin": - *h = Hdarwin - case "dragonfly": - *h = Hdragonfly - case "freebsd": - *h = Hfreebsd - case "js": - *h = Hjs - case "linux", "android": - *h = Hlinux - case "netbsd": - *h = Hnetbsd - case "openbsd": - *h = Hopenbsd - case "plan9": - *h = Hplan9 - case "illumos", "solaris": - *h = Hsolaris - case "windows": - *h = Hwindows - default: - return fmt.Errorf("invalid headtype: %q", s) - } - return nil -} - -func (h *HeadType) String() string { - switch *h { - case Haix: - return "aix" - case Hdarwin: - return "darwin" - case Hdragonfly: - return "dragonfly" - case Hfreebsd: - return "freebsd" - case Hjs: - return "js" - case Hlinux: - return "linux" - case Hnetbsd: - return "netbsd" - case Hopenbsd: - return "openbsd" - case Hplan9: - return "plan9" - case Hsolaris: - return "solaris" - case Hwindows: - return "windows" - } - return fmt.Sprintf("HeadType(%d)", *h) -} - -// WorkingDir returns the current working directory -// (or "/???" if the directory cannot be identified), -// with "/" as separator. -func WorkingDir() string { - var path string - path, _ = os.Getwd() - if path == "" { - path = "/???" - } - return filepath.ToSlash(path) -} - -// AbsFile returns the absolute filename for file in the given directory, -// as rewritten by the rewrites argument. -// For unrewritten paths, AbsFile rewrites a leading $GOROOT prefix to the literal "$GOROOT". -// If the resulting path is the empty string, the result is "??". -// -// The rewrites argument is a ;-separated list of rewrites. -// Each rewrite is of the form "prefix" or "prefix=>replace", -// where prefix must match a leading sequence of path elements -// and is either removed entirely or replaced by the replacement. -func AbsFile(dir, file, rewrites string) string { - abs := file - if dir != "" && !filepath.IsAbs(file) { - abs = filepath.Join(dir, file) - } - - start := 0 - for i := 0; i <= len(rewrites); i++ { - if i == len(rewrites) || rewrites[i] == ';' { - if new, ok := applyRewrite(abs, rewrites[start:i]); ok { - abs = new - goto Rewritten - } - start = i + 1 - } - } - if hasPathPrefix(abs, GOROOT) { - abs = "$GOROOT" + abs[len(GOROOT):] - } - -Rewritten: - if abs == "" { - abs = "??" - } - return abs -} - -// applyRewrite applies the rewrite to the path, -// returning the rewritten path and a boolean -// indicating whether the rewrite applied at all. -func applyRewrite(path, rewrite string) (string, bool) { - prefix, replace := rewrite, "" - if j := strings.LastIndex(rewrite, "=>"); j >= 0 { - prefix, replace = rewrite[:j], rewrite[j+len("=>"):] - } - - if prefix == "" || !hasPathPrefix(path, prefix) { - return path, false - } - if len(path) == len(prefix) { - return replace, true - } - if replace == "" { - return path[len(prefix)+1:], true - } - return replace + path[len(prefix):], true -} - -// Does s have t as a path prefix? -// That is, does s == t or does s begin with t followed by a slash? -// For portability, we allow ASCII case folding, so that hasPathPrefix("a/b/c", "A/B") is true. -// Similarly, we allow slash folding, so that hasPathPrefix("a/b/c", "a\\b") is true. -// We do not allow full Unicode case folding, for fear of causing more confusion -// or harm than good. (For an example of the kinds of things that can go wrong, -// see http://article.gmane.org/gmane.linux.kernel/1853266.) -func hasPathPrefix(s string, t string) bool { - if len(t) > len(s) { - return false - } - var i int - for i = 0; i < len(t); i++ { - cs := int(s[i]) - ct := int(t[i]) - if 'A' <= cs && cs <= 'Z' { - cs += 'a' - 'A' - } - if 'A' <= ct && ct <= 'Z' { - ct += 'a' - 'A' - } - if cs == '\\' { - cs = '/' - } - if ct == '\\' { - ct = '/' - } - if cs != ct { - return false - } - } - return i >= len(s) || s[i] == '/' || s[i] == '\\' -} - -// PathToPrefix converts raw string to the prefix that will be used in the -// symbol table. All control characters, space, '%' and '"', as well as -// non-7-bit clean bytes turn into %xx. The period needs escaping only in the -// last segment of the path, and it makes for happier users if we escape that as -// little as possible. -func PathToPrefix(s string) string { - slash := strings.LastIndex(s, "/") - // check for chars that need escaping - n := 0 - for r := 0; r < len(s); r++ { - if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F { - n++ - } - } - - // quick exit - if n == 0 { - return s - } - - // escape - const hex = "0123456789abcdef" - p := make([]byte, 0, len(s)+2*n) - for r := 0; r < len(s); r++ { - if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F { - p = append(p, '%', hex[c>>4], hex[c&0xF]) - } else { - p = append(p, c) - } - } - - return string(p) -} - -type RelocType int16 - -//go:generate stringer -type=RelocType -const ( - R_ADDR RelocType = 1 + iota - // R_ADDRPOWER relocates a pair of "D-form" instructions (instructions with 16-bit - // immediates in the low half of the instruction word), usually addis followed by - // another add or a load, inserting the "high adjusted" 16 bits of the address of - // the referenced symbol into the immediate field of the first instruction and the - // low 16 bits into that of the second instruction. - R_ADDRPOWER - // R_ADDRARM64 relocates an adrp, add pair to compute the address of the - // referenced symbol. - R_ADDRARM64 - // R_ADDRMIPS (only used on mips/mips64) resolves to the low 16 bits of an external - // address, by encoding it into the instruction. - R_ADDRMIPS - // R_ADDROFF resolves to a 32-bit offset from the beginning of the section - // holding the data being relocated to the referenced symbol. - R_ADDROFF - // R_WEAKADDROFF resolves just like R_ADDROFF but is a weak relocation. - // A weak relocation does not make the symbol it refers to reachable, - // and is only honored by the linker if the symbol is in some other way - // reachable. - R_WEAKADDROFF - R_SIZE - R_CALL - R_CALLARM - R_CALLARM64 - R_CALLIND - R_CALLPOWER - // R_CALLMIPS (only used on mips64) resolves to non-PC-relative target address - // of a CALL (JAL) instruction, by encoding the address into the instruction. - R_CALLMIPS - // R_CALLRISCV marks RISC-V CALLs for stack checking. - R_CALLRISCV - R_CONST - R_PCREL - // R_TLS_LE, used on 386, amd64, and ARM, resolves to the offset of the - // thread-local symbol from the thread local base and is used to implement the - // "local exec" model for tls access (r.Sym is not set on intel platforms but is - // set to a TLS symbol -- runtime.tlsg -- in the linker when externally linking). - R_TLS_LE - // R_TLS_IE, used 386, amd64, and ARM resolves to the PC-relative offset to a GOT - // slot containing the offset from the thread-local symbol from the thread local - // base and is used to implemented the "initial exec" model for tls access (r.Sym - // is not set on intel platforms but is set to a TLS symbol -- runtime.tlsg -- in - // the linker when externally linking). - R_TLS_IE - R_GOTOFF - R_PLT0 - R_PLT1 - R_PLT2 - R_USEFIELD - // R_USETYPE resolves to an *rtype, but no relocation is created. The - // linker uses this as a signal that the pointed-to type information - // should be linked into the final binary, even if there are no other - // direct references. (This is used for types reachable by reflection.) - R_USETYPE - // R_METHODOFF resolves to a 32-bit offset from the beginning of the section - // holding the data being relocated to the referenced symbol. - // It is a variant of R_ADDROFF used when linking from the uncommonType of a - // *rtype, and may be set to zero by the linker if it determines the method - // text is unreachable by the linked program. - R_METHODOFF - R_POWER_TOC - R_GOTPCREL - // R_JMPMIPS (only used on mips64) resolves to non-PC-relative target address - // of a JMP instruction, by encoding the address into the instruction. - // The stack nosplit check ignores this since it is not a function call. - R_JMPMIPS - - // R_DWARFSECREF resolves to the offset of the symbol from its section. - // Target of relocation must be size 4 (in current implementation). - R_DWARFSECREF - - // R_DWARFFILEREF resolves to an index into the DWARF .debug_line - // file table for the specified file symbol. Must be applied to an - // attribute of form DW_FORM_data4. - R_DWARFFILEREF - - // Platform dependent relocations. Architectures with fixed width instructions - // have the inherent issue that a 32-bit (or 64-bit!) displacement cannot be - // stuffed into a 32-bit instruction, so an address needs to be spread across - // several instructions, and in turn this requires a sequence of relocations, each - // updating a part of an instruction. This leads to relocation codes that are - // inherently processor specific. - - // Arm64. - - // Set a MOV[NZ] immediate field to bits [15:0] of the offset from the thread - // local base to the thread local variable defined by the referenced (thread - // local) symbol. Error if the offset does not fit into 16 bits. - R_ARM64_TLS_LE - - // Relocates an ADRP; LD64 instruction sequence to load the offset between - // the thread local base and the thread local variable defined by the - // referenced (thread local) symbol from the GOT. - R_ARM64_TLS_IE - - // R_ARM64_GOTPCREL relocates an adrp, ld64 pair to compute the address of the GOT - // slot of the referenced symbol. - R_ARM64_GOTPCREL - - // R_ARM64_GOT resolves a GOT-relative instruction sequence, usually an adrp - // followed by another ld instruction. - R_ARM64_GOT - - // R_ARM64_PCREL resolves a PC-relative addresses instruction sequence, usually an - // adrp followed by another add instruction. - R_ARM64_PCREL - - // R_ARM64_LDST8 sets a LD/ST immediate value to bits [11:0] of a local address. - R_ARM64_LDST8 - - // R_ARM64_LDST32 sets a LD/ST immediate value to bits [11:2] of a local address. - R_ARM64_LDST32 - - // R_ARM64_LDST64 sets a LD/ST immediate value to bits [11:3] of a local address. - R_ARM64_LDST64 - - // R_ARM64_LDST128 sets a LD/ST immediate value to bits [11:4] of a local address. - R_ARM64_LDST128 - - // PPC64. - - // R_POWER_TLS_LE is used to implement the "local exec" model for tls - // access. It resolves to the offset of the thread-local symbol from the - // thread pointer (R13) and inserts this value into the low 16 bits of an - // instruction word. - R_POWER_TLS_LE - - // R_POWER_TLS_IE is used to implement the "initial exec" model for tls access. It - // relocates a D-form, DS-form instruction sequence like R_ADDRPOWER_DS. It - // inserts to the offset of GOT slot for the thread-local symbol from the TOC (the - // GOT slot is filled by the dynamic linker with the offset of the thread-local - // symbol from the thread pointer (R13)). - R_POWER_TLS_IE - - // R_POWER_TLS marks an X-form instruction such as "MOVD 0(R13)(R31*1), g" as - // accessing a particular thread-local symbol. It does not affect code generation - // but is used by the system linker when relaxing "initial exec" model code to - // "local exec" model code. - R_POWER_TLS - - // R_ADDRPOWER_DS is similar to R_ADDRPOWER above, but assumes the second - // instruction is a "DS-form" instruction, which has an immediate field occupying - // bits [15:2] of the instruction word. Bits [15:2] of the address of the - // relocated symbol are inserted into this field; it is an error if the last two - // bits of the address are not 0. - R_ADDRPOWER_DS - - // R_ADDRPOWER_PCREL relocates a D-form, DS-form instruction sequence like - // R_ADDRPOWER_DS but inserts the offset of the GOT slot for the referenced symbol - // from the TOC rather than the symbol's address. - R_ADDRPOWER_GOT - - // R_ADDRPOWER_PCREL relocates two D-form instructions like R_ADDRPOWER, but - // inserts the displacement from the place being relocated to the address of the - // relocated symbol instead of just its address. - R_ADDRPOWER_PCREL - - // R_ADDRPOWER_TOCREL relocates two D-form instructions like R_ADDRPOWER, but - // inserts the offset from the TOC to the address of the relocated symbol - // rather than the symbol's address. - R_ADDRPOWER_TOCREL - - // R_ADDRPOWER_TOCREL relocates a D-form, DS-form instruction sequence like - // R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the - // relocated symbol rather than the symbol's address. - R_ADDRPOWER_TOCREL_DS - - // RISC-V. - - // R_RISCV_PCREL_ITYPE resolves a 32-bit PC-relative address using an - // AUIPC + I-type instruction pair. - R_RISCV_PCREL_ITYPE - - // R_RISCV_PCREL_STYPE resolves a 32-bit PC-relative address using an - // AUIPC + S-type instruction pair. - R_RISCV_PCREL_STYPE - - // R_PCRELDBL relocates s390x 2-byte aligned PC-relative addresses. - // TODO(mundaym): remove once variants can be serialized - see issue 14218. - R_PCRELDBL - - // R_ADDRMIPSU (only used on mips/mips64) resolves to the sign-adjusted "upper" 16 - // bits (bit 16-31) of an external address, by encoding it into the instruction. - R_ADDRMIPSU - // R_ADDRMIPSTLS (only used on mips64) resolves to the low 16 bits of a TLS - // address (offset from thread pointer), by encoding it into the instruction. - R_ADDRMIPSTLS - - // R_ADDRCUOFF resolves to a pointer-sized offset from the start of the - // symbol's DWARF compile unit. - R_ADDRCUOFF - - // R_WASMIMPORT resolves to the index of the WebAssembly function import. - R_WASMIMPORT - - // R_XCOFFREF (only used on aix/ppc64) prevents garbage collection by ld - // of a symbol. This isn't a real relocation, it can be placed in anywhere - // in a symbol and target any symbols. - R_XCOFFREF -) - -// IsDirectCall reports whether r is a relocation for a direct call. -// A direct call is a CALL instruction that takes the target address -// as an immediate. The address is embedded into the instruction, possibly -// with limited width. An indirect call is a CALL instruction that takes -// the target address in register or memory. -func (r RelocType) IsDirectCall() bool { - switch r { - case R_CALL, R_CALLARM, R_CALLARM64, R_CALLMIPS, R_CALLPOWER, R_CALLRISCV: - return true - } - return false -} - -// IsDirectJump reports whether r is a relocation for a direct jump. -// A direct jump is a JMP instruction that takes the target address -// as an immediate. The address is embedded into the instruction, possibly -// with limited width. An indirect jump is a JMP instruction that takes -// the target address in register or memory. -func (r RelocType) IsDirectJump() bool { - switch r { - case R_JMPMIPS: - return true - } - return false -} - -// IsDirectCallOrJump reports whether r is a relocation for a direct -// call or a direct jump. -func (r RelocType) IsDirectCallOrJump() bool { - return r.IsDirectCall() || r.IsDirectJump() -} - -const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_WEAKADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CALLRISCVR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_METHODOFFR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_LDST8R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_PCRELDBLR_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF" - -var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 60, 66, 72, 81, 92, 101, 112, 122, 133, 140, 147, 155, 163, 171, 177, 183, 189, 199, 208, 219, 230, 240, 249, 262, 276, 290, 304, 320, 331, 344, 357, 371, 385, 400, 414, 428, 439, 453, 468, 485, 503, 524, 543, 562, 572, 583, 596, 607, 619, 629} - -func (i RelocType) String() string { - i -= 1 - if i < 0 || i >= RelocType(len(_RelocType_index)-1) { - return "RelocType(" + strconv.FormatInt(int64(i+1), 10) + ")" - } - return _RelocType_name[_RelocType_index[i]:_RelocType_index[i+1]] -} - -// For the linkers. Must match Go definitions. - -const ( - STACKSYSTEM = 0 - StackSystem = STACKSYSTEM - StackBig = 4096 - StackSmall = 128 -) - -const ( - StackPreempt = -1314 // 0xfff...fade -) - -// Initialize StackGuard and StackLimit according to target system. -var StackGuard = 928*stackGuardMultiplier() + StackSystem - -var StackLimit = StackGuard - StackSystem - StackSmall - -// stackGuardMultiplier returns a multiplier to apply to the default -// stack guard size. Larger multipliers are used for non-optimized -// builds that have larger stack frames or for specific targets. -func stackGuardMultiplier() int { - // On AIX, a larger stack is needed for syscalls. - if GOOS == "aix" { - return 2 - } - return stackGuardMultiplierDefault -} - -// A SymKind describes the kind of memory represented by a symbol. -type SymKind uint8 - -// Defined SymKind values. -// These are used to index into cmd/link/internal/sym/AbiSymKindToSymKind -// -// TODO(rsc): Give idiomatic Go names. -// -//go:generate stringer -type=SymKind -const ( - // An otherwise invalid zero value for the type - Sxxx SymKind = iota - // Executable instructions - STEXT - // Read only static data - SRODATA - // Static data that does not contain any pointers - SNOPTRDATA - // Static data - SDATA - // Statically data that is initially all 0s - SBSS - // Statically data that is initially all 0s and does not contain pointers - SNOPTRBSS - // Thread-local data that is initially all 0s - STLSBSS - // Debugging data - SDWARFINFO - SDWARFRANGE - SDWARFLOC - SDWARFLINES - // ABI alias. An ABI alias symbol is an empty symbol with a - // single relocation with 0 size that references the native - // function implementation symbol. - // - // TODO(austin): Remove this and all uses once the compiler - // generates real ABI wrappers rather than symbol aliases. - SABIALIAS - // Coverage instrumentation counter for libfuzzer. - SLIBFUZZER_EXTRA_COUNTER - // Update cmd/link/internal/sym/AbiSymKindToSymKind for new SymKind values. - -) - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[Sxxx-0] - _ = x[STEXT-1] - _ = x[SRODATA-2] - _ = x[SNOPTRDATA-3] - _ = x[SDATA-4] - _ = x[SBSS-5] - _ = x[SNOPTRBSS-6] - _ = x[STLSBSS-7] - _ = x[SDWARFINFO-8] - _ = x[SDWARFRANGE-9] - _ = x[SDWARFLOC-10] - _ = x[SDWARFLINES-11] - _ = x[SABIALIAS-12] - _ = x[SLIBFUZZER_EXTRA_COUNTER-13] -} - -const _SymKind_name = "SxxxSTEXTSRODATASNOPTRDATASDATASBSSSNOPTRBSSSTLSBSSSDWARFINFOSDWARFRANGESDWARFLOCSDWARFLINESSABIALIASSLIBFUZZER_EXTRA_COUNTER" - -var _SymKind_index = [...]uint8{0, 4, 9, 16, 26, 31, 35, 44, 51, 61, 72, 81, 92, 101, 125} - -func (i SymKind) String() string { - if i >= SymKind(len(_SymKind_index)-1) { - return "SymKind(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _SymKind_name[_SymKind_index[i]:_SymKind_index[i+1]] -} - -// Must match runtime and reflect. -// Included by cmd/gc. - -const ( - KindBool = 1 + iota - KindInt - KindInt8 - KindInt16 - KindInt32 - KindInt64 - KindUint - KindUint8 - KindUint16 - KindUint32 - KindUint64 - KindUintptr - KindFloat32 - KindFloat64 - KindComplex64 - KindComplex128 - KindArray - KindChan - KindFunc - KindInterface - KindMap - KindPtr - KindSlice - KindString - KindStruct - KindUnsafePointer - KindDirectIface = 1 << 5 - KindGCProg = 1 << 6 - KindMask = (1 << 5) - 1 -) - -func envOr(key, value string) string { - if x := os.Getenv(key); x != "" { - return x - } - return value -} - -var ( - defaultGOROOT string // set by linker - - GOROOT = envOr("GOROOT", defaultGOROOT) - GOARCH = envOr("GOARCH", defaultGOARCH) - GOOS = envOr("GOOS", defaultGOOS) - GO386 = envOr("GO386", defaultGO386) - GOAMD64 = goamd64() - GOARM = goarm() - GOMIPS = gomips() - GOMIPS64 = gomips64() - GOPPC64 = goppc64() - GOWASM = gowasm() - GO_LDSO = defaultGO_LDSO - Version = version -) - -const ( - ElfRelocOffset = 256 - MachoRelocOffset = 2048 // reserve enough space for ELF relocations - Go115AMD64 = "alignedjumps" // Should be "alignedjumps" or "normaljumps"; this replaces environment variable introduced in CL 219357. -) - -// TODO(1.16): assuming no issues in 1.15 release, remove this and related constant. -func goamd64() string { - return Go115AMD64 -} - -func goarm() int { - switch v := envOr("GOARM", defaultGOARM); v { - case "5": - return 5 - case "6": - return 6 - case "7": - return 7 - } - // Fail here, rather than validate at multiple call sites. - log.Fatalf("Invalid GOARM value. Must be 5, 6, or 7.") - panic("unreachable") -} - -func gomips() string { - switch v := envOr("GOMIPS", defaultGOMIPS); v { - case "hardfloat", "softfloat": - return v - } - log.Fatalf("Invalid GOMIPS value. Must be hardfloat or softfloat.") - panic("unreachable") -} - -func gomips64() string { - switch v := envOr("GOMIPS64", defaultGOMIPS64); v { - case "hardfloat", "softfloat": - return v - } - log.Fatalf("Invalid GOMIPS64 value. Must be hardfloat or softfloat.") - panic("unreachable") -} - -func goppc64() int { - switch v := envOr("GOPPC64", defaultGOPPC64); v { - case "power8": - return 8 - case "power9": - return 9 - } - log.Fatalf("Invalid GOPPC64 value. Must be power8 or power9.") - panic("unreachable") -} - -type gowasmFeatures struct { - SignExt bool - SatConv bool -} - -func (f gowasmFeatures) String() string { - var flags []string - if f.SatConv { - flags = append(flags, "satconv") - } - if f.SignExt { - flags = append(flags, "signext") - } - return strings.Join(flags, ",") -} - -func gowasm() (f gowasmFeatures) { - for _, opt := range strings.Split(envOr("GOWASM", ""), ",") { - switch opt { - case "satconv": - f.SatConv = true - case "signext": - f.SignExt = true - case "": - // ignore - default: - log.Fatalf("Invalid GOWASM value. No such feature: " + opt) - } - } - return -} - -func Getgoextlinkenabled() string { - return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED) -} - -func init() { - for _, f := range strings.Split(goexperiment, ",") { - if f != "" { - addexp(f) - } - } -} - -func Framepointer_enabled(goos, goarch string) bool { - return framepointer_enabled != 0 && (goarch == "amd64" || goarch == "arm64" && (goos == "linux" || goos == "darwin")) -} - -func addexp(s string) { - // Could do general integer parsing here, but the runtime copy doesn't yet. - v := 1 - name := s - if len(name) > 2 && name[:2] == "no" { - v = 0 - name = name[2:] - } - for i := 0; i < len(exper); i++ { - if exper[i].name == name { - if exper[i].val != nil { - *exper[i].val = v - } - return - } - } - - fmt.Printf("unknown experiment %s\n", s) - os.Exit(2) -} - -var ( - framepointer_enabled int = 1 - Fieldtrack_enabled int - Preemptibleloops_enabled int - Staticlockranking_enabled int -) - -// Toolchain experiments. -// These are controlled by the GOEXPERIMENT environment -// variable recorded when the toolchain is built. -// This list is also known to cmd/gc. -var exper = []struct { - name string - val *int -}{ - {"fieldtrack", &Fieldtrack_enabled}, - {"framepointer", &framepointer_enabled}, - {"preemptibleloops", &Preemptibleloops_enabled}, - {"staticlockranking", &Staticlockranking_enabled}, -} - -var defaultExpstring = Expstring() - -func DefaultExpstring() string { - return defaultExpstring -} - -func Expstring() string { - buf := "X" - for i := range exper { - if *exper[i].val != 0 { - buf += "," + exper[i].name - } - } - if buf == "X" { - buf += ",none" - } - return "X:" + buf[2:] -} - -const defaultGO386 = `sse2` - -const defaultGOARM = `5` - -const defaultGOMIPS = `hardfloat` - -const defaultGOMIPS64 = `hardfloat` - -const defaultGOPPC64 = `power8` - -const defaultGOOS = runtime.GOOS - -const defaultGOARCH = runtime.GOARCH - -const defaultGO_EXTLINK_ENABLED = `` - -const defaultGO_LDSO = `` - -const version = `devel +11f92e9 Mon Jul 20 18:18:56 2020 +0000` - -const stackGuardMultiplierDefault = 1 - -const goexperiment = `` diff --git a/odiglet/pkg/allocator/debug/goobj2/internal/unsafeheader/unsafeheader.go b/odiglet/pkg/allocator/debug/goobj2/internal/unsafeheader/unsafeheader.go deleted file mode 100644 index e592239ac0..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/internal/unsafeheader/unsafeheader.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT. -//go:generate bundle -o unsafeheader.go -prefix= internal/unsafeheader - -// Package unsafeheader contains header declarations for the Go runtime's slice -// and string implementations. -// -// This package allows packages that cannot import "reflect" to use types that -// are tested to be equivalent to reflect.SliceHeader and reflect.StringHeader. -// - -package unsafeheader - -import ( - "unsafe" -) - -// Slice is the runtime representation of a slice. -// It cannot be used safely or portably and its representation may -// change in a later release. -// -// Unlike reflect.SliceHeader, its Data field is sufficient to guarantee the -// data it references will not be garbage collected. -type Slice struct { - Data unsafe.Pointer - Len int - Cap int -} - -// String is the runtime representation of a string. -// It cannot be used safely or portably and its representation may -// change in a later release. -// -// Unlike reflect.StringHeader, its Data field is sufficient to guarantee the -// data it references will not be garbage collected. -type String struct { - Data unsafe.Pointer - Len int -} diff --git a/odiglet/pkg/allocator/debug/goobj2/testdata/aes_encrypt.go b/odiglet/pkg/allocator/debug/goobj2/testdata/aes_encrypt.go deleted file mode 100644 index 9cabe45075..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/testdata/aes_encrypt.go +++ /dev/null @@ -1,39 +0,0 @@ -package main - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/rand" - "encoding/hex" - "fmt" - "io" -) - -func main() { - // Load your secret key from a safe place and reuse it across multiple - // Seal/Open calls. (Obviously don't use this example key for anything - // real.) If you want to convert a passphrase to a key, use a suitable - // package like bcrypt or scrypt. - // When decoded the key should be 16 bytes (AES-128) or 32 (AES-256). - key, _ := hex.DecodeString("6368616e676520746869732070617373776f726420746f206120736563726574") - plaintext := []byte("exampleplaintext") - - block, err := aes.NewCipher(key) - if err != nil { - panic(err.Error()) - } - - // Never use more than 2^32 random nonces with a given key because of the risk of a repeat. - nonce := make([]byte, 12) - if _, err := io.ReadFull(rand.Reader, nonce); err != nil { - panic(err.Error()) - } - - aesgcm, err := cipher.NewGCM(block) - if err != nil { - panic(err.Error()) - } - - ciphertext := aesgcm.Seal(nil, nonce, plaintext, nil) - fmt.Printf("%x\n", ciphertext) -} diff --git a/odiglet/pkg/allocator/debug/goobj2/testdata/format.go b/odiglet/pkg/allocator/debug/goobj2/testdata/format.go deleted file mode 100644 index 9d00462b49..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/testdata/format.go +++ /dev/null @@ -1,33 +0,0 @@ -package main - -import ( - "bytes" - "fmt" - "go/format" - "go/parser" - "go/token" - "log" -) - -func main() { - const expr = "(6+2*3)/4" - - // parser.ParseExpr parses the argument and returns the - // corresponding ast.Node. - node, err := parser.ParseExpr(expr) - if err != nil { - log.Fatal(err) - } - - // Create a FileSet for node. Since the node does not come - // from a real source file, fset will be empty. - fset := token.NewFileSet() - - var buf bytes.Buffer - err = format.Node(&buf, fset, node) - if err != nil { - log.Fatal(err) - } - - fmt.Println(buf.String()) -} diff --git a/odiglet/pkg/allocator/debug/goobj2/testdata/hello_world.go b/odiglet/pkg/allocator/debug/goobj2/testdata/hello_world.go deleted file mode 100644 index b1b14d0c79..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/testdata/hello_world.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import "fmt" - -func main() { - fmt.Println("Hello World!") -} diff --git a/odiglet/pkg/allocator/debug/goobj2/testdata/http_not_found_handler.go b/odiglet/pkg/allocator/debug/goobj2/testdata/http_not_found_handler.go deleted file mode 100644 index 9bf6aeff16..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/testdata/http_not_found_handler.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import ( - "fmt" - "log" - "net/http" -) - -func newPeopleHandler() http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, "This is the people handler.") - }) -} - -func main() { - mux := http.NewServeMux() - - // Create sample handler to returns 404 - mux.Handle("/resources", http.NotFoundHandler()) - - // Create sample handler that returns 200 - mux.Handle("/resources/people/", newPeopleHandler()) - - log.Fatal(http.ListenAndServe(":8080", mux)) -} diff --git a/odiglet/pkg/allocator/debug/goobj2/testdata/loop_de_loop.go b/odiglet/pkg/allocator/debug/goobj2/testdata/loop_de_loop.go deleted file mode 100644 index e7a6b5e62e..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/testdata/loop_de_loop.go +++ /dev/null @@ -1,12 +0,0 @@ -package main - -import "fmt" - -func main() { - fmt.Println("I like fruit loops") - - j := 0 - for i := 0; i < 10; i++ { - fmt.Println(i, j-i) - } -} diff --git a/odiglet/pkg/allocator/debug/goobj2/testdata/reflect.go b/odiglet/pkg/allocator/debug/goobj2/testdata/reflect.go deleted file mode 100644 index d96a054e75..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/testdata/reflect.go +++ /dev/null @@ -1,43 +0,0 @@ -package main - -import ( - "bytes" - "encoding/json" - "fmt" - "reflect" -) - -func main() { - typ := reflect.StructOf([]reflect.StructField{ - { - Name: "Height", - Type: reflect.TypeOf(float64(0)), - Tag: `json:"height"`, - }, - { - Name: "Age", - Type: reflect.TypeOf(int(0)), - Tag: `json:"age"`, - }, - }) - - v := reflect.New(typ).Elem() - v.Field(0).SetFloat(0.4) - v.Field(1).SetInt(2) - s := v.Addr().Interface() - - w := new(bytes.Buffer) - if err := json.NewEncoder(w).Encode(s); err != nil { - panic(err) - } - - fmt.Printf("value: %+v\n", s) - fmt.Printf("json: %s", w.Bytes()) - - r := bytes.NewReader([]byte(`{"height":1.5,"age":10}`)) - if err := json.NewDecoder(r).Decode(s); err != nil { - panic(err) - } - fmt.Printf("value: %+v\n", s) - -} diff --git a/odiglet/pkg/allocator/debug/goobj2/testdata/trim_string.go b/odiglet/pkg/allocator/debug/goobj2/testdata/trim_string.go deleted file mode 100644 index cd6e4b1b1d..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/testdata/trim_string.go +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "fmt" - "strings" -) - -func main() { - s := "prefix this should be all you see" - trimmed := strings.TrimPrefix(s, "prefix") - if trimmed != "this should be all you see" { - fmt.Println("oh noes") - } - - fmt.Println(trimmed) -} diff --git a/odiglet/pkg/allocator/debug/goobj2/write.go b/odiglet/pkg/allocator/debug/goobj2/write.go deleted file mode 100644 index 9757d10f15..0000000000 --- a/odiglet/pkg/allocator/debug/goobj2/write.go +++ /dev/null @@ -1,412 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Writing Go object files. - -// This file is a modified version of cmd/internal/obj/objfile2.go - -package goobj2 - -import ( - "bytes" - "fmt" - "github.com/keyval-dev/odigos/odiglet/pkg/allocator/debug/goobj2/internal/bio" - "github.com/keyval-dev/odigos/odiglet/pkg/allocator/debug/goobj2/internal/goobj2" - "path/filepath" - "strings" -) - -// Write writes the contents of the parsed archive to disk. -func (pkg *Package) Write(path string) (err error) { - b, err := bio.Create(path) - if err != nil { - return fmt.Errorf("error creating object file: %v", err) - } - defer func() { - closeErr := b.Close() - if closeErr != nil && err == nil { - err = closeErr - } - }() - - // Archive headers - b.Write(archiveHeader) - var arhdr [archiveHeaderLen]byte - var curArHdrOff, curObjStartOff int64 - for i := range pkg.ArchiveMembers { - ctxt := &pkg.ArchiveMembers[i] - ar := ctxt.ArchiveHeader - curArHdrOff = b.Offset() - - copy(arhdr[:], fmt.Sprintf("%-16s%-12s%-6s%-6s%-8s%-10d`\n", ar.Name, ar.Date, ar.UID, ar.GID, ar.Mode, ar.Size)) - b.Write(arhdr[:]) - curObjStartOff = b.Offset() - b.Write(ar.Data) - if ctxt.IsDataObj { - continue - } - - genFuncInfoSyms(ctxt) - - w := writer{ - Writer: goobj2.NewWriter(b), - ctxt: ctxt, - } - - start := b.Offset() - - // Header - // We just reserve the space. We'll fill in the offsets later. - ctxt.ObjHeader.Write(w.Writer) - - // String table - w.StringTable() - - // Autolib - ctxt.ObjHeader.Offsets[goobj2.BlkAutolib] = w.Offset() - for i := range ctxt.Imports { - ctxt.Imports[i].Write(w.Writer) - } - - // Package references - ctxt.ObjHeader.Offsets[goobj2.BlkPkgIdx] = w.Offset() - w.StringRef("") - for _, pkg := range ctxt.Packages { - w.StringRef(pkg) - } - - // DWARF file table - ctxt.ObjHeader.Offsets[goobj2.BlkDwarfFile] = w.Offset() - for _, f := range ctxt.DWARFFileList { - w.StringRef(filepath.ToSlash(f)) - } - - // Symbol definitions - ctxt.ObjHeader.Offsets[goobj2.BlkSymdef] = w.Offset() - for _, s := range ctxt.SymDefs { - w.Sym(s) - } - - // Non-pkg symbol definitions - ctxt.ObjHeader.Offsets[goobj2.BlkNonpkgdef] = w.Offset() - for _, s := range ctxt.NonPkgSymDefs { - w.Sym(s) - } - - // Non-pkg symbol references - ctxt.ObjHeader.Offsets[goobj2.BlkNonpkgref] = w.Offset() - for _, s := range ctxt.NonPkgSymRefs { - w.Sym(s) - } - - // Reloc indexes - ctxt.ObjHeader.Offsets[goobj2.BlkRelocIdx] = w.Offset() - nreloc := uint32(0) - lists := [][]*Sym{ctxt.SymDefs, ctxt.NonPkgSymDefs} - for _, list := range lists { - for _, s := range list { - w.Uint32(nreloc) - nreloc += uint32(len(s.Reloc)) - } - } - w.Uint32(nreloc) - - // Symbol Info indexes - ctxt.ObjHeader.Offsets[goobj2.BlkAuxIdx] = w.Offset() - naux := uint32(0) - for _, list := range lists { - for _, s := range list { - w.Uint32(naux) - naux += uint32(nAuxSym(s)) - } - } - w.Uint32(naux) - - // Data indexes - ctxt.ObjHeader.Offsets[goobj2.BlkDataIdx] = w.Offset() - dataOff := uint32(0) - for _, list := range lists { - for _, s := range list { - w.Uint32(dataOff) - dataOff += uint32(len(s.Data)) - } - } - w.Uint32(dataOff) - - // Relocs - ctxt.ObjHeader.Offsets[goobj2.BlkReloc] = w.Offset() - for _, list := range lists { - for _, s := range list { - for i := range s.Reloc { - w.Reloc(&s.Reloc[i]) - } - } - } - - // Aux symbol info - ctxt.ObjHeader.Offsets[goobj2.BlkAux] = w.Offset() - for _, list := range lists { - for _, s := range list { - w.Aux(s) - } - } - - // Data - ctxt.ObjHeader.Offsets[goobj2.BlkData] = w.Offset() - for _, list := range lists { - for _, s := range list { - w.Bytes(s.Data) - } - } - - // Pcdata - ctxt.ObjHeader.Offsets[goobj2.BlkPcdata] = w.Offset() - for _, ts := range ctxt.textSyms { - w.Bytes(ts.Func.PCSP) - w.Bytes(ts.Func.PCFile) - w.Bytes(ts.Func.PCLine) - w.Bytes(ts.Func.PCInline) - for i := range ts.Func.PCData { - w.Bytes(ts.Func.PCData[i]) - } - } - - // Referenced symbol names from other packages - ctxt.ObjHeader.Offsets[goobj2.BlkRefName] = w.Offset() - for _, ref := range ctxt.SymRefs { - var o goobj2.RefName - o.SetSym(ref.SymRef) - o.SetName(ref.Name, w.Writer) - o.Write(w.Writer) - } - - objEnd := w.Offset() - ctxt.ObjHeader.Offsets[goobj2.BlkEnd] = objEnd - - // If the object size is odd, make it even by adding an - // extra null byte as padding - size := int64(objEnd) + (start - curObjStartOff) - end := start + int64(w.Offset()) - if size%2 != 0 { - b.WriteByte(0x00) - end++ - } - - // Fix size field of the last archive header - b.MustSeek(curArHdrOff+48, 0) - b.WriteString(fmt.Sprintf("%-10d", size)) - - // Fix up block offsets in the object header - b.MustSeek(start, 0) - ctxt.ObjHeader.Write(w.Writer) - b.MustSeek(end, 0) - } - - return nil -} - -type writer struct { - *goobj2.Writer - ctxt *ArchiveMember -} - -func (w *writer) StringTable() { - w.AddString("") - for _, p := range w.ctxt.Imports { - w.AddString(p.Pkg) - } - for _, pkg := range w.ctxt.Packages { - w.AddString(pkg) - } - - writeSymStrings := func(s *Sym) { - w.AddString(s.Name) - - for _, r := range s.Reloc { - w.AddString(r.Name) - } - if s.Type != nil { - w.AddString(s.Name) - } - - if s.Kind == STEXT && s.Func != nil { - for _, d := range s.Func.FuncData { - w.AddString(d.Sym.Name) - } - for _, f := range s.Func.File { - w.AddString(filepath.ToSlash(f.Name)) - } - for _, call := range s.Func.InlTree { - w.AddString(call.File.Name) - w.AddString(call.Func.Name) - } - - dwsyms := []*SymRef{s.Func.DwarfRanges, s.Func.DwarfLoc, s.Func.DwarfDebugLines, s.Func.FuncInfo} - for _, dws := range dwsyms { - if dws != nil { - w.AddString(dws.Name) - } - } - } - } - - // Symbols of type STEXT (that have functions) are written first - for _, ts := range w.ctxt.textSyms { - writeSymStrings(ts) - } - - syms := [][]*Sym{w.ctxt.NonPkgSymDefs, w.ctxt.SymDefs, w.ctxt.NonPkgSymRefs} - for _, list := range syms { - for _, s := range list { - if s.Kind == STEXT { - continue - } - - writeSymStrings(s) - } - } - for _, r := range w.ctxt.SymRefs { - w.AddString(r.Name) - } - - for _, f := range w.ctxt.DWARFFileList { - w.AddString(filepath.ToSlash(f)) - } -} - -func (w *writer) Sym(s *Sym) { - name := s.Name - if strings.HasPrefix(name, "gofile..") { - name = filepath.ToSlash(name) - } - - var o goobj2.Sym - o.SetName(name, w.Writer) - o.SetABI(s.ABI) - o.SetType(uint8(s.Kind)) - o.SetFlag(s.Flag) - o.SetSiz(s.Size) - o.SetAlign(s.Align) - o.Write(w.Writer) -} - -func (w *writer) Reloc(r *Reloc) { - var o goobj2.Reloc - o.SetOff(int32(r.Offset)) - o.SetSiz(uint8(r.Size)) - o.SetType(uint8(r.Type)) - o.SetAdd(r.Add) - o.SetSym(r.Sym) - o.Write(w.Writer) -} - -func (w *writer) aux1(typ uint8, rs goobj2.SymRef) { - var o goobj2.Aux - o.SetType(typ) - o.SetSym(rs) - o.Write(w.Writer) -} - -func (w *writer) Aux(s *Sym) { - if s.Type != nil { - w.aux1(goobj2.AuxGotype, s.Type.SymRef) - } - if s.Func != nil { - w.aux1(goobj2.AuxFuncInfo, s.Func.FuncInfo.SymRef) - - for _, d := range s.Func.FuncData { - w.aux1(goobj2.AuxFuncdata, d.Sym.SymRef) - } - - if s.Func.DwarfInfo != nil { - w.aux1(goobj2.AuxDwarfInfo, s.Func.DwarfInfo.SymRef) - } - if s.Func.DwarfLoc != nil { - w.aux1(goobj2.AuxDwarfLoc, s.Func.DwarfLoc.SymRef) - } - if s.Func.DwarfRanges != nil { - w.aux1(goobj2.AuxDwarfRanges, s.Func.DwarfRanges.SymRef) - } - if s.Func.DwarfDebugLines != nil { - w.aux1(goobj2.AuxDwarfLines, s.Func.DwarfDebugLines.SymRef) - } - } -} - -// return the number of aux symbols s have. -func nAuxSym(s *Sym) int { - n := 0 - if s.Type != nil { - n++ - } - if s.Func != nil { - // FuncInfo is an aux symbol, each Funcdata is an aux symbol - n += 1 + len(s.Func.FuncData) - if s.Func.DwarfInfo != nil { - n++ - } - if s.Func.DwarfLoc != nil { - n++ - } - if s.Func.DwarfRanges != nil { - n++ - } - if s.Func.DwarfDebugLines != nil { - n++ - } - } - return n -} - -// generate symbols for FuncInfo. -func genFuncInfoSyms(ctxt *ArchiveMember) { - var pcdataoff uint32 - var b bytes.Buffer - for _, s := range ctxt.textSyms { - if s.Func == nil { - continue - } - - o := goobj2.FuncInfo{ - Args: uint32(s.Func.Args), - Locals: uint32(s.Func.Frame), - } - o.Pcsp = pcdataoff - pcdataoff += uint32(len(s.Func.PCSP)) - o.Pcfile = pcdataoff - pcdataoff += uint32(len(s.Func.PCFile)) - o.Pcline = pcdataoff - pcdataoff += uint32(len(s.Func.PCLine)) - o.Pcinline = pcdataoff - pcdataoff += uint32(len(s.Func.PCInline)) - o.Pcdata = make([]uint32, len(s.Func.PCData)) - for i, pcd := range s.Func.PCData { - o.Pcdata[i] = pcdataoff - pcdataoff += uint32(len(pcd)) - } - o.PcdataEnd = pcdataoff - o.Funcdataoff = make([]uint32, len(s.Func.FuncData)) - for i, x := range s.Func.FuncData { - o.Funcdataoff[i] = x.Offset - } - o.File = make([]goobj2.SymRef, len(s.Func.File)) - for i, f := range s.Func.File { - o.File[i] = f.SymRef - } - o.InlTree = make([]goobj2.InlTreeNode, len(s.Func.InlTree)) - for i, inl := range s.Func.InlTree { - o.InlTree[i] = goobj2.InlTreeNode{ - Parent: inl.Parent, - File: inl.File.SymRef, - Line: inl.Line, - Func: inl.Func.SymRef, - ParentPC: inl.ParentPC, - } - } - - o.Write(&b) - ctxt.symMap[s.Func.dataSymIdx].Data = append([]byte(nil), b.Bytes()...) - b.Reset() - } -} diff --git a/odiglet/pkg/allocator/debug/gosym/pclntab.go b/odiglet/pkg/allocator/debug/gosym/pclntab.go deleted file mode 100644 index ad99b4dc5a..0000000000 --- a/odiglet/pkg/allocator/debug/gosym/pclntab.go +++ /dev/null @@ -1,454 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* - * Line tables - */ - -package gosym - -import ( - "bytes" - "encoding/binary" - "sync" -) - -// A LineTable is a data structure mapping program counters to line numbers. -// -// In Go 1.1 and earlier, each function (represented by a Func) had its own LineTable, -// and the line number corresponded to a numbering of all source lines in the -// program, across all files. That absolute line number would then have to be -// converted separately to a file name and line number within the file. -// -// In Go 1.2, the format of the data changed so that there is a single LineTable -// for the entire program, shared by all Funcs, and there are no absolute line -// numbers, just line numbers within specific files. -// -// For the most part, LineTable's methods should be treated as an internal -// detail of the package; callers should use the methods on Table instead. -type LineTable struct { - Data []byte - PC uint64 - Line int - - // Go 1.2 state - mu sync.Mutex - go12 int // is this in Go 1.2 format? -1 no, 0 unknown, 1 yes - binary binary.ByteOrder - quantum uint32 - ptrsize uint32 - functab []byte - nfunctab uint32 - filetab []byte - nfiletab uint32 - fileMap map[string]uint32 - strings map[uint32]string // interned substrings of Data, keyed by offset -} - -// NOTE(rsc): This is wrong for GOARCH=arm, which uses a quantum of 4, -// but we have no idea whether we're using arm or not. This only -// matters in the old (pre-Go 1.2) symbol table format, so it's not worth -// fixing. -const oldQuantum = 1 - -func (t *LineTable) parse(targetPC uint64, targetLine int) (b []byte, pc uint64, line int) { - // The PC/line table can be thought of as a sequence of - // * - // batches. Each update batch results in a (pc, line) pair, - // where line applies to every PC from pc up to but not - // including the pc of the next pair. - // - // Here we process each update individually, which simplifies - // the code, but makes the corner cases more confusing. - b, pc, line = t.Data, t.PC, t.Line - for pc <= targetPC && line != targetLine && len(b) > 0 { - code := b[0] - b = b[1:] - switch { - case code == 0: - if len(b) < 4 { - b = b[0:0] - break - } - val := binary.BigEndian.Uint32(b) - b = b[4:] - line += int(val) - case code <= 64: - line += int(code) - case code <= 128: - line -= int(code - 64) - default: - pc += oldQuantum * uint64(code-128) - continue - } - pc += oldQuantum - } - return b, pc, line -} - -func (t *LineTable) slice(pc uint64) *LineTable { - data, pc, line := t.parse(pc, -1) - return &LineTable{Data: data, PC: pc, Line: line} -} - -// PCToLine returns the line number for the given program counter. -// Callers should use Table's PCToLine method instead. -func (t *LineTable) PCToLine(pc uint64) int { - if t.isGo12() { - return t.go12PCToLine(pc) - } - _, _, line := t.parse(pc, -1) - return line -} - -// LineToPC returns the program counter for the given line number, -// considering only program counters before maxpc. -// Callers should use Table's LineToPC method instead. -func (t *LineTable) LineToPC(line int, maxpc uint64) uint64 { - if t.isGo12() { - return 0 - } - _, pc, line1 := t.parse(maxpc, line) - if line1 != line { - return 0 - } - // Subtract quantum from PC to account for post-line increment - return pc - oldQuantum -} - -// NewLineTable returns a new PC/line table -// corresponding to the encoded data. -// Text must be the start address of the -// corresponding text segment. -func NewLineTable(data []byte, text uint64) *LineTable { - return &LineTable{Data: data, PC: text, Line: 0, strings: make(map[uint32]string)} -} - -// Go 1.2 symbol table format. -// See golang.org/s/go12symtab. -// -// A general note about the methods here: rather than try to avoid -// index out of bounds errors, we trust Go to detect them, and then -// we recover from the panics and treat them as indicative of a malformed -// or incomplete table. -// -// The methods called by symtab.go, which begin with "go12" prefixes, -// are expected to have that recovery logic. - -// isGo12 reports whether this is a Go 1.2 (or later) symbol table. -func (t *LineTable) isGo12() bool { - t.go12Init() - return t.go12 == 1 -} - -const go12magic = 0xfffffffb - -// uintptr returns the pointer-sized value encoded at b. -// The pointer size is dictated by the table being read. -func (t *LineTable) uintptr(b []byte) uint64 { - if t.ptrsize == 4 { - return uint64(t.binary.Uint32(b)) - } - return t.binary.Uint64(b) -} - -// go12init initializes the Go 1.2 metadata if t is a Go 1.2 symbol table. -func (t *LineTable) go12Init() { - t.mu.Lock() - defer t.mu.Unlock() - if t.go12 != 0 { - return - } - - defer func() { - // If we panic parsing, assume it's not a Go 1.2 symbol table. - recover() - }() - - // Check header: 4-byte magic, two zeros, pc quantum, pointer size. - t.go12 = -1 // not Go 1.2 until proven otherwise - if len(t.Data) < 16 || t.Data[4] != 0 || t.Data[5] != 0 || - (t.Data[6] != 1 && t.Data[6] != 2 && t.Data[6] != 4) || // pc quantum - (t.Data[7] != 4 && t.Data[7] != 8) { // pointer size - return - } - - switch uint32(go12magic) { - case binary.LittleEndian.Uint32(t.Data): - t.binary = binary.LittleEndian - case binary.BigEndian.Uint32(t.Data): - t.binary = binary.BigEndian - default: - return - } - - t.quantum = uint32(t.Data[6]) - t.ptrsize = uint32(t.Data[7]) - - t.nfunctab = uint32(t.uintptr(t.Data[8:])) - t.functab = t.Data[8+t.ptrsize:] - functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize - fileoff := t.binary.Uint32(t.functab[functabsize:]) - t.functab = t.functab[:functabsize] - t.filetab = t.Data[fileoff:] - t.nfiletab = t.binary.Uint32(t.filetab) - t.filetab = t.filetab[:t.nfiletab*4] - - t.go12 = 1 // so far so good -} - -// go12Funcs returns a slice of Funcs derived from the Go 1.2 pcln table. -func (t *LineTable) go12Funcs() []Func { - // Assume it is malformed and return nil on error. - defer func() { - recover() - }() - - n := len(t.functab) / int(t.ptrsize) / 2 - funcs := make([]Func, n) - for i := range funcs { - f := &funcs[i] - f.Entry = t.uintptr(t.functab[2*i*int(t.ptrsize):]) - f.End = t.uintptr(t.functab[(2*i+2)*int(t.ptrsize):]) - info := t.Data[t.uintptr(t.functab[(2*i+1)*int(t.ptrsize):]):] - f.LineTable = t - f.FrameSize = int(t.binary.Uint32(info[t.ptrsize+2*4:])) - f.Sym = &Sym{ - Value: f.Entry, - Type: 'T', - Name: t.string(t.binary.Uint32(info[t.ptrsize:])), - GoType: 0, - Func: f, - } - } - return funcs -} - -// findFunc returns the func corresponding to the given program counter. -func (t *LineTable) findFunc(pc uint64) []byte { - if pc < t.uintptr(t.functab) || pc >= t.uintptr(t.functab[len(t.functab)-int(t.ptrsize):]) { - return nil - } - - // The function table is a list of 2*nfunctab+1 uintptrs, - // alternating program counters and offsets to func structures. - f := t.functab - nf := t.nfunctab - for nf > 0 { - m := nf / 2 - fm := f[2*t.ptrsize*m:] - if t.uintptr(fm) <= pc && pc < t.uintptr(fm[2*t.ptrsize:]) { - return t.Data[t.uintptr(fm[t.ptrsize:]):] - } else if pc < t.uintptr(fm) { - nf = m - } else { - f = f[(m+1)*2*t.ptrsize:] - nf -= m + 1 - } - } - return nil -} - -// readvarint reads, removes, and returns a varint from *pp. -func (t *LineTable) readvarint(pp *[]byte) uint32 { - var v, shift uint32 - p := *pp - for shift = 0; ; shift += 7 { - b := p[0] - p = p[1:] - v |= (uint32(b) & 0x7F) << shift - if b&0x80 == 0 { - break - } - } - *pp = p - return v -} - -// string returns a Go string found at off. -func (t *LineTable) string(off uint32) string { - if s, ok := t.strings[off]; ok { - return s - } - i := bytes.IndexByte(t.Data[off:], 0) - s := string(t.Data[off : off+uint32(i)]) - t.strings[off] = s - return s -} - -// step advances to the next pc, value pair in the encoded table. -func (t *LineTable) step(p *[]byte, pc *uint64, val *int32, first bool) bool { - uvdelta := t.readvarint(p) - if uvdelta == 0 && !first { - return false - } - if uvdelta&1 != 0 { - uvdelta = ^(uvdelta >> 1) - } else { - uvdelta >>= 1 - } - vdelta := int32(uvdelta) - pcdelta := t.readvarint(p) * t.quantum - *pc += uint64(pcdelta) - *val += vdelta - return true -} - -// pcvalue reports the value associated with the target pc. -// off is the offset to the beginning of the pc-value table, -// and entry is the start PC for the corresponding function. -func (t *LineTable) pcvalue(off uint32, entry, targetpc uint64) int32 { - p := t.Data[off:] - - val := int32(-1) - pc := entry - for t.step(&p, &pc, &val, pc == entry) { - if targetpc < pc { - return val - } - } - return -1 -} - -// findFileLine scans one function in the binary looking for a -// program counter in the given file on the given line. -// It does so by running the pc-value tables mapping program counter -// to file number. Since most functions come from a single file, these -// are usually short and quick to scan. If a file match is found, then the -// code goes to the expense of looking for a simultaneous line number match. -func (t *LineTable) findFileLine(entry uint64, filetab, linetab uint32, filenum, line int32) uint64 { - if filetab == 0 || linetab == 0 { - return 0 - } - - fp := t.Data[filetab:] - fl := t.Data[linetab:] - fileVal := int32(-1) - filePC := entry - lineVal := int32(-1) - linePC := entry - fileStartPC := filePC - for t.step(&fp, &filePC, &fileVal, filePC == entry) { - if fileVal == filenum && fileStartPC < filePC { - // fileVal is in effect starting at fileStartPC up to - // but not including filePC, and it's the file we want. - // Run the PC table looking for a matching line number - // or until we reach filePC. - lineStartPC := linePC - for linePC < filePC && t.step(&fl, &linePC, &lineVal, linePC == entry) { - // lineVal is in effect until linePC, and lineStartPC < filePC. - if lineVal == line { - if fileStartPC <= lineStartPC { - return lineStartPC - } - if fileStartPC < linePC { - return fileStartPC - } - } - lineStartPC = linePC - } - } - fileStartPC = filePC - } - return 0 -} - -// go12PCToLine maps program counter to line number for the Go 1.2 pcln table. -func (t *LineTable) go12PCToLine(pc uint64) (line int) { - defer func() { - if recover() != nil { - line = -1 - } - }() - - f := t.findFunc(pc) - if f == nil { - return -1 - } - entry := t.uintptr(f) - linetab := t.binary.Uint32(f[t.ptrsize+5*4:]) - return int(t.pcvalue(linetab, entry, pc)) -} - -// go12PCToFile maps program counter to file name for the Go 1.2 pcln table. -func (t *LineTable) go12PCToFile(pc uint64) (file string) { - defer func() { - if recover() != nil { - file = "" - } - }() - - f := t.findFunc(pc) - if f == nil { - return "" - } - entry := t.uintptr(f) - filetab := t.binary.Uint32(f[t.ptrsize+4*4:]) - fno := t.pcvalue(filetab, entry, pc) - if fno <= 0 { - return "" - } - return t.string(t.binary.Uint32(t.filetab[4*fno:])) -} - -// go12LineToPC maps a (file, line) pair to a program counter for the Go 1.2 pcln table. -func (t *LineTable) go12LineToPC(file string, line int) (pc uint64) { - defer func() { - if recover() != nil { - pc = 0 - } - }() - - t.initFileMap() - filenum := t.fileMap[file] - if filenum == 0 { - return 0 - } - - // Scan all functions. - // If this turns out to be a bottleneck, we could build a map[int32][]int32 - // mapping file number to a list of functions with code from that file. - for i := uint32(0); i < t.nfunctab; i++ { - f := t.Data[t.uintptr(t.functab[2*t.ptrsize*i+t.ptrsize:]):] - entry := t.uintptr(f) - filetab := t.binary.Uint32(f[t.ptrsize+4*4:]) - linetab := t.binary.Uint32(f[t.ptrsize+5*4:]) - pc := t.findFileLine(entry, filetab, linetab, int32(filenum), int32(line)) - if pc != 0 { - return pc - } - } - return 0 -} - -// initFileMap initializes the map from file name to file number. -func (t *LineTable) initFileMap() { - t.mu.Lock() - defer t.mu.Unlock() - - if t.fileMap != nil { - return - } - m := make(map[string]uint32) - - for i := uint32(1); i < t.nfiletab; i++ { - s := t.string(t.binary.Uint32(t.filetab[4*i:])) - m[s] = i - } - t.fileMap = m -} - -// go12MapFiles adds to m a key for every file in the Go 1.2 LineTable. -// Every key maps to obj. That's not a very interesting map, but it provides -// a way for callers to obtain the list of files in the program. -func (t *LineTable) go12MapFiles(m map[string]*Obj, obj *Obj) { - defer func() { - recover() - }() - - t.initFileMap() - for file := range t.fileMap { - m[file] = obj - } -} diff --git a/odiglet/pkg/allocator/debug/gosym/pclntab_test.go b/odiglet/pkg/allocator/debug/gosym/pclntab_test.go deleted file mode 100644 index d21f0e24a8..0000000000 --- a/odiglet/pkg/allocator/debug/gosym/pclntab_test.go +++ /dev/null @@ -1,263 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gosym - -import ( - "debug/elf" - "internal/testenv" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "runtime" - "strings" - "testing" -) - -var ( - pclineTempDir string - pclinetestBinary string -) - -func dotest(t *testing.T) { - testenv.MustHaveGoBuild(t) - // For now, only works on amd64 platforms. - if runtime.GOARCH != "amd64" { - t.Skipf("skipping on non-AMD64 system %s", runtime.GOARCH) - } - var err error - pclineTempDir, err = ioutil.TempDir("", "pclinetest") - if err != nil { - t.Fatal(err) - } - pclinetestBinary = filepath.Join(pclineTempDir, "pclinetest") - cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", pclinetestBinary) - cmd.Dir = "testdata" - cmd.Env = append(os.Environ(), "GOOS=linux") - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - t.Fatal(err) - } -} - -func endtest() { - if pclineTempDir != "" { - os.RemoveAll(pclineTempDir) - pclineTempDir = "" - pclinetestBinary = "" - } -} - -// skipIfNotELF skips the test if we are not running on an ELF system. -// These tests open and examine the test binary, and use elf.Open to do so. -func skipIfNotELF(t *testing.T) { - switch runtime.GOOS { - case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris": - // OK. - default: - t.Skipf("skipping on non-ELF system %s", runtime.GOOS) - } -} - -func getTable(t *testing.T) *Table { - f, tab := crack(os.Args[0], t) - f.Close() - return tab -} - -func crack(file string, t *testing.T) (*elf.File, *Table) { - // Open self - f, err := elf.Open(file) - if err != nil { - t.Fatal(err) - } - return parse(file, f, t) -} - -func parse(file string, f *elf.File, t *testing.T) (*elf.File, *Table) { - s := f.Section(".gosymtab") - if s == nil { - t.Skip("no .gosymtab section") - } - symdat, err := s.Data() - if err != nil { - f.Close() - t.Fatalf("reading %s gosymtab: %v", file, err) - } - pclndat, err := f.Section(".gopclntab").Data() - if err != nil { - f.Close() - t.Fatalf("reading %s gopclntab: %v", file, err) - } - - pcln := NewLineTable(pclndat, f.Section(".text").Addr) - tab, err := NewTable(symdat, pcln) - if err != nil { - f.Close() - t.Fatalf("parsing %s gosymtab: %v", file, err) - } - - return f, tab -} - -func TestLineFromAline(t *testing.T) { - skipIfNotELF(t) - - tab := getTable(t) - if tab.go12line != nil { - // aline's don't exist in the Go 1.2 table. - t.Skip("not relevant to Go 1.2 symbol table") - } - - // Find the sym package - pkg := tab.LookupFunc("debug/gosym.TestLineFromAline").Obj - if pkg == nil { - t.Fatalf("nil pkg") - } - - // Walk every absolute line and ensure that we hit every - // source line monotonically - lastline := make(map[string]int) - final := -1 - for i := 0; i < 10000; i++ { - path, line := pkg.lineFromAline(i) - // Check for end of object - if path == "" { - if final == -1 { - final = i - 1 - } - continue - } else if final != -1 { - t.Fatalf("reached end of package at absolute line %d, but absolute line %d mapped to %s:%d", final, i, path, line) - } - // It's okay to see files multiple times (e.g., sys.a) - if line == 1 { - lastline[path] = 1 - continue - } - // Check that the is the next line in path - ll, ok := lastline[path] - if !ok { - t.Errorf("file %s starts on line %d", path, line) - } else if line != ll+1 { - t.Fatalf("expected next line of file %s to be %d, got %d", path, ll+1, line) - } - lastline[path] = line - } - if final == -1 { - t.Errorf("never reached end of object") - } -} - -func TestLineAline(t *testing.T) { - skipIfNotELF(t) - - tab := getTable(t) - if tab.go12line != nil { - // aline's don't exist in the Go 1.2 table. - t.Skip("not relevant to Go 1.2 symbol table") - } - - for _, o := range tab.Files { - // A source file can appear multiple times in a - // object. alineFromLine will always return alines in - // the first file, so track which lines we've seen. - found := make(map[string]int) - for i := 0; i < 1000; i++ { - path, line := o.lineFromAline(i) - if path == "" { - break - } - - // cgo files are full of 'Z' symbols, which we don't handle - if len(path) > 4 && path[len(path)-4:] == ".cgo" { - continue - } - - if minline, ok := found[path]; path != "" && ok { - if minline >= line { - // We've already covered this file - continue - } - } - found[path] = line - - a, err := o.alineFromLine(path, line) - if err != nil { - t.Errorf("absolute line %d in object %s maps to %s:%d, but mapping that back gives error %s", i, o.Paths[0].Name, path, line, err) - } else if a != i { - t.Errorf("absolute line %d in object %s maps to %s:%d, which maps back to absolute line %d\n", i, o.Paths[0].Name, path, line, a) - } - } - } -} - -func TestPCLine(t *testing.T) { - dotest(t) - defer endtest() - - f, tab := crack(pclinetestBinary, t) - defer f.Close() - text := f.Section(".text") - textdat, err := text.Data() - if err != nil { - t.Fatalf("reading .text: %v", err) - } - - // Test PCToLine - sym := tab.LookupFunc("main.linefrompc") - wantLine := 0 - for pc := sym.Entry; pc < sym.End; pc++ { - off := pc - text.Addr // TODO(rsc): should not need off; bug in 8g - if textdat[off] == 255 { - break - } - wantLine += int(textdat[off]) - t.Logf("off is %d %#x (max %d)", off, textdat[off], sym.End-pc) - file, line, fn := tab.PCToLine(pc) - if fn == nil { - t.Errorf("failed to get line of PC %#x", pc) - } else if !strings.HasSuffix(file, "pclinetest.s") || line != wantLine || fn != sym { - t.Errorf("PCToLine(%#x) = %s:%d (%s), want %s:%d (%s)", pc, file, line, fn.Name, "pclinetest.s", wantLine, sym.Name) - } - } - - // Test LineToPC - sym = tab.LookupFunc("main.pcfromline") - lookupline := -1 - wantLine = 0 - off := uint64(0) // TODO(rsc): should not need off; bug in 8g - for pc := sym.Value; pc < sym.End; pc += 2 + uint64(textdat[off]) { - file, line, fn := tab.PCToLine(pc) - off = pc - text.Addr - if textdat[off] == 255 { - break - } - wantLine += int(textdat[off]) - if line != wantLine { - t.Errorf("expected line %d at PC %#x in pcfromline, got %d", wantLine, pc, line) - off = pc + 1 - text.Addr - continue - } - if lookupline == -1 { - lookupline = line - } - for ; lookupline <= line; lookupline++ { - pc2, fn2, err := tab.LineToPC(file, lookupline) - if lookupline != line { - // Should be nothing on this line - if err == nil { - t.Errorf("expected no PC at line %d, got %#x (%s)", lookupline, pc2, fn2.Name) - } - } else if err != nil { - t.Errorf("failed to get PC of line %d: %s", lookupline, err) - } else if pc != pc2 { - t.Errorf("expected PC %#x (%s) at line %d, got PC %#x (%s)", pc, fn.Name, line, pc2, fn2.Name) - } - } - off = pc + 1 - text.Addr - } -} diff --git a/odiglet/pkg/allocator/debug/gosym/symtab.go b/odiglet/pkg/allocator/debug/gosym/symtab.go deleted file mode 100644 index a84b7f6def..0000000000 --- a/odiglet/pkg/allocator/debug/gosym/symtab.go +++ /dev/null @@ -1,715 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package gosym implements access to the Go symbol -// and line number tables embedded in Go binaries generated -// by the gc compilers. -package gosym - -import ( - "bytes" - "encoding/binary" - "fmt" - "strconv" - "strings" -) - -/* - * Symbols - */ - -// A Sym represents a single symbol table entry. -type Sym struct { - Value uint64 - Type byte - Name string - GoType uint64 - // If this symbol is a function symbol, the corresponding Func - Func *Func -} - -// Static reports whether this symbol is static (not visible outside its file). -func (s *Sym) Static() bool { return s.Type >= 'a' } - -// PackageName returns the package part of the symbol name, -// or the empty string if there is none. -func (s *Sym) PackageName() string { - pathend := strings.LastIndex(s.Name, "/") - if pathend < 0 { - pathend = 0 - } - - if i := strings.Index(s.Name[pathend:], "."); i != -1 { - return s.Name[:pathend+i] - } - return "" -} - -// ReceiverName returns the receiver type name of this symbol, -// or the empty string if there is none. -func (s *Sym) ReceiverName() string { - pathend := strings.LastIndex(s.Name, "/") - if pathend < 0 { - pathend = 0 - } - l := strings.Index(s.Name[pathend:], ".") - r := strings.LastIndex(s.Name[pathend:], ".") - if l == -1 || r == -1 || l == r { - return "" - } - return s.Name[pathend+l+1 : pathend+r] -} - -// BaseName returns the symbol name without the package or receiver name. -func (s *Sym) BaseName() string { - if i := strings.LastIndex(s.Name, "."); i != -1 { - return s.Name[i+1:] - } - return s.Name -} - -// A Func collects information about a single function. -type Func struct { - Entry uint64 - *Sym - End uint64 - Params []*Sym // nil for Go 1.3 and later binaries - Locals []*Sym // nil for Go 1.3 and later binaries - FrameSize int - LineTable *LineTable - Obj *Obj -} - -// An Obj represents a collection of functions in a symbol table. -// -// The exact method of division of a binary into separate Objs is an internal detail -// of the symbol table format. -// -// In early versions of Go each source file became a different Obj. -// -// In Go 1 and Go 1.1, each package produced one Obj for all Go sources -// and one Obj per C source file. -// -// In Go 1.2, there is a single Obj for the entire program. -type Obj struct { - // Funcs is a list of functions in the Obj. - Funcs []Func - - // In Go 1.1 and earlier, Paths is a list of symbols corresponding - // to the source file names that produced the Obj. - // In Go 1.2, Paths is nil. - // Use the keys of Table.Files to obtain a list of source files. - Paths []Sym // meta -} - -/* - * Symbol tables - */ - -// Table represents a Go symbol table. It stores all of the -// symbols decoded from the program and provides methods to translate -// between symbols, names, and addresses. -type Table struct { - Syms []Sym // nil for Go 1.3 and later binaries - Funcs []Func - Files map[string]*Obj // nil for Go 1.2 and later binaries - Objs []Obj // nil for Go 1.2 and later binaries - - go12line *LineTable // Go 1.2 line number table -} - -type sym struct { - value uint64 - gotype uint64 - typ byte - name []byte -} - -var ( - littleEndianSymtab = []byte{0xFD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00} - bigEndianSymtab = []byte{0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00} - oldLittleEndianSymtab = []byte{0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00} -) - -func walksymtab(data []byte, fn func(sym) error) error { - if len(data) == 0 { // missing symtab is okay - return nil - } - var order binary.ByteOrder = binary.BigEndian - newTable := false - switch { - case bytes.HasPrefix(data, oldLittleEndianSymtab): - // Same as Go 1.0, but little endian. - // Format was used during interim development between Go 1.0 and Go 1.1. - // Should not be widespread, but easy to support. - data = data[6:] - order = binary.LittleEndian - case bytes.HasPrefix(data, bigEndianSymtab): - newTable = true - case bytes.HasPrefix(data, littleEndianSymtab): - newTable = true - order = binary.LittleEndian - } - var ptrsz int - if newTable { - if len(data) < 8 { - return &DecodingError{len(data), "unexpected EOF", nil} - } - ptrsz = int(data[7]) - if ptrsz != 4 && ptrsz != 8 { - return &DecodingError{7, "invalid pointer size", ptrsz} - } - data = data[8:] - } - var s sym - p := data - for len(p) >= 4 { - var typ byte - if newTable { - // Symbol type, value, Go type. - typ = p[0] & 0x3F - wideValue := p[0]&0x40 != 0 - goType := p[0]&0x80 != 0 - if typ < 26 { - typ += 'A' - } else { - typ += 'a' - 26 - } - s.typ = typ - p = p[1:] - if wideValue { - if len(p) < ptrsz { - return &DecodingError{len(data), "unexpected EOF", nil} - } - // fixed-width value - if ptrsz == 8 { - s.value = order.Uint64(p[0:8]) - p = p[8:] - } else { - s.value = uint64(order.Uint32(p[0:4])) - p = p[4:] - } - } else { - // varint value - s.value = 0 - shift := uint(0) - for len(p) > 0 && p[0]&0x80 != 0 { - s.value |= uint64(p[0]&0x7F) << shift - shift += 7 - p = p[1:] - } - if len(p) == 0 { - return &DecodingError{len(data), "unexpected EOF", nil} - } - s.value |= uint64(p[0]) << shift - p = p[1:] - } - if goType { - if len(p) < ptrsz { - return &DecodingError{len(data), "unexpected EOF", nil} - } - // fixed-width go type - if ptrsz == 8 { - s.gotype = order.Uint64(p[0:8]) - p = p[8:] - } else { - s.gotype = uint64(order.Uint32(p[0:4])) - p = p[4:] - } - } - } else { - // Value, symbol type. - s.value = uint64(order.Uint32(p[0:4])) - if len(p) < 5 { - return &DecodingError{len(data), "unexpected EOF", nil} - } - typ = p[4] - if typ&0x80 == 0 { - return &DecodingError{len(data) - len(p) + 4, "bad symbol type", typ} - } - typ &^= 0x80 - s.typ = typ - p = p[5:] - } - - // Name. - var i int - var nnul int - for i = 0; i < len(p); i++ { - if p[i] == 0 { - nnul = 1 - break - } - } - switch typ { - case 'z', 'Z': - p = p[i+nnul:] - for i = 0; i+2 <= len(p); i += 2 { - if p[i] == 0 && p[i+1] == 0 { - nnul = 2 - break - } - } - } - if len(p) < i+nnul { - return &DecodingError{len(data), "unexpected EOF", nil} - } - s.name = p[0:i] - i += nnul - p = p[i:] - - if !newTable { - if len(p) < 4 { - return &DecodingError{len(data), "unexpected EOF", nil} - } - // Go type. - s.gotype = uint64(order.Uint32(p[:4])) - p = p[4:] - } - fn(s) - } - return nil -} - -// NewTable decodes the Go symbol table (the ".gosymtab" section in ELF), -// returning an in-memory representation. -// Starting with Go 1.3, the Go symbol table no longer includes symbol data. -func NewTable(symtab []byte, pcln *LineTable) (*Table, error) { - var n int - err := walksymtab(symtab, func(s sym) error { - n++ - return nil - }) - if err != nil { - return nil, err - } - - var t Table - if pcln.isGo12() { - t.go12line = pcln - } - fname := make(map[uint16]string) - t.Syms = make([]Sym, 0, n) - nf := 0 - nz := 0 - lasttyp := uint8(0) - err = walksymtab(symtab, func(s sym) error { - n := len(t.Syms) - t.Syms = t.Syms[0 : n+1] - ts := &t.Syms[n] - ts.Type = s.typ - ts.Value = s.value - ts.GoType = s.gotype - switch s.typ { - default: - // rewrite name to use . instead of · (c2 b7) - w := 0 - b := s.name - for i := 0; i < len(b); i++ { - if b[i] == 0xc2 && i+1 < len(b) && b[i+1] == 0xb7 { - i++ - b[i] = '.' - } - b[w] = b[i] - w++ - } - ts.Name = string(s.name[0:w]) - case 'z', 'Z': - if lasttyp != 'z' && lasttyp != 'Z' { - nz++ - } - for i := 0; i < len(s.name); i += 2 { - eltIdx := binary.BigEndian.Uint16(s.name[i : i+2]) - elt, ok := fname[eltIdx] - if !ok { - return &DecodingError{-1, "bad filename code", eltIdx} - } - if n := len(ts.Name); n > 0 && ts.Name[n-1] != '/' { - ts.Name += "/" - } - ts.Name += elt - } - } - switch s.typ { - case 'T', 't', 'L', 'l': - nf++ - case 'f': - fname[uint16(s.value)] = ts.Name - } - lasttyp = s.typ - return nil - }) - if err != nil { - return nil, err - } - - t.Funcs = make([]Func, 0, nf) - t.Files = make(map[string]*Obj) - - var obj *Obj - if t.go12line != nil { - // Put all functions into one Obj. - t.Objs = make([]Obj, 1) - obj = &t.Objs[0] - t.go12line.go12MapFiles(t.Files, obj) - } else { - t.Objs = make([]Obj, 0, nz) - } - - // Count text symbols and attach frame sizes, parameters, and - // locals to them. Also, find object file boundaries. - lastf := 0 - for i := 0; i < len(t.Syms); i++ { - sym := &t.Syms[i] - switch sym.Type { - case 'Z', 'z': // path symbol - if t.go12line != nil { - // Go 1.2 binaries have the file information elsewhere. Ignore. - break - } - // Finish the current object - if obj != nil { - obj.Funcs = t.Funcs[lastf:] - } - lastf = len(t.Funcs) - - // Start new object - n := len(t.Objs) - t.Objs = t.Objs[0 : n+1] - obj = &t.Objs[n] - - // Count & copy path symbols - var end int - for end = i + 1; end < len(t.Syms); end++ { - if c := t.Syms[end].Type; c != 'Z' && c != 'z' { - break - } - } - obj.Paths = t.Syms[i:end] - i = end - 1 // loop will i++ - - // Record file names - depth := 0 - for j := range obj.Paths { - s := &obj.Paths[j] - if s.Name == "" { - depth-- - } else { - if depth == 0 { - t.Files[s.Name] = obj - } - depth++ - } - } - - case 'T', 't', 'L', 'l': // text symbol - if n := len(t.Funcs); n > 0 { - t.Funcs[n-1].End = sym.Value - } - if sym.Name == "runtime.etext" || sym.Name == "etext" { - continue - } - - // Count parameter and local (auto) syms - var np, na int - var end int - countloop: - for end = i + 1; end < len(t.Syms); end++ { - switch t.Syms[end].Type { - case 'T', 't', 'L', 'l', 'Z', 'z': - break countloop - case 'p': - np++ - case 'a': - na++ - } - } - - // Fill in the function symbol - n := len(t.Funcs) - t.Funcs = t.Funcs[0 : n+1] - fn := &t.Funcs[n] - sym.Func = fn - fn.Params = make([]*Sym, 0, np) - fn.Locals = make([]*Sym, 0, na) - fn.Sym = sym - fn.Entry = sym.Value - fn.Obj = obj - if t.go12line != nil { - // All functions share the same line table. - // It knows how to narrow down to a specific - // function quickly. - fn.LineTable = t.go12line - } else if pcln != nil { - fn.LineTable = pcln.slice(fn.Entry) - pcln = fn.LineTable - } - for j := i; j < end; j++ { - s := &t.Syms[j] - switch s.Type { - case 'm': - fn.FrameSize = int(s.Value) - case 'p': - n := len(fn.Params) - fn.Params = fn.Params[0 : n+1] - fn.Params[n] = s - case 'a': - n := len(fn.Locals) - fn.Locals = fn.Locals[0 : n+1] - fn.Locals[n] = s - } - } - i = end - 1 // loop will i++ - } - } - - if t.go12line != nil && nf == 0 { - t.Funcs = t.go12line.go12Funcs() - } - if obj != nil { - obj.Funcs = t.Funcs[lastf:] - } - return &t, nil -} - -// PCToFunc returns the function containing the program counter pc, -// or nil if there is no such function. -func (t *Table) PCToFunc(pc uint64) *Func { - funcs := t.Funcs - for len(funcs) > 0 { - m := len(funcs) / 2 - fn := &funcs[m] - switch { - case pc < fn.Entry: - funcs = funcs[0:m] - case fn.Entry <= pc && pc < fn.End: - return fn - default: - funcs = funcs[m+1:] - } - } - return nil -} - -// PCToLine looks up line number information for a program counter. -// If there is no information, it returns fn == nil. -func (t *Table) PCToLine(pc uint64) (file string, line int, fn *Func) { - if fn = t.PCToFunc(pc); fn == nil { - return - } - if t.go12line != nil { - file = t.go12line.go12PCToFile(pc) - line = t.go12line.go12PCToLine(pc) - } else { - file, line = fn.Obj.lineFromAline(fn.LineTable.PCToLine(pc)) - } - return -} - -// LineToPC looks up the first program counter on the given line in -// the named file. It returns UnknownPathError or UnknownLineError if -// there is an error looking up this line. -func (t *Table) LineToPC(file string, line int) (pc uint64, fn *Func, err error) { - obj, ok := t.Files[file] - if !ok { - return 0, nil, UnknownFileError(file) - } - - if t.go12line != nil { - pc := t.go12line.go12LineToPC(file, line) - if pc == 0 { - return 0, nil, &UnknownLineError{file, line} - } - return pc, t.PCToFunc(pc), nil - } - - abs, err := obj.alineFromLine(file, line) - if err != nil { - return - } - for i := range obj.Funcs { - f := &obj.Funcs[i] - pc := f.LineTable.LineToPC(abs, f.End) - if pc != 0 { - return pc, f, nil - } - } - return 0, nil, &UnknownLineError{file, line} -} - -// LookupSym returns the text, data, or bss symbol with the given name, -// or nil if no such symbol is found. -func (t *Table) LookupSym(name string) *Sym { - // TODO(austin) Maybe make a map - for i := range t.Syms { - s := &t.Syms[i] - switch s.Type { - case 'T', 't', 'L', 'l', 'D', 'd', 'B', 'b': - if s.Name == name { - return s - } - } - } - return nil -} - -// LookupFunc returns the text, data, or bss symbol with the given name, -// or nil if no such symbol is found. -func (t *Table) LookupFunc(name string) *Func { - for i := range t.Funcs { - f := &t.Funcs[i] - if f.Sym.Name == name { - return f - } - } - return nil -} - -// SymByAddr returns the text, data, or bss symbol starting at the given address. -func (t *Table) SymByAddr(addr uint64) *Sym { - for i := range t.Syms { - s := &t.Syms[i] - switch s.Type { - case 'T', 't', 'L', 'l', 'D', 'd', 'B', 'b': - if s.Value == addr { - return s - } - } - } - return nil -} - -/* - * Object files - */ - -// This is legacy code for Go 1.1 and earlier, which used the -// Plan 9 format for pc-line tables. This code was never quite -// correct. It's probably very close, and it's usually correct, but -// we never quite found all the corner cases. -// -// Go 1.2 and later use a simpler format, documented at golang.org/s/go12symtab. - -func (o *Obj) lineFromAline(aline int) (string, int) { - type stackEnt struct { - path string - start int - offset int - prev *stackEnt - } - - noPath := &stackEnt{"", 0, 0, nil} - tos := noPath - -pathloop: - for _, s := range o.Paths { - val := int(s.Value) - switch { - case val > aline: - break pathloop - - case val == 1: - // Start a new stack - tos = &stackEnt{s.Name, val, 0, noPath} - - case s.Name == "": - // Pop - if tos == noPath { - return "", 0 - } - tos.prev.offset += val - tos.start - tos = tos.prev - - default: - // Push - tos = &stackEnt{s.Name, val, 0, tos} - } - } - - if tos == noPath { - return "", 0 - } - return tos.path, aline - tos.start - tos.offset + 1 -} - -func (o *Obj) alineFromLine(path string, line int) (int, error) { - if line < 1 { - return 0, &UnknownLineError{path, line} - } - - for i, s := range o.Paths { - // Find this path - if s.Name != path { - continue - } - - // Find this line at this stack level - depth := 0 - var incstart int - line += int(s.Value) - pathloop: - for _, s := range o.Paths[i:] { - val := int(s.Value) - switch { - case depth == 1 && val >= line: - return line - 1, nil - - case s.Name == "": - depth-- - if depth == 0 { - break pathloop - } else if depth == 1 { - line += val - incstart - } - - default: - if depth == 1 { - incstart = val - } - depth++ - } - } - return 0, &UnknownLineError{path, line} - } - return 0, UnknownFileError(path) -} - -/* - * Errors - */ - -// UnknownFileError represents a failure to find the specific file in -// the symbol table. -type UnknownFileError string - -func (e UnknownFileError) Error() string { return "unknown file: " + string(e) } - -// UnknownLineError represents a failure to map a line to a program -// counter, either because the line is beyond the bounds of the file -// or because there is no code on the given line. -type UnknownLineError struct { - File string - Line int -} - -func (e *UnknownLineError) Error() string { - return "no code at " + e.File + ":" + strconv.Itoa(e.Line) -} - -// DecodingError represents an error during the decoding of -// the symbol table. -type DecodingError struct { - off int - msg string - val interface{} -} - -func (e *DecodingError) Error() string { - msg := e.msg - if e.val != nil { - msg += fmt.Sprintf(" '%v'", e.val) - } - msg += fmt.Sprintf(" at byte %#x", e.off) - return msg -} diff --git a/odiglet/pkg/allocator/debug/gosym/symtab_test.go b/odiglet/pkg/allocator/debug/gosym/symtab_test.go deleted file mode 100644 index 08e86336b8..0000000000 --- a/odiglet/pkg/allocator/debug/gosym/symtab_test.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package gosym - -import ( - "fmt" - "testing" -) - -func assertString(t *testing.T, dsc, out, tgt string) { - if out != tgt { - t.Fatalf("Expected: %q Actual: %q for %s", tgt, out, dsc) - } -} - -func TestStandardLibPackage(t *testing.T) { - s1 := Sym{Name: "io.(*LimitedReader).Read"} - s2 := Sym{Name: "io.NewSectionReader"} - assertString(t, fmt.Sprintf("package of %q", s1.Name), s1.PackageName(), "io") - assertString(t, fmt.Sprintf("package of %q", s2.Name), s2.PackageName(), "io") - assertString(t, fmt.Sprintf("receiver of %q", s1.Name), s1.ReceiverName(), "(*LimitedReader)") - assertString(t, fmt.Sprintf("receiver of %q", s2.Name), s2.ReceiverName(), "") -} - -func TestStandardLibPathPackage(t *testing.T) { - s1 := Sym{Name: "debug/gosym.(*LineTable).PCToLine"} - s2 := Sym{Name: "debug/gosym.NewTable"} - assertString(t, fmt.Sprintf("package of %q", s1.Name), s1.PackageName(), "debug/gosym") - assertString(t, fmt.Sprintf("package of %q", s2.Name), s2.PackageName(), "debug/gosym") - assertString(t, fmt.Sprintf("receiver of %q", s1.Name), s1.ReceiverName(), "(*LineTable)") - assertString(t, fmt.Sprintf("receiver of %q", s2.Name), s2.ReceiverName(), "") -} - -func TestRemotePackage(t *testing.T) { - s1 := Sym{Name: "github.com/docker/doc.ker/pkg/mflag.(*FlagSet).PrintDefaults"} - s2 := Sym{Name: "github.com/docker/doc.ker/pkg/mflag.PrintDefaults"} - assertString(t, fmt.Sprintf("package of %q", s1.Name), s1.PackageName(), "github.com/docker/doc.ker/pkg/mflag") - assertString(t, fmt.Sprintf("package of %q", s2.Name), s2.PackageName(), "github.com/docker/doc.ker/pkg/mflag") - assertString(t, fmt.Sprintf("receiver of %q", s1.Name), s1.ReceiverName(), "(*FlagSet)") - assertString(t, fmt.Sprintf("receiver of %q", s2.Name), s2.ReceiverName(), "") -} diff --git a/odiglet/pkg/allocator/debug/gosym/testdata/main.go b/odiglet/pkg/allocator/debug/gosym/testdata/main.go deleted file mode 100644 index b7702184cd..0000000000 --- a/odiglet/pkg/allocator/debug/gosym/testdata/main.go +++ /dev/null @@ -1,10 +0,0 @@ -package main - -func linefrompc() -func pcfromline() - -func main() { - // Prevent GC of our test symbols - linefrompc() - pcfromline() -} diff --git a/odiglet/pkg/allocator/debug/gosym/testdata/pclinetest.h b/odiglet/pkg/allocator/debug/gosym/testdata/pclinetest.h deleted file mode 100644 index 156c0b87b0..0000000000 --- a/odiglet/pkg/allocator/debug/gosym/testdata/pclinetest.h +++ /dev/null @@ -1,9 +0,0 @@ -// +build ignore - -// Empty include file to generate z symbols - - - - - -// EOF diff --git a/odiglet/pkg/allocator/debug/gosym/testdata/pclinetest.s b/odiglet/pkg/allocator/debug/gosym/testdata/pclinetest.s deleted file mode 100644 index 53461cdfc1..0000000000 --- a/odiglet/pkg/allocator/debug/gosym/testdata/pclinetest.s +++ /dev/null @@ -1,48 +0,0 @@ -TEXT ·linefrompc(SB),4,$0 // Each byte stores its line delta -BYTE $2; -BYTE $1; -BYTE $1; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; -BYTE $1; -BYTE $1; -BYTE $1; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; -BYTE $1; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; BYTE $0; -#include "pclinetest.h" -BYTE $2; -#include "pclinetest.h" -BYTE $2; -BYTE $255; - -TEXT ·pcfromline(SB),4,$0 // Each record stores its line delta, then n, then n more bytes -BYTE $32; BYTE $0; -BYTE $1; BYTE $1; BYTE $0; -BYTE $1; BYTE $0; - -BYTE $2; BYTE $4; BYTE $0; BYTE $0; BYTE $0; BYTE $0; - - -#include "pclinetest.h" -BYTE $4; BYTE $0; - - -BYTE $3; BYTE $3; BYTE $0; BYTE $0; BYTE $0; -#include "pclinetest.h" - - -BYTE $4; BYTE $3; BYTE $0; BYTE $0; BYTE $0; -BYTE $255; diff --git a/odiglet/pkg/allocator/debug/macho/README.md b/odiglet/pkg/allocator/debug/macho/README.md deleted file mode 100644 index a90f1abf3c..0000000000 --- a/odiglet/pkg/allocator/debug/macho/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## More Info - -More info on the Mach-O file structure here: [Mach-O Deep Dive](https://www.symbolcrash.com/2019/02/25/so-you-want-to-be-a-mach-o-man/) diff --git a/odiglet/pkg/allocator/debug/macho/exports.go b/odiglet/pkg/allocator/debug/macho/exports.go deleted file mode 100644 index d5c57205d1..0000000000 --- a/odiglet/pkg/allocator/debug/macho/exports.go +++ /dev/null @@ -1,27 +0,0 @@ -package macho - -const N_SECT = 0x0E -const N_PEXT = 0x10 -const N_EXT = 0x01 - -// Export - describes a single export entry (similar to PE version for future refactoring) -type Export struct { - //Ordinal uint32 // no ordinals for Mach-O - Name string - VirtualAddress uint64 -} - -// Exports - gets exports, including private exports -func (f *File) Exports() []Export { - var exports []Export - for _, symbol := range f.Symtab.Syms { - if (symbol.Type&N_PEXT == N_PEXT || - symbol.Type&N_EXT == N_EXT) && symbol.Value != 0 { - var export Export - export.Name = symbol.Name - export.VirtualAddress = symbol.Value - exports = append(exports, export) - } - } - return exports -} diff --git a/odiglet/pkg/allocator/debug/macho/fat.go b/odiglet/pkg/allocator/debug/macho/fat.go deleted file mode 100644 index 6bd730dc0b..0000000000 --- a/odiglet/pkg/allocator/debug/macho/fat.go +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package macho - -import ( - "encoding/binary" - "fmt" - "io" - "os" -) - -// A FatFile is a Mach-O universal binary that contains at least one architecture. -type FatFile struct { - Magic uint32 - Arches []FatArch - closer io.Closer -} - -// A FatArchHeader represents a fat header for a specific image architecture. -type FatArchHeader struct { - Cpu Cpu - SubCpu uint32 - Offset uint32 - Size uint32 - Align uint32 -} - -const fatArchHeaderSize = 5 * 4 - -// A FatArch is a Mach-O File inside a FatFile. -type FatArch struct { - FatArchHeader - *File -} - -// ErrNotFat is returned from NewFatFile or OpenFat when the file is not a -// universal binary but may be a thin binary, based on its magic number. -var ErrNotFat = &FormatError{0, "not a fat Mach-O file", nil} - -// NewFatFile creates a new FatFile for accessing all the Mach-O images in a -// universal binary. The Mach-O binary is expected to start at position 0 in -// the ReaderAt. -func NewFatFile(r io.ReaderAt) (*FatFile, error) { - var ff FatFile - sr := io.NewSectionReader(r, 0, 1<<63-1) - - // Read the fat_header struct, which is always in big endian. - // Start with the magic number. - err := binary.Read(sr, binary.BigEndian, &ff.Magic) - if err != nil { - return nil, &FormatError{0, "error reading magic number", nil} - } else if ff.Magic != MagicFat { - // See if this is a Mach-O file via its magic number. The magic - // must be converted to little endian first though. - var buf [4]byte - binary.BigEndian.PutUint32(buf[:], ff.Magic) - leMagic := binary.LittleEndian.Uint32(buf[:]) - if leMagic == Magic32 || leMagic == Magic64 { - return nil, ErrNotFat - } else { - return nil, &FormatError{0, "invalid magic number", nil} - } - } - offset := int64(4) - - // Read the number of FatArchHeaders that come after the fat_header. - var narch uint32 - err = binary.Read(sr, binary.BigEndian, &narch) - if err != nil { - return nil, &FormatError{offset, "invalid fat_header", nil} - } - offset += 4 - - if narch < 1 { - return nil, &FormatError{offset, "file contains no images", nil} - } - - // Combine the Cpu and SubCpu (both uint32) into a uint64 to make sure - // there are not duplicate architectures. - seenArches := make(map[uint64]bool, narch) - // Make sure that all images are for the same MH_ type. - var machoType Type - - // Following the fat_header comes narch fat_arch structs that index - // Mach-O images further in the file. - ff.Arches = make([]FatArch, narch) - for i := uint32(0); i < narch; i++ { - fa := &ff.Arches[i] - err = binary.Read(sr, binary.BigEndian, &fa.FatArchHeader) - if err != nil { - return nil, &FormatError{offset, "invalid fat_arch header", nil} - } - offset += fatArchHeaderSize - - fr := io.NewSectionReader(r, int64(fa.Offset), int64(fa.Size)) - fa.File, err = NewFile(fr) - if err != nil { - return nil, err - } - - // Make sure the architecture for this image is not duplicate. - seenArch := (uint64(fa.Cpu) << 32) | uint64(fa.SubCpu) - if o, k := seenArches[seenArch]; o || k { - return nil, &FormatError{offset, fmt.Sprintf("duplicate architecture cpu=%v, subcpu=%#x", fa.Cpu, fa.SubCpu), nil} - } - seenArches[seenArch] = true - - // Make sure the Mach-O type matches that of the first image. - if i == 0 { - machoType = fa.Type - } else { - if fa.Type != machoType { - return nil, &FormatError{offset, fmt.Sprintf("Mach-O type for architecture #%d (type=%#x) does not match first (type=%#x)", i, fa.Type, machoType), nil} - } - } - } - - return &ff, nil -} - -// OpenFat opens the named file using os.Open and prepares it for use as a Mach-O -// universal binary. -func OpenFat(name string) (*FatFile, error) { - f, err := os.Open(name) - if err != nil { - return nil, err - } - ff, err := NewFatFile(f) - if err != nil { - f.Close() - return nil, err - } - ff.closer = f - return ff, nil -} - -func (ff *FatFile) Close() error { - var err error - if ff.closer != nil { - err = ff.closer.Close() - ff.closer = nil - } - return err -} diff --git a/odiglet/pkg/allocator/debug/macho/file.go b/odiglet/pkg/allocator/debug/macho/file.go deleted file mode 100644 index 4c1da62be6..0000000000 --- a/odiglet/pkg/allocator/debug/macho/file.go +++ /dev/null @@ -1,952 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package macho implements access to Mach-O object files. -package macho - -// High level access to low level data structures. - -import ( - "bytes" - "compress/zlib" - "debug/dwarf" - "encoding/binary" - "fmt" - "io" - "os" - "strings" -) - -// A File represents an open Mach-O file. -type File struct { - FileHeader - ByteOrder binary.ByteOrder - Loads []Load - Sections []*Section - - Symtab *Symtab - Dysymtab *Dysymtab - SigBlock *SigBlock - FuncStarts *FuncStarts - DataInCode *DataInCode - DylinkInfo *DylinkInfo - - EntryPoint uint64 - Insertion []byte - - closer io.Closer -} - -// A Load represents any Mach-O load command. -type Load interface { - Raw() []byte -} - -// A LoadBytes is the uninterpreted bytes of a Mach-O load command. -type LoadBytes []byte - -func (b LoadBytes) Raw() []byte { return b } - -// A SegmentHeader is the header for a Mach-O 32-bit or 64-bit load segment command. -type SegmentHeader struct { - Cmd LoadCmd - Len uint32 - Name string - Addr uint64 - Memsz uint64 - Offset uint64 - Filesz uint64 - Maxprot uint32 - Prot uint32 - Nsect uint32 - Flag uint32 -} - -type SigBlock struct { - Len uint32 - Offset uint64 - RawDat []byte -} - -type FuncStarts struct { - Len uint32 - Offset uint64 - RawDat []byte -} - -type DataInCode struct { - Len uint32 - Offset uint64 - RawDat []byte -} - -type DylinkInfo struct { - RebaseLen uint32 - RebaseOffset uint64 - RebaseDat []byte - BindingInfoLen uint32 - BindingInfoOffset uint64 - BindingInfoDat []byte - WeakBindingLen uint32 - WeakBindingOffset uint64 - WeakBindingDat []byte - LazyBindingLen uint32 - LazyBindingOffset uint64 - LazyBindingDat []byte - ExportInfoLen uint32 - ExportInfoOffset uint64 - ExportInfoDat []byte -} - -// A Segment represents a Mach-O 32-bit or 64-bit load segment command. -type Segment struct { - LoadBytes - SegmentHeader - - // Embed ReaderAt for ReadAt method. - // Do not embed SectionReader directly - // to avoid having Read and Seek. - // If a client wants Read and Seek it must use - // Open() to avoid fighting over the seek offset - // with other clients. - io.ReaderAt - sr *io.SectionReader -} - -// Data reads and returns the contents of the segment. -func (s *Segment) Data() ([]byte, error) { - dat := make([]byte, s.sr.Size()) - n, err := s.sr.ReadAt(dat, 0) - if n == len(dat) { - err = nil - } - return dat[0:n], err -} - -// Open returns a new ReadSeeker reading the segment. -func (s *Segment) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) } - -type SectionHeader struct { - Name string - Seg string - Addr uint64 - Size uint64 - Offset uint32 - Align uint32 - Reloff uint32 - Nreloc uint32 - Flags uint32 -} - -// A Reloc represents a Mach-O relocation. -type Reloc struct { - Addr uint32 - Value uint32 - // when Scattered == false && Extern == true, Value is the symbol number. - // when Scattered == false && Extern == false, Value is the section number. - // when Scattered == true, Value is the value that this reloc refers to. - Type uint8 - Len uint8 // 0=byte, 1=word, 2=long, 3=quad - Pcrel bool - Extern bool // valid if Scattered == false - Scattered bool -} - -type Section struct { - SectionHeader - Relocs []Reloc - - // Embed ReaderAt for ReadAt method. - // Do not embed SectionReader directly - // to avoid having Read and Seek. - // If a client wants Read and Seek it must use - // Open() to avoid fighting over the seek offset - // with other clients. - io.ReaderAt - sr *io.SectionReader -} - -// Data reads and returns the contents of the Mach-O section. -func (s *Section) Data() ([]byte, error) { - dat := make([]byte, s.sr.Size()) - n, err := s.sr.ReadAt(dat, 0) - if n == len(dat) { - err = nil - } - return dat[0:n], err -} - -// Open returns a new ReadSeeker reading the Mach-O section. -func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) } - -// A Dylinker represents a Mach-O load dynamic library command. -type Dylinker struct { - LoadBytes - Name string -} - -// A Dylib represents a Mach-O load dynamic library command. -type Dylib struct { - LoadBytes - Name string - Time uint32 - CurrentVersion uint32 - CompatVersion uint32 -} - -// A Symtab represents a Mach-O symbol table command. -type Symtab struct { - LoadBytes - SymtabCmd - Syms []Symbol - RawSymtab []byte - RawStringtab []byte -} - -// A Dysymtab represents a Mach-O dynamic symbol table command. -type Dysymtab struct { - LoadBytes - DysymtabCmd - IndirectSyms []uint32 // indices into Symtab.Syms - RawDysymtab []byte -} - -// A Rpath represents a Mach-O rpath command. -type Rpath struct { - LoadBytes - Path string -} - -// A Symbol is a Mach-O 32-bit or 64-bit symbol table entry. -type Symbol struct { - Name string - Type uint8 - Sect uint8 - Desc uint16 - Value uint64 -} - -/* - * Mach-O reader - */ - -// FormatError is returned by some operations if the data does -// not have the correct format for an object file. -type FormatError struct { - off int64 - msg string - val interface{} -} - -func (e *FormatError) Error() string { - msg := e.msg - if e.val != nil { - msg += fmt.Sprintf(" '%v'", e.val) - } - msg += fmt.Sprintf(" in record at byte %#x", e.off) - return msg -} - -// Open opens the named file using os.Open and prepares it for use as a Mach-O binary. -func Open(name string) (*File, error) { - f, err := os.Open(name) - if err != nil { - return nil, err - } - ff, err := NewFile(f) - if err != nil { - f.Close() - return nil, err - } - ff.closer = f - return ff, nil -} - -// Close closes the File. -// If the File was created using NewFile directly instead of Open, -// Close has no effect. -func (f *File) Close() error { - var err error - if f.closer != nil { - err = f.closer.Close() - f.closer = nil - } - return err -} - -// NewFile creates a new macho.File for accessing a Mach-o binary file in an underlying reader. -func NewFile(r io.ReaderAt) (*File, error) { - return newFileInternal(r, false) -} - -// NewFileFromMemory creates a new macho.File for accessing a Mach-O binary in-memory image in an underlying reader. -func NewFileFromMemory(r io.ReaderAt) (*File, error) { - return newFileInternal(r, true) -} - -// NewFile creates a new File for accessing a PE binary in an underlying reader. -func newFileInternal(r io.ReaderAt, memoryMode bool) (*File, error) { - - f := new(File) - sr := io.NewSectionReader(r, 0, 1<<63-1) - - // Read and decode Mach magic to determine byte order, size. - // Magic32 and Magic64 differ only in the bottom bit. - var ident [4]byte - if _, err := r.ReadAt(ident[0:], 0); err != nil { - return nil, err - } - be := binary.BigEndian.Uint32(ident[0:]) - le := binary.LittleEndian.Uint32(ident[0:]) - switch Magic32 &^ 1 { - case be &^ 1: - f.ByteOrder = binary.BigEndian - f.Magic = be - case le &^ 1: - f.ByteOrder = binary.LittleEndian - f.Magic = le - default: - return nil, &FormatError{0, "invalid magic number", nil} - } - - // Read entire file header. - if err := binary.Read(sr, f.ByteOrder, &f.FileHeader); err != nil { - return nil, err - } - - // Then load commands. - offset := int64(fileHeaderSize32) - if f.Magic == Magic64 { - offset = fileHeaderSize64 - } - dat := make([]byte, f.Cmdsz) - if _, err := r.ReadAt(dat, offset); err != nil { - return nil, err - } - f.Loads = make([]Load, f.Ncmd) - bo := f.ByteOrder - for i := range f.Loads { - // Each load command begins with uint32 command and length. - if len(dat) < 8 { - return nil, &FormatError{offset, "command block too small", nil} - } - cmd, siz := LoadCmd(bo.Uint32(dat[0:4])), bo.Uint32(dat[4:8]) - if siz < 8 || siz > uint32(len(dat)) { - return nil, &FormatError{offset, "invalid command block size", nil} - } - var cmddat []byte - cmddat, dat = dat[0:siz], dat[siz:] - offset += int64(siz) - var s *Segment - //fmt.Printf("LoadCmdVal: %+v\n", cmd) - switch cmd { - default: - f.Loads[i] = LoadBytes(cmddat) - - case LoadCmdRpath: - var hdr RpathCmd - b := bytes.NewReader(cmddat) - if err := binary.Read(b, bo, &hdr); err != nil { - return nil, err - } - l := new(Rpath) - if hdr.Path >= uint32(len(cmddat)) { - return nil, &FormatError{offset, "invalid path in rpath command", hdr.Path} - } - l.Path = cstring(cmddat[hdr.Path:]) - l.LoadBytes = LoadBytes(cmddat) - f.Loads[i] = l - - case LoadCmdDylinker: - var hdr DylinkerCmd - b := bytes.NewReader(cmddat) - if err := binary.Read(b, bo, &hdr); err != nil { - return nil, err - } - l := new(Dylinker) - if hdr.Name >= uint32(len(cmddat)) { - return nil, &FormatError{offset, "invalid name in dynamic library command", hdr.Name} - } - l.Name = cstring(cmddat[hdr.Name:]) - l.LoadBytes = LoadBytes(cmddat) - f.Loads[i] = l - - case LoadCmdDylib: - var hdr DylibCmd - b := bytes.NewReader(cmddat) - if err := binary.Read(b, bo, &hdr); err != nil { - return nil, err - } - l := new(Dylib) - if hdr.Name >= uint32(len(cmddat)) { - return nil, &FormatError{offset, "invalid name in dynamic library command", hdr.Name} - } - l.Name = cstring(cmddat[hdr.Name:]) - l.Time = hdr.Time - l.CurrentVersion = hdr.CurrentVersion - l.CompatVersion = hdr.CompatVersion - l.LoadBytes = LoadBytes(cmddat) - f.Loads[i] = l - - case LoadCmdSymtab: - var hdr SymtabCmd - b := bytes.NewReader(cmddat) - if err := binary.Read(b, bo, &hdr); err != nil { - return nil, err - } - strtab := make([]byte, hdr.Strsize) - - var linkeditAddr, textAddr, linkeditOffset int64 - if !memoryMode { - if _, err := r.ReadAt(strtab, int64(hdr.Stroff)); err != nil { - return nil, err - } - } else { - // in memory, we have to translate the file offsets for strtab/symtab into offsets into LINKEDIT segment - for _, load := range f.Loads { - switch segment := load.(type) { - case *Segment: - if segment == nil { - continue - } - if segment.Name == "__LINKEDIT" { - linkeditAddr = int64(segment.Addr) - linkeditOffset = int64(segment.Offset) - } else if segment.Name == "__TEXT" { - textAddr = int64(segment.Addr) - } - } - } - strtabAddr := (linkeditAddr - textAddr) + (int64(hdr.Stroff) - linkeditOffset) - if _, err := r.ReadAt(strtab, strtabAddr); err != nil { - return nil, err - } - } - - var symsz int - if f.Magic == Magic64 { - symsz = 16 - } else { - symsz = 12 - } - symdat := make([]byte, int(hdr.Nsyms)*symsz) - - if !memoryMode { - if _, err := r.ReadAt(symdat, int64(hdr.Symoff)); err != nil { - return nil, err - } - } else { - if _, err := r.ReadAt(symdat, (linkeditAddr-textAddr)+(int64(hdr.Symoff)-linkeditOffset)); err != nil { - return nil, err - } - } - - st, err := f.parseSymtab(symdat, strtab, cmddat, &hdr, offset) - if err != nil { - return nil, err - } - f.Loads[i] = st - f.Symtab = st - f.Symtab.Symoff = hdr.Symoff - f.Symtab.Stroff = hdr.Stroff - - case LoadCmdSignature: - var sigCmd SigBlockCmd - s := bytes.NewReader(cmddat) - if err := binary.Read(s, bo, &sigCmd); err != nil { - return nil, err - } - //fmt.Printf("SigData: %+v\n", sigCmd) - sig := make([]byte, sigCmd.Sigsize) - if _, err := r.ReadAt(sig, int64(sigCmd.Sigoff)); err != nil { - return nil, err - } - var block SigBlock - block.Offset = uint64(sigCmd.Sigoff) - block.Len = sigCmd.Sigsize - block.RawDat = sig - f.SigBlock = &block - f.Loads[i] = LoadBytes(cmddat) - - case LoadCmdFuncStarts: - var funcCmd FuncStartsCmd - fsc := bytes.NewReader(cmddat) - if err := binary.Read(fsc, bo, &funcCmd); err != nil { - return nil, err - } - //fmt.Printf("FuncStartsData: %+v\n", funcCmd) - fs := make([]byte, funcCmd.Datasize) - if _, err := r.ReadAt(fs, int64(funcCmd.Dataoff)); err != nil { - return nil, err - } - var funcs FuncStarts - funcs.Offset = uint64(funcCmd.Dataoff) - funcs.Len = funcCmd.Datasize - funcs.RawDat = fs - f.FuncStarts = &funcs - f.Loads[i] = LoadBytes(cmddat) - - case LoadCmdDataInCode: - var dataCmd DataInCodeCmd - dcc := bytes.NewReader(cmddat) - if err := binary.Read(dcc, bo, &dataCmd); err != nil { - return nil, err - } - //fmt.Printf("DataInCode: %+v\n", dataCmd) - dc := make([]byte, dataCmd.Datasize) - if _, err := r.ReadAt(dc, int64(dataCmd.Dataoff)); err != nil { - return nil, err - } - var datacode DataInCode - datacode.Offset = uint64(dataCmd.Dataoff) - datacode.Len = dataCmd.Datasize - datacode.RawDat = dc - f.DataInCode = &datacode - f.Loads[i] = LoadBytes(cmddat) - - case LoadCmdDylinkInfo: - var dylinkInfoCmd DylinkInfoCmd - dic := bytes.NewReader(cmddat) - if err := binary.Read(dic, bo, &dylinkInfoCmd); err != nil { - return nil, err - } - //fmt.Printf("LoadCmdDylinkInfo: %+v\n", dylinkInfoCmd) - // Copy each section next - var dylinkInfo DylinkInfo - // Rebase deets - if dylinkInfoCmd.Rebasesize > 0 { - if !memoryMode { // this data is in LINKEDIT already - rebase := make([]byte, dylinkInfoCmd.Rebasesize) - if _, err := r.ReadAt(rebase, int64(dylinkInfoCmd.Rebaseoff)); err != nil { - return nil, err - } - dylinkInfo.RebaseDat = rebase - } - dylinkInfo.RebaseLen = dylinkInfoCmd.Rebasesize - dylinkInfo.RebaseOffset = uint64(dylinkInfoCmd.Rebaseoff) - } - // BindingInfo deets - if dylinkInfoCmd.Bindinginfosize > 0 { - if !memoryMode { // this data is in LINKEDIT already - binding := make([]byte, dylinkInfoCmd.Bindinginfosize) - if _, err := r.ReadAt(binding, int64(dylinkInfoCmd.Bindinginfooff)); err != nil { - return nil, err - } - dylinkInfo.BindingInfoDat = binding - } - dylinkInfo.BindingInfoLen = dylinkInfoCmd.Bindinginfosize - dylinkInfo.BindingInfoOffset = uint64(dylinkInfoCmd.Bindinginfooff) - } - // Weak deets - if dylinkInfoCmd.Weakbindingsize > 0 { - if !memoryMode { // this data is in LINKEDIT already - weak := make([]byte, dylinkInfoCmd.Weakbindingsize) - if _, err := r.ReadAt(weak, int64(dylinkInfoCmd.Weakbindingoff)); err != nil { - return nil, err - } - dylinkInfo.WeakBindingDat = weak - } - dylinkInfo.WeakBindingLen = dylinkInfoCmd.Weakbindingsize - dylinkInfo.WeakBindingOffset = uint64(dylinkInfoCmd.Weakbindingoff) - } - // Lazy deets - if dylinkInfoCmd.Lazybindingsize > 0 { - if !memoryMode { // this data is in LINKEDIT already - lazy := make([]byte, dylinkInfoCmd.Lazybindingsize) - if _, err := r.ReadAt(lazy, int64(dylinkInfoCmd.Lazybindingoff)); err != nil { - return nil, err - } - dylinkInfo.LazyBindingDat = lazy - } - dylinkInfo.LazyBindingLen = dylinkInfoCmd.Lazybindingsize - dylinkInfo.LazyBindingOffset = uint64(dylinkInfoCmd.Lazybindingoff) - } - // ExportInfo deets - if dylinkInfoCmd.Exportinfosize > 0 { - if !memoryMode { // this data is in LINKEDIT already - export := make([]byte, dylinkInfoCmd.Exportinfosize) - if _, err := r.ReadAt(export, int64(dylinkInfoCmd.Exportinfooff)); err != nil { - return nil, err - } - dylinkInfo.ExportInfoDat = export - } - dylinkInfo.ExportInfoLen = dylinkInfoCmd.Exportinfosize - dylinkInfo.ExportInfoOffset = uint64(dylinkInfoCmd.Exportinfooff) - } - // Finalize the object - f.DylinkInfo = &dylinkInfo - f.Loads[i] = LoadBytes(cmddat) - - case LoadCmdDysymtab: - var hdr DysymtabCmd - b := bytes.NewReader(cmddat) - if err := binary.Read(b, bo, &hdr); err != nil { - return nil, err - } - dat := make([]byte, hdr.Nindirectsyms*4) - if _, err := r.ReadAt(dat, int64(hdr.Indirectsymoff)); err != nil { - return nil, err - } - x := make([]uint32, hdr.Nindirectsyms) - if err := binary.Read(bytes.NewReader(dat), bo, x); err != nil { - return nil, err - } - st := new(Dysymtab) - st.LoadBytes = LoadBytes(cmddat) - st.DysymtabCmd = hdr - st.IndirectSyms = x - f.Loads[i] = st - f.Dysymtab = st - f.Dysymtab.Indirectsymoff = hdr.Indirectsymoff - f.Dysymtab.RawDysymtab = dat - - case LoadCmdSegment: - var seg32 Segment32 - b := bytes.NewReader(cmddat) - if err := binary.Read(b, bo, &seg32); err != nil { - return nil, err - } - s = new(Segment) - s.LoadBytes = cmddat - s.Cmd = cmd - s.Len = siz - s.Name = cstring(seg32.Name[0:]) - s.Addr = uint64(seg32.Addr) - s.Memsz = uint64(seg32.Memsz) - s.Offset = uint64(seg32.Offset) - s.Filesz = uint64(seg32.Filesz) - s.Maxprot = seg32.Maxprot - s.Prot = seg32.Prot - s.Nsect = seg32.Nsect - s.Flag = seg32.Flag - if uint64((seg32.Offset + seg32.Filesz)) > FinalSegEnd { - FinalSegEnd = uint64((seg32.Offset + seg32.Filesz)) - } - f.Loads[i] = s - for i := 0; i < int(s.Nsect); i++ { - var sh32 Section32 - if err := binary.Read(b, bo, &sh32); err != nil { - return nil, err - } - sh := new(Section) - sh.Name = cstring(sh32.Name[0:]) - sh.Seg = cstring(sh32.Seg[0:]) - sh.Addr = uint64(sh32.Addr) - sh.Size = uint64(sh32.Size) - sh.Offset = sh32.Offset - sh.Align = sh32.Align - sh.Reloff = sh32.Reloff - sh.Nreloc = sh32.Nreloc - sh.Flags = sh32.Flags - if err := f.pushSection(sh, r); err != nil { - return nil, err - } - } - - case LoadCmdSegment64: - var seg64 Segment64 - b := bytes.NewReader(cmddat) - if err := binary.Read(b, bo, &seg64); err != nil { - return nil, err - } - s = new(Segment) - s.LoadBytes = cmddat - s.Cmd = cmd - s.Len = siz - s.Name = cstring(seg64.Name[0:]) - s.Addr = seg64.Addr - s.Memsz = seg64.Memsz - s.Offset = seg64.Offset - s.Filesz = seg64.Filesz - s.Maxprot = seg64.Maxprot - s.Prot = seg64.Prot - s.Nsect = seg64.Nsect - s.Flag = seg64.Flag - if uint64((seg64.Offset + seg64.Filesz)) > FinalSegEnd { - FinalSegEnd = uint64((seg64.Offset + seg64.Filesz)) - } - f.Loads[i] = s - for i := 0; i < int(s.Nsect); i++ { - var sh64 Section64 - if err := binary.Read(b, bo, &sh64); err != nil { - return nil, err - } - sh := new(Section) - sh.Name = cstring(sh64.Name[0:]) - sh.Seg = cstring(sh64.Seg[0:]) - sh.Addr = sh64.Addr - sh.Size = sh64.Size - sh.Offset = sh64.Offset - sh.Align = sh64.Align - sh.Reloff = sh64.Reloff - sh.Nreloc = sh64.Nreloc - sh.Flags = sh64.Flags - if err := f.pushSection(sh, r); err != nil { - return nil, err - } - } - - //case LoadCmdUnixThread: - // todo: do we have to support thread_command here for older binaries? or is the LC_MAIN handling backwards compatible? - - case LoadCmdMain: - var entryPoint EntryPointCmd - b := bytes.NewReader(cmddat) - if err := binary.Read(b, bo, &entryPoint); err != nil { - return nil, err - } - f.EntryPoint = entryPoint.EntryOff - } - if s != nil { - if !memoryMode { - s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Filesz)) - } else { - s.sr = io.NewSectionReader(r, int64(s.Addr), int64(s.Filesz)) - } - s.ReaderAt = s.sr - } - } - return f, nil -} - -func (f *File) parseSymtab(symdat, strtab, cmddat []byte, hdr *SymtabCmd, offset int64) (*Symtab, error) { - bo := f.ByteOrder - symtab := make([]Symbol, hdr.Nsyms) - b := bytes.NewReader(symdat) - for i := range symtab { - var n Nlist64 - if f.Magic == Magic64 { - if err := binary.Read(b, bo, &n); err != nil { - return nil, err - } - } else { - var n32 Nlist32 - if err := binary.Read(b, bo, &n32); err != nil { - return nil, err - } - n.Name = n32.Name - n.Type = n32.Type - n.Sect = n32.Sect - n.Desc = n32.Desc - n.Value = uint64(n32.Value) - } - sym := &symtab[i] - if n.Name >= uint32(len(strtab)) { - return nil, &FormatError{offset, "invalid name in symbol table", n.Name} - } - sym.Name = cstring(strtab[n.Name:]) - sym.Type = n.Type - sym.Sect = n.Sect - sym.Desc = n.Desc - sym.Value = n.Value - } - st := new(Symtab) - st.LoadBytes = LoadBytes(cmddat) - st.Syms = symtab - st.RawSymtab = symdat - st.RawStringtab = strtab - return st, nil -} - -type relocInfo struct { - Addr uint32 - Symnum uint32 -} - -func (f *File) pushSection(sh *Section, r io.ReaderAt) error { - f.Sections = append(f.Sections, sh) - sh.sr = io.NewSectionReader(r, int64(sh.Offset), int64(sh.Size)) - sh.ReaderAt = sh.sr - - if sh.Nreloc > 0 { - reldat := make([]byte, int(sh.Nreloc)*8) - if _, err := r.ReadAt(reldat, int64(sh.Reloff)); err != nil { - return err - } - b := bytes.NewReader(reldat) - - bo := f.ByteOrder - - sh.Relocs = make([]Reloc, sh.Nreloc) - for i := range sh.Relocs { - rel := &sh.Relocs[i] - - var ri relocInfo - if err := binary.Read(b, bo, &ri); err != nil { - return err - } - - if ri.Addr&(1<<31) != 0 { // scattered - rel.Addr = ri.Addr & (1<<24 - 1) - rel.Type = uint8((ri.Addr >> 24) & (1<<4 - 1)) - rel.Len = uint8((ri.Addr >> 28) & (1<<2 - 1)) - rel.Pcrel = ri.Addr&(1<<30) != 0 - rel.Value = ri.Symnum - rel.Scattered = true - } else { - switch bo { - case binary.LittleEndian: - rel.Addr = ri.Addr - rel.Value = ri.Symnum & (1<<24 - 1) - rel.Pcrel = ri.Symnum&(1<<24) != 0 - rel.Len = uint8((ri.Symnum >> 25) & (1<<2 - 1)) - rel.Extern = ri.Symnum&(1<<27) != 0 - rel.Type = uint8((ri.Symnum >> 28) & (1<<4 - 1)) - case binary.BigEndian: - rel.Addr = ri.Addr - rel.Value = ri.Symnum >> 8 - rel.Pcrel = ri.Symnum&(1<<7) != 0 - rel.Len = uint8((ri.Symnum >> 5) & (1<<2 - 1)) - rel.Extern = ri.Symnum&(1<<4) != 0 - rel.Type = uint8(ri.Symnum & (1<<4 - 1)) - default: - panic("unreachable") - } - } - } - } - - return nil -} - -func cstring(b []byte) string { - i := bytes.IndexByte(b, 0) - if i == -1 { - i = len(b) - } - return string(b[0:i]) -} - -// Segment returns the first Segment with the given name, or nil if no such segment exists. -func (f *File) Segment(name string) *Segment { - for _, l := range f.Loads { - if s, ok := l.(*Segment); ok && s.Name == name { - return s - } - } - return nil -} - -// Section returns the first section with the given name, or nil if no such -// section exists. -func (f *File) Section(name string) *Section { - for _, s := range f.Sections { - if s.Name == name { - return s - } - } - return nil -} - -// DWARF returns the DWARF debug information for the Mach-O file. -func (f *File) DWARF() (*dwarf.Data, error) { - dwarfSuffix := func(s *Section) string { - switch { - case strings.HasPrefix(s.Name, "__debug_"): - return s.Name[8:] - case strings.HasPrefix(s.Name, "__zdebug_"): - return s.Name[9:] - default: - return "" - } - - } - sectionData := func(s *Section) ([]byte, error) { - b, err := s.Data() - if err != nil && uint64(len(b)) < s.Size { - return nil, err - } - - if len(b) >= 12 && string(b[:4]) == "ZLIB" { - dlen := binary.BigEndian.Uint64(b[4:12]) - dbuf := make([]byte, dlen) - r, err := zlib.NewReader(bytes.NewBuffer(b[12:])) - if err != nil { - return nil, err - } - if _, err := io.ReadFull(r, dbuf); err != nil { - return nil, err - } - if err := r.Close(); err != nil { - return nil, err - } - b = dbuf - } - return b, nil - } - - // There are many other DWARF sections, but these - // are the ones the debug/dwarf package uses. - // Don't bother loading others. - var dat = map[string][]byte{"abbrev": nil, "info": nil, "str": nil, "line": nil, "ranges": nil} - for _, s := range f.Sections { - suffix := dwarfSuffix(s) - if suffix == "" { - continue - } - if _, ok := dat[suffix]; !ok { - continue - } - b, err := sectionData(s) - if err != nil { - return nil, err - } - dat[suffix] = b - } - - d, err := dwarf.New(dat["abbrev"], nil, nil, dat["info"], dat["line"], nil, dat["ranges"], dat["str"]) - if err != nil { - return nil, err - } - - // Look for DWARF4 .debug_types sections. - for i, s := range f.Sections { - suffix := dwarfSuffix(s) - if suffix != "types" { - continue - } - - b, err := sectionData(s) - if err != nil { - return nil, err - } - - err = d.AddTypes(fmt.Sprintf("types-%d", i), b) - if err != nil { - return nil, err - } - } - - return d, nil -} - -// ImportedSymbols returns the names of all symbols -// referred to by the binary f that are expected to be -// satisfied by other libraries at dynamic load time. -func (f *File) ImportedSymbols() ([]string, error) { - if f.Dysymtab == nil || f.Symtab == nil { - return nil, &FormatError{0, "missing symbol table", nil} - } - - st := f.Symtab - dt := f.Dysymtab - var all []string - for _, s := range st.Syms[dt.Iundefsym : dt.Iundefsym+dt.Nundefsym] { - all = append(all, s.Name) - } - return all, nil -} - -// ImportedLibraries returns the paths of all libraries -// referred to by the binary f that are expected to be -// linked with the binary at dynamic link time. -func (f *File) ImportedLibraries() ([]string, error) { - var all []string - for _, l := range f.Loads { - if lib, ok := l.(*Dylib); ok { - all = append(all, lib.Name) - } - } - return all, nil -} diff --git a/odiglet/pkg/allocator/debug/macho/file_test.go b/odiglet/pkg/allocator/debug/macho/file_test.go deleted file mode 100644 index 003c14e69b..0000000000 --- a/odiglet/pkg/allocator/debug/macho/file_test.go +++ /dev/null @@ -1,379 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package macho - -import ( - "reflect" - "testing" -) - -type fileTest struct { - file string - hdr FileHeader - loads []interface{} - sections []*SectionHeader - relocations map[string][]Reloc -} - -var fileTests = []fileTest{ - { - "testdata/gcc-386-darwin-exec", - FileHeader{0xfeedface, Cpu386, 0x3, 0x2, 0xc, 0x3c0, 0x85}, - []interface{}{ - &SegmentHeader{LoadCmdSegment, 0x38, "__PAGEZERO", 0x0, 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, - &SegmentHeader{LoadCmdSegment, 0xc0, "__TEXT", 0x1000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x2, 0x0}, - &SegmentHeader{LoadCmdSegment, 0xc0, "__DATA", 0x2000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x2, 0x0}, - &SegmentHeader{LoadCmdSegment, 0x7c, "__IMPORT", 0x3000, 0x1000, 0x2000, 0x1000, 0x7, 0x7, 0x1, 0x0}, - &SegmentHeader{LoadCmdSegment, 0x38, "__LINKEDIT", 0x4000, 0x1000, 0x3000, 0x12c, 0x7, 0x1, 0x0, 0x0}, - nil, // LC_SYMTAB - nil, // LC_DYSYMTAB - nil, // LC_LOAD_DYLINKER - nil, // LC_UUID - nil, // LC_UNIXTHREAD - &Dylib{nil, "/usr/lib/libgcc_s.1.dylib", 0x2, 0x10000, 0x10000}, - &Dylib{nil, "/usr/lib/libSystem.B.dylib", 0x2, 0x6f0104, 0x10000}, - }, - []*SectionHeader{ - {"__text", "__TEXT", 0x1f68, 0x88, 0xf68, 0x2, 0x0, 0x0, 0x80000400}, - {"__cstring", "__TEXT", 0x1ff0, 0xd, 0xff0, 0x0, 0x0, 0x0, 0x2}, - {"__data", "__DATA", 0x2000, 0x14, 0x1000, 0x2, 0x0, 0x0, 0x0}, - {"__dyld", "__DATA", 0x2014, 0x1c, 0x1014, 0x2, 0x0, 0x0, 0x0}, - {"__jump_table", "__IMPORT", 0x3000, 0xa, 0x2000, 0x6, 0x0, 0x0, 0x4000008}, - }, - nil, - }, - { - "testdata/gcc-amd64-darwin-exec", - FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0x2, 0xb, 0x568, 0x85}, - []interface{}{ - &SegmentHeader{LoadCmdSegment64, 0x48, "__PAGEZERO", 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, - &SegmentHeader{LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x5, 0x0}, - &SegmentHeader{LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x3, 0x0}, - &SegmentHeader{LoadCmdSegment64, 0x48, "__LINKEDIT", 0x100002000, 0x1000, 0x2000, 0x140, 0x7, 0x1, 0x0, 0x0}, - nil, // LC_SYMTAB - nil, // LC_DYSYMTAB - nil, // LC_LOAD_DYLINKER - nil, // LC_UUID - nil, // LC_UNIXTHREAD - &Dylib{nil, "/usr/lib/libgcc_s.1.dylib", 0x2, 0x10000, 0x10000}, - &Dylib{nil, "/usr/lib/libSystem.B.dylib", 0x2, 0x6f0104, 0x10000}, - }, - []*SectionHeader{ - {"__text", "__TEXT", 0x100000f14, 0x6d, 0xf14, 0x2, 0x0, 0x0, 0x80000400}, - {"__symbol_stub1", "__TEXT", 0x100000f81, 0xc, 0xf81, 0x0, 0x0, 0x0, 0x80000408}, - {"__stub_helper", "__TEXT", 0x100000f90, 0x18, 0xf90, 0x2, 0x0, 0x0, 0x0}, - {"__cstring", "__TEXT", 0x100000fa8, 0xd, 0xfa8, 0x0, 0x0, 0x0, 0x2}, - {"__eh_frame", "__TEXT", 0x100000fb8, 0x48, 0xfb8, 0x3, 0x0, 0x0, 0x6000000b}, - {"__data", "__DATA", 0x100001000, 0x1c, 0x1000, 0x3, 0x0, 0x0, 0x0}, - {"__dyld", "__DATA", 0x100001020, 0x38, 0x1020, 0x3, 0x0, 0x0, 0x0}, - {"__la_symbol_ptr", "__DATA", 0x100001058, 0x10, 0x1058, 0x2, 0x0, 0x0, 0x7}, - }, - nil, - }, - { - "testdata/gcc-amd64-darwin-exec-debug", - FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0xa, 0x4, 0x5a0, 0}, - []interface{}{ - nil, // LC_UUID - &SegmentHeader{LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x0, 0x7, 0x5, 0x5, 0x0}, - &SegmentHeader{LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x0, 0x0, 0x7, 0x3, 0x3, 0x0}, - &SegmentHeader{LoadCmdSegment64, 0x278, "__DWARF", 0x100002000, 0x1000, 0x1000, 0x1bc, 0x7, 0x3, 0x7, 0x0}, - }, - []*SectionHeader{ - {"__text", "__TEXT", 0x100000f14, 0x0, 0x0, 0x2, 0x0, 0x0, 0x80000400}, - {"__symbol_stub1", "__TEXT", 0x100000f81, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000408}, - {"__stub_helper", "__TEXT", 0x100000f90, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0}, - {"__cstring", "__TEXT", 0x100000fa8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, - {"__eh_frame", "__TEXT", 0x100000fb8, 0x0, 0x0, 0x3, 0x0, 0x0, 0x6000000b}, - {"__data", "__DATA", 0x100001000, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0}, - {"__dyld", "__DATA", 0x100001020, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0}, - {"__la_symbol_ptr", "__DATA", 0x100001058, 0x0, 0x0, 0x2, 0x0, 0x0, 0x7}, - {"__debug_abbrev", "__DWARF", 0x100002000, 0x36, 0x1000, 0x0, 0x0, 0x0, 0x0}, - {"__debug_aranges", "__DWARF", 0x100002036, 0x30, 0x1036, 0x0, 0x0, 0x0, 0x0}, - {"__debug_frame", "__DWARF", 0x100002066, 0x40, 0x1066, 0x0, 0x0, 0x0, 0x0}, - {"__debug_info", "__DWARF", 0x1000020a6, 0x54, 0x10a6, 0x0, 0x0, 0x0, 0x0}, - {"__debug_line", "__DWARF", 0x1000020fa, 0x47, 0x10fa, 0x0, 0x0, 0x0, 0x0}, - {"__debug_pubnames", "__DWARF", 0x100002141, 0x1b, 0x1141, 0x0, 0x0, 0x0, 0x0}, - {"__debug_str", "__DWARF", 0x10000215c, 0x60, 0x115c, 0x0, 0x0, 0x0, 0x0}, - }, - nil, - }, - { - "testdata/clang-386-darwin-exec-with-rpath", - FileHeader{0xfeedface, Cpu386, 0x3, 0x2, 0x10, 0x42c, 0x1200085}, - []interface{}{ - nil, // LC_SEGMENT - nil, // LC_SEGMENT - nil, // LC_SEGMENT - nil, // LC_SEGMENT - nil, // LC_DYLD_INFO_ONLY - nil, // LC_SYMTAB - nil, // LC_DYSYMTAB - nil, // LC_LOAD_DYLINKER - nil, // LC_UUID - nil, // LC_VERSION_MIN_MACOSX - nil, // LC_SOURCE_VERSION - nil, // LC_MAIN - nil, // LC_LOAD_DYLIB - &Rpath{nil, "/my/rpath"}, - nil, // LC_FUNCTION_STARTS - nil, // LC_DATA_IN_CODE - }, - nil, - nil, - }, - { - "testdata/clang-amd64-darwin-exec-with-rpath", - FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0x2, 0x10, 0x4c8, 0x200085}, - []interface{}{ - nil, // LC_SEGMENT - nil, // LC_SEGMENT - nil, // LC_SEGMENT - nil, // LC_SEGMENT - nil, // LC_DYLD_INFO_ONLY - nil, // LC_SYMTAB - nil, // LC_DYSYMTAB - nil, // LC_LOAD_DYLINKER - nil, // LC_UUID - nil, // LC_VERSION_MIN_MACOSX - nil, // LC_SOURCE_VERSION - nil, // LC_MAIN - nil, // LC_LOAD_DYLIB - &Rpath{nil, "/my/rpath"}, - nil, // LC_FUNCTION_STARTS - nil, // LC_DATA_IN_CODE - }, - nil, - nil, - }, - { - "testdata/clang-386-darwin.obj", - FileHeader{0xfeedface, Cpu386, 0x3, 0x1, 0x4, 0x138, 0x2000}, - nil, - nil, - map[string][]Reloc{ - "__text": []Reloc{ - { - Addr: 0x1d, - Type: uint8(GENERIC_RELOC_VANILLA), - Len: 2, - Pcrel: true, - Extern: true, - Value: 1, - Scattered: false, - }, - { - Addr: 0xe, - Type: uint8(GENERIC_RELOC_LOCAL_SECTDIFF), - Len: 2, - Pcrel: false, - Value: 0x2d, - Scattered: true, - }, - { - Addr: 0x0, - Type: uint8(GENERIC_RELOC_PAIR), - Len: 2, - Pcrel: false, - Value: 0xb, - Scattered: true, - }, - }, - }, - }, - { - "testdata/clang-amd64-darwin.obj", - FileHeader{0xfeedfacf, CpuAmd64, 0x3, 0x1, 0x4, 0x200, 0x2000}, - nil, - nil, - map[string][]Reloc{ - "__text": []Reloc{ - { - Addr: 0x19, - Type: uint8(X86_64_RELOC_BRANCH), - Len: 2, - Pcrel: true, - Extern: true, - Value: 1, - }, - { - Addr: 0xb, - Type: uint8(X86_64_RELOC_SIGNED), - Len: 2, - Pcrel: true, - Extern: false, - Value: 2, - }, - }, - "__compact_unwind": []Reloc{ - { - Addr: 0x0, - Type: uint8(X86_64_RELOC_UNSIGNED), - Len: 3, - Pcrel: false, - Extern: false, - Value: 1, - }, - }, - }, - }, -} - -func TestOpen(t *testing.T) { - for i := range fileTests { - tt := &fileTests[i] - - f, err := Open(tt.file) - if err != nil { - t.Error(err) - continue - } - if !reflect.DeepEqual(f.FileHeader, tt.hdr) { - t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr) - continue - } - for i, l := range f.Loads { - if len(l.Raw()) < 8 { - t.Errorf("open %s, command %d:\n\tload command %T don't have enough data\n", tt.file, i, l) - } - } - if tt.loads != nil { - for i, l := range f.Loads { - if i >= len(tt.loads) { - break - } - - want := tt.loads[i] - if want == nil { - continue - } - - switch l := l.(type) { - case *Segment: - have := &l.SegmentHeader - if !reflect.DeepEqual(have, want) { - t.Errorf("open %s, command %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want) - } - case *Dylib: - have := l - have.LoadBytes = nil - if !reflect.DeepEqual(have, want) { - t.Errorf("open %s, command %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want) - } - case *Rpath: - have := l - have.LoadBytes = nil - if !reflect.DeepEqual(have, want) { - t.Errorf("open %s, command %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want) - } - default: - t.Errorf("open %s, command %d: unknown load command\n\thave %#v\n\twant %#v\n", tt.file, i, l, want) - } - } - tn := len(tt.loads) - fn := len(f.Loads) - if tn != fn { - t.Errorf("open %s: len(Loads) = %d, want %d", tt.file, fn, tn) - } - } - - if tt.sections != nil { - for i, sh := range f.Sections { - if i >= len(tt.sections) { - break - } - have := &sh.SectionHeader - want := tt.sections[i] - if !reflect.DeepEqual(have, want) { - t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want) - } - } - tn := len(tt.sections) - fn := len(f.Sections) - if tn != fn { - t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn) - } - } - - if tt.relocations != nil { - for i, sh := range f.Sections { - have := sh.Relocs - want := tt.relocations[sh.Name] - if !reflect.DeepEqual(have, want) { - t.Errorf("open %s, relocations in section %d (%s):\n\thave %#v\n\twant %#v\n", tt.file, i, sh.Name, have, want) - } - } - } - } -} - -func TestOpenFailure(t *testing.T) { - filename := "file.go" // not a Mach-O file - _, err := Open(filename) // don't crash - if err == nil { - t.Errorf("open %s: succeeded unexpectedly", filename) - } -} - -func TestOpenFat(t *testing.T) { - ff, err := OpenFat("testdata/fat-gcc-386-amd64-darwin-exec") - if err != nil { - t.Fatal(err) - } - - if ff.Magic != MagicFat { - t.Errorf("OpenFat: got magic number %#x, want %#x", ff.Magic, MagicFat) - } - if len(ff.Arches) != 2 { - t.Errorf("OpenFat: got %d architectures, want 2", len(ff.Arches)) - } - - for i := range ff.Arches { - arch := &ff.Arches[i] - ftArch := &fileTests[i] - - if arch.Cpu != ftArch.hdr.Cpu || arch.SubCpu != ftArch.hdr.SubCpu { - t.Errorf("OpenFat: architecture #%d got cpu=%#x subtype=%#x, expected cpu=%#x, subtype=%#x", i, arch.Cpu, arch.SubCpu, ftArch.hdr.Cpu, ftArch.hdr.SubCpu) - } - - if !reflect.DeepEqual(arch.FileHeader, ftArch.hdr) { - t.Errorf("OpenFat header:\n\tgot %#v\n\twant %#v\n", arch.FileHeader, ftArch.hdr) - } - } -} - -func TestOpenFatFailure(t *testing.T) { - filename := "file.go" // not a Mach-O file - if _, err := OpenFat(filename); err == nil { - t.Errorf("OpenFat %s: succeeded unexpectedly", filename) - } - - filename = "testdata/gcc-386-darwin-exec" // not a fat Mach-O - ff, err := OpenFat(filename) - if err != ErrNotFat { - t.Errorf("OpenFat %s: got %v, want ErrNotFat", filename, err) - } - if ff != nil { - t.Errorf("OpenFat %s: got %v, want nil", filename, ff) - } -} - -func TestRelocTypeString(t *testing.T) { - if X86_64_RELOC_BRANCH.String() != "X86_64_RELOC_BRANCH" { - t.Errorf("got %v, want %v", X86_64_RELOC_BRANCH.String(), "X86_64_RELOC_BRANCH") - } - if X86_64_RELOC_BRANCH.GoString() != "macho.X86_64_RELOC_BRANCH" { - t.Errorf("got %v, want %v", X86_64_RELOC_BRANCH.GoString(), "macho.X86_64_RELOC_BRANCH") - } -} - -func TestTypeString(t *testing.T) { - if TypeExec.String() != "Exec" { - t.Errorf("got %v, want %v", TypeExec.String(), "Exec") - } - if TypeExec.GoString() != "macho.Exec" { - t.Errorf("got %v, want %v", TypeExec.GoString(), "macho.Exec") - } -} diff --git a/odiglet/pkg/allocator/debug/macho/macho.go b/odiglet/pkg/allocator/debug/macho/macho.go deleted file mode 100644 index 692bdfc9e6..0000000000 --- a/odiglet/pkg/allocator/debug/macho/macho.go +++ /dev/null @@ -1,414 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Mach-O header data structures -// http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html - -package macho - -import "strconv" - -// A FileHeader represents a Mach-O file header. -type FileHeader struct { - Magic uint32 - Cpu Cpu - SubCpu uint32 - Type Type - Ncmd uint32 - Cmdsz uint32 - Flags uint32 -} - -const ( - fileHeaderSize32 = 7 * 4 - fileHeaderSize64 = 8 * 4 -) - -const ( - Magic32 uint32 = 0xfeedface - Magic64 uint32 = 0xfeedfacf - MagicFat uint32 = 0xcafebabe -) - -// A Type is the Mach-O file type, e.g. an object file, executable, or dynamic library. -type Type uint32 - -const ( - TypeObj Type = 1 - TypeExec Type = 2 - TypeDylib Type = 6 - TypeBundle Type = 8 -) - -var typeStrings = []intName{ - {uint32(TypeObj), "Obj"}, - {uint32(TypeExec), "Exec"}, - {uint32(TypeDylib), "Dylib"}, - {uint32(TypeBundle), "Bundle"}, -} - -func (t Type) String() string { return stringName(uint32(t), typeStrings, false) } -func (t Type) GoString() string { return stringName(uint32(t), typeStrings, true) } - -// A Cpu is a Mach-O cpu type. -type Cpu uint32 - -const cpuArch64 = 0x01000000 - -const ( - Cpu386 Cpu = 7 - CpuAmd64 Cpu = Cpu386 | cpuArch64 - CpuArm Cpu = 12 - CpuArm64 Cpu = CpuArm | cpuArch64 - CpuPpc Cpu = 18 - CpuPpc64 Cpu = CpuPpc | cpuArch64 -) - -var cpuStrings = []intName{ - {uint32(Cpu386), "Cpu386"}, - {uint32(CpuAmd64), "CpuAmd64"}, - {uint32(CpuArm), "CpuArm"}, - {uint32(CpuArm64), "CpuArm64"}, - {uint32(CpuPpc), "CpuPpc"}, - {uint32(CpuPpc64), "CpuPpc64"}, -} - -var FinalSegEnd uint64 - -func (i Cpu) String() string { return stringName(uint32(i), cpuStrings, false) } -func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) } - -// A LoadCmd is a Mach-O load command. -type LoadCmd uint32 - -const ( - LoadCmdSegment LoadCmd = 0x1 - LoadCmdSymtab LoadCmd = 0x2 - LoadCmdThread LoadCmd = 0x4 - LoadCmdUnixThread LoadCmd = 0x5 // thread+stack - LoadCmdDysymtab LoadCmd = 0xb - LoadCmdDylib LoadCmd = 0xc // load dylib command - LoadCmdDylinker LoadCmd = 0xf // id dylinker command (not load dylinker command) - LoadCmdSegment64 LoadCmd = 0x19 - LoadCmdSignature LoadCmd = 0x1d - LoadCmdFuncStarts LoadCmd = 0x26 // Function Starts - LoadCmdDataInCode LoadCmd = 0x29 // Data In Code - - LoadReqDyld LoadCmd = 0x80000000 - LoadCmdMain LoadCmd = (0x28 | LoadReqDyld) // replacement for LC_UNIXTHREAD - LoadCmdRpath LoadCmd = 0x8000001c - LoadCmdDylinkInfo LoadCmd = 0x80000022 // Dynamic Linker Info Only -) - -var cmdStrings = []intName{ - {uint32(LoadCmdSegment), "LoadCmdSegment"}, - {uint32(LoadCmdThread), "LoadCmdThread"}, - {uint32(LoadCmdUnixThread), "LoadCmdUnixThread"}, - {uint32(LoadCmdDylib), "LoadCmdDylib"}, - {uint32(LoadCmdSegment64), "LoadCmdSegment64"}, - {uint32(LoadCmdRpath), "LoadCmdRpath"}, - {uint32(LoadCmdSignature), "LoadCmdSignature"}, - {uint32(LoadCmdFuncStarts), "LoadCmdFuncStarts"}, - {uint32(LoadCmdDataInCode), "LoadCmdDataInCode"}, - {uint32(LoadCmdDylinkInfo), "LoadCmdDylinkInfo"}, -} - -func (i LoadCmd) String() string { return stringName(uint32(i), cmdStrings, false) } -func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) } - -// Prog.Flag -type ProgFlag uint32 - -const ( - PF_NONE ProgFlag = 0x0 /* None */ - PF_R ProgFlag = 0x1 /* Readable. */ - PF_W ProgFlag = 0x2 /* Writable. */ - PF_X ProgFlag = 0x4 /* Executable. */ -) - -type ( - // A Segment32 is a 32-bit Mach-O segment load command. - Segment32 struct { - Cmd LoadCmd - Len uint32 - Name [16]byte - Addr uint32 - Memsz uint32 - Offset uint32 - Filesz uint32 - Maxprot uint32 // ProgFlag - Maximum Segment Virtual Memory Protections - Prot uint32 // ProgFlag - Initial Segment Virtual Memory Protections - Nsect uint32 - Flag uint32 - } - - // A Segment64 is a 64-bit Mach-O segment load command. - Segment64 struct { - Cmd LoadCmd - Len uint32 - Name [16]byte - Addr uint64 - Memsz uint64 - Offset uint64 - Filesz uint64 - Maxprot uint32 - Prot uint32 - Nsect uint32 - Flag uint32 - } - - // A SigBlockCmd is a Mach-O symbol table command. - SigBlockCmd struct { - Cmd LoadCmd - Len uint32 - Sigoff uint32 - Sigsize uint32 - } - - // A SymtabCmd is a Mach-O symbol table command. - SymtabCmd struct { - Cmd LoadCmd - Len uint32 - Symoff uint32 - Nsyms uint32 - Stroff uint32 - Strsize uint32 - } - - // A DysymtabCmd is a Mach-O dynamic symbol table command. - DysymtabCmd struct { - Cmd LoadCmd - Len uint32 - Ilocalsym uint32 - Nlocalsym uint32 - Iextdefsym uint32 - Nextdefsym uint32 - Iundefsym uint32 - Nundefsym uint32 - Tocoffset uint32 - Ntoc uint32 - Modtaboff uint32 - Nmodtab uint32 - Extrefsymoff uint32 - Nextrefsyms uint32 - Indirectsymoff uint32 - Nindirectsyms uint32 - Extreloff uint32 - Nextrel uint32 - Locreloff uint32 - Nlocrel uint32 - } - - // DylinkerCmd is a load command to identify the dynamic linker - DylinkerCmd struct { - Cmd LoadCmd - Len uint32 - Name uint32 - } - - // A DylibCmd is a Mach-O load dynamic library command. - DylibCmd struct { - Cmd LoadCmd - Len uint32 - Name uint32 - Time uint32 - CurrentVersion uint32 - CompatVersion uint32 - } - - // A FuncStartsCmd is a Mach-O load Function Starts command - FuncStartsCmd struct { - Cmd LoadCmd - Len uint32 - Dataoff uint32 - Datasize uint32 - } - - // A DataInCodeCmd is a Mach-O load for Data In Code command - DataInCodeCmd struct { - Cmd LoadCmd - Len uint32 - Dataoff uint32 - Datasize uint32 - } - - // A DylinkInfoCmd is a Mach-O load for Dynamic Linker Info Only Command - DylinkInfoCmd struct { - Cmd LoadCmd - Len uint32 - Rebaseoff uint32 - Rebasesize uint32 - Bindinginfooff uint32 - Bindinginfosize uint32 - Weakbindingoff uint32 - Weakbindingsize uint32 - Lazybindingoff uint32 - Lazybindingsize uint32 - Exportinfooff uint32 - Exportinfosize uint32 - } - - // A RpathCmd is a Mach-O rpath command. - RpathCmd struct { - Cmd LoadCmd - Len uint32 - Path uint32 - } - - // A Thread is a Mach-O thread state command. - Thread struct { - Cmd LoadCmd - Len uint32 - Type uint32 - Data []uint32 - } - - // A EntryPointCmd is a Mach-O entry point command. - EntryPointCmd struct { - Cmd uint32 /* LC_MAIN only used in MH_EXECUTE filetypes */ - CmdSize uint32 /* 24 */ - EntryOff uint64 /* file (__TEXT) offset of main() */ - StackSize uint64 /* if not zero, initial stack size */ - } -) - -const ( - FlagNoUndefs uint32 = 0x1 - FlagIncrLink uint32 = 0x2 - FlagDyldLink uint32 = 0x4 - FlagBindAtLoad uint32 = 0x8 - FlagPrebound uint32 = 0x10 - FlagSplitSegs uint32 = 0x20 - FlagLazyInit uint32 = 0x40 - FlagTwoLevel uint32 = 0x80 - FlagForceFlat uint32 = 0x100 - FlagNoMultiDefs uint32 = 0x200 - FlagNoFixPrebinding uint32 = 0x400 - FlagPrebindable uint32 = 0x800 - FlagAllModsBound uint32 = 0x1000 - FlagSubsectionsViaSymbols uint32 = 0x2000 - FlagCanonical uint32 = 0x4000 - FlagWeakDefines uint32 = 0x8000 - FlagBindsToWeak uint32 = 0x10000 - FlagAllowStackExecution uint32 = 0x20000 - FlagRootSafe uint32 = 0x40000 - FlagSetuidSafe uint32 = 0x80000 - FlagNoReexportedDylibs uint32 = 0x100000 - FlagPIE uint32 = 0x200000 - FlagDeadStrippableDylib uint32 = 0x400000 - FlagHasTLVDescriptors uint32 = 0x800000 - FlagNoHeapExecution uint32 = 0x1000000 - FlagAppExtensionSafe uint32 = 0x2000000 -) - -// A Section32 is a 32-bit Mach-O section header. -type Section32 struct { - Name [16]byte - Seg [16]byte - Addr uint32 - Size uint32 - Offset uint32 - Align uint32 - Reloff uint32 - Nreloc uint32 - Flags uint32 - Reserve1 uint32 - Reserve2 uint32 -} - -// A Section64 is a 64-bit Mach-O section header. -type Section64 struct { - Name [16]byte - Seg [16]byte - Addr uint64 - Size uint64 - Offset uint32 - Align uint32 - Reloff uint32 - Nreloc uint32 - Flags uint32 - Reserve1 uint32 - Reserve2 uint32 - Reserve3 uint32 -} - -// An Nlist32 is a Mach-O 32-bit symbol table entry. -type Nlist32 struct { - Name uint32 - Type uint8 - Sect uint8 - Desc uint16 - Value uint32 -} - -// An Nlist64 is a Mach-O 64-bit symbol table entry. -type Nlist64 struct { - Name uint32 - Type uint8 - Sect uint8 - Desc uint16 - Value uint64 -} - -// Regs386 is the Mach-O 386 register structure. -type Regs386 struct { - AX uint32 - BX uint32 - CX uint32 - DX uint32 - DI uint32 - SI uint32 - BP uint32 - SP uint32 - SS uint32 - FLAGS uint32 - IP uint32 - CS uint32 - DS uint32 - ES uint32 - FS uint32 - GS uint32 -} - -// RegsAMD64 is the Mach-O AMD64 register structure. -type RegsAMD64 struct { - AX uint64 - BX uint64 - CX uint64 - DX uint64 - DI uint64 - SI uint64 - BP uint64 - SP uint64 - R8 uint64 - R9 uint64 - R10 uint64 - R11 uint64 - R12 uint64 - R13 uint64 - R14 uint64 - R15 uint64 - IP uint64 - FLAGS uint64 - CS uint64 - FS uint64 - GS uint64 -} - -type intName struct { - i uint32 - s string -} - -func stringName(i uint32, names []intName, goSyntax bool) string { - for _, n := range names { - if n.i == i { - if goSyntax { - return "macho." + n.s - } - return n.s - } - } - return strconv.FormatUint(uint64(i), 10) -} diff --git a/odiglet/pkg/allocator/debug/macho/reloctype.go b/odiglet/pkg/allocator/debug/macho/reloctype.go deleted file mode 100644 index 496dfce7ec..0000000000 --- a/odiglet/pkg/allocator/debug/macho/reloctype.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package macho - -//go:generate stringer -type=RelocTypeGeneric,RelocTypeX86_64,RelocTypeARM,RelocTypeARM64 -output reloctype_string.go - -type RelocTypeGeneric int - -const ( - GENERIC_RELOC_VANILLA RelocTypeGeneric = 0 - GENERIC_RELOC_PAIR RelocTypeGeneric = 1 - GENERIC_RELOC_SECTDIFF RelocTypeGeneric = 2 - GENERIC_RELOC_PB_LA_PTR RelocTypeGeneric = 3 - GENERIC_RELOC_LOCAL_SECTDIFF RelocTypeGeneric = 4 - GENERIC_RELOC_TLV RelocTypeGeneric = 5 -) - -func (r RelocTypeGeneric) GoString() string { return "macho." + r.String() } - -type RelocTypeX86_64 int - -const ( - X86_64_RELOC_UNSIGNED RelocTypeX86_64 = 0 - X86_64_RELOC_SIGNED RelocTypeX86_64 = 1 - X86_64_RELOC_BRANCH RelocTypeX86_64 = 2 - X86_64_RELOC_GOT_LOAD RelocTypeX86_64 = 3 - X86_64_RELOC_GOT RelocTypeX86_64 = 4 - X86_64_RELOC_SUBTRACTOR RelocTypeX86_64 = 5 - X86_64_RELOC_SIGNED_1 RelocTypeX86_64 = 6 - X86_64_RELOC_SIGNED_2 RelocTypeX86_64 = 7 - X86_64_RELOC_SIGNED_4 RelocTypeX86_64 = 8 - X86_64_RELOC_TLV RelocTypeX86_64 = 9 -) - -func (r RelocTypeX86_64) GoString() string { return "macho." + r.String() } - -type RelocTypeARM int - -const ( - ARM_RELOC_VANILLA RelocTypeARM = 0 - ARM_RELOC_PAIR RelocTypeARM = 1 - ARM_RELOC_SECTDIFF RelocTypeARM = 2 - ARM_RELOC_LOCAL_SECTDIFF RelocTypeARM = 3 - ARM_RELOC_PB_LA_PTR RelocTypeARM = 4 - ARM_RELOC_BR24 RelocTypeARM = 5 - ARM_THUMB_RELOC_BR22 RelocTypeARM = 6 - ARM_THUMB_32BIT_BRANCH RelocTypeARM = 7 - ARM_RELOC_HALF RelocTypeARM = 8 - ARM_RELOC_HALF_SECTDIFF RelocTypeARM = 9 -) - -func (r RelocTypeARM) GoString() string { return "macho." + r.String() } - -type RelocTypeARM64 int - -const ( - ARM64_RELOC_UNSIGNED RelocTypeARM64 = 0 - ARM64_RELOC_SUBTRACTOR RelocTypeARM64 = 1 - ARM64_RELOC_BRANCH26 RelocTypeARM64 = 2 - ARM64_RELOC_PAGE21 RelocTypeARM64 = 3 - ARM64_RELOC_PAGEOFF12 RelocTypeARM64 = 4 - ARM64_RELOC_GOT_LOAD_PAGE21 RelocTypeARM64 = 5 - ARM64_RELOC_GOT_LOAD_PAGEOFF12 RelocTypeARM64 = 6 - ARM64_RELOC_POINTER_TO_GOT RelocTypeARM64 = 7 - ARM64_RELOC_TLVP_LOAD_PAGE21 RelocTypeARM64 = 8 - ARM64_RELOC_TLVP_LOAD_PAGEOFF12 RelocTypeARM64 = 9 - ARM64_RELOC_ADDEND RelocTypeARM64 = 10 -) - -func (r RelocTypeARM64) GoString() string { return "macho." + r.String() } diff --git a/odiglet/pkg/allocator/debug/macho/reloctype_string.go b/odiglet/pkg/allocator/debug/macho/reloctype_string.go deleted file mode 100644 index 9c2b13186e..0000000000 --- a/odiglet/pkg/allocator/debug/macho/reloctype_string.go +++ /dev/null @@ -1,49 +0,0 @@ -// Code generated by "stringer -type=RelocTypeGeneric,RelocTypeX86_64,RelocTypeARM,RelocTypeARM64 -output reloctype_string.go"; DO NOT EDIT. - -package macho - -import "strconv" - -const _RelocTypeGeneric_name = "GENERIC_RELOC_VANILLAGENERIC_RELOC_PAIRGENERIC_RELOC_SECTDIFFGENERIC_RELOC_PB_LA_PTRGENERIC_RELOC_LOCAL_SECTDIFFGENERIC_RELOC_TLV" - -var _RelocTypeGeneric_index = [...]uint8{0, 21, 39, 61, 84, 112, 129} - -func (i RelocTypeGeneric) String() string { - if i < 0 || i >= RelocTypeGeneric(len(_RelocTypeGeneric_index)-1) { - return "RelocTypeGeneric(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _RelocTypeGeneric_name[_RelocTypeGeneric_index[i]:_RelocTypeGeneric_index[i+1]] -} - -const _RelocTypeX86_64_name = "X86_64_RELOC_UNSIGNEDX86_64_RELOC_SIGNEDX86_64_RELOC_BRANCHX86_64_RELOC_GOT_LOADX86_64_RELOC_GOTX86_64_RELOC_SUBTRACTORX86_64_RELOC_SIGNED_1X86_64_RELOC_SIGNED_2X86_64_RELOC_SIGNED_4X86_64_RELOC_TLV" - -var _RelocTypeX86_64_index = [...]uint8{0, 21, 40, 59, 80, 96, 119, 140, 161, 182, 198} - -func (i RelocTypeX86_64) String() string { - if i < 0 || i >= RelocTypeX86_64(len(_RelocTypeX86_64_index)-1) { - return "RelocTypeX86_64(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _RelocTypeX86_64_name[_RelocTypeX86_64_index[i]:_RelocTypeX86_64_index[i+1]] -} - -const _RelocTypeARM_name = "ARM_RELOC_VANILLAARM_RELOC_PAIRARM_RELOC_SECTDIFFARM_RELOC_LOCAL_SECTDIFFARM_RELOC_PB_LA_PTRARM_RELOC_BR24ARM_THUMB_RELOC_BR22ARM_THUMB_32BIT_BRANCHARM_RELOC_HALFARM_RELOC_HALF_SECTDIFF" - -var _RelocTypeARM_index = [...]uint8{0, 17, 31, 49, 73, 92, 106, 126, 148, 162, 185} - -func (i RelocTypeARM) String() string { - if i < 0 || i >= RelocTypeARM(len(_RelocTypeARM_index)-1) { - return "RelocTypeARM(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _RelocTypeARM_name[_RelocTypeARM_index[i]:_RelocTypeARM_index[i+1]] -} - -const _RelocTypeARM64_name = "ARM64_RELOC_UNSIGNEDARM64_RELOC_SUBTRACTORARM64_RELOC_BRANCH26ARM64_RELOC_PAGE21ARM64_RELOC_PAGEOFF12ARM64_RELOC_GOT_LOAD_PAGE21ARM64_RELOC_GOT_LOAD_PAGEOFF12ARM64_RELOC_POINTER_TO_GOTARM64_RELOC_TLVP_LOAD_PAGE21ARM64_RELOC_TLVP_LOAD_PAGEOFF12ARM64_RELOC_ADDEND" - -var _RelocTypeARM64_index = [...]uint16{0, 20, 42, 62, 80, 101, 128, 158, 184, 212, 243, 261} - -func (i RelocTypeARM64) String() string { - if i < 0 || i >= RelocTypeARM64(len(_RelocTypeARM64_index)-1) { - return "RelocTypeARM64(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _RelocTypeARM64_name[_RelocTypeARM64_index[i]:_RelocTypeARM64_index[i+1]] -} diff --git a/odiglet/pkg/allocator/debug/macho/testdata/clang-386-darwin-exec-with-rpath b/odiglet/pkg/allocator/debug/macho/testdata/clang-386-darwin-exec-with-rpath deleted file mode 100644 index a8720feb923693232bce4fa9642988c86a28c372..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8416 zcmeHM&r1|h9Dl284Q8nwN-%O14GVJ%f;rQo=QFb}r?L72;(gigy!ZY2zV9<{Vc&k&zkU9( zQwY%rZUDD|2ckmU5@sZV`4Cvj@sYFf>+vg>At<8bUx;yc@Q`vcK0O(5VvLHz$aS0Q zOfM;2Yr*Brr*QmCmk>u`nrRgRC2mnvEGj|DVmX`4+p_4El2C?oEF;Gb=$Da$bt*EN z{2a6)2ZCkVvI~~u$-nPo1v&OXzk(dZ>=)H@P?mDG=sKC)&AKsM$0~B{fo&Bzf)var zWhpnG$)#i_H<)dNWfrXuHHxeU8plaFDY}t(1)_% zI)98e=!n>0&BRaPDy5zHR}RDU-=h)Aq0S@IGnan`FOFTh5FZ^==jj*>h!ds|8yFa) z*2Prx2(d^P+UeGYu>+%`e$&?vVH|*xd!RiHnP=+}My|UHJPr;LeH91w!TEhNbVln& zzVid%7I3UobYgZU8B3Mz6y#1YYv_D;@9X-tleZu5KmX)``Q~XablihzY4-StlBomr zW3P);ax#(Ki!83!XA(QlK^KyChWy>+AkZ{w8KLlnC zDbwHA;krz`G-(7h0vZ90fJQ(gpb^jrXaqC@J_1vf_e-BTHYrTsT|AB9W&As(O0;)# zH^$?yEAcOtS4%HCZalBn`V13ykSHFtK3-j_{Ov71e5}=KxQ^QS0dqd@*r{gkuETo- zDLC?XKJNki-B0E{m&7^mcP)r)^P;KUqKCLkYSIX31T+E~0gZr0KqH_L&+L^w1_lOZAZ7$&79h3&F%%&D13)G=U=0)u0jdMhApIcB1jHZ^A77GMQ37E@ z_#v(lAqYN*r3=I${UG}$0BMl@Ku!aQ0)hDWT|%)E367sy971Eil1h#P@=kpavN zATbpn7637LxIiS>eG))=1yB!2-2osClII5E03b#NAY)+|S)3SlXy?=BHxe&EN+Wt3 zlz`N6*FPX$CyUC9`~Uy{H$2(t`lIti^AU;I!x^bLIr%yY<@rT9DL`k+0+j*n6X&9mRy#6Y0Wp+gUP^kPWg#3orZLXs77!9;$qMRYZV; z2AwKj;P>;%tYw!h2SKg*)>Xbfm4KMM*JaoE=F6^=E8JB9t@)m-dYIfb}2hwt&9T-R-=l;g3PSjdC*Yg*S}eM9StJy*{yWx_qKcI-0548DPp$D93SsaA;?wZ}jcs|Ov{Ltkgj3bx!TOU*Tym98M zQKyu0vv8e;vfnw==k=_@Gy|Fe&46a$UomhivHCHw^2JE3T^dE7 zuj4=1^9!+k0A^%sHU52dGqLi@n0;9rSVq;v+VOiZvFX}C3U;0Ew&L@rTCIjpO1n5{ zE*2d-)8&0r;9c00u;sfn-?h)fQXi@JZkG8y(~Xvf*BYSt)5NQIg7}D6(htpmW{uc&%`;95irFV>%ecolbOyhnSm)BE{SQn1bJ0?rG zfOZ#vAQ6fC_%@l(N^8lQuecWOx>F24nNQ^kVt_v&+Qo+xjD-XRR`*2wn?e3xIOJjf nUj;G$VZhdZJ@8&JjQzBz6k?2J6F0=W#~{5i1moQ`BeeSkgV?^% diff --git a/odiglet/pkg/allocator/debug/macho/testdata/clang-amd64-darwin.obj b/odiglet/pkg/allocator/debug/macho/testdata/clang-amd64-darwin.obj deleted file mode 100644 index 23cc3c1bcb18a3256f515a1fe69a8bd199a6ef53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 768 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 YIe}f$IZ?D?rX`S+#wLgJDVnj z(nx4wDS_bGyP>BXJmg}Vw1?7D5j}X879vs!A|7&Z`uokkm&{Cq9&>pgy#4;X_x*VD zdo#;?^Zm8+@5@dhtPUX-4+$ZTV9dNB#1GJvcQ9-WDaSLPWxvW^`jXM8SW$Ohk2nvp zP|C^d)MRu?ke`aigz~XBf$ao?E2Q+Cd5>0G;&{h;a50#wsCoLlu3brp#a$bQl#PW- zzE+kEubDsl|NY%icwH)qepr$U@30C24?uFpDc2nrvH1R06ke}dPd~E1FnEw(Xn1a^ zI<4Yyyj6vFRL#>5OB`EDXGUIka}}q(Dvr0V@Ob7F`nWfC1^36bT?YowbtpL3;ml+v zG=uYtoU1FPcH$E&efr?2HrxsxEG1zrPcn1)Drry#w+La zty1?~oNIJ{Qwk3%5c*;6c^`-Uz2|ClWbBLV@Q8jU(lOrPQ$7jE6oNR)4C2HL?xl45 z+1-F%M2yezI0l7lIGFpUvZ3~swX_h4eP+55!<682FxYIkgXL0wFhudYh;ttoPOZD$ z*|`U&e}39p+kF2DpWSr~VxGY`Xwm-o^TAR7Z`2S7t9 zk6B7QFJaXXjpj`(G(4v=@M$D5$TmNQ0mFb{z%XDKFbo(53QWx9&Yj*h`y9d+EGrzM!@B0XEtCW9vhx=b4Go<>R-veLpkd z_x*}U&q?9;{Q~1ML6)`&)@yNd(eL0eY!#*dlTyM9pCq1-=)0@8wF*# z)}Q{S=C-SvV_XcezP%)@`IMFF>P)WS6}2BR)<`#zLwTEvC<(s5cBg(klwg^2RM)GV zdZnZ`r2oATNu{}#NWHq=Q97wK>vqoTI`@{UCz)r&Fkl!k3>XFs1BL;^fMLKeU>GnA z7zPXjhJk}&fW55~DA>nUoz6ZU{i5;*;P>ETfv)#IQhrL+`5!A^*ZrTv@1O(WcYv!H z%-7!s*vIa{#H_++pPs(%%QfIz!fLnNU@ydc_AlSU&^j&Hglsq6^QCGLopRlLZ?}Nu z^=7po%eC6q&AO0dQyF)Wab6o6;!qzO$335^7(8-p4F62z?(LIDXH6{xyF2o+jH#neumA8_o*c2K%2 zLV|5?0IP~4u;31C;SelAA`9S+J>xizqvQY{X=Xg{=bPs@ww0G}!=Has2w@SSqeX;J z0{W*U46H4~d>;Cx-0(;8`McDgmmfdeEZs6Mfb2U)h>)EJdppdSO&~@nKQ7}d*b7lS z-+~ZF8#r7$$t#|L;6`fqN(inK=qR`(#6Ik*rcP|9udYq<-bV0({%OWrU_#&lh_p4m zr&%Bi-|uk*Z!Eqb-1V>9j@2<*K7TxapCfodM3_y8)+S9$>1v);IKD3tJUDB=We_^> z7jQw(b=^JJ`?Z}~Km+GF>s%?9vk7S^jxzEmWD0L&;`;_f{w44Z^@hKMa~S7IJid|1 z44$s=N2TXj6TH0$UNHCcIS#IA-Uc9mxOQt#9*&}rLV08F#aB0(2vH8r8J%f^`_$Ba zizupUX>X?Us-F4O_l&E3o~0Nq&7O#_DtYm(GKVUQkNbyb&f||<_qa;|{S z;yl#7!V1b{?t%y^lQO!O6?3;UcQTi=+e_49gZ@i!4Z2tTq+RGMR%M=x+5%)n=>MQ$ zga`R-Dt*kVpA}{w_D@iKF8^Lg(Awzq!ebcOeweCo35M&?xnr=b7ZS-`P>J{jwG?rb z9e##3K`S8oyB*`-zZPNi&H* diff --git a/odiglet/pkg/allocator/debug/macho/testdata/hello.c b/odiglet/pkg/allocator/debug/macho/testdata/hello.c deleted file mode 100644 index a689d3644e..0000000000 --- a/odiglet/pkg/allocator/debug/macho/testdata/hello.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int -main(void) -{ - printf("hello, world\n"); - return 0; -} diff --git a/odiglet/pkg/allocator/debug/macho/write.go b/odiglet/pkg/allocator/debug/macho/write.go deleted file mode 100644 index 285c617900..0000000000 --- a/odiglet/pkg/allocator/debug/macho/write.go +++ /dev/null @@ -1,343 +0,0 @@ -package macho - -import ( - "bufio" - "bytes" - "encoding/binary" - "io/ioutil" - "log" - "os" - "sort" -) - -// Bytes - Returns the bytes of an assembled *macho.File -func (machoFile *File) Bytes() ([]byte, error) { - var bytesWritten uint64 - w := bytes.NewBuffer(nil) - - // Write entire file header. - buf := &bytes.Buffer{} - err := binary.Write(buf, machoFile.ByteOrder, machoFile.FileHeader) - if err != nil { - panic(err) - } - headerLength := len(buf.Bytes()) - binary.Write(w, machoFile.ByteOrder, machoFile.FileHeader) - bytesWritten += uint64(headerLength) - //log.Printf("%x: Wrote file header of size: %v", bytesWritten, bytesWritten) - - // Reserved 4 bytes at end of header - w.Write([]byte{0, 0, 0, 0}) - bytesWritten += 4 - - // Write Load Commands Loop - for _, singleLoad := range machoFile.Loads { - buf2 := &bytes.Buffer{} - err = binary.Write(buf2, machoFile.ByteOrder, singleLoad.Raw()) - if err != nil { - panic(err) - } - LoadCmdLen := len(buf2.Bytes()) - binary.Write(w, machoFile.ByteOrder, singleLoad.Raw()) - bytesWritten += uint64(LoadCmdLen) - //log.Printf("%x: Wrote Load Command, total size of: %v", bytesWritten, LoadCmdLen) - } - - // Shellcode gets caved in between the final load command and the first section - if len(machoFile.Insertion) > 0 { - binary.Write(w, machoFile.ByteOrder, machoFile.Insertion) - bytesWritten += uint64(len(machoFile.Insertion)) - } - - // Sort Sections - sortedSections := machoFile.Sections[:] - sort.Slice(sortedSections, func(a, b int) bool { return machoFile.Sections[a].Offset < machoFile.Sections[b].Offset }) - - /* - var caveOffset, caveSize uint64 - for _, s := range sortedSections { - if s.SectionHeader.Seg == "__TEXT" && s.Name == "__text" { - caveOffset = bytesWritten - caveSize = uint64(s.Offset) - caveOffset - log.Printf("Code Cave Size: %d - %d = %d\n", s.Offset, caveOffset, caveSize) - log.Println("Shellcode Size: ", len(machoFile.Insertion)) - break - } - } - */ - - // Write Sections - for _, s := range sortedSections { - - if bytesWritten > uint64(s.Offset) { - log.Printf("Overlapping Sections in Generated macho: %+v\n", s.Name) - continue - } - if bytesWritten < uint64(s.Offset) { - pad := make([]byte, uint64(s.Offset)-bytesWritten) - w.Write(pad) - bytesWritten += uint64(len(pad)) - //log.Printf("%x: wrote %d padding bytes\n", bytesWritten, len(pad)) - } - section, err := ioutil.ReadAll(s.Open()) - if err != nil { - return nil, err - } - binary.Write(w, machoFile.ByteOrder, section) - bytesWritten += uint64(len(section)) - //log.Printf("%x: wrote %d bytes section/segment named: %s %s\n", bytesWritten, uint64(len(section)), s.Name, s.Seg) - } - // Write Dynamic Loader Info if it exists - if machoFile.DylinkInfo != nil { - // Write Rebase if it exists - if len(machoFile.DylinkInfo.RebaseDat) > 0 { - //log.Printf("Rebase Offset: %d", machoFile.DylinkInfo.RebaseOffset) - if int64(machoFile.DylinkInfo.RebaseOffset)-int64(bytesWritten) > 0 { - padA := make([]byte, machoFile.DylinkInfo.RebaseOffset-bytesWritten) - w.Write(padA) - bytesWritten += uint64(len(padA)) - //log.Printf("%x: wrote pad of: %d", bytesWritten, len(padA)) - } - //log.Printf("Rebase: %+v \n", machoFile.DylinkInfo.RebaseDat) - w.Write(machoFile.DylinkInfo.RebaseDat) - bytesWritten += uint64(machoFile.DylinkInfo.RebaseLen) - //log.Printf("%x: Wrote raw Rebase, length of: %d", bytesWritten, machoFile.DylinkInfo.RebaseLen) - } - //Binding - if len(machoFile.DylinkInfo.BindingInfoDat) > 0 { - //log.Printf("Binding Offset: %d", machoFile.DylinkInfo.BindingInfoOffset) - if int64(machoFile.DylinkInfo.BindingInfoOffset)-int64(bytesWritten) > 0 { - padB := make([]byte, machoFile.DylinkInfo.BindingInfoOffset-bytesWritten) - w.Write(padB) - bytesWritten += uint64(len(padB)) - //log.Printf("%x: wrote pad of: %d", bytesWritten, len(padB)) - } - //log.Printf("Binding Info: %+v \n", machoFile.DylinkInfo.BindingInfoDat) - w.Write(machoFile.DylinkInfo.BindingInfoDat) - bytesWritten += uint64(machoFile.DylinkInfo.BindingInfoLen) - //log.Printf("%x: Wrote raw Binding Info, length of: %d", bytesWritten, machoFile.DylinkInfo.BindingInfoLen) - } - //Lazy - if len(machoFile.DylinkInfo.LazyBindingDat) > 0 { - //log.Printf("Lazy Offset: %d", machoFile.DylinkInfo.LazyBindingOffset) - if int64(machoFile.DylinkInfo.LazyBindingOffset)-int64(bytesWritten) > 0 { - padD := make([]byte, machoFile.DylinkInfo.LazyBindingOffset-bytesWritten) - w.Write(padD) - bytesWritten += uint64(len(padD)) - //log.Printf("%x: wrote pad of: %d", bytesWritten, len(padD)) - } - //log.Printf("Lazy Binding Data: %+v \n", machoFile.DylinkInfo.LazyBindingDat) - w.Write(machoFile.DylinkInfo.LazyBindingDat) - bytesWritten += uint64(machoFile.DylinkInfo.LazyBindingLen) - //log.Printf("%x: Wrote raw lazybinding, length of: %d", bytesWritten, machoFile.DylinkInfo.LazyBindingLen) - } - //Export - if len(machoFile.DylinkInfo.ExportInfoDat) > 0 { - //log.Printf("Export Offset: %d", machoFile.DylinkInfo.ExportInfoOffset) - if int64(machoFile.DylinkInfo.ExportInfoOffset)-int64(bytesWritten) > 0 { - padE := make([]byte, machoFile.DylinkInfo.ExportInfoOffset-bytesWritten) - w.Write(padE) - bytesWritten += uint64(len(padE)) - //log.Printf("%x: wrote pad of: %d", bytesWritten, len(padE)) - } - //log.Printf("Export Info: %+v \n", machoFile.DylinkInfo.ExportInfoDat) - w.Write(machoFile.DylinkInfo.ExportInfoDat) - bytesWritten += uint64(machoFile.DylinkInfo.ExportInfoLen) - //log.Printf("%x: Wrote raw Export Info, length of: %d", bytesWritten, machoFile.DylinkInfo.ExportInfoLen) - } - //Weak - if len(machoFile.DylinkInfo.WeakBindingDat) > 0 { - //log.Printf("Weak Offset: %d", machoFile.DylinkInfo.WeakBindingOffset) - if int64(machoFile.DylinkInfo.WeakBindingOffset)-int64(bytesWritten) > 0 { - padC := make([]byte, machoFile.DylinkInfo.WeakBindingOffset-bytesWritten) - w.Write(padC) - bytesWritten += uint64(len(padC)) - //log.Printf("%x: wrote pad of: %d", bytesWritten, len(padC)) - } - //log.Printf("Weak Binding: %+v \n", machoFile.DylinkInfo.WeakBindingDat) - w.Write(machoFile.DylinkInfo.WeakBindingDat) - bytesWritten += uint64(machoFile.DylinkInfo.WeakBindingLen) - //log.Printf("%x: Wrote raw Weak Binding, length of: %d", bytesWritten, machoFile.DylinkInfo.WeakBindingLen) - } - } - - // Write the Func Starts if they exist - if machoFile.FuncStarts != nil { - //log.Printf("new pad: %d", machoFile.FuncStarts.Offset-bytesWritten) - if int64(machoFile.FuncStarts.Offset)-int64(bytesWritten) > 0 { - padY := make([]byte, machoFile.FuncStarts.Offset-bytesWritten) - w.Write(padY) - bytesWritten += uint64(len(padY)) - //log.Printf("%x: wrote pad of: %d", bytesWritten, len(padY)) - } - //log.Printf("FuncStarts: %+v \n", machoFile.FuncStarts) - w.Write(machoFile.FuncStarts.RawDat) - bytesWritten += uint64(machoFile.FuncStarts.Len) - //log.Printf("%x: Wrote raw funcstarts, length of: %d", bytesWritten, machoFile.FuncStarts.Len) - } - - // Write the Data in Code Entries if they exist - if machoFile.DataInCode != nil { - if int64(machoFile.DataInCode.Offset)-int64(bytesWritten) > 0 { - padZ := make([]byte, machoFile.DataInCode.Offset-bytesWritten) - w.Write(padZ) - bytesWritten += uint64(len(padZ)) - //log.Printf("%x: wrote pad of: %d", bytesWritten, len(padZ)) - } - //log.Printf("DataInCode: %+v \n", machoFile.DataInCode) - w.Write(machoFile.DataInCode.RawDat) - bytesWritten += uint64(machoFile.DataInCode.Len) - //log.Printf("%x: Wrote raw dataincode, length of: %d", bytesWritten, machoFile.DataInCode.Len) - } - - // Write Symbols is next I think - symtab := machoFile.Symtab - //log.Printf("Bytes written: %d", bytesWritten) - //log.Printf("Indirect symbol offset: %d", machoFile.Dysymtab.DysymtabCmd.Indirectsymoff) - //log.Printf("Locrel offset: %d", machoFile.Dysymtab.Locreloff) - //log.Printf("Symtab offset: %d", symtab.Symoff) - //log.Printf("String table offset: %d", symtab.Stroff) - if int64(symtab.Symoff)-int64(bytesWritten) > 0 { - pad := make([]byte, uint64(symtab.Symoff)-bytesWritten) - w.Write(pad) - bytesWritten += (uint64(symtab.Symoff) - bytesWritten) - //log.Printf("%x: wrote pad of: %d", bytesWritten, uint64(symtab.Symoff)-bytesWritten) - } - w.Write(symtab.RawSymtab) - bytesWritten += uint64(len(symtab.RawSymtab)) - //log.Printf("%x: Wrote raw symtab, length of: %d", bytesWritten, len(symtab.RawSymtab)) - - // Write DySymTab next! - dysymtab := machoFile.Dysymtab - if int64(dysymtab.Indirectsymoff)-int64(bytesWritten) > 0 { - pad2 := make([]byte, uint64(dysymtab.Indirectsymoff)-bytesWritten) - w.Write(pad2) - bytesWritten += uint64(len(pad2)) - //log.Printf("%x: wrote pad of: %d", bytesWritten, len(pad2)) - } - w.Write(dysymtab.RawDysymtab) - bytesWritten += uint64(len(dysymtab.RawDysymtab)) - //log.Printf("%x: Wrote raw indirect symbols, length of: %d", bytesWritten, len(dysymtab.RawDysymtab)) - - // Write StringTab! - if int64(symtab.Stroff)-int64(bytesWritten) > 0 { - pad3 := make([]byte, uint64(symtab.Stroff)-bytesWritten) - w.Write(pad3) - bytesWritten += uint64(len(pad3)) - //log.Printf("%x: wrote pad of: %d", bytesWritten, len(pad3)) - } - w.Write(symtab.RawStringtab) - bytesWritten += uint64(len(symtab.RawStringtab)) - //log.Printf("%x: Wrote raw stringtab, length of: %d", bytesWritten, len(symtab.RawStringtab)) - - // Write The Signature Block, if it exists - //log.Printf("SigBlock Dat: %v", machoFile.SigBlock) - if machoFile.SigBlock != nil { - if int64(machoFile.SigBlock.Offset)-int64(bytesWritten) > 0 { - padX := make([]byte, int64(machoFile.SigBlock.Offset)-int64(bytesWritten)) - w.Write(padX) - bytesWritten += uint64(len(padX)) - //log.Printf("%x: wrote pad of: %d", bytesWritten, len(padX)) - } - w.Write(machoFile.SigBlock.RawDat) - bytesWritten += uint64(machoFile.SigBlock.Len) - //log.Printf("%x: Wrote raw sigblock, length of: %d", bytesWritten, machoFile.SigBlock.Len) - } - - // Write 0s to the end of the final segment - if int64(FinalSegEnd)-int64(bytesWritten) > 0 { - pad4 := make([]byte, uint64(FinalSegEnd)-bytesWritten) - w.Write(pad4) - bytesWritten += uint64(len(pad4)) - //log.Printf("%x: wrote pad of: %d", bytesWritten, len(pad4)) - } - - //log.Println("All done!") - machoBytes := w.Bytes() - return machoBytes, nil -} - -// WriteFile - Creates a new file and writes it using the Bytes func above -func (machoFile *File) WriteFile(destFile string) error { - f, err := os.Create(destFile) - if err != nil { - return err - } - defer f.Close() - machoData, err := machoFile.Bytes() - if err != nil { - return err - } - _, err = f.Write(machoData) - if err != nil { - return err - } - - return nil -} - -// WriteFatFile - Creates a new Fat file and multiple machos into it -func (FatyFile *FatFile) WriteFatFile(destFile string) error { - f, err := os.Create(destFile) - if err != nil { - return err - } - defer f.Close() - w := bufio.NewWriter(f) - bytesWritten := uint64(0) - var FatyMachos []File - var FatyMachosOffsets []uint32 - - // Fat Header First - // Magic Bytes - binary.Write(w, binary.BigEndian, FatyFile.Magic) - bytesWritten += 4 - // Number of Fat Arches [4 bytes] - FatArches := uint32(len(FatyFile.Arches)) - binary.Write(w, binary.BigEndian, FatArches) - bytesWritten += 4 - w.Flush() - // Arch Size - for _, arch := range FatyFile.Arches { - log.Printf("Arch details: %v\n", arch) - FatyMachos = append(FatyMachos, *(arch.File)) - //Cpu Type - binary.Write(w, binary.BigEndian, uint32(arch.Cpu)) - bytesWritten += 4 - //Sub CPU type - binary.Write(w, binary.BigEndian, uint32(arch.SubCpu)) - bytesWritten += 4 - //FileOffset - FatyMachosOffsets = append(FatyMachosOffsets, arch.Offset) - binary.Write(w, binary.BigEndian, uint32(arch.Offset)) - bytesWritten += 4 - //Size - binary.Write(w, binary.BigEndian, uint32(arch.Size)) - bytesWritten += 4 - //Align - binary.Write(w, binary.BigEndian, uint32(arch.Align)) - bytesWritten += 4 - w.Flush() - } - // End of Fat Headers - - // Write each Macho File at its Offset - for index, mach := range FatyMachos { - // Pad to the offset - if bytesWritten < uint64(FatyMachosOffsets[index]) { - pad := make([]byte, uint64(FatyMachosOffsets[index])-bytesWritten) - w.Write(pad) - bytesWritten += uint64(len(pad)) - } - // Write the Mach-o file - machOut, err := mach.Bytes() - if err != nil { - return err - } - binary.Write(w, binary.BigEndian, machOut) - bytesWritten += uint64(len(machOut)) - w.Flush() - } - - return nil -} diff --git a/odiglet/pkg/allocator/debug/pe/cert.go b/odiglet/pkg/allocator/debug/pe/cert.go deleted file mode 100644 index 40cb175f38..0000000000 --- a/odiglet/pkg/allocator/debug/pe/cert.go +++ /dev/null @@ -1,50 +0,0 @@ -package pe - -import ( - "errors" - "fmt" - "io" -) - -// CERTIFICATE_TABLE is the index of the Certificate Table info in the Data Directory structure -// in the PE header -const CERTIFICATE_TABLE = 4 - -func readCertTable(f *File, r io.ReadSeeker) ([]byte, error) { - if f.OptionalHeader == nil { // Optional header is optional, might not exist - return nil, nil - } - - var certTableOffset, certTableSize uint32 - - switch f.FileHeader.Machine { - case IMAGE_FILE_MACHINE_I386: - certTableOffset = f.OptionalHeader.(*OptionalHeader32).DataDirectory[CERTIFICATE_TABLE].VirtualAddress - certTableSize = f.OptionalHeader.(*OptionalHeader32).DataDirectory[CERTIFICATE_TABLE].Size - case IMAGE_FILE_MACHINE_AMD64: - certTableOffset = f.OptionalHeader.(*OptionalHeader64).DataDirectory[CERTIFICATE_TABLE].VirtualAddress - certTableSize = f.OptionalHeader.(*OptionalHeader64).DataDirectory[CERTIFICATE_TABLE].Size - default: - return nil, errors.New("architecture not supported") - } - - // check if certificate table exists - if certTableOffset == 0 || certTableSize == 0 { - return nil, nil - } - - var err error - _, err = r.Seek(int64(certTableOffset), seekStart) - if err != nil { - return nil, fmt.Errorf("fail to seek to certificate table: %v", err) - } - - // grab the cert - cert := make([]byte, certTableSize) - _, err = io.ReadFull(r, cert) - if err != nil { - return nil, fmt.Errorf("fail to read certificate table: %v", err) - } - - return cert, nil -} diff --git a/odiglet/pkg/allocator/debug/pe/exports.go b/odiglet/pkg/allocator/debug/pe/exports.go deleted file mode 100644 index eddac10739..0000000000 --- a/odiglet/pkg/allocator/debug/pe/exports.go +++ /dev/null @@ -1,141 +0,0 @@ -package pe - -import ( - "encoding/binary" -) - -// ExportDirectory - data directory definition for exported functions -type ExportDirectory struct { - ExportFlags uint32 // reserved, must be zero - TimeDateStamp uint32 - MajorVersion uint16 - MinorVersion uint16 - NameRVA uint32 // pointer to the name of the DLL - OrdinalBase uint32 - NumberOfFunctions uint32 - NumberOfNames uint32 // also Ordinal Table Len - AddressTableAddr uint32 // RVA of EAT, relative to image base - NameTableAddr uint32 // RVA of export name pointer table, relative to image base - OrdinalTableAddr uint32 // address of the ordinal table, relative to iamge base - - DllName string -} - -// Export - describes a single export entry -type Export struct { - Ordinal uint32 - Name string - VirtualAddress uint32 - Forward string -} - -// Exports - gets exports -func (f *File) Exports() ([]Export, error) { - pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64 - - // grab the number of data directory entries - var ddLength uint32 - if pe64 { - ddLength = f.OptionalHeader.(*OptionalHeader64).NumberOfRvaAndSizes - } else { - ddLength = f.OptionalHeader.(*OptionalHeader32).NumberOfRvaAndSizes - } - - // check that the length of data directory entries is large - // enough to include the exports directory. - if ddLength < IMAGE_DIRECTORY_ENTRY_EXPORT+1 { - return nil, nil - } - - // grab the export data directory entry - var edd DataDirectory - if pe64 { - edd = f.OptionalHeader.(*OptionalHeader64).DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] - } else { - edd = f.OptionalHeader.(*OptionalHeader32).DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] - } - - // figure out which section contains the export directory table - var ds *Section - ds = nil - for _, s := range f.Sections { - if s.VirtualAddress <= edd.VirtualAddress && edd.VirtualAddress < s.VirtualAddress+s.VirtualSize { - ds = s - break - } - } - - // didn't find a section, so no exports were found - if ds == nil { - return nil, nil - } - - d, err := ds.Data() - if err != nil { - return nil, err - } - - exportDirOffset := edd.VirtualAddress - ds.VirtualAddress - - // seek to the virtual address specified in the export data directory - dxd := d[exportDirOffset:] - - // deserialize export directory - var dt ExportDirectory - dt.ExportFlags = binary.LittleEndian.Uint32(dxd[0:4]) - dt.TimeDateStamp = binary.LittleEndian.Uint32(dxd[4:8]) - dt.MajorVersion = binary.LittleEndian.Uint16(dxd[8:10]) - dt.MinorVersion = binary.LittleEndian.Uint16(dxd[10:12]) - dt.NameRVA = binary.LittleEndian.Uint32(dxd[12:16]) - dt.OrdinalBase = binary.LittleEndian.Uint32(dxd[16:20]) - dt.NumberOfFunctions = binary.LittleEndian.Uint32(dxd[20:24]) - dt.NumberOfNames = binary.LittleEndian.Uint32(dxd[24:28]) - dt.AddressTableAddr = binary.LittleEndian.Uint32(dxd[28:32]) - dt.NameTableAddr = binary.LittleEndian.Uint32(dxd[32:36]) - dt.OrdinalTableAddr = binary.LittleEndian.Uint32(dxd[36:40]) - - dt.DllName, _ = getString(d, int(dt.NameRVA-ds.VirtualAddress)) - - ordinalTable := make(map[uint16]uint32) - if dt.OrdinalTableAddr > ds.VirtualAddress && dt.NameTableAddr > ds.VirtualAddress { - // seek to ordinal table - dno := d[dt.OrdinalTableAddr-ds.VirtualAddress:] - // seek to names table - dnn := d[dt.NameTableAddr-ds.VirtualAddress:] - - // build whole ordinal->name table - for n := uint32(0); n < dt.NumberOfNames; n++ { - ord := binary.LittleEndian.Uint16(dno[n*2 : (n*2)+2]) - nameRVA := binary.LittleEndian.Uint32(dnn[n*4 : (n*4)+4]) - ordinalTable[ord] = nameRVA - } - dno = nil - dnn = nil - } - - // seek to ordinal table - dna := d[dt.AddressTableAddr-ds.VirtualAddress:] - - var exports []Export - for i := uint32(0); i < dt.NumberOfFunctions; i++ { - var export Export - export.VirtualAddress = - binary.LittleEndian.Uint32(dna[i*4 : (i*4)+4]) - export.Ordinal = dt.OrdinalBase + i - - // if this address is inside the export section, this export is a Forwarder RVA - if ds.VirtualAddress <= export.VirtualAddress && - export.VirtualAddress < ds.VirtualAddress+ds.VirtualSize { - export.Forward, _ = getString(d, int(export.VirtualAddress-ds.VirtualAddress)) - } - - // check the entire ordinal table looking for this index to see if we have a name - _, ok := ordinalTable[uint16(i)] - if ok { // a name exists for this exported function - nameRVA, _ := ordinalTable[uint16(i)] - export.Name, _ = getString(d, int(nameRVA-ds.VirtualAddress)) - } - exports = append(exports, export) - } - return exports, nil -} diff --git a/odiglet/pkg/allocator/debug/pe/file.go b/odiglet/pkg/allocator/debug/pe/file.go deleted file mode 100644 index 0a5bb0483c..0000000000 --- a/odiglet/pkg/allocator/debug/pe/file.go +++ /dev/null @@ -1,469 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package pe implements access to PE (Microsoft Windows Portable Executable) files. -package pe - -import ( - "bytes" - "compress/zlib" - "debug/dwarf" - "encoding/binary" - "fmt" - "io" - "os" - "strings" -) - -// Avoid use of post-Go 1.4 io features, to make safe for toolchain bootstrap. -const ( - seekStart = 0 - seekCurrent = 1 -) - -// A File represents an open PE file. -type File struct { - DosHeader - DosExists bool - DosStub [64]byte // TODO(capnspacehook) make slice and correctly parse any DOS stub - RichHeader []byte - FileHeader - OptionalHeader interface{} // of type *OptionalHeader32 or *OptionalHeader64 - Sections []*Section - BaseRelocationTable *[]RelocationTableEntry - Symbols []*Symbol // COFF symbols with auxiliary symbol records removed - COFFSymbols []COFFSymbol // all COFF symbols (including auxiliary symbol records) - StringTable StringTable - CertificateTable []byte - - OptionalHeaderOffset int64 // offset of the start of the Optional Header - InsertionAddr uint32 - InsertionBytes []byte - - Net Net //If a managed executable, Net provides an interface to some of the metadata - - closer io.Closer -} - -// Open opens the named file using os.Open and prepares it for use as a PE binary. -func Open(name string) (*File, error) { - f, err := os.Open(name) - if err != nil { - return nil, err - } - ff, err := NewFile(f) - if err != nil { - f.Close() - return nil, err - } - ff.closer = f - return ff, nil -} - -// Close closes the File. -// If the File was created using NewFile directly instead of Open, -// Close has no effect. -func (f *File) Close() error { - var err error - if f.closer != nil { - err = f.closer.Close() - f.closer = nil - } - return err -} - -var ( - sizeofOptionalHeader32 = uint16(binary.Size(OptionalHeader32{})) - sizeofOptionalHeader64 = uint16(binary.Size(OptionalHeader64{})) -) - -// TODO(brainman): add Load function, as a replacement for NewFile, that does not call removeAuxSymbols (for performance) - -// NewFile creates a new pe.File for accessing a PE binary file in an underlying reader. -func NewFile(r io.ReaderAt) (*File, error) { - return newFileInternal(r, false) -} - -// NewFileFromMemory creates a new pe.File for accessing a PE binary in-memory image in an underlying reader. -func NewFileFromMemory(r io.ReaderAt) (*File, error) { - return newFileInternal(r, true) -} - -// NewFile creates a new File for accessing a PE binary in an underlying reader. -func newFileInternal(r io.ReaderAt, memoryMode bool) (*File, error) { - - f := new(File) - sr := io.NewSectionReader(r, 0, 1<<63-1) - - binary.Read(sr, binary.LittleEndian, &f.DosHeader) - dosHeaderSize := binary.Size(f.DosHeader) - if dosHeaderSize > int(f.DosHeader.AddressOfNewExeHeader) { - binary.Read(sr, binary.LittleEndian, &f.DosStub) - f.DosExists = true - } else { - f.DosExists = false - } - - possibleRichHeaderStart := dosHeaderSize - if f.DosExists { - possibleRichHeaderStart += binary.Size(f.DosStub) - } - possibleRichHeaderEnd := int(f.DosHeader.AddressOfNewExeHeader) - if possibleRichHeaderEnd > possibleRichHeaderStart { - richHeader := make([]byte, possibleRichHeaderEnd-possibleRichHeaderStart) - binary.Read(sr, binary.LittleEndian, richHeader) - - if richIndex := bytes.Index(richHeader, []byte("Rich")); richIndex != -1 { - f.RichHeader = richHeader[:richIndex+8] - } - } - - var peHeaderOffset int64 - if f.DosHeader.MZSignature == 0x5a4d { - peHeaderOffset = int64(f.DosHeader.AddressOfNewExeHeader) - var sign [4]byte - r.ReadAt(sign[:], peHeaderOffset) - if !(sign[0] == 'P' && sign[1] == 'E' && sign[2] == 0 && sign[3] == 0) { - return nil, fmt.Errorf("Invalid PE COFF file signature of %v", sign) - } - peHeaderOffset += int64(4) - } else { - peHeaderOffset = int64(0) - } - - sr.Seek(peHeaderOffset, seekStart) - if err := binary.Read(sr, binary.LittleEndian, &f.FileHeader); err != nil { - return nil, err - } - switch f.FileHeader.Machine { - case IMAGE_FILE_MACHINE_UNKNOWN, IMAGE_FILE_MACHINE_ARMNT, IMAGE_FILE_MACHINE_AMD64, IMAGE_FILE_MACHINE_I386: - default: - return nil, fmt.Errorf("Unrecognised COFF file header machine value of 0x%x", f.FileHeader.Machine) - } - - var err error - - if memoryMode { - //get strings table location - offset is wrong in the header because we are in memory mode. Can we fix it? Yes we can! - restore, err := sr.Seek(0, seekCurrent) - if err != nil { - return nil, fmt.Errorf("Had a bad time getting restore point: %v", err) - } - //seek to table start (skip the headers) - sr.Seek(peHeaderOffset+int64(binary.Size(f.FileHeader))+int64(f.FileHeader.SizeOfOptionalHeader), seekStart) - - //iterate through the sections to find the raw offset value that matches the original symbol table value - for i := 0; i < int(f.FileHeader.NumberOfSections); i++ { - sh := new(SectionHeader32) - if err := binary.Read(sr, binary.LittleEndian, sh); err != nil { - return nil, err - } - //original offset matches the pointer to the symbol table, update the header so other things can reference it good again - if sh.PointerToRawData == f.FileHeader.PointerToSymbolTable { - f.FileHeader.PointerToSymbolTable = sh.VirtualAddress - } - } - //restore the original location of sr (this shouldn't actually be required, but just in case) - sr.Seek(restore, seekStart) - } - - // Read string table. - f.StringTable, err = readStringTable(&f.FileHeader, sr) - if err != nil { - return nil, err - } - - // Read symbol table. - f.COFFSymbols, err = readCOFFSymbols(&f.FileHeader, sr) - if err != nil { - return nil, err - } - f.Symbols, err = removeAuxSymbols(f.COFFSymbols, f.StringTable) - if err != nil { - return nil, err - } - - // Read optional header. - f.OptionalHeaderOffset = peHeaderOffset + int64(binary.Size(f.FileHeader)) - sr.Seek(f.OptionalHeaderOffset, seekStart) - - var oh32 OptionalHeader32 - var oh64 OptionalHeader64 - switch f.FileHeader.SizeOfOptionalHeader { - case sizeofOptionalHeader32: - if err := binary.Read(sr, binary.LittleEndian, &oh32); err != nil { - return nil, err - } - if oh32.Magic != 0x10b { // PE32 - return nil, fmt.Errorf("pe32 optional header has unexpected Magic of 0x%x", oh32.Magic) - } - f.OptionalHeader = &oh32 - case sizeofOptionalHeader64: - if err := binary.Read(sr, binary.LittleEndian, &oh64); err != nil { - return nil, err - } - if oh64.Magic != 0x20b { // PE32+ - return nil, fmt.Errorf("pe32+ optional header has unexpected Magic of 0x%x", oh64.Magic) - } - f.OptionalHeader = &oh64 - } - - // Process sections. - f.Sections = make([]*Section, f.FileHeader.NumberOfSections) - for i := 0; i < int(f.FileHeader.NumberOfSections); i++ { - sh := new(SectionHeader32) - if err := binary.Read(sr, binary.LittleEndian, sh); err != nil { - return nil, err - } - name, err := sh.fullName(f.StringTable) - if err != nil { - return nil, err - } - s := new(Section) - s.SectionHeader = SectionHeader{ - Name: name, - OriginalName: sh.Name, - VirtualSize: sh.VirtualSize, - VirtualAddress: sh.VirtualAddress, - Size: sh.SizeOfRawData, - Offset: sh.PointerToRawData, - PointerToRelocations: sh.PointerToRelocations, - PointerToLineNumbers: sh.PointerToLineNumbers, - NumberOfRelocations: sh.NumberOfRelocations, - NumberOfLineNumbers: sh.NumberOfLineNumbers, - Characteristics: sh.Characteristics, - } - r2 := r - if sh.PointerToRawData == 0 { // .bss must have all 0s - r2 = zeroReaderAt{} - } - if !memoryMode { - s.sr = io.NewSectionReader(r2, int64(s.SectionHeader.Offset), int64(s.SectionHeader.Size)) - } else { - s.sr = io.NewSectionReader(r2, int64(s.SectionHeader.VirtualAddress), int64(s.SectionHeader.Size)) - } - s.ReaderAt = s.sr - f.Sections[i] = s - } - for i := range f.Sections { - var err error - f.Sections[i].Relocs, err = readRelocs(&f.Sections[i].SectionHeader, sr) - if err != nil { - return nil, err - } - } - - // Read Base Relocation Block and Items - f.BaseRelocationTable, err = f.readBaseRelocationTable() - if err != nil { - return nil, err - } - - // Read certificate table (only in disk mode) - if !memoryMode { - f.CertificateTable, err = readCertTable(f, sr) - if err != nil { - return nil, err - } - } - - //fill net info - if f.IsManaged() { - var va, size uint32 - - //determine location of the COM descriptor directory - switch v := f.OptionalHeader.(type) { - case *OptionalHeader32: - va = v.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress - size = v.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size - case *OptionalHeader64: - va = v.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress - size = v.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size - } - - //I'm unsure how to get a reader (not a readerat) for a particular thing, so copying buffers around.. this could be more optimal - buff := make([]byte, size) - - //none of these reads have errors being caught either, which is probably not ideal - if !memoryMode { - r.ReadAt(buff, int64(f.RVAToFileOffset(va))) - } else { - r.ReadAt(buff, int64(va)) - } - binary.Read(bytes.NewReader(buff), binary.LittleEndian, &f.Net.NetDirectory) - - //Now that we have the COR20 header (COM descriptor directory header), we can get the metadata section header, which has the version - buff = make([]byte, f.Net.NetDirectory.MetaDataSize) - //again, none of the reads are error checked :shrug: - if !memoryMode { - r.ReadAt(buff, int64(f.RVAToFileOffset(f.Net.NetDirectory.MetaDataRVA))) - } else { - r.ReadAt(buff, int64(f.Net.NetDirectory.MetaDataRVA)) - } - f.Net.MetaData, _ = newMetadataHeader(bytes.NewReader(buff)) - - } - - return f, nil -} - -// zeroReaderAt is ReaderAt that reads 0s. -type zeroReaderAt struct{} - -// ReadAt writes len(p) 0s into p. -func (w zeroReaderAt) ReadAt(p []byte, off int64) (n int, err error) { - for i := range p { - p[i] = 0 - } - return len(p), nil -} - -// getString extracts a string from symbol string table. -func getString(section []byte, start int) (string, bool) { - if start < 0 || start >= len(section) { - return "", false - } - - for end := start; end < len(section); end++ { - if section[end] == 0 { - return string(section[start:end]), true - } - } - return "", false -} - -// Section returns the first section with the given name, or nil if no such -// section exists. -func (f *File) Section(name string) *Section { - for _, s := range f.Sections { - if s.Name == name { - return s - } - } - return nil -} - -func (f *File) DWARF() (*dwarf.Data, error) { - dwarfSuffix := func(s *Section) string { - switch { - case strings.HasPrefix(s.Name, ".debug_"): - return s.Name[7:] - case strings.HasPrefix(s.Name, ".zdebug_"): - return s.Name[8:] - default: - return "" - } - - } - - // sectionData gets the data for s and checks its size. - sectionData := func(s *Section) ([]byte, error) { - b, err := s.Data() - if err != nil && uint32(len(b)) < s.Size { - return nil, err - } - - if 0 < s.VirtualSize && s.VirtualSize < s.Size { - b = b[:s.VirtualSize] - } - - if len(b) >= 12 && string(b[:4]) == "ZLIB" { - dlen := binary.BigEndian.Uint64(b[4:12]) - dbuf := make([]byte, dlen) - r, err := zlib.NewReader(bytes.NewBuffer(b[12:])) - if err != nil { - return nil, err - } - if _, err := io.ReadFull(r, dbuf); err != nil { - return nil, err - } - if err := r.Close(); err != nil { - return nil, err - } - b = dbuf - } - return b, nil - } - - // There are many other DWARF sections, but these - // are the ones the debug/dwarf package uses. - // Don't bother loading others. - var dat = map[string][]byte{"abbrev": nil, "info": nil, "str": nil, "line": nil, "ranges": nil} - for _, s := range f.Sections { - suffix := dwarfSuffix(s) - if suffix == "" { - continue - } - if _, ok := dat[suffix]; !ok { - continue - } - - b, err := sectionData(s) - if err != nil { - return nil, err - } - dat[suffix] = b - } - - d, err := dwarf.New(dat["abbrev"], nil, nil, dat["info"], dat["line"], nil, dat["ranges"], dat["str"]) - if err != nil { - return nil, err - } - - // Look for DWARF4 .debug_types sections. - for i, s := range f.Sections { - suffix := dwarfSuffix(s) - if suffix != "types" { - continue - } - - b, err := sectionData(s) - if err != nil { - return nil, err - } - - err = d.AddTypes(fmt.Sprintf("types-%d", i), b) - if err != nil { - return nil, err - } - } - - return d, nil -} - -// FormatError is unused. -// The type is retained for compatibility. -type FormatError struct { -} - -func (e *FormatError) Error() string { - return "unknown error" -} - -// RVAToFileOffset Converts a Relative offset to the actual offset in the file. -func (f *File) RVAToFileOffset(rva uint32) uint32 { - var offset uint32 - for _, section := range f.Sections { - if rva >= section.SectionHeader.VirtualAddress && rva <= section.SectionHeader.VirtualAddress+section.SectionHeader.Size { - offset = section.SectionHeader.Offset + (rva - section.SectionHeader.VirtualAddress) - } - } - return offset -} - -// IsManaged returns true if the loaded PE file references the CLR header (aka is a .net exe) -func (f *File) IsManaged() bool { - switch v := f.OptionalHeader.(type) { - case *OptionalHeader32: - if v.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress != 0 { - return true - } - case *OptionalHeader64: - if v.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress != 0 { - return true - } - } - - return false -} diff --git a/odiglet/pkg/allocator/debug/pe/file_cgo_test.go b/odiglet/pkg/allocator/debug/pe/file_cgo_test.go deleted file mode 100644 index bba3a068d6..0000000000 --- a/odiglet/pkg/allocator/debug/pe/file_cgo_test.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build cgo -// +build cgo - -package pe - -import ( - "os/exec" - "testing" -) - -func testCgoDWARF(t *testing.T, linktype int) { - if _, err := exec.LookPath("gcc"); err != nil { - t.Skip("skipping test: gcc is missing") - } - testDWARF(t, linktype) -} - -func TestDefaultLinkerDWARF(t *testing.T) { - testCgoDWARF(t, linkCgoDefault) -} - -func TestInternalLinkerDWARF(t *testing.T) { - testCgoDWARF(t, linkCgoInternal) -} - -func TestExternalLinkerDWARF(t *testing.T) { - testCgoDWARF(t, linkCgoExternal) -} diff --git a/odiglet/pkg/allocator/debug/pe/file_test.go b/odiglet/pkg/allocator/debug/pe/file_test.go deleted file mode 100644 index 0c97e0612e..0000000000 --- a/odiglet/pkg/allocator/debug/pe/file_test.go +++ /dev/null @@ -1,627 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pe - -import ( - "debug/dwarf" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "reflect" - "regexp" - "runtime" - "strconv" - "testing" - "text/template" -) - -type fileTest struct { - file string - hdr FileHeader - opthdr interface{} - sections []*SectionHeader - symbols []*Symbol - hasNoDwarfInfo bool -} - -var zero8 [8]uint8 - -var fileTests = []fileTest{ - { - file: "testdata/gcc-386-mingw-obj", - hdr: FileHeader{0x014c, 0x000c, 0x0, 0x64a, 0x1e, 0x0, 0x104}, - sections: []*SectionHeader{ - {".text", [8]uint8{0x2e, 0x74, 0x65, 0x78, 0x74, 0x0, 0x0, 0x0}, 0, 0, 36, 500, 1440, 0, 3, 0, 0x60300020}, - {".data", [8]uint8{0x2e, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0, 0x0}, 0, 0, 0, 0, 0, 0, 0, 0, 3224371264}, - {".bss", [8]uint8{0x2e, 0x62, 0x73, 0x73, 0x0, 0x0, 0x0, 0x0}, 0, 0, 0, 0, 0, 0, 0, 0, 3224371328}, - {".debug_abbrev", [8]uint8{0x2f, 0x34, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 0, 0, 137, 536, 0, 0, 0, 0, 0x42100000}, - {".debug_info", [8]uint8{0x2f, 0x31, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0}, 0, 0, 418, 673, 1470, 0, 7, 0, 1108344832}, - {".debug_line", [8]uint8{0x2f, 0x33, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0}, 0, 0, 128, 1091, 1540, 0, 1, 0, 1108344832}, - {".rdata", [8]uint8{0x2e, 0x72, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0}, 0, 0, 16, 1219, 0, 0, 0, 0, 1076887616}, - {".debug_frame", [8]uint8{0x2f, 0x34, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0}, 0, 0, 52, 1235, 1550, 0, 2, 0, 1110441984}, - {".debug_loc", [8]uint8{0x2f, 0x35, 0x35, 0x0, 0x0, 0x0, 0x0, 0x0}, 0, 0, 56, 1287, 0, 0, 0, 0, 1108344832}, - {".debug_pubnames", [8]uint8{0x2f, 0x36, 0x36, 0x0, 0x0, 0x0, 0x0, 0x0}, 0, 0, 27, 1343, 1570, 0, 1, 0, 1108344832}, - {".debug_pubtypes", [8]uint8{0x2f, 0x38, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0}, 0, 0, 38, 1370, 1580, 0, 1, 0, 1108344832}, - {".debug_aranges", [8]uint8{0x2f, 0x39, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0}, 0, 0, 32, 1408, 1590, 0, 2, 0, 1108344832}, - }, - symbols: []*Symbol{ - {".file", 0x0, -2, 0x0, 0x67}, - {"_main", 0x0, 1, 0x20, 0x2}, - {".text", 0x0, 1, 0x0, 0x3}, - {".data", 0x0, 2, 0x0, 0x3}, - {".bss", 0x0, 3, 0x0, 0x3}, - {".debug_abbrev", 0x0, 4, 0x0, 0x3}, - {".debug_info", 0x0, 5, 0x0, 0x3}, - {".debug_line", 0x0, 6, 0x0, 0x3}, - {".rdata", 0x0, 7, 0x0, 0x3}, - {".debug_frame", 0x0, 8, 0x0, 0x3}, - {".debug_loc", 0x0, 9, 0x0, 0x3}, - {".debug_pubnames", 0x0, 10, 0x0, 0x3}, - {".debug_pubtypes", 0x0, 11, 0x0, 0x3}, - {".debug_aranges", 0x0, 12, 0x0, 0x3}, - {"___main", 0x0, 0, 0x20, 0x2}, - {"_puts", 0x0, 0, 0x20, 0x2}, - }, - }, - { - file: "testdata/gcc-386-mingw-exec", - hdr: FileHeader{0x014c, 0x000f, 0x4c6a1b60, 0x3c00, 0x282, 0xe0, 0x107}, - opthdr: &OptionalHeader32{ - 0x10b, 0x2, 0x38, 0xe00, 0x1a00, 0x200, 0x1160, 0x1000, 0x2000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x10000, 0x400, 0x14abb, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10, - [16]DataDirectory{ - {0x0, 0x0}, - {0x5000, 0x3c8}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x7000, 0x18}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - }, - }, - sections: []*SectionHeader{ - {".text", [8]uint8{0x2e, 0x74, 0x65, 0x78, 0x74, 0x0, 0x0, 0x0}, 0xcd8, 0x1000, 0xe00, 0x400, 0x0, 0x0, 0x0, 0x0, 0x60500060}, - {".data", [8]uint8{0x2e, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0, 0x0}, 0x10, 0x2000, 0x200, 0x1200, 0x0, 0x0, 0x0, 0x0, 0xc0300040}, - {".rdata", [8]uint8{0x2e, 0x72, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0}, 0x120, 0x3000, 0x200, 0x1400, 0x0, 0x0, 0x0, 0x0, 0x40300040}, - {".bss", [8]uint8{0x2e, 0x62, 0x73, 0x73, 0x0, 0x0, 0x0, 0x0}, 0xdc, 0x4000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0400080}, - {".idata", [8]uint8{0x2e, 0x69, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0}, 0x3c8, 0x5000, 0x400, 0x1600, 0x0, 0x0, 0x0, 0x0, 0xc0300040}, - {".CRT", [8]uint8{0x2e, 0x43, 0x52, 0x54, 0x0, 0x0, 0x0, 0x0}, 0x18, 0x6000, 0x200, 0x1a00, 0x0, 0x0, 0x0, 0x0, 0xc0300040}, - {".tls", [8]uint8{0x2e, 0x74, 0x6c, 0x73, 0x0, 0x0, 0x0, 0x0}, 0x20, 0x7000, 0x200, 0x1c00, 0x0, 0x0, 0x0, 0x0, 0xc0300040}, - {".debug_aranges", [8]uint8{0x2f, 0x34, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 0x20, 0x8000, 0x200, 0x1e00, 0x0, 0x0, 0x0, 0x0, 0x42100000}, - {".debug_pubnames", [8]uint8{0x2f, 0x31, 0x39, 0x0, 0x0, 0x0, 0x0, 0x0}, 0x51, 0x9000, 0x200, 0x2000, 0x0, 0x0, 0x0, 0x0, 0x42100000}, - {".debug_pubtypes", [8]uint8{0x2f, 0x33, 0x35, 0x0, 0x0, 0x0, 0x0, 0x0}, 0x91, 0xa000, 0x200, 0x2200, 0x0, 0x0, 0x0, 0x0, 0x42100000}, - {".debug_info", [8]uint8{0x2f, 0x35, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0}, 0xe22, 0xb000, 0x1000, 0x2400, 0x0, 0x0, 0x0, 0x0, 0x42100000}, - {".debug_abbrev", [8]uint8{0x2f, 0x36, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0}, 0x157, 0xc000, 0x200, 0x3400, 0x0, 0x0, 0x0, 0x0, 0x42100000}, - {".debug_line", [8]uint8{0x2f, 0x37, 0x37, 0x0, 0x0, 0x0, 0x0, 0x0}, 0x144, 0xd000, 0x200, 0x3600, 0x0, 0x0, 0x0, 0x0, 0x42100000}, - {".debug_frame", [8]uint8{0x2f, 0x38, 0x39, 0x0, 0x0, 0x0, 0x0, 0x0}, 0x34, 0xe000, 0x200, 0x3800, 0x0, 0x0, 0x0, 0x0, 0x42300000}, - {".debug_loc", [8]uint8{0x2f, 0x31, 0x30, 0x32, 0x0, 0x0, 0x0, 0x0}, 0x38, 0xf000, 0x200, 0x3a00, 0x0, 0x0, 0x0, 0x0, 0x42100000}, - }, - }, - { - file: "testdata/gcc-386-mingw-no-symbols-exec", - hdr: FileHeader{0x14c, 0x8, 0x69676572, 0x0, 0x0, 0xe0, 0x30f}, - opthdr: &OptionalHeader32{0x10b, 0x2, 0x18, 0xe00, 0x1e00, 0x200, 0x1280, 0x1000, 0x2000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x9000, 0x400, 0x5306, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10, - [16]DataDirectory{ - {0x0, 0x0}, - {0x6000, 0x378}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x8004, 0x18}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x60b8, 0x7c}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - }, - }, - sections: []*SectionHeader{ - {".text", [8]uint8{0x2e, 0x74, 0x65, 0x78, 0x74, 0x0, 0x0, 0x0}, 0xc64, 0x1000, 0xe00, 0x400, 0x0, 0x0, 0x0, 0x0, 0x60500060}, - {".data", [8]uint8{0x2e, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0, 0x0}, 0x10, 0x2000, 0x200, 0x1200, 0x0, 0x0, 0x0, 0x0, 0xc0300040}, - {".rdata", [8]uint8{0x2e, 0x72, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0}, 0x134, 0x3000, 0x200, 0x1400, 0x0, 0x0, 0x0, 0x0, 0x40300040}, - {".eh_fram", [8]uint8{0x2e, 0x65, 0x68, 0x5f, 0x66, 0x72, 0x61, 0x6d}, 0x3a0, 0x4000, 0x400, 0x1600, 0x0, 0x0, 0x0, 0x0, 0x40300040}, - {".bss", [8]uint8{0x2e, 0x62, 0x73, 0x73, 0x0, 0x0, 0x0, 0x0}, 0x60, 0x5000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0300080}, - {".idata", [8]uint8{0x2e, 0x69, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0}, 0x378, 0x6000, 0x400, 0x1a00, 0x0, 0x0, 0x0, 0x0, 0xc0300040}, - {".CRT", [8]uint8{0x2e, 0x43, 0x52, 0x54, 0x0, 0x0, 0x0, 0x0}, 0x18, 0x7000, 0x200, 0x1e00, 0x0, 0x0, 0x0, 0x0, 0xc0300040}, - {".tls", [8]uint8{0x2e, 0x74, 0x6c, 0x73, 0x0, 0x0, 0x0, 0x0}, 0x20, 0x8000, 0x200, 0x2000, 0x0, 0x0, 0x0, 0x0, 0xc0300040}, - }, - hasNoDwarfInfo: true, - }, - { - file: "testdata/gcc-amd64-mingw-obj", - hdr: FileHeader{0x8664, 0x6, 0x0, 0x198, 0x12, 0x0, 0x4}, - sections: []*SectionHeader{ - {".text", [8]uint8{0x2e, 0x74, 0x65, 0x78, 0x74, 0x0, 0x0, 0x0}, 0x0, 0x0, 0x30, 0x104, 0x15c, 0x0, 0x3, 0x0, 0x60500020}, - {".data", [8]uint8{0x2e, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0, 0x0}, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0500040}, - {".bss", [8]uint8{0x2e, 0x62, 0x73, 0x73, 0x0, 0x0, 0x0, 0x0}, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0500080}, - {".rdata", [8]uint8{0x2e, 0x72, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0}, 0x0, 0x0, 0x10, 0x134, 0x0, 0x0, 0x0, 0x0, 0x40500040}, - {".xdata", [8]uint8{0x2e, 0x78, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0}, 0x0, 0x0, 0xc, 0x144, 0x0, 0x0, 0x0, 0x0, 0x40300040}, - {".pdata", [8]uint8{0x2e, 0x70, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0}, 0x0, 0x0, 0xc, 0x150, 0x17a, 0x0, 0x3, 0x0, 0x40300040}, - }, - symbols: []*Symbol{ - {".file", 0x0, -2, 0x0, 0x67}, - {"main", 0x0, 1, 0x20, 0x2}, - {".text", 0x0, 1, 0x0, 0x3}, - {".data", 0x0, 2, 0x0, 0x3}, - {".bss", 0x0, 3, 0x0, 0x3}, - {".rdata", 0x0, 4, 0x0, 0x3}, - {".xdata", 0x0, 5, 0x0, 0x3}, - {".pdata", 0x0, 6, 0x0, 0x3}, - {"__main", 0x0, 0, 0x20, 0x2}, - {"puts", 0x0, 0, 0x20, 0x2}, - }, - hasNoDwarfInfo: true, - }, - { - file: "testdata/gcc-amd64-mingw-exec", - hdr: FileHeader{0x8664, 0x11, 0x53e4364f, 0x39600, 0x6fc, 0xf0, 0x27}, - opthdr: &OptionalHeader64{ - 0x20b, 0x2, 0x16, 0x6a00, 0x2400, 0x1600, 0x14e0, 0x1000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x0, 0x0, 0x5, 0x2, 0x0, 0x45000, 0x600, 0x46f19, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10, - [16]DataDirectory{ - {0x0, 0x0}, - {0xe000, 0x990}, - {0x0, 0x0}, - {0xa000, 0x498}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x10000, 0x28}, - {0x0, 0x0}, - {0x0, 0x0}, - {0xe254, 0x218}, - {0x0, 0x0}, - {0x0, 0x0}, - {0x0, 0x0}, - }}, - sections: []*SectionHeader{ - {".text", [8]uint8{0x2e, 0x74, 0x65, 0x78, 0x74, 0x0, 0x0, 0x0}, 0x6860, 0x1000, 0x6a00, 0x600, 0x0, 0x0, 0x0, 0x0, 0x60500020}, - {".data", [8]uint8{0x2e, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0, 0x0}, 0xe0, 0x8000, 0x200, 0x7000, 0x0, 0x0, 0x0, 0x0, 0xc0500040}, - {".rdata", [8]uint8{0x2e, 0x72, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0}, 0x6b0, 0x9000, 0x800, 0x7200, 0x0, 0x0, 0x0, 0x0, 0x40600040}, - {".pdata", [8]uint8{0x2e, 0x70, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0}, 0x498, 0xa000, 0x600, 0x7a00, 0x0, 0x0, 0x0, 0x0, 0x40300040}, - {".xdata", [8]uint8{0x2e, 0x78, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0}, 0x488, 0xb000, 0x600, 0x8000, 0x0, 0x0, 0x0, 0x0, 0x40300040}, - {".bss", [8]uint8{0x2e, 0x62, 0x73, 0x73, 0x0, 0x0, 0x0, 0x0}, 0x1410, 0xc000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0600080}, - {".idata", [8]uint8{0x2e, 0x69, 0x64, 0x61, 0x74, 0x61, 0x0, 0x0}, 0x990, 0xe000, 0xa00, 0x8600, 0x0, 0x0, 0x0, 0x0, 0xc0300040}, - {".CRT", [8]uint8{0x2e, 0x43, 0x52, 0x54, 0x0, 0x0, 0x0, 0x0}, 0x68, 0xf000, 0x200, 0x9000, 0x0, 0x0, 0x0, 0x0, 0xc0400040}, - {".tls", [8]uint8{0x2e, 0x74, 0x6c, 0x73, 0x0, 0x0, 0x0, 0x0}, 0x48, 0x10000, 0x200, 0x9200, 0x0, 0x0, 0x0, 0x0, 0xc0600040}, - {".debug_aranges", [8]uint8{0x2f, 0x34, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 0x600, 0x11000, 0x600, 0x9400, 0x0, 0x0, 0x0, 0x0, 0x42500040}, - {".debug_info", [8]uint8{0x2f, 0x31, 0x39, 0x0, 0x0, 0x0, 0x0, 0x0}, 0x1316e, 0x12000, 0x13200, 0x9a00, 0x0, 0x0, 0x0, 0x0, 0x42100040}, - {".debug_abbrev", [8]uint8{0x2f, 0x33, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0}, 0x2ccb, 0x26000, 0x2e00, 0x1cc00, 0x0, 0x0, 0x0, 0x0, 0x42100040}, - {".debug_line", [8]uint8{0x2f, 0x34, 0x35, 0x0, 0x0, 0x0, 0x0, 0x0}, 0x3c4d, 0x29000, 0x3e00, 0x1fa00, 0x0, 0x0, 0x0, 0x0, 0x42100040}, - {".debug_frame", [8]uint8{0x2f, 0x35, 0x37, 0x0, 0x0, 0x0, 0x0, 0x0}, 0x18b8, 0x2d000, 0x1a00, 0x23800, 0x0, 0x0, 0x0, 0x0, 0x42400040}, - {".debug_str", [8]uint8{0x2f, 0x37, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0}, 0x396, 0x2f000, 0x400, 0x25200, 0x0, 0x0, 0x0, 0x0, 0x42100040}, - {".debug_loc", [8]uint8{0x2f, 0x38, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0}, 0x13240, 0x30000, 0x13400, 0x25600, 0x0, 0x0, 0x0, 0x0, 0x42100040}, - {".debug_ranges", [8]uint8{0x2f, 0x39, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0}, 0xa70, 0x44000, 0xc00, 0x38a00, 0x0, 0x0, 0x0, 0x0, 0x42100040}, - }, - }, -} - -func isOptHdrEq(a, b interface{}) bool { - switch va := a.(type) { - case *OptionalHeader32: - vb, ok := b.(*OptionalHeader32) - if !ok { - return false - } - return *vb == *va - case *OptionalHeader64: - vb, ok := b.(*OptionalHeader64) - if !ok { - return false - } - return *vb == *va - case nil: - return b == nil - } - return false -} - -func TestOpen(t *testing.T) { - for i := range fileTests { - tt := &fileTests[i] - - f, err := Open(tt.file) - if err != nil { - t.Error(err) - continue - } - if !reflect.DeepEqual(f.FileHeader, tt.hdr) { - t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr) - continue - } - if !isOptHdrEq(tt.opthdr, f.OptionalHeader) { - t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.OptionalHeader, tt.opthdr) - continue - } - - for i, sh := range f.Sections { - if i >= len(tt.sections) { - break - } - have := &sh.SectionHeader - want := tt.sections[i] - if !reflect.DeepEqual(have, want) { - t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want) - } - } - tn := len(tt.sections) - fn := len(f.Sections) - if tn != fn { - t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn) - } - for i, have := range f.Symbols { - if i >= len(tt.symbols) { - break - } - want := tt.symbols[i] - if !reflect.DeepEqual(have, want) { - t.Errorf("open %s, symbol %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want) - } - } - if !tt.hasNoDwarfInfo { - _, err = f.DWARF() - if err != nil { - t.Errorf("fetching %s dwarf details failed: %v", tt.file, err) - } - } - } -} - -func TestOpenFailure(t *testing.T) { - filename := "file.go" // not a PE file - _, err := Open(filename) // don't crash - if err == nil { - t.Errorf("open %s: succeeded unexpectedly", filename) - } -} - -const ( - linkNoCgo = iota - linkCgoDefault - linkCgoInternal - linkCgoExternal -) - -func getImageBase(f *File) uintptr { - switch oh := f.OptionalHeader.(type) { - case *OptionalHeader32: - return uintptr(oh.ImageBase) - case *OptionalHeader64: - return uintptr(oh.ImageBase) - default: - panic("unexpected optionalheader type") - } -} - -func testDWARF(t *testing.T, linktype int) { - if runtime.GOOS != "windows" { - t.Skip("skipping windows only test") - } - - tmpdir, err := ioutil.TempDir("", "TestDWARF") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - - src := filepath.Join(tmpdir, "a.go") - file, err := os.Create(src) - if err != nil { - t.Fatal(err) - } - err = template.Must(template.New("main").Parse(testprog)).Execute(file, linktype != linkNoCgo) - if err != nil { - if err := file.Close(); err != nil { - t.Error(err) - } - t.Fatal(err) - } - if err := file.Close(); err != nil { - t.Fatal(err) - } - - exe := filepath.Join(tmpdir, "a.exe") - args := []string{"build", "-o", exe} - switch linktype { - case linkNoCgo: - case linkCgoDefault: - case linkCgoInternal: - args = append(args, "-ldflags", "-linkmode=internal") - case linkCgoExternal: - args = append(args, "-ldflags", "-linkmode=external") - default: - t.Fatalf("invalid linktype parameter of %v", linktype) - } - args = append(args, src) - out, err := exec.Command("go", args...).CombinedOutput() - if err != nil { - t.Fatalf("building test executable for linktype %d failed: %s %s", linktype, err, out) - } - out, err = exec.Command(exe).CombinedOutput() - if err != nil { - t.Fatalf("running test executable failed: %s %s", err, out) - } - t.Logf("Testprog output:\n%s", string(out)) - - matches := regexp.MustCompile("offset=(.*)\n").FindStringSubmatch(string(out)) - if len(matches) < 2 { - t.Fatalf("unexpected program output: %s", out) - } - wantoffset, err := strconv.ParseUint(matches[1], 0, 64) - if err != nil { - t.Fatalf("unexpected main offset %q: %s", matches[1], err) - } - - f, err := Open(exe) - if err != nil { - t.Fatal(err) - } - defer f.Close() - - imageBase := getImageBase(f) - - var foundDebugGDBScriptsSection bool - for _, sect := range f.Sections { - if sect.Name == ".debug_gdb_scripts" { - foundDebugGDBScriptsSection = true - } - } - if !foundDebugGDBScriptsSection { - t.Error(".debug_gdb_scripts section is not found") - } - - d, err := f.DWARF() - if err != nil { - t.Fatal(err) - } - - // look for main.main - r := d.Reader() - for { - e, err := r.Next() - if err != nil { - t.Fatal("r.Next:", err) - } - if e == nil { - break - } - if e.Tag == dwarf.TagSubprogram { - name, ok := e.Val(dwarf.AttrName).(string) - if ok && name == "main.main" { - t.Logf("Found main.main") - addr, ok := e.Val(dwarf.AttrLowpc).(uint64) - if !ok { - t.Fatal("Failed to get AttrLowpc") - } - offset := uintptr(addr) - imageBase - if offset != uintptr(wantoffset) { - t.Fatal("Runtime offset (0x%x) did "+ - "not match dwarf offset "+ - "(0x%x)", wantoffset, offset) - } - return - } - } - } - t.Fatal("main.main not found") -} - -func TestBSSHasZeros(t *testing.T) { - - if runtime.GOOS != "windows" { - t.Skip("skipping windows only test") - } - gccpath, err := exec.LookPath("gcc") - if err != nil { - t.Skip("skipping test: gcc is missing") - } - - tmpdir, err := ioutil.TempDir("", "TestBSSHasZeros") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - - srcpath := filepath.Join(tmpdir, "a.c") - src := ` -#include - -int zero = 0; - -int -main(void) -{ - printf("%d\n", zero); - return 0; -} -` - err = ioutil.WriteFile(srcpath, []byte(src), 0644) - if err != nil { - t.Fatal(err) - } - - objpath := filepath.Join(tmpdir, "a.obj") - cmd := exec.Command(gccpath, "-c", srcpath, "-o", objpath) - out, err := cmd.CombinedOutput() - if err != nil { - t.Fatalf("failed to build object file: %v - %v", err, string(out)) - } - - f, err := Open(objpath) - if err != nil { - t.Fatal(err) - } - defer f.Close() - - var bss *Section - for _, sect := range f.Sections { - if sect.Name == ".bss" { - bss = sect - break - } - } - if bss == nil { - t.Fatal("could not find .bss section") - } - data, err := bss.Data() - if err != nil { - t.Fatal(err) - } - if len(data) == 0 { - t.Fatalf("%s file .bss section cannot be empty", objpath) - } - for _, b := range data { - if b != 0 { - t.Fatalf(".bss section has non zero bytes: %v", data) - } - } -} - -func TestDWARF(t *testing.T) { - testDWARF(t, linkNoCgo) -} - -const testprog = ` -package main - -import "fmt" -import "syscall" -import "unsafe" -{{if .}}import "C" -{{end}} - -// struct MODULEINFO from the Windows SDK -type moduleinfo struct { - BaseOfDll uintptr - SizeOfImage uint32 - EntryPoint uintptr -} - -func add(p unsafe.Pointer, x uintptr) unsafe.Pointer { - return unsafe.Pointer(uintptr(p) + x) -} - -func funcPC(f interface{}) uintptr { - var a uintptr - return **(**uintptr)(add(unsafe.Pointer(&f), unsafe.Sizeof(a))) -} - -func main() { - kernel32 := syscall.MustLoadDLL("kernel32.dll") - psapi := syscall.MustLoadDLL("psapi.dll") - getModuleHandle := kernel32.MustFindProc("GetModuleHandleW") - getCurrentProcess := kernel32.MustFindProc("GetCurrentProcess") - getModuleInformation := psapi.MustFindProc("GetModuleInformation") - - procHandle, _, _ := getCurrentProcess.Call() - moduleHandle, _, err := getModuleHandle.Call(0) - if moduleHandle == 0 { - panic(fmt.Sprintf("GetModuleHandle() failed: %d", err)) - } - - var info moduleinfo - ret, _, err := getModuleInformation.Call(procHandle, moduleHandle, - uintptr(unsafe.Pointer(&info)), unsafe.Sizeof(info)) - - if ret == 0 { - panic(fmt.Sprintf("GetModuleInformation() failed: %d", err)) - } - - offset := funcPC(main) - info.BaseOfDll - fmt.Printf("base=0x%x\n", info.BaseOfDll) - fmt.Printf("main=%p\n", main) - fmt.Printf("offset=0x%x\n", offset) -} -` - -func TestBuildingWindowsGUI(t *testing.T) { - - if runtime.GOOS != "windows" { - t.Skip("skipping windows only test") - } - tmpdir, err := ioutil.TempDir("", "TestBuildingWindowsGUI") - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(tmpdir) - - src := filepath.Join(tmpdir, "a.go") - err = ioutil.WriteFile(src, []byte(`package main; func main() {}`), 0644) - if err != nil { - t.Fatal(err) - } - exe := filepath.Join(tmpdir, "a.exe") - cmd := exec.Command("go", "build", "-ldflags", "-H=windowsgui", "-o", exe, src) - out, err := cmd.CombinedOutput() - if err != nil { - t.Fatalf("building test executable failed: %s %s", err, out) - } - - f, err := Open(exe) - if err != nil { - t.Fatal(err) - } - defer f.Close() - - const _IMAGE_SUBSYSTEM_WINDOWS_GUI = 2 - - switch oh := f.OptionalHeader.(type) { - case *OptionalHeader32: - if oh.Subsystem != _IMAGE_SUBSYSTEM_WINDOWS_GUI { - t.Errorf("unexpected Subsystem value: have %d, but want %d", oh.Subsystem, _IMAGE_SUBSYSTEM_WINDOWS_GUI) - } - case *OptionalHeader64: - if oh.Subsystem != _IMAGE_SUBSYSTEM_WINDOWS_GUI { - t.Errorf("unexpected Subsystem value: have %d, but want %d", oh.Subsystem, _IMAGE_SUBSYSTEM_WINDOWS_GUI) - } - default: - t.Fatalf("unexpected OptionalHeader type: have %T, but want *pe.OptionalHeader32 or *pe.OptionalHeader64", oh) - } -} - -func TestImportTableInUnknownSection(t *testing.T) { - if runtime.GOOS != "windows" { - t.Skip("skipping Windows-only test") - } - - // ws2_32.dll import table is located in ".rdata" section, - // so it is good enough to test issue #16103. - const filename = "ws2_32.dll" - path, err := exec.LookPath(filename) - if err != nil { - t.Fatalf("unable to locate required file %q in search path: %s", filename, err) - } - - f, err := Open(path) - if err != nil { - t.Error(err) - } - defer f.Close() - - // now we can extract its imports - symbols, err := f.ImportedSymbols() - if err != nil { - t.Error(err) - } - - if len(symbols) == 0 { - t.Fatalf("unable to locate any imported symbols within file %q.", path) - } -} diff --git a/odiglet/pkg/allocator/debug/pe/imports.go b/odiglet/pkg/allocator/debug/pe/imports.go deleted file mode 100644 index d1bc9c556c..0000000000 --- a/odiglet/pkg/allocator/debug/pe/imports.go +++ /dev/null @@ -1,182 +0,0 @@ -package pe - -import ( - "encoding/binary" - "fmt" -) - -// ImportDirectory entry -type ImportDirectory struct { - OriginalFirstThunk uint32 - TimeDateStamp uint32 - ForwarderChain uint32 - NameRVA uint32 - FirstThunk uint32 - - DllName string -} - -// IAT returns the DataDirectory for the IAT -func (f *File) IAT() *DataDirectory { - pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64 - - // grab the number of data directory entries - var ddLength uint32 - if pe64 { - ddLength = f.OptionalHeader.(*OptionalHeader64).NumberOfRvaAndSizes - } else { - ddLength = f.OptionalHeader.(*OptionalHeader32).NumberOfRvaAndSizes - } - - // check that the length of data directory entries is large - // enough to include the imports directory. - if ddLength < IMAGE_DIRECTORY_ENTRY_IAT+1 { - return nil - } - - // grab the IAT entry - var idd DataDirectory - if pe64 { - idd = f.OptionalHeader.(*OptionalHeader64).DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT] - } else { - idd = f.OptionalHeader.(*OptionalHeader32).DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT] - } - return &idd -} - -// ImportDirectoryTable - returns the Import Directory Table, a pointer to the section, and the section raw data -func (f *File) ImportDirectoryTable() ([]ImportDirectory, *Section, *[]byte, error) { - - pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64 - - // grab the number of data directory entries - var ddLength uint32 - if pe64 { - ddLength = f.OptionalHeader.(*OptionalHeader64).NumberOfRvaAndSizes - } else { - ddLength = f.OptionalHeader.(*OptionalHeader32).NumberOfRvaAndSizes - } - - // check that the length of data directory entries is large - // enough to include the imports directory. - if ddLength < IMAGE_DIRECTORY_ENTRY_IMPORT+1 { - return nil, nil, nil, nil - } - - // grab the import data directory entry - var idd DataDirectory - if pe64 { - idd = f.OptionalHeader.(*OptionalHeader64).DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] - } else { - idd = f.OptionalHeader.(*OptionalHeader32).DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] - } - - // figure out which section contains the import directory table - var ds *Section - ds = nil - for _, s := range f.Sections { - if s.VirtualAddress <= idd.VirtualAddress && idd.VirtualAddress < s.VirtualAddress+s.VirtualSize { - ds = s - break - } - } - - // didn't find a section, so no import libraries were found - if ds == nil { - return nil, nil, nil, nil - } - - sectionData, err := ds.Data() - if err != nil { - return nil, nil, nil, err - } - - // seek to the virtual address specified in the import data directory - d := sectionData[idd.VirtualAddress-ds.VirtualAddress:] - - // start decoding the import directory - var ida []ImportDirectory - for len(d) > 0 { - var dt ImportDirectory - dt.OriginalFirstThunk = binary.LittleEndian.Uint32(d[0:4]) - dt.TimeDateStamp = binary.LittleEndian.Uint32(d[4:8]) - dt.ForwarderChain = binary.LittleEndian.Uint32(d[8:12]) - dt.NameRVA = binary.LittleEndian.Uint32(d[12:16]) - dt.FirstThunk = binary.LittleEndian.Uint32(d[16:20]) - dt.DllName, _ = getString(sectionData, int(dt.NameRVA-ds.VirtualAddress)) - d = d[20:] - if dt.OriginalFirstThunk == 0 { - break - } - ida = append(ida, dt) - } - return ida, ds, §ionData, nil -} - -// ImportedSymbols returns the names of all symbols -// referred to by the binary f that are expected to be -// satisfied by other libraries at dynamic load time. -// It does not return weak symbols. -func (f *File) ImportedSymbols() ([]string, error) { - pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64 - - ida, ds, sectionData, err := f.ImportDirectoryTable() - if err != nil { - return nil, err - } - - var all []string - for _, dt := range ida { - d := (*sectionData)[:] - // seek to OriginalFirstThunk - if dt.OriginalFirstThunk-ds.VirtualAddress > uint32(len(d)) { - return all, fmt.Errorf("bad object ref start, got %d maxlen %d", dt.OriginalFirstThunk-ds.VirtualAddress, len(d)) - } - d = d[dt.OriginalFirstThunk-ds.VirtualAddress:] - for len(d) > 0 { - if pe64 { // 64bit - va := binary.LittleEndian.Uint64(d[0:8]) - d = d[8:] - if va == 0 { - break - } - if va&0x8000000000000000 > 0 { // is Ordinal - // TODO add dynimport ordinal support. - } else { - fn, _ := getString(*sectionData, int(uint32(va)-ds.VirtualAddress+2)) - all = append(all, fn+":"+dt.DllName) - } - } else { // 32bit - va := binary.LittleEndian.Uint32(d[0:4]) - d = d[4:] - if va == 0 { - break - } - if va&0x80000000 > 0 { // is Ordinal - // TODO add dynimport ordinal support. - //ord := va&0x0000FFFF - } else { - fn, _ := getString(*sectionData, int(va-ds.VirtualAddress+2)) - all = append(all, fn+":"+dt.DllName) - } - } - } - } - - return all, nil -} - -// ImportedLibraries returns the names of all libraries -// referred to by the binary f that are expected to be -// linked with the binary at dynamic link time. -func (f *File) ImportedLibraries() ([]string, error) { - ida, _, _, err := f.ImportDirectoryTable() - if err != nil { - return nil, err - } - var all []string - for _, dt := range ida { - all = append(all, dt.DllName) - } - return all, nil -} diff --git a/odiglet/pkg/allocator/debug/pe/net.go b/odiglet/pkg/allocator/debug/pe/net.go deleted file mode 100644 index 6ee7c71b22..0000000000 --- a/odiglet/pkg/allocator/debug/pe/net.go +++ /dev/null @@ -1,69 +0,0 @@ -package pe - -import ( - "encoding/binary" - "io" -) - -type IMAGE_COR20_HEADER struct { - Cb uint32 - MajorRuntimeVersion uint16 - MinorRuntimeVersion uint16 - MetaDataRVA, MetaDataSize uint32 - Flags uint32 //todo: define flags - EntryPointToken uint32 - ResourcesRVA, ResourcesSize, - StrongNameSignatureRVA, StrongNameSignatureSize, - CodeManagerTableRVA, CodeManagerTableSize, - VTableFixupsRVA, VTableFixupsSize, - ExportAddressTableJumpsRVA, ExportAddressTableJumpsSize, - ManagedNativeHeaderRVA, ManagedNativeHeaderSize uint32 -} - -// Net provides a public interface for getting at some net info. -type Net struct { - NetDirectory IMAGE_COR20_HEADER //Net directory information - MetaData NetMetaData //MetaData Header -} - -type NetMetaData struct { - Signature [4]byte //should be 0x424a4542 - MajorVersion uint16 - MinorVersion uint16 - Reserved uint32 - VersionLength uint32 - VersionString []byte - Flags uint16 //todo: define flags betterer - NumberOfStreams uint16 -} - -func newMetadataHeader(i io.Reader) (NetMetaData, error) { - r := NetMetaData{} - - //todo: error checks/sanity checks - binary.Read(i, binary.LittleEndian, &r.Signature) - binary.Read(i, binary.LittleEndian, &r.MajorVersion) - binary.Read(i, binary.LittleEndian, &r.MinorVersion) - binary.Read(i, binary.LittleEndian, &r.Reserved) - - // it appears that this value is terminated by two nulls.. that might be important at some point - binary.Read(i, binary.LittleEndian, &r.VersionLength) - r.VersionString = make([]byte, r.VersionLength) - i.Read(r.VersionString) - - binary.Read(i, binary.LittleEndian, r.Flags) - - return r, nil -} - -// NetCLRVersion returns the CLR version specified by the binary. Returns an empty string if not a net binary. String has had trailing nulls stripped. -func (f File) NetCLRVersion() string { - b := f.Net.MetaData.VersionString - for i, x := range b { - if x == 0x00 { - b = b[:i] - break - } - } - return string(b) -} diff --git a/odiglet/pkg/allocator/debug/pe/pe.go b/odiglet/pkg/allocator/debug/pe/pe.go deleted file mode 100644 index 6bfb19d5af..0000000000 --- a/odiglet/pkg/allocator/debug/pe/pe.go +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pe - -type DosHeader struct { - MZSignature uint16 - UsedBytesInTheLastPage uint16 - FileSizeInPages uint16 - NumberOfRelocationItems uint16 - HeaderSizeInParagraphs uint16 - MinimumExtraParagraphs uint16 - MaximumExtraParagraphs uint16 - InitialRelativeSS uint16 - InitialSP uint16 - CheckSum uint16 - InitialIP uint16 - InitialRelativeCS uint16 - AddressOfRelocationTable uint16 - OverlayNumber uint16 - Reserved [4]uint16 - OEMid uint16 - OEMinfo uint16 - Reserved2 [10]uint16 - AddressOfNewExeHeader uint32 -} - -type FileHeader struct { - Machine uint16 - NumberOfSections uint16 - TimeDateStamp uint32 - PointerToSymbolTable uint32 - NumberOfSymbols uint32 - SizeOfOptionalHeader uint16 - Characteristics uint16 -} - -type DataDirectory struct { - VirtualAddress uint32 - Size uint32 -} - -type OptionalHeader32 struct { - Magic uint16 - MajorLinkerVersion uint8 - MinorLinkerVersion uint8 - SizeOfCode uint32 - SizeOfInitializedData uint32 - SizeOfUninitializedData uint32 - AddressOfEntryPoint uint32 - BaseOfCode uint32 - BaseOfData uint32 - ImageBase uint32 - SectionAlignment uint32 - FileAlignment uint32 - MajorOperatingSystemVersion uint16 - MinorOperatingSystemVersion uint16 - MajorImageVersion uint16 - MinorImageVersion uint16 - MajorSubsystemVersion uint16 - MinorSubsystemVersion uint16 - Win32VersionValue uint32 - SizeOfImage uint32 - SizeOfHeaders uint32 - CheckSum uint32 - Subsystem uint16 - DllCharacteristics uint16 - SizeOfStackReserve uint32 - SizeOfStackCommit uint32 - SizeOfHeapReserve uint32 - SizeOfHeapCommit uint32 - LoaderFlags uint32 - NumberOfRvaAndSizes uint32 - DataDirectory [16]DataDirectory -} - -type OptionalHeader64 struct { - Magic uint16 - MajorLinkerVersion uint8 - MinorLinkerVersion uint8 - SizeOfCode uint32 - SizeOfInitializedData uint32 - SizeOfUninitializedData uint32 - AddressOfEntryPoint uint32 - BaseOfCode uint32 - ImageBase uint64 - SectionAlignment uint32 - FileAlignment uint32 - MajorOperatingSystemVersion uint16 - MinorOperatingSystemVersion uint16 - MajorImageVersion uint16 - MinorImageVersion uint16 - MajorSubsystemVersion uint16 - MinorSubsystemVersion uint16 - Win32VersionValue uint32 - SizeOfImage uint32 - SizeOfHeaders uint32 - CheckSum uint32 - Subsystem uint16 - DllCharacteristics uint16 - SizeOfStackReserve uint64 - SizeOfStackCommit uint64 - SizeOfHeapReserve uint64 - SizeOfHeapCommit uint64 - LoaderFlags uint32 - NumberOfRvaAndSizes uint32 - DataDirectory [16]DataDirectory -} - -const ( - IMAGE_FILE_MACHINE_UNKNOWN = 0x0 - IMAGE_FILE_MACHINE_AM33 = 0x1d3 - IMAGE_FILE_MACHINE_AMD64 = 0x8664 - IMAGE_FILE_MACHINE_ARM = 0x1c0 - IMAGE_FILE_MACHINE_ARMNT = 0x1c4 - IMAGE_FILE_MACHINE_ARM64 = 0xaa64 - IMAGE_FILE_MACHINE_EBC = 0xebc - IMAGE_FILE_MACHINE_I386 = 0x14c - IMAGE_FILE_MACHINE_IA64 = 0x200 - IMAGE_FILE_MACHINE_M32R = 0x9041 - IMAGE_FILE_MACHINE_MIPS16 = 0x266 - IMAGE_FILE_MACHINE_MIPSFPU = 0x366 - IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466 - IMAGE_FILE_MACHINE_POWERPC = 0x1f0 - IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1 - IMAGE_FILE_MACHINE_R4000 = 0x166 - IMAGE_FILE_MACHINE_SH3 = 0x1a2 - IMAGE_FILE_MACHINE_SH3DSP = 0x1a3 - IMAGE_FILE_MACHINE_SH4 = 0x1a6 - IMAGE_FILE_MACHINE_SH5 = 0x1a8 - IMAGE_FILE_MACHINE_THUMB = 0x1c2 - IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169 -) - -// IMAGE_DIRECTORY_ENTRY constants -const ( - IMAGE_DIRECTORY_ENTRY_EXPORT = 0 - IMAGE_DIRECTORY_ENTRY_IMPORT = 1 - IMAGE_DIRECTORY_ENTRY_RESOURCE = 2 - IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3 - IMAGE_DIRECTORY_ENTRY_SECURITY = 4 - IMAGE_DIRECTORY_ENTRY_BASERELOC = 5 - IMAGE_DIRECTORY_ENTRY_DEBUG = 6 - IMAGE_DIRECTORY_ENTRY_ARCHITECTURE = 7 - IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8 - IMAGE_DIRECTORY_ENTRY_TLS = 9 - IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10 - IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11 - IMAGE_DIRECTORY_ENTRY_IAT = 12 - IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = 13 - IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14 -) diff --git a/odiglet/pkg/allocator/debug/pe/reloc.go b/odiglet/pkg/allocator/debug/pe/reloc.go deleted file mode 100644 index e29ee8ecc9..0000000000 --- a/odiglet/pkg/allocator/debug/pe/reloc.go +++ /dev/null @@ -1,171 +0,0 @@ -package pe - -import ( - "bytes" - "encoding/binary" - "fmt" - "io" -) - -// RelocationTable - for base relocation entries -type RelocationTableEntry struct { - RelocationBlock - BlockItems []BlockItem -} - -// RelocationBlock - for base relocation entries -type RelocationBlock struct { - VirtualAddress uint32 - SizeOfBlock uint32 -} - -// BlockItem - relocation block item -type BlockItem struct { - Type byte // 4 bits - Offset uint16 // 12 bits -} - -// Reloc represents a PE COFF relocation. -// Each section contains its own relocation list. -type Reloc struct { - VirtualAddress uint32 - SymbolTableIndex uint32 - Type uint16 -} - -const ( - //IMAGE_REL_BASED_ABSOLUTE - The base relocation is skipped. This type can be used to pad a block. - IMAGE_REL_BASED_ABSOLUTE = 0 - - //IMAGE_REL_BASED_HIGH = 1 - //IMAGE_REL_BASED_LOW = 2 - - //IMAGE_REL_BASED_HIGHLOW - The base relocation applies all 32 bits of the difference to the 32-bit field at offset. - IMAGE_REL_BASED_HIGHLOW = 3 - - //IMAGE_REL_BASED_HIGHADJ = 4 - //IMAGE_REL_BASED_MIPS_JMPADDR = 5 - //IMAGE_REL_BASED_ARM_MOV32 = 5 - //IMAGE_REL_BASED_RISCV_HIGH20 = 5 - //IMAGE_REL_BASED_THUMB_MOV32 = 7 - //IMAGE_REL_BASED_RISCV_LOW12I = 7 - //IMAGE_REL_BASED_RISCV_LOW12S = 8 - //IMAGE_REL_BASED_MIPS_JMPADDR16 = 9 - IMAGE_REL_BASED_DIR64 = 10 -) - -// readBaseRelocationTable - reads the base relocation table from the file and stores it -func (f *File) readBaseRelocationTable() (*[]RelocationTableEntry, error) { - - if f.OptionalHeader == nil { // Optional header is optional, might not exist - return nil, nil - } - - var dd DataDirectory - if f.Machine == IMAGE_FILE_MACHINE_AMD64 { - dd = f.OptionalHeader.(*OptionalHeader64).DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC] - } else { - dd = f.OptionalHeader.(*OptionalHeader32).DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC] - } - var sectionData []byte - var err error - for _, section := range f.Sections { - if section.VirtualAddress == dd.VirtualAddress { - sectionData, err = section.Data() - if err != nil { - return nil, err - } - break - } - } - r := bytes.NewReader(sectionData) - var reloBlocks []RelocationTableEntry - bytesRead := uint32(0) - for bytesRead < dd.Size { - var reloBlock RelocationBlock - err = binary.Read(r, binary.LittleEndian, &reloBlock) - bytesRead += 8 - if err != nil { - return nil, fmt.Errorf("fail to read relocation block: %v", err) - } - numBlocks := (reloBlock.SizeOfBlock - 8) / 2 - blocks := make([]BlockItem, numBlocks) - for i := uint32(0); i < numBlocks; i++ { - var buf [2]byte - err = binary.Read(r, binary.LittleEndian, &buf) - bytesRead += 2 - if err != nil { - return nil, fmt.Errorf("fail to read relocation block item %d: %v", i, err) - } - var item BlockItem - val := binary.LittleEndian.Uint16(buf[:2]) - item.Type = byte(val >> 12) - item.Offset = val & 0x0fff - blocks[i] = item - } - reloBlocks = append(reloBlocks, RelocationTableEntry{reloBlock, blocks}) - } - return &reloBlocks, nil -} - -// Relocate - performs base relocations on this image to the given offset -func (f *File) Relocate(baseAddr uint64, image *[]byte) { - var imageBase uint64 - pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64 - if pe64 { - imageBase = f.OptionalHeader.(*OptionalHeader64).ImageBase - } else { - imageBase = uint64(f.OptionalHeader.(*OptionalHeader32).ImageBase) - } - for _, block := range *f.BaseRelocationTable { - pageRVA := block.VirtualAddress - for _, item := range block.BlockItems { - if item.Type == IMAGE_REL_BASED_HIGHLOW { // 32 bit - delta := uint32(baseAddr - imageBase) - fileOffset := f.RVAToFileOffset(pageRVA) - idx := fileOffset + uint32(item.Offset) - originalAddress := binary.LittleEndian.Uint32((*image)[idx : idx+4]) - b := make([]byte, 4) - binary.LittleEndian.PutUint32(b, originalAddress+delta) - copy((*image)[idx:idx+4], b) - } else if item.Type == IMAGE_REL_BASED_DIR64 { // 64 bit - delta := baseAddr - imageBase - fileOffset := f.RVAToFileOffset(pageRVA) - idx := fileOffset + uint32(item.Offset) - originalAddress := binary.LittleEndian.Uint64((*image)[idx : idx+8]) - b := make([]byte, 8) - binary.LittleEndian.PutUint64(b, originalAddress+delta) - copy((*image)[idx:idx+8], b) - } - } - } - - // update imageBase in the optional header - if pe64 { - b := make([]byte, 8) - binary.LittleEndian.PutUint64(b, baseAddr) - idx := f.OptionalHeaderOffset + 24 - copy((*image)[idx:idx+8], b) - } else { - b := make([]byte, 4) - binary.LittleEndian.PutUint32(b, uint32(baseAddr)) - idx := f.OptionalHeaderOffset + 28 - copy((*image)[idx:idx+4], b) - } -} - -func readRelocs(sh *SectionHeader, r io.ReadSeeker) ([]Reloc, error) { - if sh.NumberOfRelocations <= 0 { - return nil, nil - } - _, err := r.Seek(int64(sh.PointerToRelocations), seekStart) - if err != nil { - return nil, fmt.Errorf("fail to seek to %q section relocations: %v", sh.Name, err) - } - relocs := make([]Reloc, sh.NumberOfRelocations) - err = binary.Read(r, binary.LittleEndian, relocs) - if err != nil { - return nil, fmt.Errorf("fail to read section relocations: %v", err) - } - return relocs, nil -} diff --git a/odiglet/pkg/allocator/debug/pe/section.go b/odiglet/pkg/allocator/debug/pe/section.go deleted file mode 100644 index 50e703f1f2..0000000000 --- a/odiglet/pkg/allocator/debug/pe/section.go +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pe - -import ( - "io" - "strconv" -) - -// SectionHeader32 represents real PE COFF section header. -type SectionHeader32 struct { - Name [8]uint8 - VirtualSize uint32 - VirtualAddress uint32 - SizeOfRawData uint32 - PointerToRawData uint32 - PointerToRelocations uint32 - PointerToLineNumbers uint32 - NumberOfRelocations uint16 - NumberOfLineNumbers uint16 - Characteristics uint32 -} - -// fullName finds real name of section sh. Normally name is stored -// in sh.Name, but if it is longer then 8 characters, it is stored -// in COFF string table st instead. -func (sh *SectionHeader32) fullName(st StringTable) (string, error) { - if sh.Name[0] != '/' { - return cstring(sh.Name[:]), nil - } - i, err := strconv.Atoi(cstring(sh.Name[1:])) - if err != nil { - return "", err - } - return st.String(uint32(i)) -} - -// SectionHeader is similar to SectionHeader32 with Name -// field replaced by Go string. OriginalName is the -// original name of the section on disk. -type SectionHeader struct { - Name string - OriginalName [8]uint8 - VirtualSize uint32 - VirtualAddress uint32 - Size uint32 - Offset uint32 - PointerToRelocations uint32 - PointerToLineNumbers uint32 - NumberOfRelocations uint16 - NumberOfLineNumbers uint16 - Characteristics uint32 -} - -// Section provides access to PE COFF section. -type Section struct { - SectionHeader - Relocs []Reloc - - // Embed ReaderAt for ReadAt method. - // Do not embed SectionReader directly - // to avoid having Read and Seek. - // If a client wants Read and Seek it must use - // Open() to avoid fighting over the seek offset - // with other clients. - io.ReaderAt - sr *io.SectionReader -} - -// Data reads and returns the contents of the PE section s. -func (s *Section) Data() ([]byte, error) { - - if s.sr == nil { // This section was added from code, the internal SectionReader is nil - return nil, nil - } - - dat := make([]byte, s.sr.Size()) - n, err := s.sr.ReadAt(dat, 0) - if n == len(dat) { - err = nil - } - return dat[0:n], err -} - -// Open returns a new ReadSeeker reading the PE section s. -func (s *Section) Open() io.ReadSeeker { - return io.NewSectionReader(s.sr, 0, 1<<63-1) -} - -// Replace Section's Data -func (s *Section) Replace(reader io.ReaderAt, length int64) { - s.sr = io.NewSectionReader(reader, 0, length) - s.ReaderAt = s.sr -} - -// Section Flags (Characteristics field) -const ( - IMAGE_SCN_CNT_CODE = 0x00000020 // Section contains code - IMAGE_SCN_MEM_EXECUTE = 0x20000000 // Section is executable - IMAGE_SCN_MEM_READ = 0x40000000 // Section is readable - - IMAGE_FILE_RELOCS_STRIPPED = 0x0001 // Relocation info stripped from file - - IMAGE_DLLCHARACTERISTICS_NX_COMPAT = 0x0100 // Image is NX compatable - - IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE = 0x0040 // DLL can move -) diff --git a/odiglet/pkg/allocator/debug/pe/string.go b/odiglet/pkg/allocator/debug/pe/string.go deleted file mode 100644 index 1cefe68f2e..0000000000 --- a/odiglet/pkg/allocator/debug/pe/string.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pe - -import ( - "bytes" - "encoding/binary" - "fmt" - "io" -) - -// cstring converts ASCII byte sequence b to string. -// It stops once it finds 0 or reaches end of b. -func cstring(b []byte) string { - i := bytes.IndexByte(b, 0) - if i == -1 { - i = len(b) - } - return string(b[:i]) -} - -// StringTable is a COFF string table. -type StringTable []byte - -func readStringTable(fh *FileHeader, r io.ReadSeeker) (StringTable, error) { - // COFF string table is located right after COFF symbol table. - if fh.PointerToSymbolTable <= 0 { - return nil, nil - } - offset := fh.PointerToSymbolTable + COFFSymbolSize*fh.NumberOfSymbols - _, err := r.Seek(int64(offset), seekStart) - if err != nil { - return nil, fmt.Errorf("fail to seek to string table: %v", err) - } - var l uint32 - err = binary.Read(r, binary.LittleEndian, &l) - if err != nil { - return nil, fmt.Errorf("fail to read string table length: %v", err) - } - // string table length includes itself - if l <= 4 { - return nil, nil - } - l -= 4 - buf := make([]byte, l) - _, err = io.ReadFull(r, buf) - if err != nil { - return nil, fmt.Errorf("fail to read string table: %v", err) - } - // re-add the length to the first four bytes of the string table - lbuf := make([]byte, 4) - binary.LittleEndian.PutUint32(lbuf, l) - - return StringTable(append(lbuf, buf...)), nil -} - -// String extracts string from COFF string table st at offset start. -func (st StringTable) String(start uint32) (string, error) { - // start includes 4 bytes of string table length - if start < 4 { - return "", fmt.Errorf("offset %d is before the start of string table", start) - } - //start -= 4 // we are now including the uint32 length in the StringTable buffer as a prefix, this might change - if int(start) > len(st) { - return "", fmt.Errorf("offset %d is beyond the end of string table", start) - } - return cstring(st[start:]), nil -} diff --git a/odiglet/pkg/allocator/debug/pe/symbol.go b/odiglet/pkg/allocator/debug/pe/symbol.go deleted file mode 100644 index 7fa5948641..0000000000 --- a/odiglet/pkg/allocator/debug/pe/symbol.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pe - -import ( - "encoding/binary" - "fmt" - "io" -) - -const COFFSymbolSize = 18 - -// COFFSymbol represents single COFF symbol table record. -type COFFSymbol struct { - Name [8]uint8 - Value uint32 - SectionNumber int16 - Type uint16 - StorageClass uint8 - NumberOfAuxSymbols uint8 -} - -func readCOFFSymbols(fh *FileHeader, r io.ReadSeeker) ([]COFFSymbol, error) { - if fh.PointerToSymbolTable == 0 { - return nil, nil - } - if fh.NumberOfSymbols <= 0 { - return nil, nil - } - _, err := r.Seek(int64(fh.PointerToSymbolTable), seekStart) - if err != nil { - return nil, fmt.Errorf("fail to seek to symbol table: %v", err) - } - syms := make([]COFFSymbol, fh.NumberOfSymbols) - err = binary.Read(r, binary.LittleEndian, syms) - if err != nil { - return nil, fmt.Errorf("fail to read symbol table: %v", err) - } - return syms, nil -} - -// isSymNameOffset checks symbol name if it is encoded as offset into string table. -func isSymNameOffset(name [8]byte) (bool, uint32) { - if name[0] == 0 && name[1] == 0 && name[2] == 0 && name[3] == 0 { - return true, binary.LittleEndian.Uint32(name[4:]) - } - return false, 0 -} - -// FullName finds real name of symbol sym. Normally name is stored -// in sym.Name, but if it is longer then 8 characters, it is stored -// in COFF string table st instead. -func (sym *COFFSymbol) FullName(st StringTable) (string, error) { - if ok, offset := isSymNameOffset(sym.Name); ok { - return st.String(offset) - } - return cstring(sym.Name[:]), nil -} - -func removeAuxSymbols(allsyms []COFFSymbol, st StringTable) ([]*Symbol, error) { - if len(allsyms) == 0 { - return nil, nil - } - syms := make([]*Symbol, 0) - aux := uint8(0) - for _, sym := range allsyms { - if aux > 0 { - aux-- - continue - } - name, err := sym.FullName(st) - if err != nil { - return nil, err - } - aux = sym.NumberOfAuxSymbols - s := &Symbol{ - Name: name, - Value: sym.Value, - SectionNumber: sym.SectionNumber, - Type: sym.Type, - StorageClass: sym.StorageClass, - } - syms = append(syms, s) - } - return syms, nil -} - -// Symbol is similar to COFFSymbol with Name field replaced -// by Go string. Symbol also does not have NumberOfAuxSymbols. -type Symbol struct { - Name string - Value uint32 - SectionNumber int16 - Type uint16 - StorageClass uint8 -} diff --git a/odiglet/pkg/allocator/debug/pe/testdata/gcc-386-mingw-exec b/odiglet/pkg/allocator/debug/pe/testdata/gcc-386-mingw-exec deleted file mode 100644 index 4b808d043200a8cc10fb5038fe51b70ad6630765..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29941 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 Q5`5|q+b;CMm#GW>2}%E~IRF3v diff --git a/odiglet/pkg/allocator/debug/pe/testdata/gcc-386-mingw-obj b/odiglet/pkg/allocator/debug/pe/testdata/gcc-386-mingw-obj deleted file mode 100644 index 0c84d898d5eee045c703a500883f97d0bdee113c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2372 zcmcgtO>Epm6nz4pv<&iEyA`vSP{lKe`s7r2Y{9Bv!hC5=eKT$vCCs;pZm7tY6;yW9Rq3cmAsU2>|`1aeXP4zhUX;d;9zQVp=?@ zR}ED^p-+p)L>5Zh2sD=U@y+5cC3I! zt7Qp$s@$k@uWRU47ot(+PL9oE?1_amVzvA{Z_Uq8CAqMgc;&Ur<|T8%TD0mUHtoT{ zx4Pu4H2tCNh5jh$+D*rAhC#PEe9LL}?9Rw(4((=Shf!K#9)(HKN+U0H9nbEWt{0J_ zl)_Cvh|IiI6uX=4fYg@jcSe0Ol@CrKA+0rx0#bHZR?a}}at|M#iB(N&b=sj#%C23JEYu}{xWoT0RKl)uOJ*_aQDg`X_`S7qkib#BxO%p=CoF{HSBxsEd+inJ3dJT z?Y(#^1)f3i<;KQKq};vDCcQB5J;#h$JUvYsjCNv@P8r=e3AsbwXf2StF1z>!-gtJoHay{q9#S68L>(wl)HgG#Nr`t`< zaWUDEey-OYjC$y9TwwHt`nkTfDNk%6-VU?-SH8WXC>Slqoi}gz!Jr2$@$r2C5+rWv zWlg(-Oir>Rp?UmYoYHrd^~u839|1`0oU}rb#(%!zAnWp~V|k>TuyHJ7@QdkjaJf7A z61s*KuO|CW=UiNrWDoJO#-(BuCzfn)R%7Bp#)RV(-wQJ|4e2;qk!Hb9q0K<%>JS;U z0nW)5>Gf241JWd#K^}&b-XN8(L&C9xH%KGqAn`axoR^H?F^sr9Oyb3sI4j=NP(k+} z5IN}yl{V(Bbai-tn3#F?twBPhih1S?PAU7&@LH)1JVe}coKem2-PR~12!de26O9VOdO-RWu)n|jrykjT25#&lyq@&# zCF@P@cP}ZKGq=uOQ(HZ|wrrlgylnpbYL9(pg}v50-#&M~-7#U3eO~pfiXo|~y|Xy! zVy7U?dZ4c`;o8q936CcT-zN$}m+)&L*=+77{02yb*iR5T(*e_{PyzkX!)CqR6txP7 z(61Oh0ge9E7S=C8u(M>nECm^n7>G;J@j3;eF-Z@yzpDk|Nn+0b@y{e=p98n#kRW98 zCY~c(7~-i|gsQs2>!_@7-UE*&zf%u|NMPRgjqLo{pf#Qh3{;?R&<9dQlO zXvAZ~QyYhbV1ZCtFr-GuV|`qWM8dxZPu#CS$SoMMNXKg+UaY}Gc=dSVehhDBT^%K* z(RhU@^wVFxP#PLCSEt8#-3grDcpf+#7xY3y3MZCODzOEEq4$^i6Zb0+3PM9XRjgi_ zrJHoThvSeCM1Mn9594Xn{xskbe3Ykg0RD}>IxnBa=H~&&j%O&I-}l5z8-4XPc`R|q zV1QB##t^`FfE)KK5P&yqI7=xS3D5|<8v)Op18?|s3~zlVKnL(H1RMbv_d|b2UwvIJ zOTm-@Uyx7ZGO;Hf>K&oCuYlSw0C^bTlyl(a4`uXfXdDVaECui(BHsO@esstF8~VS2 z11**8H$)uhXWfx~M@OjEewg77HFY3>J80Ej69hS!v7dp|odAmUa~83FOh9pD*|kUo zCGVoRZ_9|5IC|N6p~~f>e*1MaT69~R^%G!_D7G5~^sL@lI7ed3b zTQ*RYniF&)YsGUZd|G4+;#X0uO0=fo)XaLZmcG zC6lL4nItbiN;=J<4*2L*Dz_mOF*#V0Wp@S+%F2h|$}fw77I2_KRxN{Q=F93dTVAM3 z7XLn=KlK?b8ZPIzi2iZFlGRb!yFlkeB#EV6hqMhECUf*dS?OYhK5t@$yq~DnT?pnK z^qn$^{!4+VT0=+(ghW57vo`DAzv%;}T3_baW}_Ku2O^3!8-3J1!{})%&!gOoh4)cEb%WL1cq*XZBv85!8-8O(-N_JvI1+O+yJ_N9j< zrCsuMnd;A6Dv6Hv$mim~dbCLZeo7o#*9k|~bQ7BJ@1q!f#rnq(OdwK$vXb#`^o3 zAdGJR4a`wfCs0I5bF0={SaQZ_!kj#dP1u_eR;&g1>kMoY{q3OTP_3CP9`Yt@^HHB_ zwIePs-$D|1`<*lHkfyg(#^%4c&XH9bP9|9v2RaD*A8!l7o9GuC`oO<1DjNnOrd`2k zJ&IhCiNH~0(0mGJY&Zz=!PI8}v{WFqS?>ap8D+w4K$4YR(Tx5(5xbgV!Hk!5{D%PA ztOY=&%CtRYz-RzQ-m&oKKSrZU6Kjvwg7n7j_CjA}w^^TgnV0&wFN(hSJtkHoo9*~Z z`S&BAe%f1<-_Ro;VwLGTli)djJ=M(0q4T;v)RHqG5wY|}%vDhIjXM7>bjj1Z&Dx6s zDCRq3_MGQC19cI@zWvS?=z{^L4-h|wA19Fit*28~6G+C*(GJLf4N2Z(@kO-X!E}mj zI-=H}ks0wU3jG1LtOVVzz3;19VYXR+>fs0F0a**vR}eyj>xD-5cIrY3=FXK_KgC=fd3buh!3tJL=1kt=zpAoP-!9WJ7`EUV%jad zA)+4)Ahjm?mm`~*t%2^~p!;583RgLa71FI7{<|Ge4vyMO znkDD!$TgUM);oYBwOT$(Qbz7mN2e%>38QVUVERX-f#sYd$`qS2#v=P#u`YaP_gn+v z)D~a~KocNB-pw+x>QB#q#(T>*85>p`P`axFvV$P{% zrD^%6$hR*)U068QF8WsjkBRPrv0U&5qs!t0dnuhs!W~Q!ME~bVVf|IDr(e+dF_z|@ zZ%g*=cVhM%`bnPwuFb?bV+QP-jsk3<{t>Cf$_={YcdSQaFtdmTm**3sEl}QbkQ_P0 z<^##M=R@(qXQ@df+n()AuEhZHz>sZktcs9ch3KD%Y%bf8Ct~u+rj+MFHl4)45a5K1 z@h6sVNPJd|pwA#^B7!7c(T;E-!c1QCPJ}b!%j@#Kfy?_&$Y1z^_mlJ+@9nED$I#{`*8+NXdN{vejdgu8*#nve!X1pPD(I@k&sB*qRtE~fdj>Oo#% zs<0$0`?%P*Br8`AB97qntP%L@$SR0-(26weC-%0Ix&guz9*jC-^0P?H@njWAnbve{(T=TpJF!1=Y_;F{Znidz7iJHBDc6lF(Oluo+~iuUZbeB�itgmm?lVs%pdaM;AL;DPAarS~VMVcJb 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

Js3LxhqvBHD_y@_@%5}RSk@riaW5}Rr1`G7eW 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�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�`-uI)TM&%!z}O%aVQN1HgSFHVof?q=1*p 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 HX`rfq)vQIg diff --git a/odiglet/pkg/allocator/debug/pe/testdata/hello.c b/odiglet/pkg/allocator/debug/pe/testdata/hello.c deleted file mode 100644 index a689d3644e..0000000000 --- a/odiglet/pkg/allocator/debug/pe/testdata/hello.c +++ /dev/null @@ -1,8 +0,0 @@ -#include - -int -main(void) -{ - printf("hello, world\n"); - return 0; -} diff --git a/odiglet/pkg/allocator/debug/pe/write.go b/odiglet/pkg/allocator/debug/pe/write.go deleted file mode 100644 index aa0b6e8dd3..0000000000 --- a/odiglet/pkg/allocator/debug/pe/write.go +++ /dev/null @@ -1,195 +0,0 @@ -package pe - -import ( - "bytes" - "encoding/binary" - "errors" - "os" -) - -func (peFile *File) Bytes() ([]byte, error) { - var bytesWritten uint64 - peBuf := bytes.NewBuffer(nil) - - // write DOS header and stub - binary.Write(peBuf, binary.LittleEndian, peFile.DosHeader) - bytesWritten += uint64(binary.Size(peFile.DosHeader)) - if peFile.DosExists { - binary.Write(peBuf, binary.LittleEndian, peFile.DosStub) - bytesWritten += uint64(binary.Size(peFile.DosStub)) - } - - // write Rich header - if peFile.RichHeader != nil { - binary.Write(peBuf, binary.LittleEndian, peFile.RichHeader) - bytesWritten += uint64(len(peFile.RichHeader)) - } - - // apply padding before PE header if necessary - if uint32(bytesWritten) != peFile.DosHeader.AddressOfNewExeHeader { - padding := make([]byte, peFile.DosHeader.AddressOfNewExeHeader-uint32(bytesWritten)) - binary.Write(peBuf, binary.LittleEndian, padding) - bytesWritten += uint64(len(padding)) - } - - // write PE header - peMagic := []byte{'P', 'E', 0x00, 0x00} - binary.Write(peBuf, binary.LittleEndian, peMagic) - binary.Write(peBuf, binary.LittleEndian, peFile.FileHeader) - bytesWritten += uint64(binary.Size(peFile.FileHeader) + len(peMagic)) - - var ( - is32bit bool - oldCertTableOffset, oldCertTableSize uint32 - ) - - switch peFile.FileHeader.Machine { - case IMAGE_FILE_MACHINE_I386: - is32bit = true - optionalHeader := peFile.OptionalHeader.(*OptionalHeader32) - binary.Write(peBuf, binary.LittleEndian, peFile.OptionalHeader.(*OptionalHeader32)) - bytesWritten += uint64(binary.Size(optionalHeader)) - - oldCertTableOffset = optionalHeader.DataDirectory[CERTIFICATE_TABLE].VirtualAddress - oldCertTableSize = optionalHeader.DataDirectory[CERTIFICATE_TABLE].Size - case IMAGE_FILE_MACHINE_AMD64: - is32bit = false - optionalHeader := peFile.OptionalHeader.(*OptionalHeader64) - binary.Write(peBuf, binary.LittleEndian, optionalHeader) - bytesWritten += uint64(binary.Size(optionalHeader)) - - oldCertTableOffset = optionalHeader.DataDirectory[CERTIFICATE_TABLE].VirtualAddress - oldCertTableSize = optionalHeader.DataDirectory[CERTIFICATE_TABLE].Size - default: - return nil, errors.New("architecture not supported") - } - - // write section headers - sectionHeaders := make([]SectionHeader32, len(peFile.Sections)) - for idx, section := range peFile.Sections { - // write section header - sectionHeader := SectionHeader32{ - Name: section.OriginalName, - VirtualSize: section.VirtualSize, - VirtualAddress: section.VirtualAddress, - SizeOfRawData: section.Size, - PointerToRawData: section.Offset, - PointerToRelocations: section.PointerToRelocations, - PointerToLineNumbers: section.PointerToLineNumbers, - NumberOfRelocations: section.NumberOfRelocations, - NumberOfLineNumbers: section.NumberOfLineNumbers, - Characteristics: section.Characteristics, - } - - // if the PE file was pulled from memory, the symbol table offset in the header will be wrong. - // Fix it up by picking the section that lines up, and use the raw offset instead. - if peFile.FileHeader.PointerToSymbolTable == sectionHeader.VirtualAddress { - peFile.FileHeader.PointerToSymbolTable = sectionHeader.PointerToRawData - } - - sectionHeaders[idx] = sectionHeader - - //log.Printf("section: %+v\nsectionHeader: %+v\n", section, sectionHeader) - - binary.Write(peBuf, binary.LittleEndian, sectionHeader) - bytesWritten += uint64(binary.Size(sectionHeader)) - } - - // write sections' data - for idx, sectionHeader := range sectionHeaders { - section := peFile.Sections[idx] - sectionData, err := section.Data() - if err != nil { - return nil, err - } - if sectionData == nil { // for sections that weren't in the original file - sectionData = []byte{} - } - if section.Offset != 0 && bytesWritten < uint64(section.Offset) { - pad := make([]byte, uint64(section.Offset)-bytesWritten) - peBuf.Write(pad) - //log.Printf("Padding before section %s at %x: length:%x to:%x\n", section.Name, bytesWritten, len(pad), section.Offset) - bytesWritten += uint64(len(pad)) - } - // if our shellcode insertion address is inside this section, insert it at the correct offset in sectionData - if peFile.InsertionAddr >= section.Offset && int64(peFile.InsertionAddr) < (int64(section.Offset)+int64(section.Size)-int64(len(peFile.InsertionBytes))) { - sectionData = append(sectionData, peFile.InsertionBytes[:]...) - datalen := len(sectionData) - if sectionHeader.SizeOfRawData > uint32(datalen) { - paddingSize := sectionHeader.SizeOfRawData - uint32(datalen) - padding := make([]byte, paddingSize, paddingSize) - sectionData = append(sectionData, padding...) - //log.Printf("Padding after section %s: length:%d\n", section.Name, paddingSize) - } - } - - binary.Write(peBuf, binary.LittleEndian, sectionData) - bytesWritten += uint64(len(sectionData)) - } - - // write symbols - binary.Write(peBuf, binary.LittleEndian, peFile.COFFSymbols) - bytesWritten += uint64(binary.Size(peFile.COFFSymbols)) - - // write the string table - binary.Write(peBuf, binary.LittleEndian, peFile.StringTable) - bytesWritten += uint64(binary.Size(peFile.StringTable)) - - var newCertTableOffset, newCertTableSize uint32 - - // write the certificate table - if peFile.CertificateTable != nil { - newCertTableOffset = uint32(bytesWritten) - newCertTableSize = uint32(len(peFile.CertificateTable)) - } else { - newCertTableOffset = 0 - newCertTableSize = 0 - } - - binary.Write(peBuf, binary.LittleEndian, peFile.CertificateTable) - bytesWritten += uint64(len(peFile.CertificateTable)) - - peData := peBuf.Bytes() - - // write the offset and size of the new Certificate Table if it changed - if newCertTableOffset != oldCertTableOffset || newCertTableSize != oldCertTableSize { - certTableInfo := &DataDirectory{ - VirtualAddress: newCertTableOffset, - Size: newCertTableSize, - } - - var certTableInfoBuf bytes.Buffer - binary.Write(&certTableInfoBuf, binary.LittleEndian, certTableInfo) - - var certTableLoc int64 - if is32bit { - certTableLoc = int64(peFile.DosHeader.AddressOfNewExeHeader) + 24 + 128 - } else { - certTableLoc = int64(peFile.DosHeader.AddressOfNewExeHeader) + 24 + 144 - } - - peData = append(peData[:certTableLoc], append(certTableInfoBuf.Bytes(), peData[int(certTableLoc)+binary.Size(certTableInfo):]...)...) - } - - return peData, nil -} - -func (peFile *File) WriteFile(destFile string) error { - f, err := os.Create(destFile) - if err != nil { - return err - } - defer f.Close() - - peData, err := peFile.Bytes() - if err != nil { - return err - } - - _, err = f.Write(peData) - if err != nil { - return err - } - - return nil -} diff --git a/odiglet/pkg/allocator/debug/plan9obj/file.go b/odiglet/pkg/allocator/debug/plan9obj/file.go deleted file mode 100644 index 314608da61..0000000000 --- a/odiglet/pkg/allocator/debug/plan9obj/file.go +++ /dev/null @@ -1,328 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package plan9obj implements access to Plan 9 a.out object files. -package plan9obj - -import ( - "encoding/binary" - "errors" - "fmt" - "io" - "os" -) - -// A FileHeader represents a Plan 9 a.out file header. -type FileHeader struct { - Magic uint32 - Bss uint32 - Entry uint64 - PtrSize int - LoadAddress uint64 - HdrSize uint64 -} - -// A File represents an open Plan 9 a.out file. -type File struct { - FileHeader - Sections []*Section - closer io.Closer -} - -// A SectionHeader represents a single Plan 9 a.out section header. -// This structure doesn't exist on-disk, but eases navigation -// through the object file. -type SectionHeader struct { - Name string - Size uint32 - Offset uint32 -} - -// A Section represents a single section in a Plan 9 a.out file. -type Section struct { - SectionHeader - - // Embed ReaderAt for ReadAt method. - // Do not embed SectionReader directly - // to avoid having Read and Seek. - // If a client wants Read and Seek it must use - // Open() to avoid fighting over the seek offset - // with other clients. - io.ReaderAt - sr *io.SectionReader -} - -// Data reads and returns the contents of the Plan 9 a.out section. -func (s *Section) Data() ([]byte, error) { - dat := make([]byte, s.sr.Size()) - n, err := s.sr.ReadAt(dat, 0) - if n == len(dat) { - err = nil - } - return dat[0:n], err -} - -// Open returns a new ReadSeeker reading the Plan 9 a.out section. -func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) } - -// A Symbol represents an entry in a Plan 9 a.out symbol table section. -type Sym struct { - Value uint64 - Type rune - Name string -} - -/* - * Plan 9 a.out reader - */ - -// formatError is returned by some operations if the data does -// not have the correct format for an object file. -type formatError struct { - off int - msg string - val interface{} -} - -func (e *formatError) Error() string { - msg := e.msg - if e.val != nil { - msg += fmt.Sprintf(" '%v'", e.val) - } - msg += fmt.Sprintf(" in record at byte %#x", e.off) - return msg -} - -// Open opens the named file using os.Open and prepares it for use as a Plan 9 a.out binary. -func Open(name string) (*File, error) { - f, err := os.Open(name) - if err != nil { - return nil, err - } - ff, err := NewFile(f) - if err != nil { - f.Close() - return nil, err - } - ff.closer = f - return ff, nil -} - -// Close closes the File. -// If the File was created using NewFile directly instead of Open, -// Close has no effect. -func (f *File) Close() error { - var err error - if f.closer != nil { - err = f.closer.Close() - f.closer = nil - } - return err -} - -func parseMagic(magic []byte) (uint32, error) { - m := binary.BigEndian.Uint32(magic) - switch m { - case Magic386, MagicAMD64, MagicARM: - return m, nil - } - return 0, &formatError{0, "bad magic number", magic} -} - -// NewFile creates a new File for accessing a Plan 9 binary in an underlying reader. -// The Plan 9 binary is expected to start at position 0 in the ReaderAt. -func NewFile(r io.ReaderAt) (*File, error) { - sr := io.NewSectionReader(r, 0, 1<<63-1) - // Read and decode Plan 9 magic - var magic [4]byte - if _, err := r.ReadAt(magic[:], 0); err != nil { - return nil, err - } - _, err := parseMagic(magic[:]) - if err != nil { - return nil, err - } - - ph := new(prog) - if err := binary.Read(sr, binary.BigEndian, ph); err != nil { - return nil, err - } - - f := &File{FileHeader: FileHeader{ - Magic: ph.Magic, - Bss: ph.Bss, - Entry: uint64(ph.Entry), - PtrSize: 4, - LoadAddress: 0x1000, - HdrSize: 4 * 8, - }} - - if ph.Magic&Magic64 != 0 { - if err := binary.Read(sr, binary.BigEndian, &f.Entry); err != nil { - return nil, err - } - f.PtrSize = 8 - f.LoadAddress = 0x200000 - f.HdrSize += 8 - } - - var sects = []struct { - name string - size uint32 - }{ - {"text", ph.Text}, - {"data", ph.Data}, - {"syms", ph.Syms}, - {"spsz", ph.Spsz}, - {"pcsz", ph.Pcsz}, - } - - f.Sections = make([]*Section, 5) - - off := uint32(f.HdrSize) - - for i, sect := range sects { - s := new(Section) - s.SectionHeader = SectionHeader{ - Name: sect.name, - Size: sect.size, - Offset: off, - } - off += sect.size - s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Size)) - s.ReaderAt = s.sr - f.Sections[i] = s - } - - return f, nil -} - -func walksymtab(data []byte, ptrsz int, fn func(sym) error) error { - var order binary.ByteOrder = binary.BigEndian - var s sym - p := data - for len(p) >= 4 { - // Symbol type, value. - if len(p) < ptrsz { - return &formatError{len(data), "unexpected EOF", nil} - } - // fixed-width value - if ptrsz == 8 { - s.value = order.Uint64(p[0:8]) - p = p[8:] - } else { - s.value = uint64(order.Uint32(p[0:4])) - p = p[4:] - } - - var typ byte - typ = p[0] & 0x7F - s.typ = typ - p = p[1:] - - // Name. - var i int - var nnul int - for i = 0; i < len(p); i++ { - if p[i] == 0 { - nnul = 1 - break - } - } - switch typ { - case 'z', 'Z': - p = p[i+nnul:] - for i = 0; i+2 <= len(p); i += 2 { - if p[i] == 0 && p[i+1] == 0 { - nnul = 2 - break - } - } - } - if len(p) < i+nnul { - return &formatError{len(data), "unexpected EOF", nil} - } - s.name = p[0:i] - i += nnul - p = p[i:] - - fn(s) - } - return nil -} - -// NewTable decodes the Go symbol table in data, -// returning an in-memory representation. -func newTable(symtab []byte, ptrsz int) ([]Sym, error) { - var n int - err := walksymtab(symtab, ptrsz, func(s sym) error { - n++ - return nil - }) - if err != nil { - return nil, err - } - - fname := make(map[uint16]string) - syms := make([]Sym, 0, n) - err = walksymtab(symtab, ptrsz, func(s sym) error { - n := len(syms) - syms = syms[0 : n+1] - ts := &syms[n] - ts.Type = rune(s.typ) - ts.Value = s.value - switch s.typ { - default: - ts.Name = string(s.name) - case 'z', 'Z': - for i := 0; i < len(s.name); i += 2 { - eltIdx := binary.BigEndian.Uint16(s.name[i : i+2]) - elt, ok := fname[eltIdx] - if !ok { - return &formatError{-1, "bad filename code", eltIdx} - } - if n := len(ts.Name); n > 0 && ts.Name[n-1] != '/' { - ts.Name += "/" - } - ts.Name += elt - } - } - switch s.typ { - case 'f': - fname[uint16(s.value)] = ts.Name - } - return nil - }) - if err != nil { - return nil, err - } - - return syms, nil -} - -// Symbols returns the symbol table for f. -func (f *File) Symbols() ([]Sym, error) { - symtabSection := f.Section("syms") - if symtabSection == nil { - return nil, errors.New("no symbol section") - } - - symtab, err := symtabSection.Data() - if err != nil { - return nil, errors.New("cannot load symbol section") - } - - return newTable(symtab, f.PtrSize) -} - -// Section returns a section with the given name, or nil if no such -// section exists. -func (f *File) Section(name string) *Section { - for _, s := range f.Sections { - if s.Name == name { - return s - } - } - return nil -} diff --git a/odiglet/pkg/allocator/debug/plan9obj/file_test.go b/odiglet/pkg/allocator/debug/plan9obj/file_test.go deleted file mode 100644 index 7e107bca2f..0000000000 --- a/odiglet/pkg/allocator/debug/plan9obj/file_test.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package plan9obj - -import ( - "reflect" - "testing" -) - -type fileTest struct { - file string - hdr FileHeader - sections []*SectionHeader -} - -var fileTests = []fileTest{ - { - "testdata/386-plan9-exec", - FileHeader{Magic386, 0x324, 0x14, 4, 0x1000, 32}, - []*SectionHeader{ - {"text", 0x4c5f, 0x20}, - {"data", 0x94c, 0x4c7f}, - {"syms", 0x2c2b, 0x55cb}, - {"spsz", 0x0, 0x81f6}, - {"pcsz", 0xf7a, 0x81f6}, - }, - }, - { - "testdata/amd64-plan9-exec", - FileHeader{MagicAMD64, 0x618, 0x13, 8, 0x200000, 40}, - []*SectionHeader{ - {"text", 0x4213, 0x28}, - {"data", 0xa80, 0x423b}, - {"syms", 0x2c8c, 0x4cbb}, - {"spsz", 0x0, 0x7947}, - {"pcsz", 0xca0, 0x7947}, - }, - }, -} - -func TestOpen(t *testing.T) { - for i := range fileTests { - tt := &fileTests[i] - - f, err := Open(tt.file) - if err != nil { - t.Error(err) - continue - } - if !reflect.DeepEqual(f.FileHeader, tt.hdr) { - t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr) - continue - } - - for i, sh := range f.Sections { - if i >= len(tt.sections) { - break - } - have := &sh.SectionHeader - want := tt.sections[i] - if !reflect.DeepEqual(have, want) { - t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want) - } - } - tn := len(tt.sections) - fn := len(f.Sections) - if tn != fn { - t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn) - } - } -} - -func TestOpenFailure(t *testing.T) { - filename := "file.go" // not a Plan 9 a.out file - _, err := Open(filename) // don't crash - if err == nil { - t.Errorf("open %s: succeeded unexpectedly", filename) - } -} diff --git a/odiglet/pkg/allocator/debug/plan9obj/plan9obj.go b/odiglet/pkg/allocator/debug/plan9obj/plan9obj.go deleted file mode 100644 index 7a194514c2..0000000000 --- a/odiglet/pkg/allocator/debug/plan9obj/plan9obj.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* - * Plan 9 a.out constants and data structures - */ - -package plan9obj - -// Plan 9 Program header. -type prog struct { - Magic uint32 /* magic number */ - Text uint32 /* size of text segment */ - Data uint32 /* size of initialized data */ - Bss uint32 /* size of uninitialized data */ - Syms uint32 /* size of symbol table */ - Entry uint32 /* entry point */ - Spsz uint32 /* size of pc/sp offset table */ - Pcsz uint32 /* size of pc/line number table */ -} - -// Plan 9 symbol table entries. -type sym struct { - value uint64 - typ byte - name []byte -} - -const ( - Magic64 = 0x8000 // 64-bit expanded header - - Magic386 = (4*11+0)*11 + 7 - MagicAMD64 = (4*26+0)*26 + 7 + Magic64 - MagicARM = (4*20+0)*20 + 7 -) diff --git a/odiglet/pkg/allocator/debug/plan9obj/testdata/386-plan9-exec b/odiglet/pkg/allocator/debug/plan9obj/testdata/386-plan9-exec deleted file mode 100644 index 748e83f8e6acc310edc5081a27d989c63f0eb2de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37232 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

Y)F+f*6M$||H$)p@hh?u|@d*UGPA5sgqKdoGS> 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 S=qDPNM3&i=eclVzoc|w+l~vRL diff --git a/odiglet/pkg/allocator/debug/plan9obj/testdata/amd64-plan9-exec b/odiglet/pkg/allocator/debug/plan9obj/testdata/amd64-plan9-exec deleted file mode 100644 index 3e257dd8ffc00ca4a19d9552a10d782134387e8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34279 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 diff --git a/odiglet/pkg/allocator/debug/plan9obj/testdata/hello.c b/odiglet/pkg/allocator/debug/plan9obj/testdata/hello.c deleted file mode 100644 index c0d633e29f..0000000000 --- a/odiglet/pkg/allocator/debug/plan9obj/testdata/hello.c +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include - -void -main(void) -{ - print("hello, world\n"); -} diff --git a/odiglet/pkg/allocator/fix.go b/odiglet/pkg/allocator/fix.go deleted file mode 100644 index f7df5d2707..0000000000 --- a/odiglet/pkg/allocator/fix.go +++ /dev/null @@ -1,22 +0,0 @@ -package allocator - -import ( - "github.com/keyval-dev/odigos/odiglet/pkg/allocator/debug/elf" -) - -// Fix section table offset -// Go binaries place the section table header at the begging of the file (after the segments table) -// Allocator moves the section table to the end of the file and therefore the file header need to be patched -// The shoff field in the header points to the old location (start of the file) we change it to point to the new location -// (end of file) 40 - 48 is the relevant bytes in the header (fixed for 64bit, other values for 32bit) -func applyFixForGoBinaries(f *elf.File, shoff uint64, output []byte) []byte { - b := make([]byte, 8) - f.ByteOrder.PutUint64(b, shoff) - j := 0 - for i := 40; i < 48; i++ { - output[i] = b[j] - j++ - } - - return output -} diff --git a/odiglet/pkg/allocator/payload/mmap.asm b/odiglet/pkg/allocator/payload/mmap.asm deleted file mode 100644 index 520bf9b9e3..0000000000 --- a/odiglet/pkg/allocator/payload/mmap.asm +++ /dev/null @@ -1,9 +0,0 @@ -[BITS 64] -mov r8, -1 ; annonymous fd -mov rax, 9 ; mmap number -mov rdi, 0 ; operating system will choose mapping destination -mov rsi, 12582912 ; page size -mov rdx, 0x7 ; PROT_READ|PROT_WRITE|PROT_EXEC -mov r10, 0x8022 ; MAP_PRIVATE|MAP_ANON|MAP_POPULATE -mov r9, 0 ; offset inside test.txt -syscall ; now rax will point to mapped location \ No newline at end of file diff --git a/odiglet/pkg/containers/container.go b/odiglet/pkg/containers/container.go deleted file mode 100644 index 3072624d95..0000000000 --- a/odiglet/pkg/containers/container.go +++ /dev/null @@ -1,89 +0,0 @@ -package containers - -import ( - "context" - "errors" - "github.com/keyval-dev/odigos/odiglet/pkg/log" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/kubernetes" - "strings" - "time" -) - -type ContainerID struct { - Runtime string - ID string -} - -func newContainerID(str string) (*ContainerID, error) { - parts := strings.Split(str, "://") - if len(parts) != 2 { - return nil, errors.New("invalid container id") - } - - return &ContainerID{ - Runtime: parts[0], - ID: parts[1], - }, nil -} - -func FindIDs(ctx context.Context, podName string, podNamespace string, kubeClient kubernetes.Interface) ([]*ContainerID, error) { - // Wait for all the containers to be running - err := wait.PollImmediate(time.Second, 3*time.Minute, isPodRunning(ctx, kubeClient, podName, podNamespace)) - if err != nil { - return nil, err - } - - // Get the pod - pod, err := kubeClient.CoreV1().Pods(podNamespace).Get(ctx, podName, metav1.GetOptions{}) - if err != nil { - return nil, err - } - - // Get container ids of found containers - var containerIds []*ContainerID - for _, container := range pod.Status.ContainerStatuses { - if !isInstrumentationContainerStatus(&container) { - log.Logger.V(0).Info("container status", "container", container) - id, err := newContainerID(container.ContainerID) - if err != nil { - return nil, err - } - - containerIds = append(containerIds, id) - } - } - - log.Logger.V(0).Info("Found container ids", "containerIds", containerIds) - return containerIds, nil -} - -// return a condition function that indicates whether the given pod is -// currently running -func isPodRunning(ctx context.Context, kubeClient kubernetes.Interface, podName string, namespace string) wait.ConditionFunc { - return func() (bool, error) { - pod, err := kubeClient.CoreV1().Pods(namespace).Get(ctx, podName, metav1.GetOptions{}) - if err != nil { - return false, err - } - - if len(pod.Status.ContainerStatuses) == 0 { - return false, nil - } - - for _, containerStatus := range pod.Status.ContainerStatuses { - if !isInstrumentationContainerStatus(&containerStatus) && (containerStatus.Started == nil || !*containerStatus.Started) { - log.Logger.V(0).Info("Container not ready", "container", containerStatus) - return false, nil - } - } - - return true, nil - } -} - -func isInstrumentationContainerStatus(containerStatus *corev1.ContainerStatus) bool { - return strings.Contains(containerStatus.Image, "otel-go-agent") -} diff --git a/odiglet/pkg/containers/runtimes/containerd.go b/odiglet/pkg/containers/runtimes/containerd.go deleted file mode 100644 index 436d221c51..0000000000 --- a/odiglet/pkg/containers/runtimes/containerd.go +++ /dev/null @@ -1,41 +0,0 @@ -package runtimes - -import ( - "errors" - "github.com/keyval-dev/odigos/odiglet/pkg/log" - "github.com/moby/sys/mountinfo" - "strings" -) - -var ErrNoMountFound = errors.New("no mount found") - -type containerdRuntime struct{} - -func (c *containerdRuntime) Name() ContainerRuntime { - return Containerd -} - -func (c *containerdRuntime) GetFileSystemPath(containerId string) (string, error) { - // Containerd overlayfs mount path include the container id, so we can simply iterate over the existing mounts - // and find the one that matches the container id - mounts, err := mountinfo.GetMounts(func(info *mountinfo.Info) (skip, stop bool) { - if strings.Contains(info.Mountpoint, containerId) { - return false, true - } - - return true, false - }) - - if err != nil { - log.Logger.Error(err, "Failed to get mounts") - return "", err - } - - if len(mounts) == 0 { - err = ErrNoMountFound - log.Logger.Error(err, "No mounts found") - return "", err - } - - return mounts[0].Mountpoint, nil -} diff --git a/odiglet/pkg/containers/runtimes/crio.go b/odiglet/pkg/containers/runtimes/crio.go deleted file mode 100644 index 112822f39b..0000000000 --- a/odiglet/pkg/containers/runtimes/crio.go +++ /dev/null @@ -1,71 +0,0 @@ -package runtimes - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "github.com/keyval-dev/odigos/odiglet/pkg/log" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" - cri "k8s.io/cri-api/pkg/apis/runtime/v1" -) - -const ( - runtimeEndpoint = "unix:///run/crio/crio.sock" - infoKey = "info" -) - -var ( - ErrMountAnnotationNotFound = errors.New("mount path annotation not found") -) - -type crioRuntime struct{} - -func (c *crioRuntime) Name() ContainerRuntime { - return Crio -} - -func (c *crioRuntime) GetFileSystemPath(containerId string) (string, error) { - // Create connection cri endpoint - conn, err := grpc.Dial(runtimeEndpoint, grpc.WithTransportCredentials(insecure.NewCredentials())) - if err != nil { - log.Logger.Error(err, "Failed to connect to cri endpoint") - return "", err - } - - defer conn.Close() - client := cri.NewRuntimeServiceClient(conn) - res, err := client.ContainerStatus(context.Background(), &cri.ContainerStatusRequest{ContainerId: containerId, Verbose: true}) - if err != nil { - log.Logger.Error(err, "Failed to get container status") - return "", err - } - - infoMap := res.GetInfo() - infoJsonRaw, exists := infoMap[infoKey] - if !exists { - err = ErrMountAnnotationNotFound - log.Logger.Error(err, "No key 'info' in container info map") - return "", err - } - - // Parse infoJsonRaw to json - var infoJson map[string]interface{} - err = json.Unmarshal([]byte(infoJsonRaw), &infoJson) - if err != nil { - log.Logger.Error(err, "Failed to parse container info json") - return "", err - } - - // Get pid from infoJson and use it to get the mount path - pidRaw, exists := infoJson["pid"] - if !exists { - err = ErrMountAnnotationNotFound - log.Logger.Error(err, "No key 'pid' in container info json") - return "", err - } - - pid := int(pidRaw.(float64)) - return fmt.Sprintf("/proc/%d/root", pid), nil -} diff --git a/odiglet/pkg/containers/runtimes/docker.go b/odiglet/pkg/containers/runtimes/docker.go deleted file mode 100644 index f75c32f723..0000000000 --- a/odiglet/pkg/containers/runtimes/docker.go +++ /dev/null @@ -1,40 +0,0 @@ -package runtimes - -import ( - "context" - "errors" - docker "github.com/docker/docker/client" - "github.com/keyval-dev/odigos/odiglet/pkg/log" -) - -type dockerRuntime struct{} - -func (d *dockerRuntime) Name() ContainerRuntime { - return Docker -} - -func (d *dockerRuntime) GetFileSystemPath(containerId string) (string, error) { - // Init docker client - client, err := docker.NewClientWithOpts(docker.FromEnv) - if err != nil { - log.Logger.Error(err, "Failed to init docker client") - return "", err - } - - // Inspect container and print response - defer client.Close() - inspect, err := client.ContainerInspect(context.Background(), containerId) - if err != nil { - log.Logger.Error(err, "Failed to inspect container") - return "", err - } - - fs, exists := inspect.GraphDriver.Data["MergedDir"] - if !exists { - err = errors.New("MergeDir not found in GraphDriver.Data") - log.Logger.Error(err, "Failed to get filesystem path") - return "", err - } - - return fs, nil -} diff --git a/odiglet/pkg/containers/runtimes/root.go b/odiglet/pkg/containers/runtimes/root.go deleted file mode 100644 index 3d0c39d1e1..0000000000 --- a/odiglet/pkg/containers/runtimes/root.go +++ /dev/null @@ -1,40 +0,0 @@ -package runtimes - -import "errors" - -type ContainerRuntime string - -const ( - Docker ContainerRuntime = "docker" - Containerd ContainerRuntime = "containerd" - Crio ContainerRuntime = "cri-o" -) - -type Runtime interface { - Name() ContainerRuntime - GetFileSystemPath(containerId string) (string, error) -} - -var ( - availableRuntimes = []Runtime{&containerdRuntime{}, &dockerRuntime{}, &crioRuntime{}} - ErrRuntimeNotFound = errors.New("runtime not found") - runtimesMap = calculateRuntimesMap() -) - -func calculateRuntimesMap() map[ContainerRuntime]Runtime { - result := make(map[ContainerRuntime]Runtime) - for _, runtime := range availableRuntimes { - result[runtime.Name()] = runtime - } - - return result -} - -func ByName(name string) (Runtime, error) { - runtime, ok := runtimesMap[ContainerRuntime(name)] - if !ok { - return nil, ErrRuntimeNotFound - } - - return runtime, nil -} diff --git a/odiglet/pkg/env/current.go b/odiglet/pkg/env/current.go index 1cf769ba47..33b0d56fd7 100644 --- a/odiglet/pkg/env/current.go +++ b/odiglet/pkg/env/current.go @@ -7,10 +7,12 @@ import ( const ( NodeNameEnvVar = "NODE_NAME" + NodeIPEnvVar = "NODE_IP" ) type Environment struct { NodeName string + NodeIP string } var Current Environment @@ -21,8 +23,14 @@ func Load() error { return fmt.Errorf("env var %s is not set", NodeNameEnvVar) } + ni, ok := os.LookupEnv(NodeIPEnvVar) + if !ok { + return fmt.Errorf("env var %s is not set", NodeIPEnvVar) + } + Current = Environment{ NodeName: nn, + NodeIP: ni, } return nil } diff --git a/odiglet/pkg/instrumentation/consts/consts.go b/odiglet/pkg/instrumentation/consts/consts.go new file mode 100644 index 0000000000..16a01d841f --- /dev/null +++ b/odiglet/pkg/instrumentation/consts/consts.go @@ -0,0 +1,6 @@ +package consts + +const ( + OTLPPort = 4317 + OTLPHttpPort = 4318 +) diff --git a/odiglet/pkg/instrumentation/devices/ids_manager.go b/odiglet/pkg/instrumentation/devices/ids_manager.go new file mode 100644 index 0000000000..17731f6d73 --- /dev/null +++ b/odiglet/pkg/instrumentation/devices/ids_manager.go @@ -0,0 +1,54 @@ +package devices + +import ( + "github.com/google/uuid" + "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" + "strings" +) + +type PodDetails string + +func NewPodDetails(name string, namespace string) PodDetails { + return PodDetails(name + "_" + namespace) +} + +func (p PodDetails) Details() (string, string) { + parts := strings.Split(string(p), "_") + return parts[0], parts[1] +} + +type DeviceManager interface { + Init(initialDevices int64) + GetDevices() []*v1beta1.Device +} + +type IDManager struct { + devices []string +} + +func NewIDManager(initialSize int64) *IDManager { + m := &IDManager{ + devices: make([]string, initialSize), + } + + m.Init(initialSize) + return m +} + +func (m *IDManager) Init(initialDevices int64) { + for i := int64(0); i < initialDevices; i++ { + m.devices[i] = uuid.New().String() + } +} + +func (m *IDManager) GetDevices() []*v1beta1.Device { + var devicesList []*v1beta1.Device + for _, deviceId := range m.devices { + devicesList = append(devicesList, &v1beta1.Device{ + ID: deviceId, + Health: v1beta1.Healthy, + }) + } + + return devicesList +} diff --git a/odiglet/pkg/instrumentation/devices/kubelet.go b/odiglet/pkg/instrumentation/devices/kubelet.go new file mode 100644 index 0000000000..b4ccad0711 --- /dev/null +++ b/odiglet/pkg/instrumentation/devices/kubelet.go @@ -0,0 +1,91 @@ +package devices + +import ( + "context" + "errors" + "fmt" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1alpha1" + "strings" + "time" +) + +var ( + socketDir = "/var/lib/kubelet/pod-resources" + socketPath = "unix://" + socketDir + "/kubelet.sock" + + connectionTimeout = 10 * time.Second + ErrNoDeviceFound = errors.New("no device found") +) + +type kubeletClient struct { + conn *grpc.ClientConn +} + +func NewKubeletClient() (*kubeletClient, error) { + conn, err := connectToKubelet(socketPath) + if err != nil { + return nil, err + } + + return &kubeletClient{ + conn: conn, + }, nil +} + +func (c *kubeletClient) Close() { + if c.conn != nil { + c.conn.Close() + } +} + +func (c *kubeletClient) GetAllocations() (map[PodDetails]string, error) { + pods, err := c.listPods() + if err != nil { + return nil, err + } + + allocations := make(map[PodDetails]string) + for _, pod := range pods.GetPodResources() { + podDetails := NewPodDetails(pod.Name, pod.Namespace) + for _, container := range pod.Containers { + for _, device := range container.Devices { + for _, id := range device.DeviceIds { + if strings.Contains(device.GetResourceName(), "odigos.io") { + allocations[podDetails] = id + } + } + } + } + } + + return allocations, nil +} + +func connectToKubelet(socket string) (*grpc.ClientConn, error) { + ctx, cancel := context.WithTimeout(context.Background(), connectionTimeout) + defer cancel() + + conn, err := grpc.DialContext(ctx, socket, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock()) + + if err != nil { + return nil, fmt.Errorf("failure connecting to %s: %v", socket, err) + } + + return conn, nil +} + +func (c *kubeletClient) listPods() (*podresourcesapi.ListPodResourcesResponse, error) { + client := podresourcesapi.NewPodResourcesListerClient(c.conn) + + ctx, cancel := context.WithTimeout(context.Background(), connectionTimeout) + defer cancel() + + resp, err := client.List(ctx, &podresourcesapi.ListPodResourcesRequest{}) + if err != nil { + return nil, fmt.Errorf("failure getting pod resources %v", err) + } + + return resp, nil +} diff --git a/odiglet/pkg/instrumentation/fs/agents.go b/odiglet/pkg/instrumentation/fs/agents.go new file mode 100644 index 0000000000..02af005c3a --- /dev/null +++ b/odiglet/pkg/instrumentation/fs/agents.go @@ -0,0 +1,14 @@ +package fs + +import ( + cp "github.com/otiai10/copy" +) + +const ( + containerDir = "/instrumentations" + hostDir = "/odigos" +) + +func CopyAgentsDirectoryToHost() error { + return cp.Copy(containerDir, hostDir) +} diff --git a/odiglet/pkg/instrumentation/instrumentlang/dotnet.go b/odiglet/pkg/instrumentation/instrumentlang/dotnet.go new file mode 100644 index 0000000000..95e7300623 --- /dev/null +++ b/odiglet/pkg/instrumentation/instrumentlang/dotnet.go @@ -0,0 +1,54 @@ +package instrumentlang + +import ( + "fmt" + + "github.com/keyval-dev/odigos/odiglet/pkg/env" + "github.com/keyval-dev/odigos/odiglet/pkg/instrumentation/consts" + "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" +) + +const ( + enableProfilingEnvVar = "CORECLR_ENABLE_PROFILING" + profilerEndVar = "CORECLR_PROFILER" + profilerId = "{918728DD-259F-4A6A-AC2B-B85E1B658318}" + profilerPathEnv = "CORECLR_PROFILER_PATH" + profilerPath = "/odigos/dotnet/OpenTelemetry.AutoInstrumentation.ClrProfiler.Native.so" + serviceNameEnv = "OTEL_SERVICE_NAME" + collectorUrlEnv = "OTEL_EXPORTER_OTLP_ENDPOINT" + tracerHomeEnv = "OTEL_DOTNET_AUTO_HOME" + exportTypeEnv = "OTEL_TRACES_EXPORTER" + tracerHome = "/odigos/dotnet" + resourceAttrEnv = "OTEL_RESOURCE_ATTRIBUTES" + startupHookEnv = "DOTNET_STARTUP_HOOKS" + startupHook = "/odigos/dotnet/net/OpenTelemetry.AutoInstrumentation.StartupHook.dll" + additonalDepsEnv = "DOTNET_ADDITIONAL_DEPS" + additonalDeps = "/odigos/dotnet/AdditionalDeps" + sharedStoreEnv = "DOTNET_SHARED_STORE" + sharedStore = "/odigos/dotnet/store" +) + +func DotNet(deviceId string) *v1beta1.ContainerAllocateResponse { + return &v1beta1.ContainerAllocateResponse{ + Envs: map[string]string{ + enableProfilingEnvVar: "1", + profilerEndVar: profilerId, + profilerPathEnv: profilerPath, + tracerHomeEnv: tracerHome, + collectorUrlEnv: fmt.Sprintf("http://%s:%d", env.Current.NodeIP, consts.OTLPHttpPort), + serviceNameEnv: deviceId, + exportTypeEnv: "otlp", + resourceAttrEnv: "odigos.device=dotnet", + startupHookEnv: startupHook, + additonalDepsEnv: additonalDeps, + sharedStoreEnv: sharedStore, + }, + Mounts: []*v1beta1.Mount{ + { + ContainerPath: "/odigos/dotnet", + HostPath: "/odigos/dotnet", + ReadOnly: true, + }, + }, + } +} diff --git a/odiglet/pkg/instrumentation/instrumentlang/java.go b/odiglet/pkg/instrumentation/instrumentlang/java.go new file mode 100644 index 0000000000..e1f56a5d4c --- /dev/null +++ b/odiglet/pkg/instrumentation/instrumentlang/java.go @@ -0,0 +1,35 @@ +package instrumentlang + +import ( + "fmt" + "github.com/keyval-dev/odigos/odiglet/pkg/env" + "github.com/keyval-dev/odigos/odiglet/pkg/instrumentation/consts" + "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" +) + +const ( + otelResourceAttributesEnvVar = "OTEL_RESOURCE_ATTRIBUTES" + otelResourceAttrPatteern = "service.name=%s,odigos.device=java" + javaToolOptionsEnvVar = "JAVA_TOOL_OPTIONS" + javaOptsEnvVar = "JAVA_OPTS" + javaToolOptionsPattern = "-javaagent:/odigos/java/javaagent.jar " + + "-Dotel.traces.sampler=always_on -Dotel.exporter.otlp.endpoint=http://%s:%d" +) + +func Java(deviceId string) *v1beta1.ContainerAllocateResponse { + javaOpts := fmt.Sprintf(javaToolOptionsPattern, env.Current.NodeIP, consts.OTLPPort) + return &v1beta1.ContainerAllocateResponse{ + Envs: map[string]string{ + otelResourceAttributesEnvVar: fmt.Sprintf(otelResourceAttrPatteern, deviceId), + javaToolOptionsEnvVar: javaOpts, + javaOptsEnvVar: javaOpts, + }, + Mounts: []*v1beta1.Mount{ + { + ContainerPath: "/odigos/java", + HostPath: "/odigos/java", + ReadOnly: true, + }, + }, + } +} diff --git a/odiglet/pkg/instrumentation/instrumentlang/nodejs.go b/odiglet/pkg/instrumentation/instrumentlang/nodejs.go new file mode 100644 index 0000000000..2cfd3aea6f --- /dev/null +++ b/odiglet/pkg/instrumentation/instrumentlang/nodejs.go @@ -0,0 +1,39 @@ +package instrumentlang + +import ( + "fmt" + "github.com/keyval-dev/odigos/odiglet/pkg/env" + "github.com/keyval-dev/odigos/odiglet/pkg/instrumentation/consts" + "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" +) + +const ( + nodeMountPath = "/odigos/nodejs" + nodeEnvNodeDebug = "OTEL_NODEJS_DEBUG" + nodeEnvTraceExporter = "OTEL_TRACES_EXPORTER" + nodeEnvEndpoint = "OTEL_EXPORTER_OTLP_ENDPOINT" + nodeEnvServiceName = "OTEL_SERVICE_NAME" + nodeEnvNodeOptions = "NODE_OPTIONS" + nodeEnvResourceAttributes = "OTEL_RESOURCE_ATTRIBUTES" +) + +func NodeJS(deviceId string) *v1beta1.ContainerAllocateResponse { + otlpEndpoint := fmt.Sprintf("http://%s:%d", env.Current.NodeIP, consts.OTLPPort) + return &v1beta1.ContainerAllocateResponse{ + Envs: map[string]string{ + nodeEnvNodeDebug: "true", + nodeEnvTraceExporter: "otlp", + nodeEnvEndpoint: otlpEndpoint, + nodeEnvServiceName: deviceId, + nodeEnvResourceAttributes: "odigos.device=nodejs", + nodeEnvNodeOptions: fmt.Sprintf("--require %s/autoinstrumentation.js", nodeMountPath), + }, + Mounts: []*v1beta1.Mount{ + { + ContainerPath: nodeMountPath, + HostPath: nodeMountPath, + ReadOnly: true, + }, + }, + } +} diff --git a/odiglet/pkg/instrumentation/instrumentlang/python.go b/odiglet/pkg/instrumentation/instrumentlang/python.go new file mode 100644 index 0000000000..746e9ce2c6 --- /dev/null +++ b/odiglet/pkg/instrumentation/instrumentlang/python.go @@ -0,0 +1,40 @@ +package instrumentlang + +import ( + "fmt" + "github.com/keyval-dev/odigos/odiglet/pkg/env" + "github.com/keyval-dev/odigos/odiglet/pkg/instrumentation/consts" + "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" +) + +const ( + pythonVolumeName = "agentdir-python" + pythonMountPath = "/otel-auto-instrumentation" + envOtelTracesExporter = "OTEL_TRACES_EXPORTER" + envOtelMetricsExporter = "OTEL_METRICS_EXPORTER" + envValOtelHttpExporter = "otlp_proto_http" + envLogCorrelation = "OTEL_PYTHON_LOG_CORRELATION" + pythonInitContainerName = "copy-python-agent" + envPythonPath = "PYTHONPATH" +) + +func Python(deviceId string) *v1beta1.ContainerAllocateResponse { + otlpEndpoint := fmt.Sprintf("http://%s:%d", env.Current.NodeIP, consts.OTLPHttpPort) + return &v1beta1.ContainerAllocateResponse{ + Envs: map[string]string{ + envLogCorrelation: "true", + envPythonPath: "/odigos/python/opentelemetry/instrumentation/auto_instrumentation:/odigos/python", + "OTEL_EXPORTER_OTLP_ENDPOINT": otlpEndpoint, + "OTEL_RESOURCE_ATTRIBUTES": fmt.Sprintf("service.name=%s,odigos.device=python", deviceId), + envOtelTracesExporter: envValOtelHttpExporter, + envOtelMetricsExporter: "", + }, + Mounts: []*v1beta1.Mount{ + { + ContainerPath: "/odigos/python", + HostPath: "/odigos/python", + ReadOnly: true, + }, + }, + } +} diff --git a/odiglet/pkg/instrumentation/lister.go b/odiglet/pkg/instrumentation/lister.go new file mode 100644 index 0000000000..23690b061f --- /dev/null +++ b/odiglet/pkg/instrumentation/lister.go @@ -0,0 +1,75 @@ +package instrumentation + +import ( + "context" + "github.com/keyval-dev/odigos/odiglet/pkg/env" + "github.com/keyval-dev/odigos/odiglet/pkg/instrumentation/fs" + "github.com/keyval-dev/odigos/odiglet/pkg/instrumentation/instrumentlang" + "github.com/keyval-dev/odigos/odiglet/pkg/log" + "github.com/kubevirt/device-plugin-manager/pkg/dpm" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" +) + +const ( + defaultMaxDevices = 100 +) + +type lister struct { + plugins map[string]dpm.PluginInterface +} + +func (l *lister) GetResourceNamespace() string { + return "instrumentation.odigos.io" +} + +func (l *lister) Discover(pluginNameLists chan dpm.PluginNameList) { + var pluginNames []string + for name, _ := range l.plugins { + pluginNames = append(pluginNames, name) + } + + pluginNameLists <- pluginNames +} + +func (l *lister) NewPlugin(s string) dpm.PluginInterface { + return l.plugins[s] +} + +func NewLister(ctx context.Context, clientset *kubernetes.Clientset) (dpm.ListerInterface, error) { + maxPods, err := getInitialDeviceAmount(clientset) + if err != nil { + return nil, err + } + var availablePlugins = map[string]dpm.PluginInterface{ + "java": NewPlugin(maxPods, instrumentlang.Java), + "python": NewPlugin(maxPods, instrumentlang.Python), + "nodejs": NewPlugin(maxPods, instrumentlang.NodeJS), + "dotnet": NewPlugin(maxPods, instrumentlang.DotNet), + } + + err = fs.CopyAgentsDirectoryToHost() + if err != nil { + return nil, err + } + + return &lister{ + plugins: availablePlugins, + }, nil +} + +func getInitialDeviceAmount(clientset *kubernetes.Clientset) (int64, error) { + // get max pods per current node + node, err := clientset.CoreV1().Nodes().Get(context.Background(), env.Current.NodeName, metav1.GetOptions{}) + if err != nil { + return 0, err + } + + maxPods, ok := node.Status.Allocatable.Pods().AsInt64() + if !ok { + log.Logger.V(0).Info("Failed to get max pods from node status, using default value", "default", defaultMaxDevices) + maxPods = defaultMaxDevices + } + + return maxPods, nil +} diff --git a/odiglet/pkg/instrumentation/plugin.go b/odiglet/pkg/instrumentation/plugin.go new file mode 100644 index 0000000000..bedcfca5b6 --- /dev/null +++ b/odiglet/pkg/instrumentation/plugin.go @@ -0,0 +1,83 @@ +package instrumentation + +import ( + "context" + "fmt" + "github.com/keyval-dev/odigos/odiglet/pkg/instrumentation/devices" + "github.com/keyval-dev/odigos/odiglet/pkg/log" + "github.com/kubevirt/device-plugin-manager/pkg/dpm" + "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" +) + +type LangSpecificFunc func(deviceId string) *v1beta1.ContainerAllocateResponse + +type plugin struct { + idsManager devices.DeviceManager + stopCh chan struct{} + LangSpecificFunc LangSpecificFunc +} + +func NewPlugin(maxPods int64, lsf LangSpecificFunc) dpm.PluginInterface { + idManager := devices.NewIDManager(maxPods) + return &plugin{ + idsManager: idManager, + stopCh: make(chan struct{}), + LangSpecificFunc: lsf, + } +} + +func (p *plugin) GetDevicePluginOptions(ctx context.Context, empty *v1beta1.Empty) (*v1beta1.DevicePluginOptions, error) { + fmt.Println("GetDevicePluginOptions") + return &v1beta1.DevicePluginOptions{ + PreStartRequired: false, + GetPreferredAllocationAvailable: false, + }, nil +} + +func (p *plugin) ListAndWatch(empty *v1beta1.Empty, server v1beta1.DevicePlugin_ListAndWatchServer) error { + devicesList := p.idsManager.GetDevices() + log.Logger.V(3).Info("ListAndWatch", "devices", devicesList) + err := server.Send(&v1beta1.ListAndWatchResponse{ + Devices: devicesList, + }) + + if err != nil { + log.Logger.Error(err, "Failed to send ListAndWatchResponse") + } + + <-p.stopCh + server.Send(&v1beta1.ListAndWatchResponse{ + Devices: []*v1beta1.Device{}, + }) + return nil +} + +func (p *plugin) Stop() error { + log.Logger.V(0).Info("Stopping Odigos Device Plugin ...") + p.stopCh <- struct{}{} + return nil +} + +func (p *plugin) GetPreferredAllocation(ctx context.Context, request *v1beta1.PreferredAllocationRequest) (*v1beta1.PreferredAllocationResponse, error) { + return &v1beta1.PreferredAllocationResponse{}, nil +} + +func (p *plugin) Allocate(ctx context.Context, request *v1beta1.AllocateRequest) (*v1beta1.AllocateResponse, error) { + res := &v1beta1.AllocateResponse{} + + for _, req := range request.ContainerRequests { + if len(req.DevicesIDs) != 1 { + log.Logger.V(0).Info("got instrumentation device not equal to 1, skipping", "devices", req.DevicesIDs) + continue + } + + deviceId := req.DevicesIDs[0] + res.ContainerResponses = append(res.ContainerResponses, p.LangSpecificFunc(deviceId)) + } + + return res, nil +} + +func (p *plugin) PreStartContainer(ctx context.Context, request *v1beta1.PreStartContainerRequest) (*v1beta1.PreStartContainerResponse, error) { + return &v1beta1.PreStartContainerResponse{}, nil +} diff --git a/odiglet/pkg/log/logger.go b/odiglet/pkg/log/logger.go index 8fa9a4eb41..3c517c1040 100644 --- a/odiglet/pkg/log/logger.go +++ b/odiglet/pkg/log/logger.go @@ -1,6 +1,7 @@ package log import ( + "flag" "github.com/go-logr/logr" "github.com/go-logr/zapr" "go.uber.org/zap" @@ -15,5 +16,9 @@ func Init() error { } Logger = zapr.NewLogger(zapLog) + + // used by device manager logger + flag.Parse() + return nil } diff --git a/odiglet/pkg/request.go b/odiglet/pkg/request.go deleted file mode 100644 index fdab95b215..0000000000 --- a/odiglet/pkg/request.go +++ /dev/null @@ -1,7 +0,0 @@ -package pkg - -type LaunchRequest struct { - ExePath string `json:"exe_path"` - PodName string `json:"pod_name"` - PodNamespace string `json:"pod_namespace"` -}