diff --git a/Cargo.toml b/Cargo.toml index 21d32b65..7d88e0b7 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ name = "object" version = "0.30.3" edition = "2018" exclude = ["/.github", "/testfiles"] -keywords = ["object", "elf", "mach-o", "pe", "coff"] +keywords = ["object", "elf", "mach-o", "pe", "coff", "xcoff"] license = "Apache-2.0 OR MIT" repository = "https://github.com/gimli-rs/object" description = "A unified interface for reading and writing object file formats." diff --git a/crates/examples/testfiles/xcoff/base.o.objdump b/crates/examples/testfiles/xcoff/base.o.objdump index 7154e67a..2218ef55 100644 --- a/crates/examples/testfiles/xcoff/base.o.objdump +++ b/crates/examples/testfiles/xcoff/base.o.objdump @@ -8,15 +8,15 @@ Entry Address: 0 1: Section { name: ".data", address: 68, size: 20, align: 4, kind: Data, flags: Xcoff { s_flags: 40 } } Symbols -0: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -3: Symbol { name: ".printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -5: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -7: Symbol { name: ".text", address: 0, size: 57, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -9: Symbol { name: ".main", address: 0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -11: Symbol { name: ".rodata.str1.1L...str", address: 58, size: d, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -13: Symbol { name: "main", address: 68, size: 18, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -15: Symbol { name: "TOC", address: 80, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -17: Symbol { name: ".rodata.str1.1L...str", address: 80, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +0: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +3: Symbol { name: ".printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +5: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +7: Symbol { name: ".text", address: 0, size: 57, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +9: Symbol { name: ".main", address: 0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +11: Symbol { name: ".rodata.str1.1L...str", address: 58, size: d, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +13: Symbol { name: "main", address: 68, size: 18, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +15: Symbol { name: "TOC", address: 80, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +17: Symbol { name: ".rodata.str1.1L...str", address: 80, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } .text relocations (1e, Relocation { kind: Got, encoding: Generic, size: 10, target: Symbol(SymbolIndex(11)), addend: 0, implicit_addend: true }) diff --git a/crates/examples/testfiles/xcoff/base.xcoff.objdump b/crates/examples/testfiles/xcoff/base.xcoff.objdump index 0e17c788..2d3685bf 100644 --- a/crates/examples/testfiles/xcoff/base.xcoff.objdump +++ b/crates/examples/testfiles/xcoff/base.xcoff.objdump @@ -10,85 +10,85 @@ Entry Address: 110000848 3: Section { name: ".loader", address: 0, size: 485, align: 4, kind: Metadata, flags: Xcoff { s_flags: 1000 } } Symbols -0: Symbol { name: "errno", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -2: Symbol { name: "__mod_init", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -4: Symbol { name: "exit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -6: Symbol { name: "atexit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -8: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -10: Symbol { name: "__run_final_dtors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -12: Symbol { name: "__run_initial_ctors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -14: Symbol { name: "__n_pthreads", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -16: Symbol { name: "__crt0v", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -18: Symbol { name: "__malloc_user_defined_name", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -20: Symbol { name: "TOC", address: 1100008b8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -22: Symbol { name: "__crt0v", address: 110000900, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -24: Symbol { name: "crt0_data", address: 110000908, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -26: Symbol { name: "__run_final_dtors", address: 110000910, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -28: Symbol { name: "_$STATIC", address: 110000918, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -30: Symbol { name: "__C_runtime_termination", address: 110000920, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -32: Symbol { name: "atexit", address: 110000928, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -34: Symbol { name: "_cdtors", address: 110000930, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -36: Symbol { name: "__run_initial_ctors", address: 110000938, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -38: Symbol { name: "exit", address: 110000940, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -40: Symbol { name: "__n_pthreads", address: 110000948, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -42: Symbol { name: "__mod_init", address: 110000950, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -44: Symbol { name: "__malloc_user_defined_name", address: 110000958, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -46: Symbol { name: "errno", address: 110000960, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -48: Symbol { name: ".rodata.str1.1L...str", address: 110000968, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -50: Symbol { name: "printf", address: 110000970, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -52: Symbol { name: "", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -53: Symbol { name: "crt0_64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -54: Symbol { name: ".__start", address: 1000001f8, size: ad, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -56: Symbol { name: ".__start", address: 1000001f8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -58: Symbol { name: "__start", address: 110000848, size: 10, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -60: Symbol { name: "crt0_data", address: 1100006d0, size: 68, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -62: Symbol { name: "p_xargc", address: 1100008c0, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -64: Symbol { name: "p_xargv", address: 1100008f0, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -66: Symbol { name: "p_xrcfg", address: 1100008f8, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -68: Symbol { name: "p_xrc", address: 1100008fc, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -70: Symbol { name: "_malloc_user_defined_name", address: 1100008b8, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -72: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -76: Symbol { name: "", address: 1000002c0, size: 160, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -78: Symbol { name: ".__threads_init", address: 1000002c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -80: Symbol { name: ".__threads_init@AF2_1", address: 100000300, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -82: Symbol { name: "_$STATIC", address: 110000738, size: 59, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -84: Symbol { name: "__threads_init", address: 110000858, size: 18, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -86: Symbol { name: "__pth_init_routine", address: 1100008c8, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -88: Symbol { name: "_bsd_init_routine", address: 1100008d0, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -90: Symbol { name: "_xti_tli_init_routine", address: 1100008d8, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -92: Symbol { name: "_nsl_init_routine", address: 1100008e0, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -94: Symbol { name: "__dce_compat_init_routine", address: 1100008e8, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -96: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -100: Symbol { name: "", address: 100000420, size: 178, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -102: Symbol { name: ".__User_sinit_begin", address: 100000420, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -104: Symbol { name: ".__C_runtime_termination", address: 100000448, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -106: Symbol { name: ".__C_runtime_startup", address: 100000498, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -108: Symbol { name: ".__dftdt__L304e50f8c42_5CatchFv", address: 100000520, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -110: Symbol { name: "_$STATIC", address: 1100007a0, size: 95, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -112: Symbol { name: "__dftdt__L304e50f8c42_5CatchFv", address: 110000888, size: 18, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -114: Symbol { name: "__C_runtime_termination", address: 1100008a0, size: 18, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -116: Symbol { name: "__C_runtime_startup", address: 110000870, size: 18, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -118: Symbol { name: "_cdtors", address: 110000838, size: 10, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: true, flags: None } -120: Symbol { name: "__C_runtime_pstartup", address: 110000798, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -122: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -125: Symbol { name: ".text", address: 100000640, size: 57, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -127: Symbol { name: ".main", address: 100000640, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -129: Symbol { name: ".rodata.str1.1L...str", address: 1000006c0, size: d, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -131: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -132: Symbol { name: ".exit", address: 100000610, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -134: Symbol { name: ".exit", address: 100000610, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -136: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -137: Symbol { name: ".__run_final_dtors", address: 100000598, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -139: Symbol { name: ".__run_final_dtors", address: 100000598, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -141: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -142: Symbol { name: ".atexit", address: 1000005c0, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -144: Symbol { name: ".atexit", address: 1000005c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -146: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -147: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -149: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -151: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -152: Symbol { name: ".printf", address: 100000698, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -154: Symbol { name: ".printf", address: 100000698, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +0: Symbol { name: "errno", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +2: Symbol { name: "__mod_init", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +4: Symbol { name: "exit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +6: Symbol { name: "atexit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +8: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +10: Symbol { name: "__run_final_dtors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +12: Symbol { name: "__run_initial_ctors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +14: Symbol { name: "__n_pthreads", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +16: Symbol { name: "__crt0v", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +18: Symbol { name: "__malloc_user_defined_name", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +20: Symbol { name: "TOC", address: 1100008b8, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +22: Symbol { name: "__crt0v", address: 110000900, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +24: Symbol { name: "crt0_data", address: 110000908, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +26: Symbol { name: "__run_final_dtors", address: 110000910, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +28: Symbol { name: "_$STATIC", address: 110000918, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +30: Symbol { name: "__C_runtime_termination", address: 110000920, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +32: Symbol { name: "atexit", address: 110000928, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +34: Symbol { name: "_cdtors", address: 110000930, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +36: Symbol { name: "__run_initial_ctors", address: 110000938, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +38: Symbol { name: "exit", address: 110000940, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +40: Symbol { name: "__n_pthreads", address: 110000948, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +42: Symbol { name: "__mod_init", address: 110000950, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +44: Symbol { name: "__malloc_user_defined_name", address: 110000958, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +46: Symbol { name: "errno", address: 110000960, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +48: Symbol { name: ".rodata.str1.1L...str", address: 110000968, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +50: Symbol { name: "printf", address: 110000970, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +52: Symbol { name: "", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +53: Symbol { name: "crt0_64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +54: Symbol { name: ".__start", address: 1000001f8, size: ad, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +56: Symbol { name: ".__start", address: 1000001f8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +58: Symbol { name: "__start", address: 110000848, size: 10, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +60: Symbol { name: "crt0_data", address: 1100006d0, size: 68, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +62: Symbol { name: "p_xargc", address: 1100008c0, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +64: Symbol { name: "p_xargv", address: 1100008f0, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +66: Symbol { name: "p_xrcfg", address: 1100008f8, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +68: Symbol { name: "p_xrc", address: 1100008fc, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +70: Symbol { name: "_malloc_user_defined_name", address: 1100008b8, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +72: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +76: Symbol { name: "", address: 1000002c0, size: 160, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +78: Symbol { name: ".__threads_init", address: 1000002c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +80: Symbol { name: ".__threads_init@AF2_1", address: 100000300, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +82: Symbol { name: "_$STATIC", address: 110000738, size: 59, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +84: Symbol { name: "__threads_init", address: 110000858, size: 18, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +86: Symbol { name: "__pth_init_routine", address: 1100008c8, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +88: Symbol { name: "_bsd_init_routine", address: 1100008d0, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +90: Symbol { name: "_xti_tli_init_routine", address: 1100008d8, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +92: Symbol { name: "_nsl_init_routine", address: 1100008e0, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +94: Symbol { name: "__dce_compat_init_routine", address: 1100008e8, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +96: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +100: Symbol { name: "", address: 100000420, size: 178, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +102: Symbol { name: ".__User_sinit_begin", address: 100000420, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +104: Symbol { name: ".__C_runtime_termination", address: 100000448, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +106: Symbol { name: ".__C_runtime_startup", address: 100000498, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +108: Symbol { name: ".__dftdt__L304e50f8c42_5CatchFv", address: 100000520, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +110: Symbol { name: "_$STATIC", address: 1100007a0, size: 95, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +112: Symbol { name: "__dftdt__L304e50f8c42_5CatchFv", address: 110000888, size: 18, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +114: Symbol { name: "__C_runtime_termination", address: 1100008a0, size: 18, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +116: Symbol { name: "__C_runtime_startup", address: 110000870, size: 18, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +118: Symbol { name: "_cdtors", address: 110000838, size: 10, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: true, flags: Xcoff { n_sclass: 6f } } +120: Symbol { name: "__C_runtime_pstartup", address: 110000798, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +122: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +125: Symbol { name: ".text", address: 100000640, size: 57, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +127: Symbol { name: ".main", address: 100000640, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +129: Symbol { name: ".rodata.str1.1L...str", address: 1000006c0, size: d, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +131: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +132: Symbol { name: ".exit", address: 100000610, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +134: Symbol { name: ".exit", address: 100000610, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +136: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +137: Symbol { name: ".__run_final_dtors", address: 100000598, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +139: Symbol { name: ".__run_final_dtors", address: 100000598, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +141: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +142: Symbol { name: ".atexit", address: 1000005c0, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +144: Symbol { name: ".atexit", address: 1000005c0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +146: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +147: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +149: Symbol { name: ".__run_initial_ctors", address: 1000005e8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +151: Symbol { name: "glink64.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +152: Symbol { name: ".printf", address: 100000698, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +154: Symbol { name: ".printf", address: 100000698, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } .text relocations (1000001fa, Relocation { kind: Got, encoding: Generic, size: 10, target: Symbol(SymbolIndex(46)), addend: 0, implicit_addend: true }) diff --git a/crates/examples/testfiles/xcoff/base32.o.objdump b/crates/examples/testfiles/xcoff/base32.o.objdump index 3601e09f..9faf6862 100644 --- a/crates/examples/testfiles/xcoff/base32.o.objdump +++ b/crates/examples/testfiles/xcoff/base32.o.objdump @@ -8,15 +8,15 @@ Entry Address: 0 1: Section { name: ".data", address: 6c, size: 10, align: 4, kind: Data, flags: Xcoff { s_flags: 40 } } Symbols -0: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -3: Symbol { name: ".printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -5: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -7: Symbol { name: ".text", address: 0, size: 5b, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -9: Symbol { name: ".main", address: 0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -11: Symbol { name: ".rodata.str1.1L...str", address: 5c, size: d, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -13: Symbol { name: "main", address: 6c, size: c, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -15: Symbol { name: "TOC", address: 78, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -17: Symbol { name: ".rodata.str1.1L...str", address: 78, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } +0: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +3: Symbol { name: ".printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +5: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +7: Symbol { name: ".text", address: 0, size: 5b, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +9: Symbol { name: ".main", address: 0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +11: Symbol { name: ".rodata.str1.1L...str", address: 5c, size: d, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +13: Symbol { name: "main", address: 6c, size: c, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +15: Symbol { name: "TOC", address: 78, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +17: Symbol { name: ".rodata.str1.1L...str", address: 78, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } .text relocations (22, Relocation { kind: Got, encoding: Generic, size: 10, target: Symbol(SymbolIndex(11)), addend: 0, implicit_addend: true }) diff --git a/crates/examples/testfiles/xcoff/base32.xcoff.objdump b/crates/examples/testfiles/xcoff/base32.xcoff.objdump index c384254b..1c8bf180 100644 --- a/crates/examples/testfiles/xcoff/base32.xcoff.objdump +++ b/crates/examples/testfiles/xcoff/base32.xcoff.objdump @@ -10,83 +10,83 @@ Entry Address: 20000710 3: Section { name: ".loader", address: 0, size: 37a, align: 4, kind: Metadata, flags: Xcoff { s_flags: 1000 } } Symbols -0: Symbol { name: "errno", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -2: Symbol { name: "exit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -4: Symbol { name: "atexit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -6: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -8: Symbol { name: "__run_final_dtors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -10: Symbol { name: "__run_initial_ctors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -12: Symbol { name: "__mod_init", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -14: Symbol { name: "__crt0v", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -16: Symbol { name: "__malloc_user_defined_name", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: None } -18: Symbol { name: "TOC", address: 20000748, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -20: Symbol { name: "__crt0v", address: 20000770, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -22: Symbol { name: "__mod_init", address: 20000774, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -24: Symbol { name: "crt0_data", address: 20000778, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -26: Symbol { name: "__run_final_dtors", address: 2000077c, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -28: Symbol { name: "_$STATIC", address: 20000780, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -30: Symbol { name: "__C_runtime_termination", address: 20000784, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -32: Symbol { name: "atexit", address: 20000788, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -34: Symbol { name: "_cdtors", address: 2000078c, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -36: Symbol { name: "__run_initial_ctors", address: 20000790, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -38: Symbol { name: "exit", address: 20000794, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -40: Symbol { name: "__malloc_user_defined_name", address: 20000798, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -42: Symbol { name: "errno", address: 2000079c, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -44: Symbol { name: ".rodata.str1.1L...str", address: 200007a0, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -46: Symbol { name: "printf", address: 200007a4, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -48: Symbol { name: " ", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -49: Symbol { name: "crt0main.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -50: Symbol { name: ".__start", address: 10000128, size: a5, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -52: Symbol { name: ".__start", address: 10000128, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -54: Symbol { name: "__start", address: 20000710, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -56: Symbol { name: "crt0_data", address: 200005f4, size: 2c, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -58: Symbol { name: "p_xargc", address: 2000074c, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -60: Symbol { name: "p_xargv", address: 20000764, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -62: Symbol { name: "p_xrcfg", address: 20000768, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -64: Symbol { name: "p_xrc", address: 2000076c, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -66: Symbol { name: "_malloc_user_defined_name", address: 20000748, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -68: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -72: Symbol { name: "", address: 100001e0, size: 160, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -74: Symbol { name: ".__threads_init", address: 100001e0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -76: Symbol { name: ".__threads_init@AF2_1", address: 10000220, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -78: Symbol { name: "_$STATIC", address: 20000620, size: 59, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -80: Symbol { name: "__threads_init", address: 20000718, size: c, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -82: Symbol { name: "__pth_init_routine", address: 20000750, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -84: Symbol { name: "_bsd_init_routine", address: 20000754, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -86: Symbol { name: "_xti_tli_init_routine", address: 20000758, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -88: Symbol { name: "_nsl_init_routine", address: 2000075c, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -90: Symbol { name: "__dce_compat_init_routine", address: 20000760, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -92: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -96: Symbol { name: "", address: 10000340, size: 178, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -98: Symbol { name: ".__User_sinit_begin", address: 10000340, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -100: Symbol { name: ".__C_runtime_termination", address: 10000368, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -102: Symbol { name: ".__C_runtime_startup", address: 100003b8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -104: Symbol { name: ".__dftdt__L304e4b28c42_5CatchFv", address: 10000440, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -106: Symbol { name: "_$STATIC", address: 20000680, size: 81, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -108: Symbol { name: "__dftdt__L304e4b28c42_5CatchFv", address: 20000730, size: c, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -110: Symbol { name: "__C_runtime_termination", address: 2000073c, size: c, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -112: Symbol { name: "__C_runtime_startup", address: 20000724, size: c, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -114: Symbol { name: "_cdtors", address: 20000708, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: true, flags: None } -116: Symbol { name: "__C_runtime_pstartup", address: 2000067c, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: None } -118: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -121: Symbol { name: ".text", address: 10000560, size: 5b, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -123: Symbol { name: ".main", address: 10000560, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -125: Symbol { name: ".rodata.str1.1L...str", address: 100005e4, size: d, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -127: Symbol { name: "glink.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -128: Symbol { name: ".exit", address: 10000530, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -130: Symbol { name: ".exit", address: 10000530, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -132: Symbol { name: "glink.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -133: Symbol { name: ".__run_final_dtors", address: 100004b8, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -135: Symbol { name: ".__run_final_dtors", address: 100004b8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -137: Symbol { name: "glink.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -138: Symbol { name: ".atexit", address: 100004e0, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -140: Symbol { name: ".atexit", address: 100004e0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -142: Symbol { name: "glink.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -143: Symbol { name: ".__run_initial_ctors", address: 10000508, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -145: Symbol { name: ".__run_initial_ctors", address: 10000508, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -147: Symbol { name: "glink.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: None } -148: Symbol { name: ".printf", address: 100005bc, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } -150: Symbol { name: ".printf", address: 100005bc, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: None } +0: Symbol { name: "errno", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +2: Symbol { name: "exit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +4: Symbol { name: "atexit", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +6: Symbol { name: "printf", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +8: Symbol { name: "__run_final_dtors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +10: Symbol { name: "__run_initial_ctors", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +12: Symbol { name: "__mod_init", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +14: Symbol { name: "__crt0v", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +16: Symbol { name: "__malloc_user_defined_name", address: 0, size: 0, kind: Unknown, section: Undefined, scope: Unknown, weak: false, flags: Xcoff { n_sclass: 2 } } +18: Symbol { name: "TOC", address: 20000748, size: 0, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +20: Symbol { name: "__crt0v", address: 20000770, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +22: Symbol { name: "__mod_init", address: 20000774, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +24: Symbol { name: "crt0_data", address: 20000778, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +26: Symbol { name: "__run_final_dtors", address: 2000077c, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +28: Symbol { name: "_$STATIC", address: 20000780, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +30: Symbol { name: "__C_runtime_termination", address: 20000784, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +32: Symbol { name: "atexit", address: 20000788, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +34: Symbol { name: "_cdtors", address: 2000078c, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +36: Symbol { name: "__run_initial_ctors", address: 20000790, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +38: Symbol { name: "exit", address: 20000794, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +40: Symbol { name: "__malloc_user_defined_name", address: 20000798, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +42: Symbol { name: "errno", address: 2000079c, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +44: Symbol { name: ".rodata.str1.1L...str", address: 200007a0, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +46: Symbol { name: "printf", address: 200007a4, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +48: Symbol { name: " ", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +49: Symbol { name: "crt0main.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +50: Symbol { name: ".__start", address: 10000128, size: a5, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +52: Symbol { name: ".__start", address: 10000128, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +54: Symbol { name: "__start", address: 20000710, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +56: Symbol { name: "crt0_data", address: 200005f4, size: 2c, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +58: Symbol { name: "p_xargc", address: 2000074c, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +60: Symbol { name: "p_xargv", address: 20000764, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +62: Symbol { name: "p_xrcfg", address: 20000768, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +64: Symbol { name: "p_xrc", address: 2000076c, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +66: Symbol { name: "_malloc_user_defined_name", address: 20000748, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +68: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +72: Symbol { name: "", address: 100001e0, size: 160, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +74: Symbol { name: ".__threads_init", address: 100001e0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +76: Symbol { name: ".__threads_init@AF2_1", address: 10000220, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +78: Symbol { name: "_$STATIC", address: 20000620, size: 59, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +80: Symbol { name: "__threads_init", address: 20000718, size: c, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +82: Symbol { name: "__pth_init_routine", address: 20000750, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +84: Symbol { name: "_bsd_init_routine", address: 20000754, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +86: Symbol { name: "_xti_tli_init_routine", address: 20000758, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +88: Symbol { name: "_nsl_init_routine", address: 2000075c, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +90: Symbol { name: "__dce_compat_init_routine", address: 20000760, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +92: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +96: Symbol { name: "", address: 10000340, size: 178, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +98: Symbol { name: ".__User_sinit_begin", address: 10000340, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +100: Symbol { name: ".__C_runtime_termination", address: 10000368, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +102: Symbol { name: ".__C_runtime_startup", address: 100003b8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +104: Symbol { name: ".__dftdt__L304e4b28c42_5CatchFv", address: 10000440, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +106: Symbol { name: "_$STATIC", address: 20000680, size: 81, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +108: Symbol { name: "__dftdt__L304e4b28c42_5CatchFv", address: 20000730, size: c, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +110: Symbol { name: "__C_runtime_termination", address: 2000073c, size: c, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +112: Symbol { name: "__C_runtime_startup", address: 20000724, size: c, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +114: Symbol { name: "_cdtors", address: 20000708, size: 8, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: true, flags: Xcoff { n_sclass: 6f } } +116: Symbol { name: "__C_runtime_pstartup", address: 2000067c, size: 4, kind: Data, section: Section(SectionIndex(2)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +118: Symbol { name: ".file", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +121: Symbol { name: ".text", address: 10000560, size: 5b, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +123: Symbol { name: ".main", address: 10000560, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +125: Symbol { name: ".rodata.str1.1L...str", address: 100005e4, size: d, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +127: Symbol { name: "glink.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +128: Symbol { name: ".exit", address: 10000530, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +130: Symbol { name: ".exit", address: 10000530, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +132: Symbol { name: "glink.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +133: Symbol { name: ".__run_final_dtors", address: 100004b8, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +135: Symbol { name: ".__run_final_dtors", address: 100004b8, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +137: Symbol { name: "glink.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +138: Symbol { name: ".atexit", address: 100004e0, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +140: Symbol { name: ".atexit", address: 100004e0, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +142: Symbol { name: "glink.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +143: Symbol { name: ".__run_initial_ctors", address: 10000508, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +145: Symbol { name: ".__run_initial_ctors", address: 10000508, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } +147: Symbol { name: "glink.s", address: 0, size: 0, kind: File, section: None, scope: Compilation, weak: false, flags: Xcoff { n_sclass: 67 } } +148: Symbol { name: ".printf", address: 100005bc, size: 28, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 6b } } +150: Symbol { name: ".printf", address: 100005bc, size: 0, kind: Text, section: Section(SectionIndex(1)), scope: Dynamic, weak: false, flags: Xcoff { n_sclass: 2 } } .text relocations (1000012a, Relocation { kind: Got, encoding: Generic, size: 10, target: Symbol(SymbolIndex(42)), addend: 0, implicit_addend: true }) diff --git a/src/common.rs b/src/common.rs index 91508342..2d10cdeb 100644 --- a/src/common.rs +++ b/src/common.rs @@ -477,4 +477,9 @@ pub enum SymbolFlags
{ /// `Number` field in the auxiliary symbol for the section. associative_section: Option
, }, + /// XCOFF symbol flags. + Xcoff { + /// `n_sclass` field in the XCOFF symbol. + n_sclass: u8, + }, } diff --git a/src/read/traits.rs b/src/read/traits.rs index f1a473e0..1565775c 100644 --- a/src/read/traits.rs +++ b/src/read/traits.rs @@ -2,7 +2,7 @@ use alloc::borrow::Cow; use alloc::vec::Vec; use crate::read::{ - self, Architecture, CodeView, ComdatKind, CompressedData, CompressedFileRange, Export, + self, Architecture, CodeView, ComdatKind, CompressedData, CompressedFileRange, Error, Export, FileFlags, Import, ObjectKind, ObjectMap, Relocation, Result, SectionFlags, SectionIndex, SectionKind, SegmentFlags, SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, SymbolMapName, SymbolScope, SymbolSection, @@ -119,6 +119,21 @@ pub trait Object<'data: 'file, 'file>: read::private::Sealed { /// Returns an error if the index is invalid. fn symbol_by_index(&'file self, index: SymbolIndex) -> Result; + /// Get the address of symbol named `symbol_name`, if such a symbol exists. + fn symbol_address_by_name(&'file self, symbol_name: &str) -> Result { + if let Some(table) = self.symbol_table().or_else(|| self.dynamic_symbol_table()) { + for symbol in table.symbols() { + if !symbol.is_definition() { + continue; + } + if symbol.name() == Ok(symbol_name) { + return Ok(symbol.address()); + } + } + } + return Err(Error("Invalid symbol name")); + } + /// Get an iterator over the debugging symbols in the file. /// /// This may skip over symbols that are malformed or unsupported. diff --git a/src/read/xcoff/symbol.rs b/src/read/xcoff/symbol.rs index 6738ad17..af218495 100644 --- a/src/read/xcoff/symbol.rs +++ b/src/read/xcoff/symbol.rs @@ -283,7 +283,8 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> | xcoff::C_HIDEXT | xcoff::C_FCN | xcoff::C_BLOCK - | xcoff::C_STAT => self.symbol.n_value().into(), + | xcoff::C_STAT + | xcoff::C_INFO => self.symbol.n_value().into(), _ => 0, } } @@ -408,7 +409,9 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> #[inline] fn flags(&self) -> SymbolFlags { - SymbolFlags::None + SymbolFlags::Xcoff { + n_sclass: self.symbol.n_sclass(), + } } } diff --git a/src/write/mod.rs b/src/write/mod.rs index ca9af518..33f4715c 100644 --- a/src/write/mod.rs +++ b/src/write/mod.rs @@ -31,6 +31,9 @@ pub use macho::MachOBuildVersion; #[cfg(feature = "pe")] pub mod pe; +#[cfg(feature = "xcoff")] +mod xcoff; + mod string; pub use string::StringId; @@ -233,6 +236,8 @@ impl<'a> Object<'a> { BinaryFormat::Elf => self.elf_section_info(section), #[cfg(feature = "macho")] BinaryFormat::MachO => self.macho_section_info(section), + #[cfg(feature = "xcoff")] + BinaryFormat::Xcoff => self.xcoff_section_info(section), _ => unimplemented!(), } } @@ -258,7 +263,7 @@ impl<'a> Object<'a> { fn has_subsections_via_symbols(&self) -> bool { match self.format { - BinaryFormat::Coff | BinaryFormat::Elf => false, + BinaryFormat::Coff | BinaryFormat::Elf | BinaryFormat::Xcoff => false, BinaryFormat::MachO => true, _ => unimplemented!(), } @@ -521,6 +526,8 @@ impl<'a> Object<'a> { BinaryFormat::Elf => self.elf_fixup_relocation(&mut relocation)?, #[cfg(feature = "macho")] BinaryFormat::MachO => self.macho_fixup_relocation(&mut relocation), + #[cfg(feature = "xcoff")] + BinaryFormat::Xcoff => self.xcoff_fixup_relocation(&mut relocation), _ => unimplemented!(), }; if addend != 0 { @@ -589,6 +596,8 @@ impl<'a> Object<'a> { BinaryFormat::Elf => self.elf_write(buffer), #[cfg(feature = "macho")] BinaryFormat::MachO => self.macho_write(buffer), + #[cfg(feature = "xcoff")] + BinaryFormat::Xcoff => self.xcoff_write(buffer), _ => unimplemented!(), } } @@ -908,6 +917,8 @@ pub enum Mangling { Elf, /// Mach-O symbol mangling. MachO, + /// Xcoff symbol mangling. + Xcoff, } impl Mangling { @@ -918,6 +929,7 @@ impl Mangling { (BinaryFormat::Coff, _) => Mangling::Coff, (BinaryFormat::Elf, _) => Mangling::Elf, (BinaryFormat::MachO, _) => Mangling::MachO, + (BinaryFormat::Xcoff, _) => Mangling::Xcoff, _ => Mangling::None, } } @@ -925,7 +937,7 @@ impl Mangling { /// Return the prefix to use for global symbols. pub fn global_prefix(self) -> Option { match self { - Mangling::None | Mangling::Elf | Mangling::Coff => None, + Mangling::None | Mangling::Elf | Mangling::Coff | Mangling::Xcoff => None, Mangling::CoffI386 | Mangling::MachO => Some(b'_'), } } diff --git a/src/write/xcoff.rs b/src/write/xcoff.rs new file mode 100644 index 00000000..5b9e9c58 --- /dev/null +++ b/src/write/xcoff.rs @@ -0,0 +1,507 @@ +use core::mem; + +use crate::endian::{BigEndian as BE, I16, U16, U32}; +use crate::write::string::*; +use crate::write::util::*; +use crate::write::*; + +use crate::{xcoff, AddressSize}; + +#[derive(Default, Clone, Copy)] +struct SectionOffsets { + address: usize, + data_offset: usize, + reloc_offset: usize, +} + +#[derive(Default, Clone, Copy)] +struct SymbolOffsets { + index: usize, + str_id: Option, + aux_count: u8, + storage_class: u8, +} + +impl<'a> Object<'a> { + pub(crate) fn xcoff_section_info( + &self, + section: StandardSection, + ) -> (&'static [u8], &'static [u8], SectionKind) { + match section { + StandardSection::Text => (&[], &b".text"[..], SectionKind::Text), + StandardSection::Data => (&[], &b".data"[..], SectionKind::Data), + StandardSection::ReadOnlyData + | StandardSection::ReadOnlyDataWithRel + | StandardSection::ReadOnlyString => (&[], &b".rdata"[..], SectionKind::ReadOnlyData), + StandardSection::UninitializedData => { + (&[], &b".bss"[..], SectionKind::UninitializedData) + } + StandardSection::Tls => (&[], &b".tdata"[..], SectionKind::Tls), + StandardSection::UninitializedTls => { + (&[], &b".tbss"[..], SectionKind::UninitializedTls) + } + StandardSection::TlsVariables => { + // Unsupported section. + (&[], &[], SectionKind::TlsVariables) + } + StandardSection::Common => { + // Unsupported section. + (&[], &[], SectionKind::Common) + } + } + } + + pub(crate) fn xcoff_fixup_relocation(&mut self, mut relocation: &mut Relocation) -> i64 { + let constant = match relocation.kind { + RelocationKind::Relative => relocation.addend + 4, + _ => relocation.addend, + }; + relocation.addend -= constant; + constant + } + + pub(crate) fn xcoff_write(&self, buffer: &mut dyn WritableBuffer) -> Result<()> { + let is_64 = match self.architecture.address_size().unwrap() { + AddressSize::U8 | AddressSize::U16 | AddressSize::U32 => false, + AddressSize::U64 => true, + }; + + let (hdr_size, sechdr_size, rel_size, sym_size) = if is_64 { + ( + mem::size_of::(), + mem::size_of::(), + mem::size_of::(), + mem::size_of::(), + ) + } else { + ( + mem::size_of::(), + mem::size_of::(), + mem::size_of::(), + mem::size_of::(), + ) + }; + + // Calculate offsets and build strtab. + let mut offset = 0; + let mut strtab = StringTable::default(); + // We place the shared address 0 immediately after the section header table. + let mut address = 0; + + // XCOFF file header. + offset += hdr_size; + // Section headers. + offset += self.sections.len() * sechdr_size; + + // Calculate size of section data. + let mut section_offsets = vec![SectionOffsets::default(); self.sections.len()]; + for (index, section) in self.sections.iter().enumerate() { + let len = section.data.len(); + let sectype = section.kind; + // Section address should be 0 for all sections except the .text, .data, and .bss sections. + if sectype == SectionKind::Data + || sectype == SectionKind::Text + || sectype == SectionKind::UninitializedData + { + section_offsets[index].address = address; + address += len; + address = align(address, 4); + } else { + section_offsets[index].address = 0; + } + if len != 0 { + // Set the default section alignment as 4. + offset = align(offset, 4); + section_offsets[index].data_offset = offset; + offset += len; + } else { + section_offsets[index].data_offset = 0; + } + } + + // Calculate size of relocations. + for (index, section) in self.sections.iter().enumerate() { + let count = section.relocations.len(); + if count != 0 { + section_offsets[index].reloc_offset = offset; + offset += count * rel_size; + } else { + section_offsets[index].reloc_offset = 0; + } + } + + // Calculate size of symbols. + let mut symbol_offsets = vec![SymbolOffsets::default(); self.symbols.len()]; + let mut symtab_count = 0; + for (index, symbol) in self.symbols.iter().enumerate() { + symbol_offsets[index].index = symtab_count; + if is_64 || symbol.name.len() > 8 { + symbol_offsets[index].str_id = Some(strtab.add(&symbol.name)); + } + symtab_count += 1; + symbol_offsets[index].aux_count = 0; + let storage_class = if let SymbolFlags::Xcoff { n_sclass } = symbol.flags { + n_sclass + } else { + match symbol.kind { + SymbolKind::File => xcoff::C_FILE, + SymbolKind::Null => xcoff::C_NULL, + SymbolKind::Data | SymbolKind::Text => { + if symbol.is_local() { + xcoff::C_STAT + } else { + xcoff::C_EXT + } + } + SymbolKind::Label => { + if symbol.is_undefined() { + xcoff::C_ULABEL + } else { + xcoff::C_LABEL + } + } + SymbolKind::Tls => { + if symbol.is_local() { + xcoff::C_STTLS + } else { + xcoff::C_GTLS + } + } + SymbolKind::Section => { + if symbol.weak { + xcoff::C_WEAKEXT + } else if symbol.is_undefined() { + xcoff::C_HIDEXT + } else { + xcoff::C_EXT + } + } + SymbolKind::Unknown => { + return Err(Error(format!( + "unimplemented symbol `{}` kind {:?}", + symbol.name().unwrap_or(""), + symbol.kind + ))); + } + } + }; + symbol_offsets[index].storage_class = storage_class; + match storage_class { + xcoff::C_EXT | xcoff::C_WEAKEXT | xcoff::C_HIDEXT => { + symbol_offsets[index].aux_count = 1; + symtab_count += 1; + } + // TODO: support auxiliary entry for other types of symbol. + _ => {} + } + } + let symtab_offset = offset; + let symtab_len = symtab_count * sym_size; + offset += symtab_len; + + // Calculate size of strtab. + let strtab_offset = offset; + let mut strtab_data = Vec::new(); + // First 4 bytes of strtab are the length. + strtab.write(4, &mut strtab_data); + let strtab_len = strtab_data.len() + 4; + offset += strtab_len; + + // Start writing. + buffer + .reserve(offset) + .map_err(|_| Error(String::from("Cannot allocate buffer")))?; + + // Write file header. + if is_64 { + let header = xcoff::FileHeader64 { + f_magic: U16::new(BE, xcoff::MAGIC_64), + f_nscns: U16::new(BE, self.sections.len() as u16), + f_timdat: U32::new(BE, 0), + f_symptr: U64::new(BE, symtab_offset as u64), + f_nsyms: U32::new(BE, symtab_count as u32), + f_opthdr: U16::new(BE, 0), + f_flags: match self.flags { + FileFlags::Xcoff { f_flags } => U16::new(BE, f_flags), + _ => U16::default(), + }, + }; + buffer.write(&header); + } else { + let header = xcoff::FileHeader32 { + f_magic: U16::new(BE, xcoff::MAGIC_32), + f_nscns: U16::new(BE, self.sections.len() as u16), + f_timdat: U32::new(BE, 0), + f_symptr: U32::new(BE, symtab_offset as u32), + f_nsyms: U32::new(BE, symtab_count as u32), + f_opthdr: U16::new(BE, 0), + f_flags: match self.flags { + FileFlags::Xcoff { f_flags } => U16::new(BE, f_flags), + _ => U16::default(), + }, + }; + buffer.write(&header); + } + + // Write section headers. + for (index, section) in self.sections.iter().enumerate() { + let mut sectname = [0; 8]; + sectname + .get_mut(..section.name.len()) + .ok_or_else(|| { + Error(format!( + "section name `{}` is too long", + section.name().unwrap_or(""), + )) + })? + .copy_from_slice(§ion.name); + let flags = if let SectionFlags::Xcoff { s_flags } = section.flags { + s_flags + } else { + match section.kind { + SectionKind::Text + | SectionKind::ReadOnlyData + | SectionKind::ReadOnlyString + | SectionKind::ReadOnlyDataWithRel => xcoff::STYP_TEXT, + SectionKind::Data => xcoff::STYP_DATA, + SectionKind::UninitializedData => xcoff::STYP_BSS, + SectionKind::Tls => xcoff::STYP_TDATA, + SectionKind::UninitializedTls => xcoff::STYP_TBSS, + SectionKind::OtherString => xcoff::STYP_INFO, + SectionKind::Debug => xcoff::STYP_DEBUG, + SectionKind::Other | SectionKind::Metadata => 0, + SectionKind::Note + | SectionKind::Linker + | SectionKind::Common + | SectionKind::Unknown + | SectionKind::TlsVariables + | SectionKind::Elf(_) => { + return Err(Error(format!( + "unimplemented section `{}` kind {:?}", + section.name().unwrap_or(""), + section.kind + ))); + } + } + .into() + }; + if is_64 { + let section_header = xcoff::SectionHeader64 { + s_name: sectname, + s_paddr: U64::new(BE, section_offsets[index].address as u64), + // This field has the same value as the s_paddr field. + s_vaddr: U64::new(BE, section_offsets[index].address as u64), + s_size: U64::new(BE, section.data.len() as u64), + s_scnptr: U64::new(BE, section_offsets[index].data_offset as u64), + s_relptr: U64::new(BE, section_offsets[index].reloc_offset as u64), + s_lnnoptr: U64::new(BE, 0), + s_nreloc: U32::new(BE, section.relocations.len() as u32), + s_nlnno: U32::new(BE, 0), + s_flags: U32::new(BE, flags), + s_reserve: U32::new(BE, 0), + }; + buffer.write(§ion_header); + } else { + let section_header = xcoff::SectionHeader32 { + s_name: sectname, + s_paddr: U32::new(BE, 0), + s_vaddr: U32::new(BE, 0), + s_size: U32::new(BE, section.data.len() as u32), + s_scnptr: U32::new(BE, section_offsets[index].data_offset as u32), + s_relptr: U32::new(BE, section_offsets[index].reloc_offset as u32), + s_lnnoptr: U32::new(BE, 0), + // TODO: If more than 65,534 relocation entries are required, the field + // value will be 65535, and an STYP_OVRFLO section header will contain + // the actual count of relocation entries in the s_paddr field. + s_nreloc: U16::new(BE, section.relocations.len() as u16), + s_nlnno: U16::new(BE, 0), + s_flags: U32::new(BE, flags), + }; + buffer.write(§ion_header); + } + } + + // Write section data. + for (index, section) in self.sections.iter().enumerate() { + let len = section.data.len(); + if len != 0 { + write_align(buffer, 4); + debug_assert_eq!(section_offsets[index].data_offset, buffer.len()); + buffer.write_bytes(§ion.data); + } + } + + // Write relocations. + for (index, section) in self.sections.iter().enumerate() { + if !section.relocations.is_empty() { + debug_assert_eq!(section_offsets[index].reloc_offset, buffer.len()); + for reloc in §ion.relocations { + let rtype = match reloc.kind { + RelocationKind::Absolute => xcoff::R_POS, + RelocationKind::Relative => xcoff::R_REL, + RelocationKind::Got => xcoff::R_TOC, + RelocationKind::Xcoff(x) => x, + _ => { + return Err(Error(format!("unimplemented relocation {:?}", reloc))); + } + }; + if is_64 { + let xcoff_rel = xcoff::Rel64 { + r_vaddr: U64::new(BE, reloc.offset as u64), + r_symndx: U32::new(BE, symbol_offsets[reloc.symbol.0].index as u32), + // Specifies the bit length of the relocatable reference minus one. + r_rsize: (reloc.size - 1), + r_rtype: rtype, + }; + buffer.write(&xcoff_rel); + } else { + let xcoff_rel = xcoff::Rel32 { + r_vaddr: U32::new(BE, reloc.offset as u32), + r_symndx: U32::new(BE, symbol_offsets[reloc.symbol.0].index as u32), + r_rsize: (reloc.size - 1), + r_rtype: rtype, + }; + buffer.write(&xcoff_rel); + } + } + } + } + + // Write symbols. + debug_assert_eq!(symtab_offset, buffer.len()); + for (index, symbol) in self.symbols.iter().enumerate() { + let (n_scnum, section) = match symbol.section { + SymbolSection::None => { + debug_assert_eq!(symbol.kind, SymbolKind::File); + (xcoff::N_DEBUG, None) + } + SymbolSection::Undefined | SymbolSection::Common => (xcoff::N_UNDEF, None), + SymbolSection::Absolute => (xcoff::N_ABS, None), + SymbolSection::Section(id) => (id.0 as i16 + 1, Some(&self.sections[id.0])), + }; + let n_sclass = symbol_offsets[index].storage_class; + let n_type = if (symbol.scope == SymbolScope::Linkage) + && (n_sclass == xcoff::C_EXT + || n_sclass == xcoff::C_WEAKEXT + || n_sclass == xcoff::C_HIDEXT) + { + xcoff::SYM_V_HIDDEN + } else { + 0 + }; + let n_numaux = symbol_offsets[index].aux_count; + if is_64 { + let xcoff_sym = xcoff::Symbol64 { + n_value: U64::new(BE, symbol.value), + n_offset: U32::new( + BE, + strtab.get_offset(symbol_offsets[index].str_id.unwrap()) as u32, + ), + n_scnum: I16::new(BE, n_scnum), + n_type: U16::new(BE, n_type), + n_sclass: n_sclass, + n_numaux: n_numaux, + }; + buffer.write(&xcoff_sym); + } else { + let mut sym_name = [0; 8]; + let name = &symbol.name[..]; + if name.len() <= 8 { + sym_name[..name.len()].copy_from_slice(name); + } else { + let str_offset = strtab.get_offset(symbol_offsets[index].str_id.unwrap()); + sym_name[4..8].copy_from_slice(&u32::to_be_bytes(str_offset as u32)); + } + let xcoff_sym = xcoff::Symbol32 { + n_name: sym_name, + n_value: U32::new(BE, symbol.value as u32), + n_scnum: I16::new(BE, n_scnum), + n_type: U16::new(BE, n_type), + n_sclass: n_sclass, + n_numaux: n_numaux, + }; + buffer.write(&xcoff_sym); + } + // Generate a csect auxiliary entry for C_EXT, C_WEAKEXT, and C_HIDEXT Symbols. + if n_sclass == xcoff::C_EXT + || n_sclass == xcoff::C_WEAKEXT + || n_sclass == xcoff::C_HIDEXT + { + debug_assert_eq!(n_numaux, 1); + let (x_smtyp, x_smclas) = if let Some(section) = section { + match section.kind { + SectionKind::Data => (xcoff::XTY_SD, xcoff::XMC_RW), + SectionKind::Tls => (xcoff::XTY_SD, xcoff::XMC_TL), + SectionKind::UninitializedData => (xcoff::XTY_CM, xcoff::XMC_BS), + SectionKind::UninitializedTls => (xcoff::XTY_CM, xcoff::XMC_UL), + SectionKind::ReadOnlyData | SectionKind::ReadOnlyString => { + (xcoff::XTY_SD, xcoff::XMC_RO) + } + SectionKind::Text | SectionKind::OtherString => { + if symbol.kind == SymbolKind::Label { + (xcoff::XTY_LD, xcoff::XMC_PR) + } else { + (xcoff::XTY_SD, xcoff::XMC_PR) + } + } + _ => { + return Err(Error(format!( + "unimplemented section `{}` kind {:?}", + section.name().unwrap_or(""), + section.kind + ))); + } + } + } else { + match symbol.kind { + SymbolKind::Text + | SymbolKind::Data + | SymbolKind::Tls + | SymbolKind::Section => { + let smt = xcoff::XTY_SD; + let smc = if symbol.kind == SymbolKind::Data { + xcoff::XMC_RW + } else { + xcoff::XMC_PR + }; + (smt, smc) + } + _ => (xcoff::XTY_ER, xcoff::XMC_PR), + } + }; + if is_64 { + let csect_aux = xcoff::CsectAux64 { + x_scnlen_lo: U32::new(BE, (symbol.size & 0xFFFFFFFF) as u32), + x_scnlen_hi: U32::new(BE, ((symbol.size >> 32) & 0xFFFFFFFF) as u32), + x_parmhash: U32::new(BE, 0), + x_snhash: U16::new(BE, 0), + x_smtyp: x_smtyp, + x_smclas: x_smclas, + pad: 0, + x_auxtype: xcoff::AUX_CSECT, + }; + buffer.write(&csect_aux); + } else { + let csect_aux = xcoff::CsectAux32 { + x_scnlen: U32::new(BE, symbol.size as u32), + x_parmhash: U32::new(BE, 0), + x_snhash: U16::new(BE, 0), + x_smtyp: x_smtyp, + x_smclas: x_smclas, + x_stab: U32::new(BE, 0), + x_snstab: U16::new(BE, 0), + }; + buffer.write(&csect_aux); + } + } + } + + // Write string table. + debug_assert_eq!(strtab_offset, buffer.len()); + buffer.write_bytes(&u32::to_be_bytes(strtab_len as u32)); + buffer.write_bytes(&strtab_data); + + debug_assert_eq!(offset, buffer.len()); + Ok(()) + } +} diff --git a/tests/round_trip/mod.rs b/tests/round_trip/mod.rs index 89bed8bf..667a013c 100644 --- a/tests/round_trip/mod.rs +++ b/tests/round_trip/mod.rs @@ -1,7 +1,7 @@ #![cfg(all(feature = "read", feature = "write"))] use object::read::{Object, ObjectSection, ObjectSymbol}; -use object::{read, write}; +use object::{read, write, SectionIndex}; use object::{ Architecture, BinaryFormat, Endianness, RelocationEncoding, RelocationKind, SectionKind, SymbolFlags, SymbolKind, SymbolScope, SymbolSection, @@ -449,3 +449,98 @@ fn macho_x86_64() { assert_eq!(symbol.name(), "_func1"); assert_eq!(map.get(func1_offset - 1), None); } + +#[cfg(feature = "xcoff")] +#[test] +fn xcoff_powerpc() { + for arch in [Architecture::PowerPc, Architecture::PowerPc64] { + let mut object = write::Object::new(BinaryFormat::Xcoff, arch, Endianness::Big); + + object.add_file_symbol(b"file.c".to_vec()); + + let text = object.section_id(write::StandardSection::Text); + object.append_section_data(text, &[1; 30], 4); + + let func1_offset = object.append_section_data(text, &[1; 30], 4); + assert_eq!(func1_offset, 32); + let func1_symbol = object.add_symbol(write::Symbol { + name: b"func1".to_vec(), + value: func1_offset, + size: 32, + kind: SymbolKind::Text, + scope: SymbolScope::Linkage, + weak: false, + section: write::SymbolSection::Section(text), + flags: SymbolFlags::None, + }); + + object + .add_relocation( + text, + write::Relocation { + offset: 8, + size: 64, + kind: RelocationKind::Absolute, + encoding: RelocationEncoding::Generic, + symbol: func1_symbol, + addend: 0, + }, + ) + .unwrap(); + + let bytes = object.write().unwrap(); + let object = read::File::parse(&*bytes).unwrap(); + assert_eq!(object.format(), BinaryFormat::Xcoff); + assert_eq!(object.architecture(), arch); + assert_eq!(object.endianness(), Endianness::Big); + + let mut sections = object.sections(); + + let text = sections.next().unwrap(); + println!("{:?}", text); + let text_index = text.index().0 + 1; + assert_eq!(text.name(), Ok(".text")); + assert_eq!(text.kind(), SectionKind::Text); + assert_eq!(text.address(), 0); + assert_eq!(text.size(), 62); + assert_eq!(&text.data().unwrap()[..30], &[1; 30]); + assert_eq!(&text.data().unwrap()[32..62], &[1; 30]); + + let mut symbols = object.symbols(); + + let mut symbol = symbols.next().unwrap(); + println!("{:?}", symbol); + assert_eq!(symbol.name(), Ok("file.c")); + assert_eq!(symbol.address(), 0); + assert_eq!(symbol.kind(), SymbolKind::File); + assert_eq!(symbol.section_index(), None); + assert_eq!(symbol.scope(), SymbolScope::Compilation); + assert_eq!(symbol.is_weak(), false); + assert_eq!(symbol.is_undefined(), false); + + symbol = symbols.next().unwrap(); + println!("{:?}", symbol); + let func1_symbol = symbol.index(); + assert_eq!(symbol.name(), Ok("func1")); + assert_eq!(symbol.address(), func1_offset); + assert_eq!(symbol.kind(), SymbolKind::Text); + assert_eq!(symbol.section_index(), Some(SectionIndex(text_index))); + assert_eq!(symbol.scope(), SymbolScope::Linkage); + assert_eq!(symbol.is_weak(), false); + assert_eq!(symbol.is_undefined(), false); + + let mut relocations = text.relocations(); + + let (offset, relocation) = relocations.next().unwrap(); + println!("{:?}", relocation); + assert_eq!(offset, 8); + assert_eq!(relocation.kind(), RelocationKind::Absolute); + assert_eq!(relocation.encoding(), RelocationEncoding::Generic); + assert_eq!(relocation.size(), 64); + assert_eq!( + relocation.target(), + read::RelocationTarget::Symbol(func1_symbol) + ); + assert_eq!(relocation.addend(), 0); + } +}