From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22706 invoked by alias); 27 Feb 2014 12:53:55 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 22696 invoked by uid 89); 27 Feb 2014 12:53:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 X-HELO: mailout1.w1.samsung.com Received: from mailout1.w1.samsung.com (HELO mailout1.w1.samsung.com) (210.118.77.11) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (DES-CBC3-SHA encrypted) ESMTPS; Thu, 27 Feb 2014 12:53:53 +0000 Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout1.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N1N00AV1NTQGKA0@mailout1.w1.samsung.com> for binutils@sourceware.org; Thu, 27 Feb 2014 12:53:50 +0000 (GMT) Received: from eusync3.samsung.com ( [203.254.199.213]) by eucpsbgm2.samsung.com (EUCPMTA) with SMTP id 94.A0.18565.D553F035; Thu, 27 Feb 2014 12:53:49 +0000 (GMT) Received: from [106.109.8.100] by eusync3.samsung.com (Oracle Communications Messaging Server 7u4-23.01(7.0.4.23.0) 64bit (built Aug 10 2011)) with ESMTPA id <0N1N008SENTPEC10@eusync3.samsung.com>; Thu, 27 Feb 2014 12:53:49 +0000 (GMT) Message-id: <530F355F.3010405@samsung.com> Date: Thu, 27 Feb 2014 12:53:00 -0000 From: Yury Gribov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.3.0 MIME-version: 1.0 To: nick clifton , Will Newton Cc: "binutils@sourceware.org" , Viacheslav Garbuzov , Yuri Gribov Subject: Re: [RFC][PATCH] Handle arbitrary .plt/.got displacements in ld on ARM References: <52F4B2B3.8060804@samsung.com> <52F8BD92.5080609@samsung.com> <5307609F.8070001@redhat.com> <530B6043.4070605@samsung.com> <530C5B23.2070306@redhat.com> In-reply-to: <530C5B23.2070306@redhat.com> Content-type: multipart/mixed; boundary=------------010900020208010706030004 X-IsSubscribed: yes X-SW-Source: 2014-02/txt/msg00161.txt.bz2 This is a multi-part message in MIME format. --------------010900020208010706030004 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 186 Nick wrote: > Fair enough - in which case the patch is approved - please apply. Unfortunately I don't have write access. Could someone commit it for me? Re-attaching just in case. -Y --------------010900020208010706030004 Content-Type: text/x-diff; name="long_plt_2.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="long_plt_2.diff" Content-length: 8171 diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index c7c5a7d..52fa19e 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -887,6 +887,8 @@ extern bfd_boolean bfd_is_arm_special_symbol_name extern void bfd_elf32_arm_set_byteswap_code (struct bfd_link_info *, int); +extern void bfd_elf32_arm_use_long_plt (void); + /* ARM Note section processing. */ extern bfd_boolean bfd_arm_merge_machines (bfd *, bfd *); diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 33792f4..92cd688 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -894,6 +894,8 @@ extern bfd_boolean bfd_is_arm_special_symbol_name extern void bfd_elf32_arm_set_byteswap_code (struct bfd_link_info *, int); +extern void bfd_elf32_arm_use_long_plt (void); + /* ARM Note section processing. */ extern bfd_boolean bfd_arm_merge_machines (bfd *, bfd *); diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 7216244..ecc5ee4 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -2140,15 +2140,27 @@ static const bfd_vma elf32_arm_plt0_entry [] = 0x00000000, /* &GOT[0] - . */ }; -/* Subsequent entries in a procedure linkage table look like - this. */ -static const bfd_vma elf32_arm_plt_entry [] = +/* By default subsequent entries in a procedure linkage table look like + this. Offsets that don't fit into 28 bits will cause link error. */ +static const bfd_vma elf32_arm_plt_entry_short [] = { 0xe28fc600, /* add ip, pc, #0xNN00000 */ 0xe28cca00, /* add ip, ip, #0xNN000 */ 0xe5bcf000, /* ldr pc, [ip, #0xNNN]! */ }; +/* When explicitly asked, we'll use this "long" entry format + which can cope with arbitrary displacements. */ +static const bfd_vma elf32_arm_plt_entry_long [] = + { + 0xe28fc200, /* add ip, pc, #0xN0000000 */ + 0xe28cc600, /* add ip, ip, #0xNN00000 */ + 0xe28cca00, /* add ip, ip, #0xNN000 */ + 0xe5bcf000, /* ldr pc, [ip, #0xNNN]! */ + }; + +static bfd_boolean elf32_arm_use_long_plt_entry = FALSE; + #endif /* The format of the first entry in the procedure linkage table @@ -3464,7 +3476,7 @@ elf32_arm_link_hash_table_create (bfd *abfd) ret->plt_entry_size = 16; #else ret->plt_header_size = 20; - ret->plt_entry_size = 12; + ret->plt_entry_size = elf32_arm_use_long_plt_entry ? 16 : 12; #endif ret->use_rel = 1; ret->obfd = abfd; @@ -6027,6 +6039,15 @@ arm_make_glue_section (bfd * abfd, const char * name) return TRUE; } +/* Set size of .plt entries. This function is called from the + linker scripts in ld/emultempl/{armelf}.em. */ + +void +bfd_elf32_arm_use_long_plt (void) +{ + elf32_arm_use_long_plt_entry = TRUE; +} + /* Add the glue sections to ABFD. This function is called from the linker scripts in ld/emultempl/{armelf}.em. */ @@ -7705,8 +7726,6 @@ elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info, of the PLT stub. */ got_displacement = got_address - (plt_address + 8); - BFD_ASSERT ((got_displacement & 0xf0000000) == 0); - if (elf32_arm_plt_needs_thumb_stub_p (info, arm_plt)) { put_thumb_insn (htab, output_bfd, @@ -7715,21 +7734,44 @@ elf32_arm_populate_plt_entry (bfd *output_bfd, struct bfd_link_info *info, elf32_arm_plt_thumb_stub[1], ptr - 2); } - put_arm_insn (htab, output_bfd, - elf32_arm_plt_entry[0] - | ((got_displacement & 0x0ff00000) >> 20), - ptr + 0); - put_arm_insn (htab, output_bfd, - elf32_arm_plt_entry[1] - | ((got_displacement & 0x000ff000) >> 12), - ptr+ 4); - put_arm_insn (htab, output_bfd, - elf32_arm_plt_entry[2] - | (got_displacement & 0x00000fff), - ptr + 8); + if (!elf32_arm_use_long_plt_entry) + { + BFD_ASSERT ((got_displacement & 0xf0000000) == 0); + put_arm_insn (htab, output_bfd, + elf32_arm_plt_entry_short[0] + | ((got_displacement & 0x0ff00000) >> 20), + ptr + 0); + put_arm_insn (htab, output_bfd, + elf32_arm_plt_entry_short[1] + | ((got_displacement & 0x000ff000) >> 12), + ptr+ 4); + put_arm_insn (htab, output_bfd, + elf32_arm_plt_entry_short[2] + | (got_displacement & 0x00000fff), + ptr + 8); #ifdef FOUR_WORD_PLT - bfd_put_32 (output_bfd, elf32_arm_plt_entry[3], ptr + 12); + bfd_put_32 (output_bfd, elf32_arm_plt_entry_short[3], ptr + 12); #endif + } + else + { + put_arm_insn (htab, output_bfd, + elf32_arm_plt_entry_long[0] + | ((got_displacement & 0xf0000000) >> 28), + ptr + 0); + put_arm_insn (htab, output_bfd, + elf32_arm_plt_entry_long[1] + | ((got_displacement & 0x0ff00000) >> 20), + ptr + 4); + put_arm_insn (htab, output_bfd, + elf32_arm_plt_entry_long[2] + | ((got_displacement & 0x000ff000) >> 12), + ptr+ 8); + put_arm_insn (htab, output_bfd, + elf32_arm_plt_entry_long[3] + | (got_displacement & 0x00000fff), + ptr + 12); + } } /* Fill in the entry in the .rel(a).(i)plt section. */ diff --git a/ld/emultempl/armelf.em b/ld/emultempl/armelf.em index 85e924f..ce3d688 100644 --- a/ld/emultempl/armelf.em +++ b/ld/emultempl/armelf.em @@ -531,6 +531,7 @@ PARSE_AND_LIST_PROLOGUE=' #define OPTION_NO_MERGE_EXIDX_ENTRIES 316 #define OPTION_FIX_ARM1176 317 #define OPTION_NO_FIX_ARM1176 318 +#define OPTION_LONG_PLT 319 ' PARSE_AND_LIST_SHORTOPTS=p @@ -555,6 +556,7 @@ PARSE_AND_LIST_LONGOPTS=' { "no-merge-exidx-entries", no_argument, NULL, OPTION_NO_MERGE_EXIDX_ENTRIES }, { "fix-arm1176", no_argument, NULL, OPTION_FIX_ARM1176 }, { "no-fix-arm1176", no_argument, NULL, OPTION_NO_FIX_ARM1176 }, + { "long-plt", no_argument, NULL, OPTION_LONG_PLT }, ' PARSE_AND_LIST_OPTIONS=' @@ -572,6 +574,8 @@ PARSE_AND_LIST_OPTIONS=' fprintf (file, _(" --no-wchar-size-warning Don'\''t warn about objects with incompatible\n" " wchar_t sizes\n")); fprintf (file, _(" --pic-veneer Always generate PIC interworking veneers\n")); + fprintf (file, _(" --long-plt Generate long .plt entries\n" + " to handle large .plt/.got displacements\n")); fprintf (file, _("\ --stub-group-size=N Maximum size of a group of input sections that\n\ can be handled by one stub section. A negative\n\ @@ -675,6 +679,10 @@ PARSE_AND_LIST_ARGS_CASES=' case OPTION_NO_FIX_ARM1176: fix_arm1176 = 0; break; + + case OPTION_LONG_PLT: + bfd_elf32_arm_use_long_plt (); + break; ' # We have our own before_allocation etc. functions, but they call diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp index 4c0f802..cea18fa 100644 --- a/ld/testsuite/ld-arm/arm-elf.exp +++ b/ld/testsuite/ld-arm/arm-elf.exp @@ -188,6 +188,10 @@ set armelftests_common { "" {exec-got-1b.s} {{readelf --relocs exec-got-1.d}} "exec-got-1"} + {"Long PLT entries in executables" "--long-plt -shared --section-start=.plt=0x200 --section-start=.got=0xf0000300" "" + "" {long-plt-format.s} + {{objdump "-d -j .plt" long-plt-format.d}} + "long-plt-format"} {"abs call" "-T arm.ld" "" "" {abs-call-1.s} {{objdump -d abs-call-1.d}} "abs-call-1"} diff --git a/ld/testsuite/ld-arm/long-plt-format.d b/ld/testsuite/ld-arm/long-plt-format.d index e69de29..c08cb71 100644 --- a/ld/testsuite/ld-arm/long-plt-format.d +++ b/ld/testsuite/ld-arm/long-plt-format.d @@ -0,0 +1,15 @@ +.*: file format elf32-.* + + +Disassembly of section .plt: + +00000200 <.plt>: + 200: .* + 204: .* + 208: .* + 20c: .* + 210: .* .word .* + 214: .* add ip, pc, #-268435456 ; 0xf0000000 + 218: .* add ip, ip, #0, 12 + 21c: .* add ip, ip, #0, 20 + 220: .* ldr pc, [ip, #[0-9]*]! ; 0x.* diff --git a/ld/testsuite/ld-arm/long-plt-format.s b/ld/testsuite/ld-arm/long-plt-format.s index e69de29..bb0c3a2 100644 --- a/ld/testsuite/ld-arm/long-plt-format.s +++ b/ld/testsuite/ld-arm/long-plt-format.s @@ -0,0 +1,7 @@ + .globl _start + .type _start,%function + .globl foo +_start: + bl foo(PLT) + .size _start,.-_start + --------------010900020208010706030004--