From 9ccf843a61bf7db4c57467c5c5761d66c1a87e52 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Wed, 22 Dec 2010 16:19:24 +0000 Subject: [PATCH] MC/Mach-O/ARM: Add enough relocation logic to get BR24 relocations. llvm-svn: 122407 --- llvm/lib/MC/MachObjectWriter.cpp | 29 +++++++- llvm/test/MC/MachO/darwin-ARM-reloc.s | 102 ++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 llvm/test/MC/MachO/darwin-ARM-reloc.s diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp index 97d8afb33806..93a3dcf8d919 100644 --- a/llvm/lib/MC/MachObjectWriter.cpp +++ b/llvm/lib/MC/MachObjectWriter.cpp @@ -24,6 +24,7 @@ #include "llvm/Target/TargetAsmBackend.h" // FIXME: Gross. +#include "../Target/ARM/ARMFixupKinds.h" #include "../Target/X86/X86FixupKinds.h" #include @@ -843,12 +844,33 @@ public: Relocations[Fragment->getParent()].push_back(MRE); } + static bool getARMFixupKindMachOInfo(unsigned Kind, bool &Is24BitBranch, + unsigned &Log2Size) { + switch (Kind) { + default: + return false; + + // Handle 24-bit branch kinds. + case ARM::fixup_arm_ldst_pcrel_12: + case ARM::fixup_arm_pcrel_10: + case ARM::fixup_arm_adr_pcrel_12: + case ARM::fixup_arm_branch: + Is24BitBranch = true; + // Report as 'long', even though that is not quite accurate. + Log2Size = llvm::Log2_32(4); + return true; + } + } void RecordARMRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) { unsigned IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); - // FIXME: Eliminate this! - unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); + unsigned Log2Size; + bool Is24BitBranch; + if (!getARMFixupKindMachOInfo(Fixup.getKind(), Is24BitBranch, Log2Size)) { + report_fatal_error("unknown ARM fixup kind!"); + return; + } // If this is a difference or a defined symbol plus an offset, then we need // a scattered relocation entry. Differences always require scattered @@ -912,7 +934,8 @@ public: if (IsPCRel) FixedValue -= getSectionAddress(Fragment->getParent()); - Type = macho::RIT_Vanilla; + // Determine the appropriate type based on the fixup kind. + Type = Is24BitBranch ? macho::RIT_ARM_Branch24Bit : macho::RIT_Vanilla; } // struct relocation_info (8 bytes) diff --git a/llvm/test/MC/MachO/darwin-ARM-reloc.s b/llvm/test/MC/MachO/darwin-ARM-reloc.s new file mode 100644 index 000000000000..2e99118f4624 --- /dev/null +++ b/llvm/test/MC/MachO/darwin-ARM-reloc.s @@ -0,0 +1,102 @@ +@ RUN: llvm-mc -n -triple armv7-apple-darwin10 %s -filetype=obj -o %t.obj +@ RUN: macho-dump --dump-section-data < %t.obj > %t.dump +@ RUN: FileCheck < %t.dump %s + + .syntax unified + .text +_f0: + bl _printf + +@ CHECK: ('cputype', 12) +@ CHECK: ('cpusubtype', 9) +@ CHECK: ('filetype', 1) +@ CHECK: ('num_load_commands', 3) +@ CHECK: ('load_commands_size', 228) +@ CHECK: ('flag', 0) +@ CHECK: ('load_commands', [ +@ CHECK: # Load Command 0 +@ CHECK: (('command', 1) +@ CHECK: ('size', 124) +@ CHECK: ('segment_name', '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +@ CHECK: ('vm_addr', 0) +@ CHECK: ('vm_size', 4) +@ CHECK: ('file_offset', 256) +@ CHECK: ('file_size', 4) +@ CHECK: ('maxprot', 7) +@ CHECK: ('initprot', 7) +@ CHECK: ('num_sections', 1) +@ CHECK: ('flags', 0) +@ CHECK: ('sections', [ +@ CHECK: # Section 0 +@ CHECK: (('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +@ CHECK: ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +@ CHECK: ('address', 0) +@ CHECK: ('size', 4) +@ CHECK: ('offset', 256) +@ CHECK: ('alignment', 0) +@ CHECK: ('reloc_offset', 260) +@ CHECK: ('num_reloc', 1) +@ CHECK: ('flags', 0x80000400) +@ CHECK: ('reserved1', 0) +@ CHECK: ('reserved2', 0) +@ CHECK: ), +@ CHECK: ('_relocations', [ +@ CHECK: # Relocation 0 +@ CHECK: (('word-0', 0x0), +@ CHECK: ('word-1', 0x5d000001)), +@ CHECK: ]) +@ CHECK: ('_section_data', 'feffffeb') +@ CHECK: ]) +@ CHECK: ), +@ CHECK: # Load Command 1 +@ CHECK: (('command', 2) +@ CHECK: ('size', 24) +@ CHECK: ('symoff', 268) +@ CHECK: ('nsyms', 2) +@ CHECK: ('stroff', 292) +@ CHECK: ('strsize', 16) +@ CHECK: ('_string_data', '\x00_printf\x00_f0\x00\x00\x00\x00') +@ CHECK: ('_symbols', [ +@ CHECK: # Symbol 0 +@ CHECK: (('n_strx', 9) +@ CHECK: ('n_type', 0xe) +@ CHECK: ('n_sect', 1) +@ CHECK: ('n_desc', 0) +@ CHECK: ('n_value', 0) +@ CHECK: ('_string', '_f0') +@ CHECK: ), +@ CHECK: # Symbol 1 +@ CHECK: (('n_strx', 1) +@ CHECK: ('n_type', 0x1) +@ CHECK: ('n_sect', 0) +@ CHECK: ('n_desc', 0) +@ CHECK: ('n_value', 0) +@ CHECK: ('_string', '_printf') +@ CHECK: ), +@ CHECK: ]) +@ CHECK: ), +@ CHECK: # Load Command 2 +@ CHECK: (('command', 11) +@ CHECK: ('size', 80) +@ CHECK: ('ilocalsym', 0) +@ CHECK: ('nlocalsym', 1) +@ CHECK: ('iextdefsym', 1) +@ CHECK: ('nextdefsym', 0) +@ CHECK: ('iundefsym', 1) +@ CHECK: ('nundefsym', 1) +@ CHECK: ('tocoff', 0) +@ CHECK: ('ntoc', 0) +@ CHECK: ('modtaboff', 0) +@ CHECK: ('nmodtab', 0) +@ CHECK: ('extrefsymoff', 0) +@ CHECK: ('nextrefsyms', 0) +@ CHECK: ('indirectsymoff', 0) +@ CHECK: ('nindirectsyms', 0) +@ CHECK: ('extreloff', 0) +@ CHECK: ('nextrel', 0) +@ CHECK: ('locreloff', 0) +@ CHECK: ('nlocrel', 0) +@ CHECK: ('_indirect_symbols', [ +@ CHECK: ]) +@ CHECK: ), +@ CHECK: ])