From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-il1-x12f.google.com (mail-il1-x12f.google.com [IPv6:2607:f8b0:4864:20::12f]) by sourceware.org (Postfix) with ESMTPS id BA4063858D34 for ; Mon, 27 May 2024 06:50:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org BA4063858D34 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org BA4063858D34 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::12f ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716792644; cv=none; b=f6vADsO4S+Kse9OXFHZNfy8BXl3KxLQb8vbbsZmSfXtJ8N4jsRXd1x+ROOOBuA8hylvxDVyqvxFSxQTeNd+QmJoyO6XG3SceJFqqpcHKpfmVSId345OKfGAI3v0JaktasfAQ1hO3iBr74d7Ve7B/0MuXJo2JeErBC8K/fur6F6Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1716792644; c=relaxed/simple; bh=iZsAV97iiDNlMVni+dSlxIRfu1PJxX/7pxuIDS0OBgE=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=JRLtoF6HBDpbaEaNJbtK6n8SU0lpe3GvIFr/tMT5zAMTB6EcGVufyKj95LI7NjHpYGIBsQnxp1djfZDpkyu7Ur665Oi+SLXxQfLW3sWw38/n+FXXiFfbrkIv11ulu3Gay0BelJnOqOX6gJ0pFjlnkvC/n1EIgBRvidougBvOmYI= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-il1-x12f.google.com with SMTP id e9e14a558f8ab-3737b412ad6so13241395ab.2 for ; Sun, 26 May 2024 23:50:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1716792640; x=1717397440; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Ny4fMmeFSCZU7dwm15M2h0EdZbEbCYNHpHvSC/2nNbY=; b=azJSswNr627WRlCF8Eo/LUMlgYnfq063S5TwCdqCIWCpZ5GOOkDt1wHw9NqPip59k0 91MhTOejMjBTbivfkYu9V01cZpgtF/tRUQQJeV+RsDHsS821Pcf4Ozlg1PYHUIkbtitc XbrlVKOLzQgmgtICfr2bzsCSFXFiQhWNp1x/OptyzjkgLwrgtyqdFSTQhJ/1xytakkQu Y0ZDnnj0mrCfe29pkNrMPM37kgpVKBFfVocDTDk0aOUuUVhccgfysgSiaMCeI+ar43ut GCj8JV1B77hJccRX16AQKMYHo+C2ghTaU+WWUC/6Ii2sOIfFxQgf/9jS/M8ae+D1SKen i/vw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1716792640; x=1717397440; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ny4fMmeFSCZU7dwm15M2h0EdZbEbCYNHpHvSC/2nNbY=; b=f8+pAPI7VHRXkM3G7esu5lXR73adnLYYuxclDSpt4gQcq2ePAO29KJH23aUMBolgqP w8mT/RmvY4l+GKeNYKc8Dx6/5zmyLlpTntu8gmJEaB1YUv35BVChYPbZ5g0UnwMHOMAP C0XFlvvuFXVDMf42JJfKXiwguHI2bETNkP3uIb5pK564l0VTggl0guAY7qgHYmqjCscO 3TuDynpi69Y/e946rlGgwZJvp4Z1YJ9T3oCxErs9OOPScRyaRSN8iGl6yKAxdTDlhZ/S Ys8FWQvIgVWfAc/6sCeXmys3B+uBLRbiB3K3D0UklLmyW5mFLZ7z/8u1orQwsZKb4EL2 A/yQ== X-Gm-Message-State: AOJu0YxN1/EDDFFXy+emWkHSw9Md8RfdBbbvgZ3HYubT1eDdqSBPFVW4 uAnEBjsnjuQ9rfvfjJJKBQPU58VJtlqZuGNRAU1u0MHZJQE1UY+Yd7Qk7w== X-Google-Smtp-Source: AGHT+IFFCvX2MdMgiqC1oSUYFE6QJtz1Z1J/AqnPcmoAfnWC/KMX2h3eqKykP7x9f0ac24wR01euHg== X-Received: by 2002:a05:6e02:20c9:b0:374:5caa:cee4 with SMTP id e9e14a558f8ab-3745caaea0emr7631025ab.12.1716792640511; Sun, 26 May 2024 23:50:40 -0700 (PDT) Received: from octofox.hsd1.ca.comcast.net ([2601:646:a200:bbd0:7323:fdbe:3f9:3274]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-682271d783esm5411226a12.76.2024.05.26.23.50.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 26 May 2024 23:50:39 -0700 (PDT) From: Max Filippov To: gcc-patches@gcc.gnu.org Cc: Ian Lance Taylor , Max Filippov Subject: [RFC 1/2] libbacktrace: add FDPIC support Date: Sun, 26 May 2024 23:50:25 -0700 Message-Id: <20240527065026.855607-2-jcmvbkbc@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240527065026.855607-1-jcmvbkbc@gmail.com> References: <20240527065026.855607-1-jcmvbkbc@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-8.8 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,FROM_LOCAL_NOVOWEL,GIT_PATCH_0,HK_RANDOM_ENVFROM,HK_RANDOM_FROM,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE 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: Instead of a single base address FDPIC ELF files use load map: a structure with an array of mappings for individual segments. Change libbacktrace functions and structures to support that. libbacktrace/ PR libbacktrace/114941 * dwarf.c: Include or if available. (struct dwarf_data): Change base_address type to base_address_type. (add_low_high_range): Change base_address argument type to base_address_type. Use __RELOC_UINTPTR for lowpc and highpc calculation. (add_ranges_from_ranges): Change base_address argument type to base_address_type. Use __RELOC_UINTPTR to calculate arguments for add_range(). (add_ranges_from_rnglists): Change base_address argument type to base_address_type. Use __RELOC_UINTPTR to calculate arguments for add_range(). Use __RELOC_UINTPTR for low calculation. (add_ranges, find_address_ranges, build_address_map): Change base_address argument type to base_address_type. (add_line): Use __RELOC_UINTPTR for ln->pc calculation. (build_dwarf_data, backtrace_dwarf_add): Change base_address argument type to base_address_type. * elf.c (elf_initialize_syminfo): Change base_address argument type to base_address_type. Use __RELOC_UINTPTR for elf_symbols[j].address calculation. (elf_add): Change base_address argument type to base_address_type. Do early return -1 in case of FDPIC executable, update corresponding comment. (backtrace_initialize): Change NULL base address parameter in the add_elf() call to no_base_address. * internal.h (base_address_type, __RELOC_POINTER) (__RELOC_UINTPTR, no_base_address): New definitions. (backtrace_dwarf_add): Change base_address argument type to base_address_type. --- libbacktrace/dwarf.c | 60 ++++++++++++++++++++++++----------------- libbacktrace/elf.c | 20 +++++++++----- libbacktrace/internal.h | 14 +++++++++- 3 files changed, 62 insertions(+), 32 deletions(-) diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c index ed0672964c24..bcab23562e2a 100644 --- a/libbacktrace/dwarf.c +++ b/libbacktrace/dwarf.c @@ -43,6 +43,15 @@ POSSIBILITY OF SUCH DAMAGE. */ #include "backtrace.h" #include "internal.h" +#ifdef __FDPIC__ + #ifdef HAVE_LINK_H + #include + #endif + #ifdef HAVE_SYS_LINK_H + #include + #endif +#endif + #if !defined(HAVE_DECL_STRNLEN) || !HAVE_DECL_STRNLEN /* If strnlen is not declared, provide our own version. */ @@ -389,7 +398,7 @@ struct dwarf_data /* The data for .gnu_debugaltlink. */ struct dwarf_data *altlink; /* The base address for this file. */ - uintptr_t base_address; + base_address_type base_address; /* A sorted list of address ranges. */ struct unit_addrs *addrs; /* Number of address ranges in list. */ @@ -1610,7 +1619,7 @@ update_pcrange (const struct attr* attr, const struct attr_val* val, static int add_low_high_range (struct backtrace_state *state, const struct dwarf_sections *dwarf_sections, - uintptr_t base_address, int is_bigendian, + base_address_type base_address, int is_bigendian, struct unit *u, const struct pcrange *pcrange, int (*add_range) (struct backtrace_state *state, void *rdata, uintptr_t lowpc, @@ -1646,8 +1655,8 @@ add_low_high_range (struct backtrace_state *state, /* Add in the base address of the module when recording PC values, so that we can look up the PC directly. */ - lowpc += base_address; - highpc += base_address; + lowpc = __RELOC_UINTPTR (lowpc, base_address); + highpc = __RELOC_UINTPTR (highpc, base_address); return add_range (state, rdata, lowpc, highpc, error_callback, data, vec); } @@ -1659,7 +1668,7 @@ static int add_ranges_from_ranges ( struct backtrace_state *state, const struct dwarf_sections *dwarf_sections, - uintptr_t base_address, int is_bigendian, + base_address_type base_address, int is_bigendian, struct unit *u, uintptr_t base, const struct pcrange *pcrange, int (*add_range) (struct backtrace_state *state, void *rdata, @@ -1706,8 +1715,8 @@ add_ranges_from_ranges ( else { if (!add_range (state, rdata, - (uintptr_t) low + base + base_address, - (uintptr_t) high + base + base_address, + __RELOC_UINTPTR (low + base, base_address), + __RELOC_UINTPTR (high + base, base_address), error_callback, data, vec)) return 0; } @@ -1726,7 +1735,7 @@ static int add_ranges_from_rnglists ( struct backtrace_state *state, const struct dwarf_sections *dwarf_sections, - uintptr_t base_address, int is_bigendian, + base_address_type base_address, int is_bigendian, struct unit *u, uintptr_t base, const struct pcrange *pcrange, int (*add_range) (struct backtrace_state *state, void *rdata, @@ -1809,9 +1818,9 @@ add_ranges_from_rnglists ( u->addrsize, is_bigendian, index, error_callback, data, &high)) return 0; - if (!add_range (state, rdata, low + base_address, - high + base_address, error_callback, data, - vec)) + if (!add_range (state, rdata, __RELOC_UINTPTR (low, base_address), + __RELOC_UINTPTR (high, base_address), + error_callback, data, vec)) return 0; } break; @@ -1828,7 +1837,7 @@ add_ranges_from_rnglists ( error_callback, data, &low)) return 0; length = read_uleb128 (&rnglists_buf); - low += base_address; + low = __RELOC_UINTPTR (low, base_address); if (!add_range (state, rdata, low, low + length, error_callback, data, vec)) return 0; @@ -1842,8 +1851,9 @@ add_ranges_from_rnglists ( low = read_uleb128 (&rnglists_buf); high = read_uleb128 (&rnglists_buf); - if (!add_range (state, rdata, low + base + base_address, - high + base + base_address, + if (!add_range (state, rdata, + __RELOC_UINTPTR (low + base, base_address), + __RELOC_UINTPTR (high + base, base_address), error_callback, data, vec)) return 0; } @@ -1860,9 +1870,9 @@ add_ranges_from_rnglists ( low = (uintptr_t) read_address (&rnglists_buf, u->addrsize); high = (uintptr_t) read_address (&rnglists_buf, u->addrsize); - if (!add_range (state, rdata, low + base_address, - high + base_address, error_callback, data, - vec)) + if (!add_range (state, rdata, __RELOC_UINTPTR (low, base_address), + __RELOC_UINTPTR (high, base_address), + error_callback, data, vec)) return 0; } break; @@ -1874,7 +1884,7 @@ add_ranges_from_rnglists ( low = (uintptr_t) read_address (&rnglists_buf, u->addrsize); length = (uintptr_t) read_uleb128 (&rnglists_buf); - low += base_address; + low = __RELOC_UINTPTR (low, base_address); if (!add_range (state, rdata, low, low + length, error_callback, data, vec)) return 0; @@ -1902,7 +1912,7 @@ add_ranges_from_rnglists ( static int add_ranges (struct backtrace_state *state, const struct dwarf_sections *dwarf_sections, - uintptr_t base_address, int is_bigendian, + base_address_type base_address, int is_bigendian, struct unit *u, uintptr_t base, const struct pcrange *pcrange, int (*add_range) (struct backtrace_state *state, void *rdata, uintptr_t lowpc, uintptr_t highpc, @@ -1938,7 +1948,8 @@ add_ranges (struct backtrace_state *state, read, 0 if there is some error. */ static int -find_address_ranges (struct backtrace_state *state, uintptr_t base_address, +find_address_ranges (struct backtrace_state *state, + base_address_type base_address, struct dwarf_buf *unit_buf, const struct dwarf_sections *dwarf_sections, int is_bigendian, struct dwarf_data *altlink, @@ -2093,7 +2104,8 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address, on success, 0 on failure. */ static int -build_address_map (struct backtrace_state *state, uintptr_t base_address, +build_address_map (struct backtrace_state *state, + base_address_type base_address, const struct dwarf_sections *dwarf_sections, int is_bigendian, struct dwarf_data *altlink, backtrace_error_callback error_callback, void *data, @@ -2312,7 +2324,7 @@ add_line (struct backtrace_state *state, struct dwarf_data *ddata, /* Add in the base address here, so that we can look up the PC directly. */ - ln->pc = pc + ddata->base_address; + ln->pc = __RELOC_UINTPTR (pc, ddata->base_address); ln->filename = filename; ln->lineno = lineno; @@ -3951,7 +3963,7 @@ dwarf_fileline (struct backtrace_state *state, uintptr_t pc, static struct dwarf_data * build_dwarf_data (struct backtrace_state *state, - uintptr_t base_address, + base_address_type base_address, const struct dwarf_sections *dwarf_sections, int is_bigendian, struct dwarf_data *altlink, @@ -4009,7 +4021,7 @@ build_dwarf_data (struct backtrace_state *state, int backtrace_dwarf_add (struct backtrace_state *state, - uintptr_t base_address, + base_address_type base_address, const struct dwarf_sections *dwarf_sections, int is_bigendian, struct dwarf_data *fileline_altlink, diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c index 3cd87020b031..c2d18b4a398e 100644 --- a/libbacktrace/elf.c +++ b/libbacktrace/elf.c @@ -633,7 +633,7 @@ elf_symbol_search (const void *vkey, const void *ventry) static int elf_initialize_syminfo (struct backtrace_state *state, - uintptr_t base_address, + base_address_type base_address, const unsigned char *symtab_data, size_t symtab_size, const unsigned char *strtab, size_t strtab_size, backtrace_error_callback error_callback, @@ -699,7 +699,7 @@ elf_initialize_syminfo (struct backtrace_state *state, = *(const b_elf_addr *) (opd->data + (sym->st_value - opd->addr)); else elf_symbols[j].address = sym->st_value; - elf_symbols[j].address += base_address; + elf_symbols[j].address = __RELOC_UINTPTR (elf_symbols[j].address, base_address); elf_symbols[j].size = sym->st_size; ++j; } @@ -6506,7 +6506,7 @@ backtrace_uncompress_lzma (struct backtrace_state *state, static int elf_add (struct backtrace_state *state, const char *filename, int descriptor, const unsigned char *memory, size_t memory_size, - uintptr_t base_address, struct elf_ppc64_opd_data *caller_opd, + base_address_type base_address, struct elf_ppc64_opd_data *caller_opd, backtrace_error_callback error_callback, void *data, fileline *fileline_fn, int *found_sym, int *found_dwarf, struct dwarf_data **fileline_entry, int exe, int debuginfo, @@ -6636,9 +6636,15 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, /* If the executable is ET_DYN, it is either a PIE, or we are running directly a shared library with .interp. We need to wait for - dl_iterate_phdr in that case to determine the actual base_address. */ + dl_iterate_phdr in that case to determine the actual base_address. + In case of FDPIC we always need the actual base_address. */ +#ifndef __FDPIC__ if (exe && ehdr.e_type == ET_DYN) return -1; +#else + if (exe) + return -1; +#endif shoff = ehdr.e_shoff; shnum = ehdr.e_shnum; @@ -7413,9 +7419,9 @@ backtrace_initialize (struct backtrace_state *state, const char *filename, fileline elf_fileline_fn = elf_nodebug; struct phdr_data pd; - ret = elf_add (state, filename, descriptor, NULL, 0, 0, NULL, error_callback, - data, &elf_fileline_fn, &found_sym, &found_dwarf, NULL, 1, 0, - NULL, 0); + ret = elf_add (state, filename, descriptor, NULL, 0, no_base_address, NULL, + error_callback, data, &elf_fileline_fn, &found_sym, + &found_dwarf, NULL, 1, 0, NULL, 0); if (!ret) return 0; diff --git a/libbacktrace/internal.h b/libbacktrace/internal.h index 4fa0af8cb6c9..456911166026 100644 --- a/libbacktrace/internal.h +++ b/libbacktrace/internal.h @@ -323,10 +323,22 @@ struct dwarf_sections struct dwarf_data; +#if defined (HAVE_DL_ITERATE_PHDR) && defined (__FDPIC__) +typedef struct elf32_fdpic_loadaddr base_address_type; +#define __RELOC_UINTPTR(ptr, base) ((uintptr_t)__RELOC_POINTER (ptr, base)) +#define no_base_address ((struct elf32_fdpic_loadaddr){0}) +#else +typedef uintptr_t base_address_type; +#define __RELOC_POINTER(ptr, base) ((ptr) + (base)) +#define __RELOC_UINTPTR(ptr, base) ((uintptr_t)__RELOC_POINTER (ptr, base)) +#define no_base_address ((uintptr_t)0) +#endif + + /* Add file/line information for a DWARF module. */ extern int backtrace_dwarf_add (struct backtrace_state *state, - uintptr_t base_address, + base_address_type base_address, const struct dwarf_sections *dwarf_sections, int is_bigendian, struct dwarf_data *fileline_altlink, -- 2.39.2