aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2023-11-01 00:33:12 +0100
committerTom de Vries <tdevries@suse.de>2023-11-01 00:33:12 +0100
commit98ef1d81d6a3970f07e98216f31c89ec77997095 (patch)
tree9f809d59ee7108324f805293a085a48c6ee6991b
parent87e3cc466e8ea352639beb6db40a36e339d608d1 (diff)
downloadgdb-98ef1d81d6a3970f07e98216f31c89ec77997095.zip
gdb-98ef1d81d6a3970f07e98216f31c89ec77997095.tar.gz
gdb-98ef1d81d6a3970f07e98216f31c89ec77997095.tar.bz2
[gdb/symtab] Add producer_is_gas
Add producer_is_gas, a generic way to get the gas version from the producer string. Tested on x86_64-linux.
-rw-r--r--gdb/dwarf2/read.c4
-rw-r--r--gdb/producer.c56
-rw-r--r--gdb/producer.h5
3 files changed, 63 insertions, 2 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 66669e2..bd43b5b 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -11250,8 +11250,8 @@ check_producer (struct dwarf2_cu *cu)
cu->producer_is_codewarrior = true;
else if (producer_is_clang (cu->producer, &major, &minor))
cu->producer_is_clang = true;
- else if (startswith (cu->producer, "GNU AS 2.39.0"))
- cu->producer_is_gas_2_39 = true;
+ else if (producer_is_gas (cu->producer, &major, &minor))
+ cu->producer_is_gas_2_39 = major == 2 && minor == 39;
else
{
/* For other non-GCC compilers, expect their behavior is DWARF version
diff --git a/gdb/producer.c b/gdb/producer.c
index 9fcf749..cd83dfc 100644
--- a/gdb/producer.c
+++ b/gdb/producer.c
@@ -82,6 +82,45 @@ producer_is_gcc (const char *producer, int *major, int *minor)
/* See producer.h. */
bool
+producer_is_gas (const char *producer, int *major, int *minor)
+{
+ if (producer == nullptr)
+ {
+ /* No producer, don't know. */
+ return false;
+ }
+
+ /* Detect prefix. */
+ const char prefix[] = "GNU AS ";
+ if (!startswith (producer, prefix))
+ {
+ /* Producer is not gas. */
+ return false;
+ }
+
+ /* Skip prefix. */
+ const char *cs = &producer[strlen (prefix)];
+
+ /* Ensure that major/minor are not nullptrs. */
+ int maj, min;
+ if (major == nullptr)
+ major = &maj;
+ if (minor == nullptr)
+ minor = &min;
+
+ int scanned = sscanf (cs, "%d.%d", major, minor);
+ if (scanned != 2)
+ {
+ /* Unable to scan major/minor version. */
+ return false;
+ }
+
+ return true;
+}
+
+ /* See producer.h. */
+
+bool
producer_is_icc_ge_19 (const char *producer)
{
int major, minor;
@@ -251,6 +290,23 @@ Version 18.0 Beta";
SELF_CHECK (!producer_is_gcc (flang_llvm_exp, &major, &minor));
SELF_CHECK (producer_is_llvm (flang_llvm_exp));
}
+
+ {
+ static const char gas_exp[] = "GNU AS 2.39.0";
+ int major = 0, minor = 0;
+ SELF_CHECK (!producer_is_gcc (gas_exp, &major, &minor));
+ SELF_CHECK (producer_is_gas (gas_exp, &major, &minor));
+ SELF_CHECK (major == 2 && minor == 39);
+
+ static const char gas_incomplete_exp[] = "GNU AS ";
+ SELF_CHECK (!producer_is_gas (gas_incomplete_exp, &major, &minor));
+ SELF_CHECK (!producer_is_gcc (gas_incomplete_exp, &major, &minor));
+
+ static const char gas_incomplete_exp_2[] = "GNU AS 2";
+ SELF_CHECK (!producer_is_gas (gas_incomplete_exp_2, &major, &minor));
+ SELF_CHECK (!producer_is_gcc (gas_incomplete_exp_2, &major, &minor));
+ }
+
}
}
}
diff --git a/gdb/producer.h b/gdb/producer.h
index c915979..0071851 100644
--- a/gdb/producer.h
+++ b/gdb/producer.h
@@ -30,6 +30,11 @@ extern int producer_is_gcc_ge_4 (const char *producer);
is NULL or it isn't GCC. */
extern int producer_is_gcc (const char *producer, int *major, int *minor);
+/* Returns nonzero if the given PRODUCER string is GAS and sets the MAJOR
+ and MINOR versions when not NULL. Returns zero if the given PRODUCER
+ is NULL or it isn't GAS. */
+bool producer_is_gas (const char *producer, int *major, int *minor);
+
/* Check for Intel compilers >= 19.0. */
extern bool producer_is_icc_ge_19 (const char *producer);