diff options
author | Tom de Vries <tdevries@suse.de> | 2023-11-01 00:33:12 +0100 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2023-11-01 00:33:12 +0100 |
commit | 98ef1d81d6a3970f07e98216f31c89ec77997095 (patch) | |
tree | 9f809d59ee7108324f805293a085a48c6ee6991b | |
parent | 87e3cc466e8ea352639beb6db40a36e339d608d1 (diff) | |
download | gdb-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.c | 4 | ||||
-rw-r--r-- | gdb/producer.c | 56 | ||||
-rw-r--r-- | gdb/producer.h | 5 |
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); |