From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by sourceware.org (Postfix) with ESMTPS id 59DEF3858D1E for ; Fri, 13 Oct 2023 08:02:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 59DEF3858D1E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com Received: by mail-wm1-x332.google.com with SMTP id 5b1f17b1804b1-40572aeb73cso19416705e9.3 for ; Fri, 13 Oct 2023 01:02:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adacore.com; s=google; t=1697184174; x=1697788974; darn=sourceware.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=BnaYN/Mm5cAUOoo2d+dw71ZKXdhhFhj6Q1RHutR/4uk=; b=RYvxQvoxxpOSpF/iTGL5fEC7wHE8xoNeCLjSKYMEINE6KB4CWty6BShioSiIpH4O2G p5azR67mGBhpoP31ui3OOeKq0rPs1XWh2UNVQo5jRcOCAdWv+MxUYE/f27HwVhY0ovEo zcJ5v+t8WSli+YSpGsvr7JlZDMS07hm3MkZdYu5RNzu0Nbhylw39Ky5iQZrLZkzWlcT/ TdAQKEzPedB33nWyOYNRT056TTLeAfrX3iQfXhT1CpH35e0+X65EOnM1DQJX0IyCytAX PfspfCf5ApCod5VKj0tLIUtbR1LS73on3JoqgJoINLk0zKdGX1f351cLFnpx9xnurlS0 +zwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697184174; x=1697788974; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=BnaYN/Mm5cAUOoo2d+dw71ZKXdhhFhj6Q1RHutR/4uk=; b=OsJLiU8lwL8SpMUkG4RNBRBLqIvRX46dK5jXePJdW4vcvHxed46aNz7RWzh9MH0l6Y MBMdRT0+SrqLppt3Q2RkEUwV44p8jw6shao6O60wy5SQIlr38jfBxQfxv+MnH7J1znWH esLS1tlzte1H7zkRbj9CydQs1mdlwWXFzsppxSkh0XfPnm/AqfEuk7stVvwX0HzFd3YU XydtJ7hatJl4VKLQMqwxwZs86/d+zUcppe1fix6tcHYdHb2b0fYtpEh4H7TY9C0D9Bv1 KlLeI3zneXtZ/Y2YF1RZRiIYKx+sf/WLcvOng8q3r7DCz2q+7KiT0e3jFmfuqmURWIno mY/A== X-Gm-Message-State: AOJu0YwsTR0DjploPBG0TssaPEntwk2eIgayIl/+nVB4tW4+XDRizKR8 MNZlAMmX5SNMpQHpUmxwLf5qXnwgTG36uCBqh9s= X-Google-Smtp-Source: AGHT+IFHt7rTHlFN51H1DdZl3902wI+Mwm7cIUtnCF6johEeaGZtyj/MshVuLHweJln5VUW94oZegQ== X-Received: by 2002:a05:600c:224a:b0:3fe:dcd0:2e32 with SMTP id a10-20020a05600c224a00b003fedcd02e32mr22581743wmm.19.1697184173490; Fri, 13 Oct 2023 01:02:53 -0700 (PDT) Received: from chigot-Dell.home ([2a01:cb15:8123:8100:139e:8567:6548:d211]) by smtp.gmail.com with ESMTPSA id p24-20020a05600c205800b00401d8181f8bsm1817917wmg.25.2023.10.13.01.02.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 13 Oct 2023 01:02:53 -0700 (PDT) From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= To: binutils@sourceware.org Cc: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= Subject: [PATCH 1/3] ld: allow update of existing QNX stack note Date: Fri, 13 Oct 2023 10:02:46 +0200 Message-Id: <20231013080248.219837-1-chigot@adacore.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-12.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Up to now, the linker would always create a QNX stack note from scratch. However, object files could already have such note, ending up into duplicates. QNX loader doesn't handle that. Update the mechanism to first search through the input files for a .note section holding a QNX stack note. If none are found, then a new section is created into the stub file as before. This requires this search to be done once the file have been opened, moving the whole logic a bit later in the emulation process. As part for this update, also allow to request an executable stack without necessarily having to provide its size as well. In this case, s etup a default lazy stack of 0x1000. ld/ChangeLog: * emultempl/nto.em (nto_create_QNX_note_section): New Function. (nto_lookup_QNX_note_section): New Function. (nto_add_note_section): Move the creation of the note section in the above new functions. (nto_create_output_section_statements): rename nto_after_open * testsuite/ld-aarch64/aarch64-nto.exp: add new test. * testsuite/ld-aarch64/nto-stack-note-3.d: New test. * testsuite/ld-aarch64/nto-stack-note.s: New test. --- ld/emultempl/nto.em | 121 +++++++++++++++------ ld/testsuite/ld-aarch64/aarch64-nto.exp | 1 + ld/testsuite/ld-aarch64/nto-stack-note-3.d | 12 ++ ld/testsuite/ld-aarch64/nto-stack-note.s | 14 +++ 4 files changed, 116 insertions(+), 32 deletions(-) create mode 100644 ld/testsuite/ld-aarch64/nto-stack-note-3.d create mode 100644 ld/testsuite/ld-aarch64/nto-stack-note.s diff --git a/ld/emultempl/nto.em b/ld/emultempl/nto.em index b38fddd251c..0d319acc9bf 100644 --- a/ld/emultempl/nto.em +++ b/ld/emultempl/nto.em @@ -39,31 +39,20 @@ struct nto_stack_note unsigned char execstack[4]; }; -/* Generate the QNT_STACK .note section. */ -static void -nto_add_note_section (void) { +static asection* +nto_create_QNX_note_section(int type) +{ asection *note_sec; flagword flags; Elf_External_Note *e_note; - bfd_size_type size, h_size; - struct nto_stack_note *n_note; - - /* Don't create a note if the stack size isn't provided. */ - if (link_info.stacksize <= 0) - return; + bfd_size_type size; /* As ${ARCH}elf.em is imported and ${ARCH}_elf_create_output_section_statements is called before this function, stub_file should already be defined. */ if (!stub_file) { einfo (_("%F%P: cannot create .note section in stub BFD.\n")); - return; - } - - if (nto_lazy_stack && !link_info.stacksize) - { - einfo (_("%F%P: error: --lazy-stack must follow -zstack-size=\n")); - return; + return NULL; } flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS @@ -72,12 +61,11 @@ nto_add_note_section (void) { if (! note_sec) { einfo (_("%F%P: failed to create .note section\n")); - return; + return NULL; } size = offsetof (Elf_External_Note, name[sizeof "QNX"]); size = (size + 3) & -(bfd_size_type) 4; - h_size = size; size += sizeof (struct nto_stack_note); note_sec->size = size; @@ -86,31 +74,100 @@ nto_add_note_section (void) { e_note = (Elf_External_Note *) note_sec->contents; bfd_h_put_32 (stub_file->the_bfd, sizeof "QNX", &e_note->namesz); bfd_h_put_32 (stub_file->the_bfd, sizeof (struct nto_stack_note), &e_note->descsz); - bfd_h_put_32 (stub_file->the_bfd, QNT_STACK, &e_note->type); + bfd_h_put_32 (stub_file->the_bfd, type, &e_note->type); memcpy (e_note->name, "QNX", sizeof "QNX"); + return note_sec; +} - /* Generate .note content.*/ - n_note = (struct nto_stack_note *) (note_sec->contents + h_size); - bfd_h_put_32 (stub_file->the_bfd, link_info.stacksize, &n_note->stacksize); +/* Lookup for a section holding a QNX note or create a new section. */ +static asection* +nto_lookup_QNX_note_section(int type) +{ + asection *stack_note_sec = NULL; + bfd *abfd; + for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next) + { + Elf_External_Note *e_note; + asection *sec; + + /* QNX notes are held under a note section simply named ".note". */ + sec = bfd_get_section_by_name (abfd, ".note"); + if (!sec) + continue; + + /* Verify that this is a QNX note of the expected type. */ + sec->contents = bfd_malloc(sec->size); + if (!bfd_get_section_contents (sec->owner, sec, sec->contents, (file_ptr) 0, + sec->size)) + einfo (_("%F%P: %pB: can't read contents of section .note: %E\n"), + sec->owner); + + e_note = (Elf_External_Note *) sec->contents; + if (! strcmp("QNX", e_note->name) && *e_note->type == type) + { + stack_note_sec = sec; + /* Allow modification of this .note content. */ + stack_note_sec->flags |= SEC_IN_MEMORY; + break; + } + } - if (nto_lazy_stack) - bfd_h_put_32 (stub_file->the_bfd, 4096, &n_note->stackalloc); + if (stack_note_sec) + return stack_note_sec; else - bfd_h_put_32 (stub_file->the_bfd, link_info.stacksize, &n_note->stackalloc); + return nto_create_QNX_note_section(type); - if (link_info.execstack != link_info.noexecstack && link_info.execstack) - bfd_h_put_32 (stub_file->the_bfd, 0, &n_note->execstack); - else - bfd_h_put_32 (stub_file->the_bfd, 1, &n_note->execstack); +} + +/* Generate the QNX stack .note section. */ +static void +nto_add_note_section (void) { + asection *note_sec; + struct nto_stack_note *n_note; + bfd_size_type h_size; + bool is_update = false; + /* Don't create a note if none of the stack parameter have to be modified. */ + if (link_info.stacksize <= 0 && (link_info.execstack == link_info.noexecstack)) + return; + + if (nto_lazy_stack && !link_info.stacksize) + { + einfo (_("%F%P: error: --lazy-stack must follow -zstack-size=\n")); + return; + } + + note_sec = nto_lookup_QNX_note_section(QNT_STACK); + if (! note_sec) + return; + + /* Update QNX stack note content. */ + h_size = note_sec->size - sizeof(struct nto_stack_note); + n_note = (struct nto_stack_note *) (note_sec->contents + h_size); + is_update = note_sec->owner != stub_file->the_bfd; + + if (link_info.stacksize > 0) + bfd_h_put_32 (note_sec->owner, link_info.stacksize, &n_note->stacksize); + else if (!is_update) + bfd_h_put_32 (note_sec->owner, 0, &n_note->stacksize); + + if (nto_lazy_stack || (!is_update && link_info.stacksize <= 0)) + bfd_h_put_32 (note_sec->owner, 4096, &n_note->stackalloc); + else if (link_info.stacksize > 0) + bfd_h_put_32 (note_sec->owner, link_info.stacksize, &n_note->stackalloc); + + if (link_info.execstack) + bfd_h_put_32 (note_sec->owner, 0, &n_note->execstack); + else if (!is_update || link_info.noexecstack) + bfd_h_put_32 (note_sec->owner, 1, &n_note->execstack); } static void -nto_create_output_section_statements (void) +nto_after_open (void) { - ${ARCH}_elf_create_output_section_statements (); nto_add_note_section(); + gld${EMULATION_NAME}_after_open (); } EOF @@ -160,4 +217,4 @@ PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}' # Put these extra Neutrino routines in ld_${EMULATION_NAME}_emulation # -LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=nto_create_output_section_statements +LDEMUL_AFTER_OPEN=nto_after_open diff --git a/ld/testsuite/ld-aarch64/aarch64-nto.exp b/ld/testsuite/ld-aarch64/aarch64-nto.exp index 4fd6245e9a2..256eb0da10e 100644 --- a/ld/testsuite/ld-aarch64/aarch64-nto.exp +++ b/ld/testsuite/ld-aarch64/aarch64-nto.exp @@ -26,3 +26,4 @@ if { ![istarget "aarch64*-*-nto*"] } { run_dump_test "nto-stack-note-1" run_dump_test "nto-stack-note-2" +run_dump_test "nto-stack-note-3" diff --git a/ld/testsuite/ld-aarch64/nto-stack-note-3.d b/ld/testsuite/ld-aarch64/nto-stack-note-3.d new file mode 100644 index 00000000000..cdc71beeee0 --- /dev/null +++ b/ld/testsuite/ld-aarch64/nto-stack-note-3.d @@ -0,0 +1,12 @@ +#name: nto-stack-note-3 +#source: nto-stack-note.s +#as: +#ld: -z noexecstack +#readelf: -n + +Displaying notes found in: .note +[ ]+Owner[ ]+Data size[ ]+Description + QNX 0x0000000c QNX stack + Stack Size: 0x4321 + Stack allocated: 1234 + Executable: no diff --git a/ld/testsuite/ld-aarch64/nto-stack-note.s b/ld/testsuite/ld-aarch64/nto-stack-note.s new file mode 100644 index 00000000000..9e48ab8d5bc --- /dev/null +++ b/ld/testsuite/ld-aarch64/nto-stack-note.s @@ -0,0 +1,14 @@ + .global _start + .text +_start: + nop + + .section .note + .long 1f - 0f /* name length */ + .long 2f - 1f /* data length */ + .long 3 /* note type */ +0: .asciz "QNX" /* vendore name */ +1: .long 0x4321 + .long 0x1234 + .long 0x0 +2: -- 2.25.1