From 93a77a441afbce5c72abf41442e154c103a108ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 9 Aug 2016 16:24:33 +0300 Subject: [PATCH] Update patches for lld 3.9 The previously existing patch needed some modifications to fit on top of lld 3.9. Patch 2 makes sure that one still can use the lld built in this way for linking in MSVC mode. Patch 3 fixes linking binaries larger than 4 MB or so (previously the binaries linked fine but didn't work). Patch 4 makes sure to error out if the relocations are too far away (instead of producing a broken binary), which happens after 16 MB. Patch 5 fixes relocations that have an offset, which probably happens in hand-written assembly (in libav). --- patches/lld-0001.patch | 122 +++++++++++++++++++---------------------- patches/lld-0002.patch | 61 +++++++++++++++++++++ patches/lld-0003.patch | 82 +++++++++++++++++++++++++++ patches/lld-0004.patch | 64 +++++++++++++++++++++ patches/lld-0005.patch | 77 ++++++++++++++++++++++++++ 5 files changed, 341 insertions(+), 65 deletions(-) create mode 100644 patches/lld-0002.patch create mode 100644 patches/lld-0003.patch create mode 100644 patches/lld-0004.patch create mode 100644 patches/lld-0005.patch diff --git a/patches/lld-0001.patch b/patches/lld-0001.patch index 4029c22..5506f05 100644 --- a/patches/lld-0001.patch +++ b/patches/lld-0001.patch @@ -1,29 +1,35 @@ -From 38ed8e461edd6df0c7f2ba2d0e8d36f6288d231e Mon Sep 17 00:00:00 2001 +From 808dcadd650fd54174a0c033547a6668bf77e4f1 Mon Sep 17 00:00:00 2001 From: Martell Malone Date: Wed, 28 Oct 2015 19:32:16 +0000 -Subject: [PATCH] add support for gnu arguments in lld coff +Subject: [PATCH 1/5] add support for gnu arguments in lld coff +--- + COFF/Driver.cpp | 31 ++++++++++++++++++++++++++++++- + COFF/Driver.h | 3 +++ + COFF/DriverUtils.cpp | 2 +- + COFF/Options.td | 20 ++++++++++++++++++++ + tools/lld/lld.cpp | 21 +++++++++++++++++++++ + 5 files changed, 75 insertions(+), 2 deletions(-) diff --git a/COFF/Driver.cpp b/COFF/Driver.cpp -index f528daf..34f422c 100644 +index bb6a60e..0821591 100644 --- a/COFF/Driver.cpp +++ b/COFF/Driver.cpp -@@ -119,6 +119,7 @@ void LinkerDriver::parseDirectives(StringRef S) { - case OPT_editandcontinue: +@@ -125,6 +125,7 @@ void LinkerDriver::parseDirectives(StringRef S) { + case OPT_fastfail: case OPT_guardsym: case OPT_throwingnew: + case OPT_aligncomm: break; default: - error(Twine(Arg->getSpelling()) + " is not allowed in .drectve"); -@@ -147,6 +148,31 @@ StringRef LinkerDriver::doFindFile(StringRef Filename) { + fatal(Arg->getSpelling() + " is not allowed in .drectve"); +@@ -153,6 +154,31 @@ StringRef LinkerDriver::doFindFile(StringRef Filename) { return Filename; } +// Searches a given library from input search paths, which are filled +// from -L command line switches. Returns a path to an existent library file. +StringRef LinkerDriver::searchLibrary(StringRef Filename) { -+// error("Unable to find library -l" + Filename); + + std::vector Names; + if (Filename[0] == ':') { @@ -42,13 +48,14 @@ index f528daf..34f422c 100644 + return Alloc.save(Path.str()); + } + } -+ error("Unable to find library -l" + Filename); ++ fatal("Unable to find library -l" + Filename); ++ return ""; +} + // Resolves a file path. This never returns the same path // (in that case, it returns None). Optional LinkerDriver::findFile(StringRef Filename) { -@@ -438,6 +464,9 @@ void LinkerDriver::link(llvm::ArrayRef ArgsArr) { +@@ -452,6 +478,9 @@ void LinkerDriver::link(llvm::ArrayRef ArgsArr) { // for /defaultlib option. std::vector Paths; std::vector MBs; @@ -58,7 +65,7 @@ index f528daf..34f422c 100644 for (auto *Arg : Args.filtered(OPT_INPUT)) if (Optional Path = findFile(Arg->getValue())) Paths.push_back(*Path); -@@ -559,7 +588,7 @@ void LinkerDriver::link(llvm::ArrayRef ArgsArr) { +@@ -573,7 +602,7 @@ void LinkerDriver::link(llvm::ArrayRef ArgsArr) { if (Config->ImageBase == uint64_t(-1)) Config->ImageBase = getDefaultImageBase(); @@ -68,10 +75,10 @@ index f528daf..34f422c 100644 Config->SEHTable = Symtab.addRelative("___safe_se_handler_table", 0); Config->SEHCount = Symtab.addAbsolute("___safe_se_handler_count", 0); diff --git a/COFF/Driver.h b/COFF/Driver.h -index e50da20..c716678 100644 +index 23969ee..230ec35 100644 --- a/COFF/Driver.h +++ b/COFF/Driver.h -@@ -87,6 +87,9 @@ private: +@@ -84,6 +84,9 @@ private: StringRef doFindFile(StringRef Filename); StringRef doFindLib(StringRef Filename); @@ -82,10 +89,10 @@ index e50da20..c716678 100644 void addLibSearchPaths(); diff --git a/COFF/DriverUtils.cpp b/COFF/DriverUtils.cpp -index 391a8ab..e876de3 100644 +index 5d7dc2b..e2f1f2d 100644 --- a/COFF/DriverUtils.cpp +++ b/COFF/DriverUtils.cpp -@@ -650,7 +650,7 @@ static const llvm::opt::OptTable::Info infoTable[] = { +@@ -591,7 +591,7 @@ static const llvm::opt::OptTable::Info infoTable[] = { class COFFOptTable : public llvm::opt::OptTable { public: @@ -95,10 +102,10 @@ index 391a8ab..e876de3 100644 // Parses a given list of options. diff --git a/COFF/Options.td b/COFF/Options.td -index a21b8de..3418de5 100644 +index e5c9c5b..322b162 100644 --- a/COFF/Options.td +++ b/COFF/Options.td -@@ -92,6 +92,26 @@ def nosymtab : F<"nosymtab">; +@@ -93,6 +93,26 @@ def nosymtab : F<"nosymtab">; // Flags for debugging def lldmap : Joined<["/", "-"], "lldmap:">; @@ -125,60 +132,45 @@ index a21b8de..3418de5 100644 //============================================================================== // The flags below do nothing. They are defined only for link.exe compatibility. //============================================================================== -diff --git a/lib/Driver/UniversalDriver.cpp b/lib/Driver/UniversalDriver.cpp -index 3dea7eb..268dafb 100644 ---- a/lib/Driver/UniversalDriver.cpp -+++ b/lib/Driver/UniversalDriver.cpp -@@ -95,6 +95,21 @@ static Flavor strToFlavor(StringRef str) { - .Default(Flavor::invalid); +diff --git a/tools/lld/lld.cpp b/tools/lld/lld.cpp +index 8805e02..68c8735 100644 +--- a/tools/lld/lld.cpp ++++ b/tools/lld/lld.cpp +@@ -51,6 +51,24 @@ static Flavor getFlavor(StringRef S) { + .Default(Invalid); } -+//std::pair getTargetFromEmulation -+ -+static bool isPETarget(const llvm::opt::InputArgList &parsedArgs) { -+ llvm::opt::Arg *argMachine = parsedArgs.getLastArg(OPT_m); -+ if (!argMachine) -+ return false; -+ if (argMachine->containsValue("i386pe")) -+ return true; -+ if (argMachine->containsValue("i386pep")) -+ return true; -+ if (argMachine->containsValue("thumb2pe")) -+ return true; ++static bool isPETarget(const std::vector &V) { ++ for (auto It = V.begin(); It != V.end(); It++) { ++ if (*It == StringRef("-m")) { ++ It++; ++ if (It == V.end()) ++ return false; ++ if (*It == StringRef("i386pe")) ++ return true; ++ if (*It == StringRef("i386pep")) ++ return true; ++ if (*It == StringRef("thumb2pe")) ++ return true; ++ return false; ++ } ++ } + return false; +} + - static ProgramNameParts parseProgramName(StringRef programName) { - SmallVector components; - llvm::SplitString(programName, components, "-"); -@@ -198,6 +213,12 @@ bool UniversalDriver::link(llvm::MutableArrayRef args, - return true; - } + static Flavor parseProgname(StringRef Progname) { + #if __APPLE__ + // Use Darwin driver for "ld" on Darwin. +@@ -101,6 +119,9 @@ int main(int Argc, const char **Argv) { + llvm_shutdown_obj Shutdown; -+ //Override gnu for pe targets to use coff -+ if(isPETarget(parsedArgs)) { -+ coff::link(args); -+ return true; -+ } + std::vector Args(Argv, Argv + Argc); ++ if (isPETarget(Args)) ++ return !coff::link(Args); + - Flavor flavor = getFlavor(args, parsedArgs); - - // Switch to appropriate driver. -diff --git a/lib/Driver/UniversalDriverOptions.td b/lib/Driver/UniversalDriverOptions.td -index 14abc9c..38e620b 100644 ---- a/lib/Driver/UniversalDriverOptions.td -+++ b/lib/Driver/UniversalDriverOptions.td -@@ -11,6 +11,10 @@ def core : Flag<["-"], "core">, - def target: Separate<["-"], "target">, - HelpText<"Select the target">; - -+// Used to override gnu pe targets -+def m : Separate<["-"], "m">, MetaVarName<"">, -+ HelpText<"Select target emulation">; -+ - def version: Flag<["-"], "version">, - HelpText<"Display the version">; - + switch (parseFlavor(Args)) { + case Gnu: + return !elf::link(Args); -- -2.6.3 +2.7.4 diff --git a/patches/lld-0002.patch b/patches/lld-0002.patch new file mode 100644 index 0000000..86276db --- /dev/null +++ b/patches/lld-0002.patch @@ -0,0 +1,61 @@ +From f8cba388440ff846c5f479889fc64a03066ff39c Mon Sep 17 00:00:00 2001 +From: Martin Storsjo +Date: Mon, 8 Aug 2016 15:37:59 +0300 +Subject: [PATCH 2/5] Make the "gnu arguments in lld coff" patch not break + using lld-link in normal MSVC mode + +--- + COFF/Driver.cpp | 1 + + COFF/DriverUtils.cpp | 5 ++++- + COFF/Options.td | 2 ++ + 3 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/COFF/Driver.cpp b/COFF/Driver.cpp +index 0821591..65cfa9f 100644 +--- a/COFF/Driver.cpp ++++ b/COFF/Driver.cpp +@@ -602,6 +602,7 @@ void LinkerDriver::link(llvm::ArrayRef ArgsArr) { + if (Config->ImageBase == uint64_t(-1)) + Config->ImageBase = getDefaultImageBase(); + ++ Symtab.addRelative(mangle("__ImageBase"), 0); + Symtab.addRelative(mangle("__image_base__"), 0); + if (Config->Machine == I386) { + Config->SEHTable = Symtab.addRelative("___safe_se_handler_table", 0); +diff --git a/COFF/DriverUtils.cpp b/COFF/DriverUtils.cpp +index e2f1f2d..f9c37ec 100644 +--- a/COFF/DriverUtils.cpp ++++ b/COFF/DriverUtils.cpp +@@ -591,7 +591,10 @@ static const llvm::opt::OptTable::Info infoTable[] = { + + class COFFOptTable : public llvm::opt::OptTable { + public: +- COFFOptTable() : OptTable(infoTable) {} ++ // GNU ld option style support requires case sensitive option matching ++ // (for -L vs -l), needing aliases for a few link.exe options that can ++ // appear in upper case in embedded directives in libraries. ++ COFFOptTable() : OptTable(infoTable, false) {} + }; + + // Parses a given list of options. +diff --git a/COFF/Options.td b/COFF/Options.td +index 322b162..4e7338a 100644 +--- a/COFF/Options.td ++++ b/COFF/Options.td +@@ -19,11 +19,13 @@ def align : P<"align", "Section alignment">; + def alternatename : P<"alternatename", "Define weak alias">; + def base : P<"base", "Base address of the program">; + def defaultlib : P<"defaultlib", "Add the library to the list of input files">; ++def DEFAULTLIB : P<"DEFAULTLIB", "">, Alias; + def delayload : P<"delayload", "Delay loaded DLL name">; + def entry : P<"entry", "Name of entry point symbol">; + def export : P<"export", "Export a function">; + // No help text because /failifmismatch is not intended to be used by the user. + def failifmismatch : P<"failifmismatch", "">; ++def FAILIFMISMATCH : P<"FAILIFMISMATCH", "">, Alias; + def heap : P<"heap", "Size of the heap">; + def implib : P<"implib", "Import library name">; + def libpath : P<"libpath", "Additional library search path">; +-- +2.7.4 + diff --git a/patches/lld-0003.patch b/patches/lld-0003.patch new file mode 100644 index 0000000..517f7fa --- /dev/null +++ b/patches/lld-0003.patch @@ -0,0 +1,82 @@ +From 2f3ad0343836886143c1f8ac83552c6734e05205 Mon Sep 17 00:00:00 2001 +From: Saleem Abdulrasool +Date: Fri, 5 Aug 2016 17:28:21 +0000 +Subject: [PATCH 3/5] COFF ARM: Clear the J1 and J2 bits when applying + relocations to 24 bit branches +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The opcode for the bl branches can initially be F000 F800, i.e. +the J1 and J2 bits are already set. Therefore mask these bits out +before or'ing in the new bits. + +Patch by Martin Storsjö! + +Cherry-picked from SVN trunk commit 277836, git mirror commit +7b7d94e63a. +--- + COFF/Chunks.cpp | 3 ++- + test/COFF/reloc-arm.test | 13 +++++++++++-- + 2 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/COFF/Chunks.cpp b/COFF/Chunks.cpp +index 1c1b181..2e6f535 100644 +--- a/COFF/Chunks.cpp ++++ b/COFF/Chunks.cpp +@@ -103,7 +103,8 @@ static void applyBranch24T(uint8_t *Off, int32_t V) { + uint32_t J1 = ((~V >> 23) & 1) ^ S; + uint32_t J2 = ((~V >> 22) & 1) ^ S; + or16(Off, (S << 10) | ((V >> 12) & 0x3ff)); +- or16(Off + 2, (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff)); ++ // Clear out the J1 and J2 bits which may be set. ++ write16le(Off + 2, (read16le(Off + 2) & 0xd000) | (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff)); + } + + void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, Defined *Sym, +diff --git a/test/COFF/reloc-arm.test b/test/COFF/reloc-arm.test +index 11b863d..f7656e7 100644 +--- a/test/COFF/reloc-arm.test ++++ b/test/COFF/reloc-arm.test +@@ -9,7 +9,7 @@ + # CHECK: 402030 fe07e62f 00000000 00000000 00000000 + # CHECK: 402040 3e04de2f 00000000 00000000 00000000 + # CHECK: 402050 fe07d62f 00000000 00000000 00000000 +-# CHECK: 402060 00000000 00000000 00000000 00000000 ++# CHECK: 402060 fef0cef7 00000000 00000000 00000000 + + --- !COFF + header: +@@ -23,7 +23,7 @@ sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 4096 +- SectionData: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ++ SectionData: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f000f8000000000000000000000000 + Relocations: + - VirtualAddress: 0 + SymbolName: foo +@@ -43,6 +43,9 @@ sections: + - VirtualAddress: 80 + SymbolName: foo + Type: 21 # IMAGE_REL_AMD64_BLX23T ++ - VirtualAddress: 96 ++ SymbolName: bar ++ Type: 20 # IMAGE_REL_ARM_BRANCH24T + symbols: + - Name: .aaa + Value: 0 +@@ -68,4 +71,10 @@ symbols: + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL ++ - Name: bar ++ Value: 0x500000 ++ SectionNumber: 1 ++ SimpleType: IMAGE_SYM_TYPE_NULL ++ ComplexType: IMAGE_SYM_DTYPE_NULL ++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL + ... +-- +2.7.4 + diff --git a/patches/lld-0004.patch b/patches/lld-0004.patch new file mode 100644 index 0000000..06d8134 --- /dev/null +++ b/patches/lld-0004.patch @@ -0,0 +1,64 @@ +From 13f5a9ac209dd87b8e3c22151a139954a49a0674 Mon Sep 17 00:00:00 2001 +From: Saleem Abdulrasool +Date: Fri, 5 Aug 2016 17:33:24 +0000 +Subject: [PATCH 4/5] COFF ARM: Error out if 24 bit thumb branches are out of + range +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In the ELF linker, the same situation already errors out with "relocation +R_ARM_THM_CALL out of range". + +Patch by Martin Storsjö! + +Cherry-picked from SVN trunk commit 277838, git mirror commit +97497d40eee0. +--- + COFF/Chunks.cpp | 2 ++ + test/COFF/Inputs/far-arm-thumb-abs.s | 2 ++ + test/COFF/arm-thumb-branch-error.s | 10 ++++++++++ + 3 files changed, 14 insertions(+) + create mode 100644 test/COFF/Inputs/far-arm-thumb-abs.s + create mode 100644 test/COFF/arm-thumb-branch-error.s + +diff --git a/COFF/Chunks.cpp b/COFF/Chunks.cpp +index 2e6f535..fb60a8b 100644 +--- a/COFF/Chunks.cpp ++++ b/COFF/Chunks.cpp +@@ -99,6 +99,8 @@ static void applyBranch20T(uint8_t *Off, int32_t V) { + } + + static void applyBranch24T(uint8_t *Off, int32_t V) { ++ if (!isInt<25>(V)) ++ fatal("relocation out of range"); + uint32_t S = V < 0 ? 1 : 0; + uint32_t J1 = ((~V >> 23) & 1) ^ S; + uint32_t J2 = ((~V >> 22) & 1) ^ S; +diff --git a/test/COFF/Inputs/far-arm-thumb-abs.s b/test/COFF/Inputs/far-arm-thumb-abs.s +new file mode 100644 +index 0000000..9f1b59a +--- /dev/null ++++ b/test/COFF/Inputs/far-arm-thumb-abs.s +@@ -0,0 +1,2 @@ ++.global too_far1 ++too_far1 = 0x1401004 +diff --git a/test/COFF/arm-thumb-branch-error.s b/test/COFF/arm-thumb-branch-error.s +new file mode 100644 +index 0000000..00b835c +--- /dev/null ++++ b/test/COFF/arm-thumb-branch-error.s +@@ -0,0 +1,10 @@ ++// RUN: llvm-mc -filetype=obj -triple=thumbv7a-windows-gnu %s -o %t ++// RUN: llvm-mc -filetype=obj -triple=thumbv7a-windows-gnu %S/Inputs/far-arm-thumb-abs.s -o %tfar ++// RUN: not lld-link -entry:_start -subsystem:console %t %tfar -out:%t2 2>&1 | FileCheck %s ++// REQUIRES: arm ++ .syntax unified ++ .globl _start ++_start: ++ bl too_far1 ++ ++// CHECK: relocation out of range +-- +2.7.4 + diff --git a/patches/lld-0005.patch b/patches/lld-0005.patch new file mode 100644 index 0000000..a59374a --- /dev/null +++ b/patches/lld-0005.patch @@ -0,0 +1,77 @@ +From c3fa3c7975a537df2e668ea59f074ce5be95b4f5 Mon Sep 17 00:00:00 2001 +From: Saleem Abdulrasool +Date: Fri, 5 Aug 2016 18:20:31 +0000 +Subject: [PATCH 5/5] COFF ARM: Apply an existing offset in MOV32T relocations +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Don't blindly OR in the new value, but clear the existing one, since it can be +nonzero. Read out the existing value before, and add into the desired offset. +(The add is done outside of the applyMOV, to handle potential overflow between +the two.) + +Patch by Martin Storsjö! + +Cherry-picked from SVN trunk commit 277846, git mirror commit +3d39965b0cdd0. +--- + COFF/Chunks.cpp | 16 ++++++++++++++-- + test/COFF/reloc-arm.test | 4 ++-- + 2 files changed, 16 insertions(+), 4 deletions(-) + +diff --git a/COFF/Chunks.cpp b/COFF/Chunks.cpp +index fb60a8b..b8d706e 100644 +--- a/COFF/Chunks.cpp ++++ b/COFF/Chunks.cpp +@@ -81,11 +81,23 @@ void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, Defined *Sym, + } + + static void applyMOV(uint8_t *Off, uint16_t V) { +- or16(Off, ((V & 0x800) >> 1) | ((V >> 12) & 0xf)); +- or16(Off + 2, ((V & 0x700) << 4) | (V & 0xff)); ++ write16le(Off, (read16le(Off) & 0xfbf0) | ((V & 0x800) >> 1) | ((V >> 12) & 0xf)); ++ write16le(Off + 2, (read16le(Off + 2) & 0x8f00) | ((V & 0x700) << 4) | (V & 0xff)); ++} ++ ++static uint16_t readMOV(uint8_t *Off) { ++ uint16_t Opcode1 = read16le(Off); ++ uint16_t Opcode2 = read16le(Off + 2); ++ uint16_t Imm = (Opcode2 & 0x00ff) | ((Opcode2 >> 4) & 0x0700); ++ Imm |= ((Opcode1 << 1) & 0x0800) | ((Opcode1 & 0x000f) << 12); ++ return Imm; + } + + static void applyMOV32T(uint8_t *Off, uint32_t V) { ++ uint16_t ImmW = readMOV(Off); // read MOVW operand ++ uint16_t ImmT = readMOV(Off + 4); // read MOVT operand ++ uint32_t Imm = ImmW | (ImmT << 16); ++ V += Imm; // add the immediate offset + applyMOV(Off, V); // set MOVW operand + applyMOV(Off + 4, V >> 16); // set MOVT operand + } +diff --git a/test/COFF/reloc-arm.test b/test/COFF/reloc-arm.test +index f7656e7..b9699e8 100644 +--- a/test/COFF/reloc-arm.test ++++ b/test/COFF/reloc-arm.test +@@ -5,7 +5,7 @@ + # CHECK: .text: + # CHECK: 402000 01104000 00000000 00000000 00000000 + # CHECK: 402010 01100000 00000000 00000000 00000000 +-# CHECK: 402020 01000100 00004000 00000000 00000000 ++# CHECK: 402020 41f20009 c0f24009 00000000 00000000 + # CHECK: 402030 fe07e62f 00000000 00000000 00000000 + # CHECK: 402040 3e04de2f 00000000 00000000 00000000 + # CHECK: 402050 fe07d62f 00000000 00000000 00000000 +@@ -23,7 +23,7 @@ sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 4096 +- SectionData: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f000f8000000000000000000000000 ++ SectionData: 00000000000000000000000000000000000000000000000000000000000000004ff6ff79cff6ff79000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f000f8000000000000000000000000 + Relocations: + - VirtualAddress: 0 + SymbolName: foo +-- +2.7.4 +